diff options
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 14 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrThumb.td | 2 | ||||
-rw-r--r-- | lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 13 | ||||
-rw-r--r-- | test/MC/ARM/basic-arm-instructions.s | 11 | ||||
-rw-r--r-- | test/MC/ARM/diagnostics.s | 7 | ||||
-rw-r--r-- | utils/TableGen/EDEmitter.cpp | 1 |
6 files changed, 44 insertions, 4 deletions
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 83a2514..c7ed266 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -515,6 +515,15 @@ def imm0_65535_expr : Operand<i32> { let ParserMatchClass = Imm0_65535ExprAsmOperand; } +/// imm24b - True if the 32-bit immediate is encodable in 24 bits. +def Imm24bitAsmOperand: AsmOperandClass { let Name = "Imm24bit"; } +def imm24b : Operand<i32>, ImmLeaf<i32, [{ + return Imm >= 0 && Imm <= 0xffffff; +}]> { + let ParserMatchClass = Imm24bitAsmOperand; +} + + /// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield /// e.g., 0xf000ffff def bf_inv_mask_imm : Operand<i32>, @@ -1730,10 +1739,9 @@ def SMC : ABI<0b0001, (outs), (ins imm0_15:$opt), NoItinerary, "smc", "\t$opt", let Inst{3-0} = opt; } -// Supervisor Call (Software Interrupt) -- for disassembly only +// Supervisor Call (Software Interrupt) let isCall = 1, Uses = [SP] in { -def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc", - [/* For disassembly only; pattern left blank */]> { +def SVC : ABI<0b1111, (outs), (ins imm24b:$svc), IIC_Br, "svc", "\t$svc", []> { bits<24> svc; let Inst{23-0} = svc; } diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td index cb242ce..19182db 100644 --- a/lib/Target/ARM/ARMInstrThumb.td +++ b/lib/Target/ARM/ARMInstrThumb.td @@ -547,7 +547,7 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in { // A8.6.16 B: Encoding T1 // If Inst{11-8} == 0b1111 then SEE SVC let isCall = 1, Uses = [SP] in -def tSVC : T1pI<(outs), (ins i32imm:$imm), IIC_Br, +def tSVC : T1pI<(outs), (ins imm0_255:$imm), IIC_Br, "svc", "\t$imm", []>, Encoding16 { bits<8> imm; let Inst{15-12} = 0b1101; diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 39ca953..c252ce8 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -467,6 +467,14 @@ public: int64_t Value = CE->getValue(); return Value >= 0 && Value < 65536; } + bool isImm24bit() const { + if (Kind != Immediate) + return false; + const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); + if (!CE) return false; + int64_t Value = CE->getValue(); + return Value >= 0 && Value <= 0xffffff; + } bool isPKHLSLImm() const { if (Kind != Immediate) return false; @@ -738,6 +746,11 @@ public: addExpr(Inst, getImm()); } + void addImm24bitOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + addExpr(Inst, getImm()); + } + void addPKHLSLImmOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); addExpr(Inst, getImm()); diff --git a/test/MC/ARM/basic-arm-instructions.s b/test/MC/ARM/basic-arm-instructions.s index 466d16e..13afd8b 100644 --- a/test/MC/ARM/basic-arm-instructions.s +++ b/test/MC/ARM/basic-arm-instructions.s @@ -1752,3 +1752,14 @@ _func: @ CHECK: sub r6, r6, r7, asr r9 @ encoding: [0x57,0x69,0x46,0xe0] @ CHECK: sub r6, r6, r7, ror r9 @ encoding: [0x77,0x69,0x46,0xe0] + +@------------------------------------------------------------------------------ +@ SVC +@------------------------------------------------------------------------------ + svc #16 + svc #0 + svc #0xffffff + +@ CHECK: svc #16 @ encoding: [0x10,0x00,0x00,0xef] +@ CHECK: svc #0 @ encoding: [0x00,0x00,0x00,0xef] +@ CHECK: svc #16777215 @ encoding: [0xff,0xff,0xff,0xef] diff --git a/test/MC/ARM/diagnostics.s b/test/MC/ARM/diagnostics.s index afbbb36..0c51887 100644 --- a/test/MC/ARM/diagnostics.s +++ b/test/MC/ARM/diagnostics.s @@ -219,3 +219,10 @@ @ CHECK-ERRORS: warning: register not in ascending order in register list @ CHECK-ERRORS: stmda sp!, {r5, r2} @ CHECK-ERRORS: ^ + + + @ Out of range immediate on SVC + svc #0x1000000 +@ CHECK-ERRORS: error: invalid operand for instruction +@ CHECK-ERRORS: svc #0x1000000 +@ CHECK-ERRORS: ^ diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp index c9542cb..83d93cb 100644 --- a/utils/TableGen/EDEmitter.cpp +++ b/utils/TableGen/EDEmitter.cpp @@ -596,6 +596,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type, IMM("imm0_4095"); IMM("imm0_65535"); IMM("imm0_65535_expr"); + IMM("imm24b"); IMM("pkh_lsl_amt"); IMM("pkh_asr_amt"); IMM("jt2block_operand"); |