(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;
}
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)))
@ 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
--- /dev/null
+# 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]