From fff76ee7ef007b2bb74804f165fee475e30ead0d Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Wed, 13 Jul 2011 20:10:10 +0000 Subject: [PATCH] Range checking for 16-bit immediates in ARM assembly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135071 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMInstrInfo.td | 5 ++++- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 13 +++++++++++++ test/MC/ARM/basic-arm-instructions.s | 5 ++--- test/MC/ARM/diagnostics.s | 7 ++++++- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 10410a54e66..7c0199dfeee 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -256,9 +256,12 @@ def lo16AllZero : PatLeaf<(i32 imm), [{ }], hi16>; /// imm0_65535 - An immediate is in the range [0.65535]. +def Imm0_65535AsmOperand: AsmOperandClass { let Name = "Imm0_65535"; } def imm0_65535 : Operand, ImmLeaf= 0 && Imm < 65536; -}]>; +}]> { + let ParserMatchClass = Imm0_65535AsmOperand; +} class BinOpFrag : PatFrag<(ops node:$LHS, node:$RHS), res>; class UnOpFrag : PatFrag<(ops node:$Src), res>; diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index c72b206db9e..0ce4b4c1282 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -386,6 +386,14 @@ public: int64_t Value = CE->getValue(); return Value >= 0 && Value < 256; } + bool isImm0_65535() const { + if (Kind != Immediate) + return false; + const MCConstantExpr *CE = dyn_cast(getImm()); + if (!CE) return false; + int64_t Value = CE->getValue(); + return Value >= 0 && Value < 65536; + } bool isT2SOImm() const { if (Kind != Immediate) return false; @@ -577,6 +585,11 @@ public: addExpr(Inst, getImm()); } + void addImm0_65535Operands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + addExpr(Inst, getImm()); + } + void addT2SOImmOperands(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 62339f7e597..f17fc66e1a0 100644 --- a/test/MC/ARM/basic-arm-instructions.s +++ b/test/MC/ARM/basic-arm-instructions.s @@ -316,6 +316,5 @@ _func: bkpt #10 bkpt #65535 -@ CHECK: bkpt #10 @ encoding: [0x7a,0x00,0x20,0xe1] -@ CHECK: bkpt #65535 @ encoding: [0x7f,0xff,0x2f,0xe1] - +@ CHECK: bkpt #10 @ encoding: [0x7a,0x00,0x20,0xe1] +@ CHECK: bkpt #65535 @ encoding: [0x7f,0xff,0x2f,0xe1] diff --git a/test/MC/ARM/diagnostics.s b/test/MC/ARM/diagnostics.s index dab84c1df10..bf8f1259e9f 100644 --- a/test/MC/ARM/diagnostics.s +++ b/test/MC/ARM/diagnostics.s @@ -40,4 +40,9 @@ @ CHECK-ERRORS: ^ @ CHECK-ERRORS: error: immediate shift value out of range @ CHECK-ERRORS: adc r4, r5, r6, ror #32 -@ CHECK-ERRORS: ^ + + + @ Out of range 16-bit immediate on BKPT + bkpt #65536 + +@ CHECK-ERRORS: error: invalid operand for instruction