unsigned Rt = fieldFromInstruction(Insn, 12, 4);
unsigned Rn = fieldFromInstruction(Insn, 16, 4);
+ uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
+ .getFeatureBits();
+ bool hasMP = featureBits & ARM::FeatureMP;
+ bool hasV7Ops = featureBits & ARM::HasV7Ops;
+
if (Rn == 15) {
switch (Inst.getOpcode()) {
case ARM::t2LDRBs:
case ARM::t2LDRSHs:
return MCDisassembler::Fail;
case ARM::t2LDRHs:
- // FIXME: this instruction is only available with MP extensions,
- // this should be checked first but we don't have access to the
- // feature bits here.
Inst.setOpcode(ARM::t2PLDWs);
break;
+ case ARM::t2LDRSBs:
+ Inst.setOpcode(ARM::t2PLIs);
default:
break;
}
switch (Inst.getOpcode()) {
case ARM::t2PLDs:
- case ARM::t2PLDWs:
+ break;
case ARM::t2PLIs:
+ if (!hasV7Ops)
+ return MCDisassembler::Fail;
+ break;
+ case ARM::t2PLDWs:
+ if (!hasV7Ops || !hasMP)
+ return MCDisassembler::Fail;
break;
default:
if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
unsigned imm = fieldFromInstruction(Insn, 0, 8);
imm |= (U << 8);
imm |= (Rn << 9);
+ unsigned add = fieldFromInstruction(Insn, 9, 1);
+
+ uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
+ .getFeatureBits();
+ bool hasMP = featureBits & ARM::FeatureMP;
+ bool hasV7Ops = featureBits & ARM::HasV7Ops;
if (Rn == 15) {
switch (Inst.getOpcode()) {
switch (Inst.getOpcode()) {
case ARM::t2LDRSHi8:
return MCDisassembler::Fail;
+ case ARM::t2LDRHi8:
+ if (!add)
+ Inst.setOpcode(ARM::t2PLDWi8);
+ break;
+ case ARM::t2LDRSBi8:
+ Inst.setOpcode(ARM::t2PLIi8);
+ break;
default:
break;
}
switch (Inst.getOpcode()) {
case ARM::t2PLDi8:
+ break;
case ARM::t2PLIi8:
- case ARM::t2PLDWi8:
+ if (!hasV7Ops)
+ return MCDisassembler::Fail;
break;
+ case ARM::t2PLDWi8:
+ if (!hasV7Ops || !hasMP)
+ return MCDisassembler::Fail;
+ break;
default:
if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
return MCDisassembler::Fail;
unsigned imm = fieldFromInstruction(Insn, 0, 12);
imm |= (Rn << 13);
+ uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
+ .getFeatureBits();
+ bool hasMP = (featureBits & ARM::FeatureMP);
+ bool hasV7Ops = (featureBits & ARM::HasV7Ops);
+
if (Rn == 15) {
switch (Inst.getOpcode()) {
case ARM::t2LDRi12:
case ARM::t2LDRSHi12:
return MCDisassembler::Fail;
case ARM::t2LDRHi12:
- Inst.setOpcode(ARM::t2PLDi12);
+ Inst.setOpcode(ARM::t2PLDWi12);
+ break;
+ case ARM::t2LDRSBi12:
+ Inst.setOpcode(ARM::t2PLIi12);
break;
default:
break;
switch (Inst.getOpcode()) {
case ARM::t2PLDi12:
- case ARM::t2PLDWi12:
+ break;
case ARM::t2PLIi12:
+ if (!hasV7Ops)
+ return MCDisassembler::Fail;
break;
+ case ARM::t2PLDWi12:
+ if (!hasV7Ops || !hasMP)
+ return MCDisassembler::Fail;
+ break;
default:
if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
return MCDisassembler::Fail;
unsigned U = fieldFromInstruction(Insn, 23, 1);
int imm = fieldFromInstruction(Insn, 0, 12);
+ uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
+ .getFeatureBits();
+ bool hasV7Ops = (featureBits & ARM::HasV7Ops);
+
if (Rt == 15) {
switch (Inst.getOpcode()) {
case ARM::t2LDRBpci:
switch(Inst.getOpcode()) {
case ARM::t2PLDpci:
+ break;
case ARM::t2PLIpci:
+ if (!hasV7Ops)
+ return MCDisassembler::Fail;
break;
default:
if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
--- /dev/null
+# RUN: not llvm-mc -triple=thumbv6t2-none-eabi -disassemble < %s 2>/dev/null | FileCheck %s --check-prefix=V6T2
+# RUN: not llvm-mc -triple=thumbv7a-none-eabi -disassemble -mattr=-mp < %s 2>/dev/null | FileCheck %s --check-prefix=V6T2 --check-prefix=V7
+# RUN: llvm-mc -triple=thumbv7a-none-eabi -disassemble -mattr=+mp < %s 2>/dev/null | FileCheck %s --check-prefix=V6T2 --check-prefix=V7 --check-prefix=MP
+# RUN: not llvm-mc -triple=thumbv7m-none-eabi -disassemble < %s 2>/dev/null | FileCheck %s --check-prefix=V6T2 --check-prefix=V7
+
+# RUN: not llvm-mc -triple=thumbv6t2-none-eabi -disassemble < %s 2>&1 >/dev/null | FileCheck %s --check-prefix=MP-ERR --check-prefix=V7-ERR
+# RUN: not llvm-mc -triple=thumbv7a-none-eabi -disassemble -mattr=-mp < %s 2>&1 >/dev/null | FileCheck %s --check-prefix=MP-ERR
+# RUN: llvm-mc -triple=thumbv7a-none-eabi -disassemble -mattr=+mp < %s 2>&1 >/dev/null
+# RUN: not llvm-mc -triple=thumbv7m-none-eabi -disassemble < %s 2>&1 >/dev/null | FileCheck %s --check-prefix=MP-ERR
+
+# V6T2: pld [r1, #3]
+[0x91,0xf8,0x03,0xf0]
+
+# V6T2: pld [r2, #-5]
+[0x12,0xf8,0x05,0xfc]
+
+# MP: pldw [r3, #4]
+# MP-ERR: invalid instruction encoding
+# MP-ERR-NEXT: [0xb3,0xf8,0x04,0xf0]
+[0xb3,0xf8,0x04,0xf0]
+
+# MP: pldw [r4, #-6]
+# MP-ERR: invalid instruction encoding
+# MP-ERR-NEXT: [0x34,0xf8,0x06,0xfc]
+[0x34,0xf8,0x06,0xfc]
+
+# V6T2: pld [pc, #8]
+[0x9f,0xf8,0x08,0xf0]
+
+# V6T2: pld [pc, #-5]
+[0x1f,0xf8,0x05,0xf0]
+
+# V6T2: pld [r5, r6]
+[0x15,0xf8,0x06,0xf0]
+
+# V6T2: pld [r7, r8, lsl #1]
+[0x17,0xf8,0x18,0xf0]
+
+# MP: pldw [r9, r10]
+# MP-ERR: invalid instruction encoding
+# MP-ERR-NEXT: [0x39,0xf8,0x0a,0xf0]
+[0x39,0xf8,0x0a,0xf0]
+
+# MP: pldw [r11, r12, lsl #2]
+# MP-ERR: invalid instruction encoding
+# MP-ERR-NEXT: [0x3b,0xf8,0x2c,0xf0]
+[0x3b,0xf8,0x2c,0xf0]
+
+# V7: pli [r1, #10]
+# V7-ERR: invalid instruction encoding
+# V7-ERR-NEXT: [0x91,0xf9,0x0a,0xf0]
+[0x91,0xf9,0x0a,0xf0]
+
+# V7: pli [r2, #-3]
+# V7-ERR: invalid instruction encoding
+# V7-ERR-NEXT: [0x12,0xf9,0x03,0xfc]
+[0x12,0xf9,0x03,0xfc]
+
+# V7: pli [pc, #6]
+# V7-ERR: invalid instruction encoding
+# V7-ERR-NEXT: [0x9f,0xf9,0x06,0xf0]
+[0x9f,0xf9,0x06,0xf0]
+
+# V7: pli [pc, #-8]
+# V7-ERR: invalid instruction encoding
+# V7-ERR-NEXT: [0x1f,0xf9,0x08,0xf0]
+[0x1f,0xf9,0x08,0xf0]
+
+# NO-ERR-NOT: invalid instruction encoding