ARM: fix more cases where predication may or may not be allowed
authorTim Northover <tnorthover@apple.com>
Wed, 26 Jun 2013 16:52:40 +0000 (16:52 +0000)
committerTim Northover <tnorthover@apple.com>
Wed, 26 Jun 2013 16:52:40 +0000 (16:52 +0000)
Unfortunately this addresses two issues (by the time I'd disentangled the logic
it wasn't worth putting it back to half-broken):

+ Coprocessor instructions should all be predicable in Thumb mode.
+ BKPT should never be predicable.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@184965 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMInstrFormats.td
lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/ARMInstrThumb2.td
lib/Target/ARM/AsmParser/ARMAsmParser.cpp
test/MC/ARM/basic-arm-instructions.s
test/MC/ARM/diagnostics.s
test/MC/ARM/thumb-only-conditionals.s
test/MC/ARM/thumb2-diagnostics.s

index bd9a212928eba8d09240cb59b9ce5d678284ca46..239632f353873bd72976ba41d8a50cb43c71933d 100644 (file)
@@ -1230,8 +1230,9 @@ class T2JTI<dag oops, dag iops, InstrItinClass itin,
   : Thumb2XI<oops, iops, AddrModeNone, 0, itin, asm, "", pattern>;
 
 // Move to/from coprocessor instructions
-class T2Cop<bits<4> opc, dag oops, dag iops, string asm, list<dag> pattern>
-  : T2XI <oops, iops, NoItinerary, asm, pattern>, Requires<[IsThumb2]> {
+class T2Cop<bits<4> opc, dag oops, dag iops, string opcstr, string asm,
+            list<dag> pattern>
+  : T2I <oops, iops, NoItinerary, opcstr, asm, pattern>, Requires<[IsThumb2]> {
   let Inst{31-28} = opc;
 }
 
index 8003e5101c7b5bf1c0e8ac4496b242025ccb4359..7f32c1f014c48ef3d2537d9e9c82bd2adaa3f308 100644 (file)
@@ -1730,12 +1730,13 @@ def SEL : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, NoItinerary, "sel",
 
 // The 16-bit operand $val can be used by a debugger to store more information
 // about the breakpoint.
-def BKPT : AI<(outs), (ins imm0_65535:$val), MiscFrm, NoItinerary,
-              "bkpt", "\t$val", []>, Requires<[IsARM]> {
+def BKPT : AInoP<(outs), (ins imm0_65535:$val), MiscFrm, NoItinerary,
+                 "bkpt", "\t$val", []>, Requires<[IsARM]> {
   bits<16> val;
   let Inst{3-0} = val{3-0};
   let Inst{19-8} = val{15-4};
   let Inst{27-20} = 0b00010010;
+  let Inst{31-28} = 0xe; // AL
   let Inst{7-4} = 0b0111;
 }
 
index 3b18df085654626c79b3c9ea5b5f4f54f09ac003..fa87fb9f3c105041820fcadbbbd2055dd9ea20ec 100644 (file)
@@ -3825,8 +3825,7 @@ def t2MSR_M : T2I<(outs), (ins msr_mask:$SYSm, rGPR:$Rn),
 
 class t2MovRCopro<bits<4> Op, string opc, bit direction, dag oops, dag iops,
                   list<dag> pattern>
-  : T2Cop<Op, oops, iops,
-          !strconcat(opc, "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2"),
+  : T2Cop<Op, oops, iops, opc, "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2",
           pattern> {
   let Inst{27-24} = 0b1110;
   let Inst{20} = direction;
@@ -3851,7 +3850,7 @@ class t2MovRRCopro<bits<4> Op, string opc, bit direction,
                    list<dag> pattern = []>
   : T2Cop<Op, (outs),
           (ins p_imm:$cop, imm0_15:$opc1, GPR:$Rt, GPR:$Rt2, c_imm:$CRm),
-          !strconcat(opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm"), pattern> {
+          opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm", pattern> {
   let Inst{27-24} = 0b1100;
   let Inst{23-21} = 0b010;
   let Inst{20} = direction;
@@ -3876,32 +3875,32 @@ def t2MCR : t2MovRCopro<0b1110, "mcr", 0,
                 c_imm:$CRm, imm0_7:$opc2),
            [(int_arm_mcr imm:$cop, imm:$opc1, GPR:$Rt, imm:$CRn,
                          imm:$CRm, imm:$opc2)]>;
-def : t2InstAlias<"mcr $cop, $opc1, $Rt, $CRn, $CRm",
+def : t2InstAlias<"mcr${p} $cop, $opc1, $Rt, $CRn, $CRm",
                   (t2MCR p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn,
-                         c_imm:$CRm, 0)>;
+                         c_imm:$CRm, 0, pred:$p)>;
 def t2MCR2 : t2MovRCopro<0b1111, "mcr2", 0,
              (outs), (ins p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn,
                           c_imm:$CRm, imm0_7:$opc2),
              [(int_arm_mcr2 imm:$cop, imm:$opc1, GPR:$Rt, imm:$CRn,
                             imm:$CRm, imm:$opc2)]>;
-def : t2InstAlias<"mcr2 $cop, $opc1, $Rt, $CRn, $CRm",
+def : t2InstAlias<"mcr2${p} $cop, $opc1, $Rt, $CRn, $CRm",
                   (t2MCR2 p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn,
-                          c_imm:$CRm, 0)>;
+                          c_imm:$CRm, 0, pred:$p)>;
 
 /* from coprocessor to ARM core register */
 def t2MRC : t2MovRCopro<0b1110, "mrc", 1,
              (outs GPR:$Rt), (ins p_imm:$cop, imm0_7:$opc1, c_imm:$CRn,
                                   c_imm:$CRm, imm0_7:$opc2), []>;
-def : t2InstAlias<"mrc $cop, $opc1, $Rt, $CRn, $CRm",
+def : t2InstAlias<"mrc${p} $cop, $opc1, $Rt, $CRn, $CRm",
                   (t2MRC GPR:$Rt, p_imm:$cop, imm0_7:$opc1, c_imm:$CRn,
-                         c_imm:$CRm, 0)>;
+                         c_imm:$CRm, 0, pred:$p)>;
 
 def t2MRC2 : t2MovRCopro<0b1111, "mrc2", 1,
              (outs GPR:$Rt), (ins p_imm:$cop, imm0_7:$opc1, c_imm:$CRn,
                                   c_imm:$CRm, imm0_7:$opc2), []>;
-def : t2InstAlias<"mrc2 $cop, $opc1, $Rt, $CRn, $CRm",
+def : t2InstAlias<"mrc2${p} $cop, $opc1, $Rt, $CRn, $CRm",
                   (t2MRC2 GPR:$Rt, p_imm:$cop, imm0_7:$opc1, c_imm:$CRn,
-                          c_imm:$CRm, 0)>;
+                          c_imm:$CRm, 0, pred:$p)>;
 
 def : T2v6Pat<(int_arm_mrc  imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2),
               (t2MRC imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2)>;
@@ -3928,7 +3927,7 @@ def t2MRRC2 : t2MovRRCopro<0b1111, "mrrc2", 1>;
 
 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",
+                 "cdp", "\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2",
                  [(int_arm_cdp imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn,
                                imm:$CRm, imm:$opc2)]> {
   let Inst{27-24} = 0b1110;
@@ -3951,7 +3950,7 @@ def tCDP : T2Cop<0b1110, (outs), (ins p_imm:$cop, imm0_15:$opc1,
 
 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",
+                   "cdp2", "\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2",
                    [(int_arm_cdp2 imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn,
                                   imm:$CRm, imm:$opc2)]> {
   let Inst{27-24} = 0b1110;
index f80fba610286b30d4a407c58bfcbd8bed612c0ec..eda55502d2dcd547328d6abcc4d302a041a48965 100644 (file)
@@ -4966,28 +4966,26 @@ getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
   } else
     CanAcceptCarrySet = false;
 
-  if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "cps" ||
-      Mnemonic == "mcr2" || Mnemonic == "it" || Mnemonic == "mcrr2" ||
-      Mnemonic == "cbz" || Mnemonic == "cdp2" || Mnemonic == "trap" ||
-      Mnemonic == "mrc2" || Mnemonic == "mrrc2" || Mnemonic == "setend" ||
-      ((Mnemonic == "clrex" ||  Mnemonic == "dmb" || Mnemonic == "dsb" ||
-       Mnemonic == "isb") && !isThumb()) ||
-      (Mnemonic == "nop" && isThumbOne()) ||
-      ((Mnemonic == "pld" || Mnemonic == "pli" || Mnemonic == "pldw" ||
-        Mnemonic == "ldc2" || Mnemonic == "ldc2l" ||
-        Mnemonic == "stc2" || Mnemonic == "stc2l") && !isThumb()) ||
-      ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) &&
-       !isThumb()) ||
-      Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumbOne())) {
+  if (Mnemonic == "bkpt" || Mnemonic == "cbnz" || Mnemonic == "setend" ||
+      Mnemonic == "cps" ||  Mnemonic == "it" ||  Mnemonic == "cbz" ||
+      Mnemonic == "trap" || Mnemonic == "setend" ||
+      Mnemonic.startswith("cps")) {
+    // These mnemonics are never predicable
     CanAcceptPredicationCode = false;
+  } else if (!isThumb()) {
+    // Some instructions are only predicable in Thumb mode
+    CanAcceptPredicationCode
+      = Mnemonic != "cdp2" && Mnemonic != "clrex" && Mnemonic != "mcr2" &&
+        Mnemonic != "mcrr2" && Mnemonic != "mrc2" && Mnemonic != "mrrc2" &&
+        Mnemonic != "dmb" && Mnemonic != "dsb" && Mnemonic != "isb" &&
+        Mnemonic != "pld" && Mnemonic != "pli" && Mnemonic != "pldw" &&
+        Mnemonic != "ldc2" && Mnemonic != "ldc2l" &&
+        Mnemonic != "stc2" && Mnemonic != "stc2l" &&
+        !Mnemonic.startswith("rfe") && !Mnemonic.startswith("srs");
+  } else if (isThumbOne()) {
+    CanAcceptPredicationCode = Mnemonic != "nop" && Mnemonic != "movs";
   } else
     CanAcceptPredicationCode = true;
-
-  if (isThumb()) {
-    if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" ||
-        Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp")
-      CanAcceptPredicationCode = false;
-  }
 }
 
 bool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic,
index 3061c0f70e2eda6c92940dc72af41f62bacdbbaf..a7c54ff3a5613511fe14daa1fb0ff4eee60442c1 100644 (file)
@@ -465,6 +465,8 @@ Lforward:
 @ CHECK: cdp2  p7, #1, c1, c1, c1, #4    @ encoding: [0x81,0x17,0x11,0xfe]
 @ CHECK: cdp2  p10, #0, c6, c12, c0, #7   @ encoding: [0xe0,0x6a,0x0c,0xfe]
 
+        cdpne  p7, #1, c1, c1, c1, #4
+@ CHECK: cdpne  p7, #1, c1, c1, c1, #4     @ encoding: [0x81,0x17,0x11,0x1e]
 
 @------------------------------------------------------------------------------
 @ CLREX
@@ -969,6 +971,9 @@ Lforward:
 @ CHECK: mcr  p7, #1, r5, c1, c1, #4    @ encoding: [0x91,0x57,0x21,0xee]
 @ CHECK: mcr2  p7, #1, r5, c1, c1, #4   @ encoding: [0x91,0x57,0x21,0xfe]
 
+        mcrls  p7, #1, r5, c1, c1, #4
+@ CHECK: mcrls  p7, #1, r5, c1, c1, #4   @ encoding: [0x91,0x57,0x21,0x9e]
+
 @------------------------------------------------------------------------------
 @ MCRR/MCRR2
 @------------------------------------------------------------------------------
@@ -978,6 +983,8 @@ Lforward:
 @ CHECK: mcrr  p7, #15, r5, r4, c1      @ encoding: [0xf1,0x57,0x44,0xec]
 @ CHECK: mcrr2  p7, #15, r5, r4, c1     @ encoding: [0xf1,0x57,0x44,0xfc]
 
+        mcrrgt  p7, #15, r5, r4, c1
+@ CHECK: mcrrgt  p7, #15, r5, r4, c1     @ encoding: [0xf1,0x57,0x44,0xcc]
 
 @------------------------------------------------------------------------------
 @ MLA
@@ -1081,6 +1088,9 @@ Lforward:
 @ CHECK: mrc2  p10, #7, apsr_nzcv, c15, c0, #1    @ encoding: [0x30,0xfa,0xff,0xfe]
 @ CHECK: mrc2  p10, #7, pc, c15, c0, #1           @ encoding: [0x30,0xfa,0xff,0xfe]
 
+        mrceq  p15, #7, pc, c15, c6, #6
+@ CHECK: mrceq  p15, #7, pc, c15, c6, #6            @ encoding: [0xd6,0xff,0xff,0x0e]
+
 @------------------------------------------------------------------------------
 @ MRRC/MRRC2
 @------------------------------------------------------------------------------
@@ -1090,6 +1100,8 @@ Lforward:
 @ CHECK: mrrc  p7, #1, r5, r4, c1       @ encoding: [0x11,0x57,0x54,0xec]
 @ CHECK: mrrc2  p7, #1, r5, r4, c1      @ encoding: [0x11,0x57,0x54,0xfc]
 
+        mrrclo  p7, #1, r5, r4, c1
+@ CHECK: mrrclo  p7, #1, r5, r4, c1      @ encoding: [0x11,0x57,0x54,0x3c]
 
 @------------------------------------------------------------------------------
 @ MRS
index 21fda1cce17e6ac91154aec4e59017ad4bb87ba2..1aea1174af5e3679337aea3608e0690d64947d93 100644 (file)
 @ CHECK-ERRORS: error: instruction 'dmb' is not predicable, but condition code specified
 @ CHECK-ERRORS: error: instruction 'dsb' is not predicable, but condition code specified
 @ CHECK-ERRORS: error: instruction 'isb' is not predicable, but condition code specified
+
+        mcr2le  p7, #1, r5, c1, c1, #4
+        mcrr2ne p7, #15, r5, r4, c1
+        mrc2lo  p14, #0, r1, c1, c2, #4
+        mrrc2lo  p7, #1, r5, r4, c1
+        cdp2hi   p10, #0, c6, c12, c0, #7
+@ CHECK-ERRORS: error: instruction 'mcr2' is not predicable, but condition code specified
+@ CHECK-ERRORS: error: instruction 'mcrr2' is not predicable, but condition code specified
+@ CHECK-ERRORS: error: instruction 'mrc2' is not predicable, but condition code specified
+@ CHECK-ERRORS: error: instruction 'mrrc2' is not predicable, but condition code specified
+@ CHECK-ERRORS: error: instruction 'cdp2' is not predicable, but condition code specified
+
+        bkpteq #7
+@ CHECK-ERRORS: error: instruction 'bkpt' is not predicable, but condition code specified
index 55b2cf4c6876b449110e0f5e5665cfba65606d75..6d13ce5cc935e766b75296a607fc50d0510fe99d 100644 (file)
 @ CHECK-NEXT: dmble sy
 @ CHECK-NEXT: dsbgt sy
 @ CHECK-NEXT: isble sy
+
+        itt gt
+        cdpgt  p7, #1, c1, c1, c1, #4
+        cdp2gt  p7, #1, c1, c1, c1, #4
+@ CHECK: itt gt
+@ CHECK-NEXT: cdpgt  p7, #1, c1, c1, c1, #4
+@ CHECK-NEXT: cdp2gt  p7, #1, c1, c1, c1, #4
+
+        itt ne
+        mcrne p0, #0, r0, c0, c0, #0
+        mcr2ne p0, #0, r0, c0, c0, #0
+@ CHECK: itt ne
+@ CHECK-NEXT: mcrne p0, #0, r0, c0, c0, #0
+@ CHECK-NEXT: mcr2ne p0, #0, r0, c0, c0, #0
+
+        ite le
+        mcrrle  p7, #15, r5, r4, c1
+        mcrr2gt  p7, #15, r5, r4, c1
+@ CHECK: ite le
+@ CHECK-NEXT: mcrrle  p7, #15, r5, r4, c1
+@ CHECK-NEXT: mcrr2gt  p7, #15, r5, r4, c1
+
+        ite eq
+        mrceq p11, #1, r1, c2, c2
+        mrc2ne p12, #3, r3, c3, c4
+@ CHECK: ite eq
+@ CHECK-NEXT: mrceq p11, #1, r1, c2, c2
+@ CHECK-NEXT: mrc2ne p12, #3, r3, c3, c4
+
+        itt lo
+        mrrclo  p7, #1, r5, r4, c1
+        mrrc2lo  p7, #1, r5, r4, c1
+@ CHECK: itt lo
+@ CHECK-NEXT: mrrclo  p7, #1, r5, r4, c1
+@ CHECK-NEXT: mrrc2lo  p7, #1, r5, r4, c1
index b7fe44d2cd6dea25b2efd2ea9470e5bc3c86192e..e1c005872f078a0267738d28dc02c640de058495 100644 (file)
@@ -47,3 +47,7 @@
         isb  #16
 @ CHECK-ERRORS: error: immediate value out of range
 @ CHECK-ERRORS: error: immediate value out of range
+
+        itt eq
+        bkpteq #1
+@ CHECK-ERRORS: error: instruction 'bkpt' is not predicable, but condition code specified