Added the B9.3.19 SUBS PC, LR, #imm (Thumb2) system instruction.
authorKevin Enderby <enderby@apple.com>
Wed, 31 Jul 2013 21:05:30 +0000 (21:05 +0000)
committerKevin Enderby <enderby@apple.com>
Wed, 31 Jul 2013 21:05:30 +0000 (21:05 +0000)
While the .td entry is nice and all, it takes a pretty gross hack in
ARMAsmParser::ParseInstruction() because of handling of other "subs"
instructions to get it to match.  Ran it by Jim Grosbach and he said it was
about what he expected to make this work given the existing code.

rdar://14214063

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187530 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMInstrThumb2.td
lib/Target/ARM/AsmParser/ARMAsmParser.cpp
test/MC/ARM/basic-thumb2-instructions.s
test/MC/Disassembler/ARM/thumb2.txt

index 8e5e8c1735a4ac7e55e86179c46faf981237d2ae..842f3372d041655a4d817190d49d974320883bca 100644 (file)
@@ -3599,6 +3599,16 @@ def t2RFEIA  : T2RFE<0b111010011001,
                    (outs), (ins GPR:$Rn), NoItinerary, "rfeia", "\t$Rn",
                    [/* For disassembly only; pattern left blank */]>;
 
+// B9.3.19 SUBS PC, LR, #imm (Thumb2) system instruction.
+let Defs = [PC], Uses = [LR] in
+def t2SUBS_PC_LR : T2I <(outs), (ins imm0_255:$imm), NoItinerary,
+                   "subs", "\tpc, lr, $imm", []>, Requires<[IsThumb2]> {
+  let Inst{31-8} = 0b111100111101111010001111;
+
+  bits<8> imm;
+  let Inst{7-0} = imm;
+}
+
 //===----------------------------------------------------------------------===//
 // Non-Instruction Patterns
 //
index 6d885a0d91827ed6925a8544aae4f352776f231c..8e56a1ab9427dcb1b4de9987ac262ca7bdd7d016 100644 (file)
@@ -5138,6 +5138,26 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
     }
   }
 
+  // FIXME: As said above, this is all a pretty gross hack.  This instruction
+  // does not fit with other "subs" and tblgen.
+  // Adjust operands of B9.3.19 SUBS PC, LR, #imm (Thumb2) system instruction
+  // so the Mnemonic is the original name "subs" and delete the predicate
+  // operand so it will match the table entry.
+  if (isThumbTwo() && Mnemonic == "sub" && Operands.size() == 6 &&
+      static_cast<ARMOperand*>(Operands[3])->isReg() &&
+      static_cast<ARMOperand*>(Operands[3])->getReg() == ARM::PC &&
+      static_cast<ARMOperand*>(Operands[4])->isReg() &&
+      static_cast<ARMOperand*>(Operands[4])->getReg() == ARM::LR &&
+      static_cast<ARMOperand*>(Operands[5])->isImm()) {
+    ARMOperand *Op0 = static_cast<ARMOperand*>(Operands[0]);
+    Operands.erase(Operands.begin());
+    delete Op0;
+    Operands.insert(Operands.begin(), ARMOperand::CreateToken(Name, NameLoc));
+
+    ARMOperand *Op1 = static_cast<ARMOperand*>(Operands[1]);
+    Operands.erase(Operands.begin() + 1);
+    delete Op1;
+  }
   return false;
 }
 
index 43e03c9833a74bd3963a112d5632af6bdc4c2194..f3a1c6a9f9f42bc329bcbea52415cb30976c1b79 100644 (file)
@@ -3588,3 +3588,7 @@ _func:
 @ rdar://12596361
          ldr r1, [pc, #12]
 @ CHECK: ldr r1, [pc, #12]              @ encoding: [0x03,0x49]
+
+@ rdar://14214063
+         subs pc, lr, #4
+@ CHECK: subs pc, lr, #4                @ encoding: [0xde,0xf3,0x04,0x8f]
index 110a4c0530e5b03a2675a56f7918bcb47f0bd522..9fc166f06633a94f2b64082e7a65803c90b26a5b 100644 (file)
 # CHECK: sub.w r12, r6, #256
 # CHECK: subw r12, r6, #256
 # CHECK: subs.w r1, r2, #496
+# CHECK: subs pc, lr, #4
 
 0x0a 0xbf
 0x11 0x1f
 0xa6 0xf5 0x80 0x7c
 0xa6 0xf2 0x00 0x1c
 0xb2 0xf5 0xf8 0x71
+0xde 0xf3 0x04 0x8f
 
 
 #------------------------------------------------------------------------------