Fix BXJ is undefined in AArch32.
authorCharlie Turner <charlie.turner@arm.com>
Wed, 15 Apr 2015 17:28:23 +0000 (17:28 +0000)
committerCharlie Turner <charlie.turner@arm.com>
Wed, 15 Apr 2015 17:28:23 +0000 (17:28 +0000)
BXJ was incorrectly said to be unsupported in ARMv8-A. It is not
supported in the A64 instruction set, but it is supported in the T32
and A32 instruction sets, because it's listed as an instruction in the
ARM ARM section F7.1.28.

Using SP as an operand to BXJ changed from UNPREDICTABLE to
PREDICTABLE in v8-A. This patch reflects that update as well.

This was found by MCHammer.

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

lib/Target/ARM/ARMInstrThumb2.td
lib/Target/ARM/AsmParser/ARMAsmParser.cpp
test/MC/ARM/thumb2-bxj-v8.s [new file with mode: 0644]
test/MC/ARM/thumb2-bxj.s

index ac3d6f9e575982e495b67830010dd7559d2dec1f..4515a8129f71ca28f4ef86ce6bd7758b284d528b 100644 (file)
@@ -3630,8 +3630,8 @@ def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
 
 // Branch and Exchange Jazelle -- for disassembly only
 // Rm = Inst{19-16}
-def t2BXJ : T2I<(outs), (ins rGPR:$func), NoItinerary, "bxj", "\t$func", []>,
-    Sched<[WriteBr]>, Requires<[IsThumb2, IsNotMClass, PreV8]> {
+def t2BXJ : T2I<(outs), (ins GPRnopc:$func), NoItinerary, "bxj", "\t$func", []>,
+    Sched<[WriteBr]>, Requires<[IsThumb2, IsNotMClass]> {
   bits<4> func;
   let Inst{31-27} = 0b11110;
   let Inst{26} = 0;
index 0fa99a94f18c8ce397c2eced836a7809528f3552..4b9fcbe38fcdcf7b00f6ddad4fcadf6408164dc1 100644 (file)
@@ -6150,6 +6150,14 @@ bool ARMAsmParser::validateInstruction(MCInst &Inst,
                    "destination operands can't be identical");
     return false;
   }
+  case ARM::t2BXJ: {
+    const unsigned RmReg = Inst.getOperand(0).getReg();
+    // Rm = SP is no longer unpredictable in v8-A
+    if (RmReg == ARM::SP && !hasV8Ops())
+      return Error(Operands[2]->getStartLoc(),
+                   "r13 (SP) is an unpredictable operand to BXJ");
+    return false;
+  }
   case ARM::STRD: {
     // Rt2 must be Rt + 1.
     unsigned Rt = MRI->getEncodingValue(Inst.getOperand(0).getReg());
diff --git a/test/MC/ARM/thumb2-bxj-v8.s b/test/MC/ARM/thumb2-bxj-v8.s
new file mode 100644 (file)
index 0000000..4420b6f
--- /dev/null
@@ -0,0 +1,11 @@
+@ RUN: not llvm-mc -triple=thumbv6t2--none-eabi -show-encoding < %s 2>&1 | FileCheck %s --check-prefix=UNDEF
+@ RUN: not llvm-mc -triple=thumbv7a--none-eabi -show-encoding < %s 2>&1  | FileCheck %s --check-prefix=UNDEF
+@ RUN: not llvm-mc -triple=thumbv7r--none-eabi -show-encoding < %s 2>&1  | FileCheck %s --check-prefix=UNDEF
+@ RUN: not llvm-mc -triple=thumbv7m--none-eabi -show-encoding < %s 2>&1  | FileCheck %s --check-prefix=ARM_MODE
+@ RUN: llvm-mc -triple=thumbv8a--none-eabi -show-encoding < %s 2>&1  | FileCheck %s
+
+bxj r13
+
+@ CHECK: bxj   sp                      @ encoding: [0xcd,0xf3,0x00,0x8f]
+@ UNDEF:  error: r13 (SP) is an unpredictable operand to BXJ
+@ ARM_MODE: error: instruction requires: arm-mode
index e60d1a447cbae3b6bfcf3e75552dde11b3350bc0..76879399ed87dc204512912954cf1c0dc6e1c335 100644 (file)
@@ -1,8 +1,8 @@
 @ RUN: llvm-mc -triple=thumbv6t2--none-eabi -show-encoding < %s | FileCheck %s
 @ RUN: llvm-mc -triple=thumbv7a--none-eabi -show-encoding < %s | FileCheck %s
 @ RUN: llvm-mc -triple=thumbv7r--none-eabi -show-encoding < %s | FileCheck %s
+@ RUN: llvm-mc -triple=thumbv8a--none-eabi -show-encoding < %s | FileCheck %s
 @ RUN: not llvm-mc -triple=thumbv7m--none-eabi -show-encoding < %s 2>&1 | FileCheck %s --check-prefix=UNDEF
-@ RUN: not llvm-mc -triple=thumbv8a--none-eabi -show-encoding < %s 2>&1 | FileCheck %s --check-prefix=UNDEF
 
         bxj r2