summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td14
-rw-r--r--lib/Target/ARM/ARMInstrThumb.td2
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp13
-rw-r--r--test/MC/ARM/basic-arm-instructions.s11
-rw-r--r--test/MC/ARM/diagnostics.s7
-rw-r--r--utils/TableGen/EDEmitter.cpp1
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");