aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohnny Chen <johnny.chen@apple.com>2011-04-08 00:29:09 +0000
committerJohnny Chen <johnny.chen@apple.com>2011-04-08 00:29:09 +0000
commit97fdff1d3f0d931247aa300a02679681d684b87d (patch)
tree2abfc0226d3941a493410c5c9804ec4e641c536c
parent9974b8b3cb49eb937cb148c4199e0d456186c3ca (diff)
Add sanity checking for bad register specifier(s) for the DPFrm instructions.
Add more test cases to exercise the logical branches related to the above change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@129117 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp30
-rw-r--r--test/MC/Disassembler/ARM/arm-tests.txt18
-rw-r--r--test/MC/Disassembler/ARM/invalid-BFI-arm.txt10
-rw-r--r--test/MC/Disassembler/ARM/invalid-SBFX-arm.txt10
-rw-r--r--test/MC/Disassembler/ARM/invalid-UQADD8-arm.txt12
5 files changed, 80 insertions, 0 deletions
diff --git a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
index 390f9f3541..ca67e5e2e6 100644
--- a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
+++ b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
@@ -949,6 +949,24 @@ static inline bool getBFCInvMask(uint32_t insn, uint32_t &mask) {
return true;
}
+// Standard data-processing instructions allow PC as a register specifier,
+// but we should reject other DPFrm instructions with PC as registers.
+static bool BadRegsDPFrm(unsigned Opcode, uint32_t insn) {
+ switch (Opcode) {
+ default:
+ // Did we miss an opcode?
+ if (decodeRd(insn) == 15 | decodeRn(insn) == 15 || decodeRm(insn) == 15) {
+ DEBUG(errs() << "DPFrm with bad reg specifier(s)\n");
+ return true;
+ }
+ case ARM::ADCrr: case ARM::ADDSrr: case ARM::ADDrr: case ARM::ANDrr:
+ case ARM::BICrr: case ARM::CMNzrr: case ARM::CMPrr: case ARM::EORrr:
+ case ARM::ORRrr: case ARM::RSBrr: case ARM::RSCrr: case ARM::SBCrr:
+ case ARM::SUBSrr: case ARM::SUBrr: case ARM::TEQrr: case ARM::TSTrr:
+ return false;
+ }
+}
+
// A major complication is the fact that some of the saturating add/subtract
// operations have Rd Rm Rn, instead of the "normal" Rd Rn Rm.
// They are QADD, QDADD, QDSUB, and QSUB.
@@ -976,6 +994,10 @@ static bool DisassembleDPFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
// Special-case handling of BFC/BFI/SBFX/UBFX.
if (Opcode == ARM::BFC || Opcode == ARM::BFI) {
+ // A8.6.17 BFC & A8.6.18 BFI
+ // Sanity check Rd.
+ if (decodeRd(insn) == 15)
+ return false;
MI.addOperand(MCOperand::CreateReg(0));
if (Opcode == ARM::BFI) {
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
@@ -991,6 +1013,9 @@ static bool DisassembleDPFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
return true;
}
if (Opcode == ARM::SBFX || Opcode == ARM::UBFX) {
+ // Sanity check Rd and Rm.
+ if (decodeRd(insn) == 15 || decodeRm(insn) == 15)
+ return false;
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRm(insn))));
MI.addOperand(MCOperand::CreateImm(slice(insn, 11, 7)));
@@ -1027,11 +1052,16 @@ static bool DisassembleDPFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
// Assert disabled because saturating operations, e.g., A8.6.127 QASX, are
// routed here as well.
// assert(getIBit(insn) == 0 && "I_Bit != '0' reg/reg form");
+ if (BadRegsDPFrm(Opcode, insn))
+ return false;
MI.addOperand(MCOperand::CreateReg(
getRegisterEnum(B, ARM::GPRRegClassID,
RmRn? decodeRn(insn) : decodeRm(insn))));
++OpIdx;
} else if (Opcode == ARM::MOVi16 || Opcode == ARM::MOVTi16) {
+ // These two instructions don't allow d as 15.
+ if (decodeRd(insn) == 15)
+ return false;
// We have an imm16 = imm4:imm12 (imm4=Inst{19:16}, imm12 = Inst{11:0}).
assert(getIBit(insn) == 1 && "I_Bit != '1' reg/imm form");
unsigned Imm16 = slice(insn, 19, 16) << 12 | slice(insn, 11, 0);
diff --git a/test/MC/Disassembler/ARM/arm-tests.txt b/test/MC/Disassembler/ARM/arm-tests.txt
index 3bed28edff..86d4f34daf 100644
--- a/test/MC/Disassembler/ARM/arm-tests.txt
+++ b/test/MC/Disassembler/ARM/arm-tests.txt
@@ -254,3 +254,21 @@
# CHECK: sxtb r9, r5, ror #8
0x75 0x94 0xaf 0xe6
+
+# CHECK: bfc r5, #0, #16
+0x1f 0x50 0xcf 0xe7
+
+# CHECK: bfi r5, r6, #0, #16
+0x16 0x50 0xcf 0xe7
+
+# CHECK: sbfx r5, r6, #8, #8
+0x56 0x54 0xa7 0xe7
+
+# CHECK: rsb pc, r5, r0
+0x00 0xf0 0x65 0xe0
+
+# CHECK: uqadd8 r5, r6, r7
+0x97 0x5f 0x66 0xe6
+
+# CHECK: uqsax r5, r6, r7
+0x57 0x5f 0x66 0xe6
diff --git a/test/MC/Disassembler/ARM/invalid-BFI-arm.txt b/test/MC/Disassembler/ARM/invalid-BFI-arm.txt
new file mode 100644
index 0000000000..ca0c1abb77
--- /dev/null
+++ b/test/MC/Disassembler/ARM/invalid-BFI-arm.txt
@@ -0,0 +1,10 @@
+# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
+
+# Opcode=60 Name=BFI Format=ARM_FORMAT_DPFRM(4)
+# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+# -------------------------------------------------------------------------------------------------
+# | 1: 1: 1: 0| 0: 1: 1: 1| 1: 1: 0: 0| 1: 1: 1: 1| 1: 1: 1: 1| 0: 0: 0: 0| 0: 0: 0: 1| 0: 1: 1: 0|
+# -------------------------------------------------------------------------------------------------
+#
+# if d == 15 then UNPREDICTABLE;
+0x16 0xf0 0xcf 0xe7
diff --git a/test/MC/Disassembler/ARM/invalid-SBFX-arm.txt b/test/MC/Disassembler/ARM/invalid-SBFX-arm.txt
new file mode 100644
index 0000000000..1ecd87df07
--- /dev/null
+++ b/test/MC/Disassembler/ARM/invalid-SBFX-arm.txt
@@ -0,0 +1,10 @@
+# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
+
+# Opcode=271 Name=SBFX Format=ARM_FORMAT_DPFRM(4)
+# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+# -------------------------------------------------------------------------------------------------
+# | 1: 1: 1: 0| 0: 1: 1: 1| 1: 0: 1: 0| 0: 1: 1: 1| 0: 1: 0: 1| 0: 1: 0: 0| 0: 1: 0: 1| 1: 1: 1: 1|
+# -------------------------------------------------------------------------------------------------
+#
+# if d == 15 || n == 15 then UNPREDICTABLE;
+0x5f 0x54 0xa7 0xe7
diff --git a/test/MC/Disassembler/ARM/invalid-UQADD8-arm.txt b/test/MC/Disassembler/ARM/invalid-UQADD8-arm.txt
new file mode 100644
index 0000000000..d3f508a1da
--- /dev/null
+++ b/test/MC/Disassembler/ARM/invalid-UQADD8-arm.txt
@@ -0,0 +1,12 @@
+# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding}
+
+# Opcode=426 Name=UQADD8 Format=ARM_FORMAT_DPFRM(4)
+# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+# -------------------------------------------------------------------------------------------------
+# | 1: 1: 1: 0| 0: 1: 1: 0| 0: 1: 1: 0| 0: 1: 1: 0| 0: 1: 0: 1| 1: 1: 1: 1| 1: 0: 0: 1| 1: 1: 1: 1|
+# -------------------------------------------------------------------------------------------------
+#
+# DPFrm with bad reg specifier(s)
+#
+# if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
+0x9f 0x5f 0x66 0xe6