Range checking for CDP[2] immediates.
authorJim Grosbach <grosbach@apple.com>
Wed, 13 Jul 2011 22:01:08 +0000 (22:01 +0000)
committerJim Grosbach <grosbach@apple.com>
Wed, 13 Jul 2011 22:01:08 +0000 (22:01 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135092 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/ARMInstrThumb.td
lib/Target/ARM/ARMInstrThumb2.td
lib/Target/ARM/AsmParser/ARMAsmParser.cpp
test/MC/ARM/basic-arm-instructions.s
test/MC/ARM/diagnostics.s
utils/TableGen/EDEmitter.cpp

index 02c9edf50740a7e266dee4898769209b909438a3..050fd9808e21c24728fd344345490c250ebffc10 100644 (file)
@@ -459,6 +459,22 @@ def arm_i32imm : PatLeaf<(imm), [{
   return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
 }]>;
 
+/// imm0_7 predicate - Immediate in the range [0,31].
+def Imm0_7AsmOperand: AsmOperandClass { let Name = "Imm0_7"; }
+def imm0_7 : Operand<i32>, ImmLeaf<i32, [{
+  return Imm >= 0 && Imm < 8;
+}]> {
+  let ParserMatchClass = Imm0_7AsmOperand;
+}
+
+/// imm0_15 predicate - Immediate in the range [0,31].
+def Imm0_15AsmOperand: AsmOperandClass { let Name = "Imm0_15"; }
+def imm0_15 : Operand<i32>, ImmLeaf<i32, [{
+  return Imm >= 0 && Imm < 16;
+}]> {
+  let ParserMatchClass = Imm0_15AsmOperand;
+}
+
 /// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
 def imm0_31 : Operand<i32>, ImmLeaf<i32, [{
   return Imm >= 0 && Imm < 32;
@@ -3465,8 +3481,8 @@ def SWPB : AIswp<1, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swpb",
 // Coprocessor Instructions.
 //
 
-def CDP : ABI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
-            c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
+def CDP : ABI<0b1110, (outs), (ins p_imm:$cop, imm0_15:$opc1,
+            c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2),
             NoItinerary, "cdp", "\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2",
             [(int_arm_cdp imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn,
                           imm:$CRm, imm:$opc2)]> {
@@ -3486,8 +3502,8 @@ def CDP : ABI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
   let Inst{23-20} = opc1;
 }
 
-def CDP2 : ABXI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
-               c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
+def CDP2 : ABXI<0b1110, (outs), (ins p_imm:$cop, imm0_15:$opc1,
+               c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2),
                NoItinerary, "cdp2\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2",
                [(int_arm_cdp2 imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn,
                               imm:$CRm, imm:$opc2)]> {
index 20a8d1207a36bc198fe95a335ee6b086aacc3bbe..db945b59c3325d051356c1711e7e2b86f279b1a8 100644 (file)
@@ -26,10 +26,6 @@ def imm_comp_XFORM : SDNodeXForm<imm, [{
   return CurDAG->getTargetConstant(~((uint32_t)N->getZExtValue()), MVT::i32);
 }]>;
 
-/// imm0_7 predicate - True if the 32-bit immediate is in the range [0,7].
-def imm0_7 : ImmLeaf<i32, [{
-  return Imm >= 0 && Imm < 8;
-}]>;
 def imm0_7_neg : PatLeaf<(i32 imm), [{
   return (uint32_t)-N->getZExtValue() < 8;
 }], imm_neg_XFORM>;
index 0d6f130260b6ad00980344376c6e1702a062fe21..68fc69d0d7f77c457a9b0b543393994e66b313d1 100644 (file)
@@ -3421,8 +3421,8 @@ def t2MRRC2 : t2MovRRCopro<0b1111, "mrrc2", 1>;
 // Other Coprocessor Instructions.
 //
 
-def tCDP : T2Cop<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
-                 c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
+def tCDP : T2Cop<0b1110, (outs), (ins p_imm:$cop, imm0_15:$opc1,
+                 c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2),
                  "cdp\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2",
                  [(int_arm_cdp imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn,
                                imm:$CRm, imm:$opc2)]> {
@@ -3444,8 +3444,8 @@ def tCDP : T2Cop<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1,
   let Inst{23-20} = opc1;
 }
 
-def t2CDP2 : T2Cop<0b1111, (outs), (ins p_imm:$cop, i32imm:$opc1,
-                   c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2),
+def t2CDP2 : T2Cop<0b1111, (outs), (ins p_imm:$cop, imm0_15:$opc1,
+                   c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2),
                    "cdp2\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2",
                    [(int_arm_cdp2 imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn,
                                   imm:$CRm, imm:$opc2)]> {
index 0ce4b4c128284cf83c69d628c438cd648d661be4..499c95440c43b025adcbfd134d0abff178fcc122 100644 (file)
@@ -386,6 +386,22 @@ public:
     int64_t Value = CE->getValue();
     return Value >= 0 && Value < 256;
   }
+  bool isImm0_7() 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 < 8;
+  }
+  bool isImm0_15() 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 < 16;
+  }
   bool isImm0_65535() const {
     if (Kind != Immediate)
       return false;
@@ -585,6 +601,16 @@ public:
     addExpr(Inst, getImm());
   }
 
+  void addImm0_7Operands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    addExpr(Inst, getImm());
+  }
+
+  void addImm0_15Operands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    addExpr(Inst, getImm());
+  }
+
   void addImm0_65535Operands(MCInst &Inst, unsigned N) const {
     assert(N == 1 && "Invalid number of operands!");
     addExpr(Inst, getImm());
index 6c1b39d24b44962b1806842e4c8f9f077d532017..14833775ba00e937a8f678ee17dfb6dca70da68b 100644 (file)
@@ -357,3 +357,17 @@ _func:
 
 @ CHECK: bxj   r2                      @ encoding: [0x22,0xff,0x2f,0xe1]
 @ CHECK: bxjne r2                      @ encoding: [0x22,0xff,0x2f,0x11]
+
+@------------------------------------------------------------------------------
+@ FIXME: CBNZ/CBZ
+@------------------------------------------------------------------------------
+
+
+@------------------------------------------------------------------------------
+@ CDP/CDP2
+@------------------------------------------------------------------------------
+        cdp  p7, #1, c1, c1, c1, #4
+        cdp2  p7, #1, c1, c1, c1, #4
+
+@ CHECK: cdp  p7, #1, c1, c1, c1, #4 @ encoding: [0x81,0x17,0x11,0xee]
+@ CHECK: cdp2  p7, #1, c1, c1, c1, #4 @ encoding: [0x81,0x17,0x11,0xfe]
index bf8f1259e9f8a456946bd45a0e6c63f0da3863c1..4069fea509df4029bc0a47b34e6777647f38fe3b 100644 (file)
         @ Out of range 16-bit immediate on BKPT
         bkpt #65536
 
+@ CHECK-ERRORS: error: invalid operand for instruction
+
+        @ Out of range 4 and 3 bit immediates on CDP[2]
+
+        @ Out of range immediates for CDP/CDP2
+        cdp  p7, #2, c1, c1, c1, #8
+        cdp  p7, #1, c1, c1, c1, #8
+        cdp2  p7, #2, c1, c1, c1, #8
+        cdp2  p7, #1, c1, c1, c1, #8
+
+@ CHECK-ERRORS: error: invalid operand for instruction
+@ CHECK-ERRORS: error: invalid operand for instruction
+@ CHECK-ERRORS: error: invalid operand for instruction
 @ CHECK-ERRORS: error: invalid operand for instruction
index afe5007ecf523a0572e7ad1ff423849ef13651c3..2f9814aee4846f276b006a77c6787b4547d4dea5 100644 (file)
@@ -588,6 +588,8 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
   IMM("imm0_31");
   IMM("imm0_31_m1");
   IMM("nModImm");
+  IMM("imm0_7");
+  IMM("imm0_15");
   IMM("imm0_255");
   IMM("imm0_4095");
   IMM("imm0_65535");