ARM: thumb stores cannot use PC as dest register
authorAmaury de la Vieuville <amaury.dlv@gmail.com>
Tue, 18 Jun 2013 08:02:56 +0000 (08:02 +0000)
committerAmaury de la Vieuville <amaury.dlv@gmail.com>
Tue, 18 Jun 2013 08:02:56 +0000 (08:02 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@184179 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/Disassembler/ARMDisassembler.cpp
test/MC/Disassembler/ARM/invalid-STR-thumb.txt [new file with mode: 0644]

index 4086f36ccb03afad5c99b428e5597b61b8e2d7a0..196fc32f48e05573b7c9b709dace8b2707b88c6c 100644 (file)
@@ -3164,6 +3164,17 @@ static DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val,
   unsigned Rm = fieldFromInstruction(Val, 2, 4);
   unsigned imm = fieldFromInstruction(Val, 0, 2);
 
+  // Thumb stores cannot use PC as dest register.
+  switch (Inst.getOpcode()) {
+  case ARM::t2STRHs:
+  case ARM::t2STRBs:
+  case ARM::t2STRs:
+    if (Rn == 15)
+      return MCDisassembler::Fail;
+  default:
+    break;
+  }
+
   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
     return MCDisassembler::Fail;
   if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
@@ -3292,6 +3303,21 @@ static DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val,
   unsigned Rn = fieldFromInstruction(Val, 9, 4);
   unsigned imm = fieldFromInstruction(Val, 0, 9);
 
+  // Thumb stores cannot use PC as dest register.
+  switch (Inst.getOpcode()) {
+  case ARM::t2STRT:
+  case ARM::t2STRBT:
+  case ARM::t2STRHT:
+  case ARM::t2STRi8:
+  case ARM::t2STRHi8:
+  case ARM::t2STRBi8:
+    if (Rn == 15)
+      return MCDisassembler::Fail;
+    break;
+  default:
+    break;
+  }
+
   // Some instructions always use an additive offset.
   switch (Inst.getOpcode()) {
     case ARM::t2LDRT:
@@ -3353,6 +3379,17 @@ static DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val,
   unsigned Rn = fieldFromInstruction(Val, 13, 4);
   unsigned imm = fieldFromInstruction(Val, 0, 12);
 
+  // Thumb stores cannot use PC as dest register.
+  switch (Inst.getOpcode()) {
+  case ARM::t2STRi12:
+  case ARM::t2STRBi12:
+  case ARM::t2STRHi12:
+    if (Rn == 15)
+      return MCDisassembler::Fail;
+  default:
+    break;
+  }
+
   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
     return MCDisassembler::Fail;
   Inst.addOperand(MCOperand::CreateImm(imm));
diff --git a/test/MC/Disassembler/ARM/invalid-STR-thumb.txt b/test/MC/Disassembler/ARM/invalid-STR-thumb.txt
new file mode 100644 (file)
index 0000000..b2da70c
--- /dev/null
@@ -0,0 +1,37 @@
+# invalid STRi12   Rn=PC
+# RUN: echo "0xcf 0xf8 0x00 0x00" | llvm-mc -triple=thumbv7 -disassemble 2>&1 | FileCheck %s
+
+# invalid STRi8    Rn=PC
+# RUN: echo "0x4f 0xf8 0x00 0x0c" | llvm-mc -triple=thumbv7 -disassemble 2>&1 | FileCheck %s
+
+# invalid STRs     Rn=PC
+# RUN: echo "0x4f 0xf8 0x00 0x00" | llvm-mc -triple=thumbv7 -disassemble 2>&1 | FileCheck %s
+
+# invalid STRBi12  Rn=PC
+# RUN: echo "0x0f 0xf8 0x00 0x00" | llvm-mc -triple=thumbv7 -disassemble 2>&1 | FileCheck %s
+
+# invalid STRBi8   Rn=PC
+# RUN: echo "0x0f 0xf8 0x00 0x0c" | llvm-mc -triple=thumbv7 -disassemble 2>&1 | FileCheck %s
+
+# invalid STRBs    Rn=PC
+# RUN: echo "0x0f 0xf8 0x00 0x00" | llvm-mc -triple=thumbv7 -disassemble 2>&1 | FileCheck %s
+
+# invalid STRHi12  Rn=PC
+# RUN: echo "0xaf 0xf8 0x00 0x00" | llvm-mc -triple=thumbv7 -disassemble 2>&1 | FileCheck %s
+
+# invalid STRHi8   Rn=PC
+# RUN: echo "0x2f 0xf8 0x00 0x0c" | llvm-mc -triple=thumbv7 -disassemble 2>&1 | FileCheck %s
+
+# invalid STRHs    Rn=PC
+# RUN: echo "0x2f 0xf8 0x00 0x00" | llvm-mc -triple=thumbv7 -disassemble 2>&1 | FileCheck %s
+
+# invalid STRBT    Rn=PC
+# RUN: echo "0x0f 0xf8 0x00 0x0e" | llvm-mc -triple=thumbv7 -disassemble 2>&1 | FileCheck %s
+
+# invalid STRHT    Rn=PC
+# RUN: echo "0x2f 0xf8 0x00 0x0e" | llvm-mc -triple=thumbv7 -disassemble 2>&1 | FileCheck %s
+
+# invalid STRT     Rn=PC
+# RUN: echo "0x4f 0xf8 0x00 0x0e" | llvm-mc -triple=thumbv7 -disassemble 2>&1 | FileCheck %s
+
+# CHECK: invalid instruction encoding