[llvm] 3a34194 - [ARM] Fix Asm/Disasm of TBB/TBH instructions

David Spickett via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 22 01:32:03 PDT 2020


Author: David Spickett
Date: 2020-07-22T09:31:56+01:00
New Revision: 3a3419460647612fba9dbecbd770fc8c84bbc05a

URL: https://github.com/llvm/llvm-project/commit/3a3419460647612fba9dbecbd770fc8c84bbc05a
DIFF: https://github.com/llvm/llvm-project/commit/3a3419460647612fba9dbecbd770fc8c84bbc05a.diff

LOG: [ARM] Fix Asm/Disasm of TBB/TBH instructions

Summary:
This fixes Bugzilla #46616 in which it was reported
that "tbb  [pc, r0]" was marked as SoftFail
(aka unpredictable) incorrectly.

Expected behaviour is:
* ARMv8 is required to use sp as rn or rm
  (tbb/tbh only have a Thumb encoding so using Arm mode
  is not an option)
* If rm is the pc then the instruction is always
  unpredictable

Some of this was implemented already and this fixes the
rest. Added tests cover the new and pre-existing handling.

Reviewers: ostannard

Reviewed By: ostannard

Subscribers: kristof.beyls, hiraditya, danielkiss, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D84227

Added: 
    llvm/test/MC/Disassembler/ARM/thumb2-diagnostic.txt

Modified: 
    llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
    llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
    llvm/test/MC/ARM/thumb2-diagnostics.s

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 05f870b90ecd..99862b41b69d 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -10598,6 +10598,12 @@ unsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
         (isThumb() && !hasV8Ops()))
       return Match_InvalidOperand;
     break;
+  case ARM::t2TBB:
+  case ARM::t2TBH:
+    // Rn = sp is only allowed with ARMv8-A
+    if (!hasV8Ops() && (Inst.getOperand(0).getReg() == ARM::SP))
+      return Match_RequiresV8;
+    break;
   default:
     break;
   }

diff  --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
index 54ff0d9966cb..ccef1ba3c830 100644
--- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
@@ -4529,12 +4529,14 @@ static DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Val,
 static DecodeStatus
 DecodeThumbTableBranch(MCInst &Inst, unsigned Insn,
                        uint64_t Address, const void *Decoder) {
+  const FeatureBitset &FeatureBits =
+    ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
   DecodeStatus S = MCDisassembler::Success;
 
   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
 
-  if (Rn == ARM::SP) S = MCDisassembler::SoftFail;
+  if (Rn == 13 && !FeatureBits[ARM::HasV8Ops]) S = MCDisassembler::SoftFail;
   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
     return MCDisassembler::Fail;
   if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))

diff  --git a/llvm/test/MC/ARM/thumb2-diagnostics.s b/llvm/test/MC/ARM/thumb2-diagnostics.s
index ccc9d7b9df6a..1154e5a9069a 100644
--- a/llvm/test/MC/ARM/thumb2-diagnostics.s
+++ b/llvm/test/MC/ARM/thumb2-diagnostics.s
@@ -165,3 +165,25 @@ foo2:
 @ CHECK-ERRORS-V7: error: operand must be a register in range [r0, r12] or r14
 @ CHECK-ERRORS-V7: operand must be a register in range [r0, r12] or r14
 @ CHECK-ERRORS-V7: operand must be a register in range [r0, r12] or r14
+
+        tbb [r0, sp]
+        @ v8 allows rm = sp
+@ CHECK-ERRORS-V7: error: instruction variant requires ARMv8 or later
+        tbb [r0, pc]
+        @ rm = pc is always unpredictable
+@ CHECK-ERRORS: error: invalid operand for instruction
+        tbb [sp, r0]
+        @ v8 allows rn = sp
+@ CHECK-ERRORS-V7: error: instruction variant requires ARMv8 or later
+        @ rn = pc is allowed so not included here
+
+        tbh [r0, sp, lsl #1]
+        @ v8 allows rm = sp
+@ CHECK-ERRORS-V7: error: instruction variant requires ARMv8 or later
+        tbh [r0, pc, lsl #1]
+        @ rm = pc is always unpredictable
+@ CHECK-ERRORS: error: invalid operand for instruction
+        tbh [sp, r0, lsl #1]
+        @ v8 allows rn = sp
+@ CHECK-ERRORS-V7: error: instruction variant requires ARMv8 or later
+        @ rn=pc is allowed so not included here

diff  --git a/llvm/test/MC/Disassembler/ARM/thumb2-diagnostic.txt b/llvm/test/MC/Disassembler/ARM/thumb2-diagnostic.txt
new file mode 100644
index 000000000000..2b49c41cdabc
--- /dev/null
+++ b/llvm/test/MC/Disassembler/ARM/thumb2-diagnostic.txt
@@ -0,0 +1,49 @@
+# RUN: llvm-mc -triple=thumbv7 -disassemble %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-V7
+# RUN: llvm-mc -triple=thumbv8 -disassemble %s 2>&1 | \
+# RUN: FileCheck %s --check-prefix=CHECK
+
+# tbb [r0, sp]
+0xd0 0xe8 0x0d 0xf0
+#      CHECK-V7: warning: potentially undefined instruction encoding
+# CHECK-V7-NEXT: 0xd0 0xe8 0x0d 0xf0
+
+# tbb [r0, pc]
+0xd0 0xe8 0x0f 0xf0
+#      CHECK: warning: potentially undefined instruction encoding
+# CHECK-NEXT: 0xd0 0xe8 0x0f 0xf0
+
+# tbb [sp, r0]
+0xdd 0xe8 0x00 0xf0
+#      CHECK-V7: warning: potentially undefined instruction encoding
+# CHECK-V7-NEXT: 0xdd 0xe8 0x00 0xf0
+
+# tbb [pc, r0]
+0xdf 0xe8 0x00 0xf0
+
+# tbh [r0, sp, lsl #1]
+0xd0 0xe8 0x1d 0xf0
+#      CHECK-V7: warning: potentially undefined instruction encoding
+# CHECK-V7-NEXT: 0xd0 0xe8 0x1d 0xf0
+
+# tbh [r0, pc, lsl #1]
+0xd0 0xe8 0x1f 0xf0
+#      CHECK: warning: potentially undefined instruction encoding
+# CHECK-NEXT: 0xd0 0xe8 0x1f 0xf0
+
+# tbh [sp, r0, lsl #1]
+0xdd 0xe8 0x10 0xf0
+#      CHECK-V7: warning: potentially undefined instruction encoding
+# CHECK-V7-NEXT: 0xdd 0xe8 0x10 0xf0
+
+# tbh [pc, r0, lsl #1]
+0xdf 0xe8 0x10 0xf0
+
+# CHECK: tbb [r0, sp]
+# CHECK: tbb [r0, pc]
+# CHECK: tbb [sp, r0]
+# CHECK: tbb [pc, r0]
+# CHECK: tbh [r0, sp, lsl #1]
+# CHECK: tbh [r0, pc, lsl #1]
+# CHECK: tbh [sp, r0, lsl #1]
+# CHECK: tbh [pc, r0, lsl #1]


        


More information about the llvm-commits mailing list