ARM pop of a single register encodes as post-indexed LDR.
authorJim Grosbach <grosbach@apple.com>
Thu, 11 Aug 2011 17:35:48 +0000 (17:35 +0000)
committerJim Grosbach <grosbach@apple.com>
Thu, 11 Aug 2011 17:35:48 +0000 (17:35 +0000)
Per the ARM ARM, a 'pop' of a single register encodes as an LDR,
not an LDM.

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

lib/Target/ARM/AsmParser/ARMAsmParser.cpp
lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
test/CodeGen/ARM/str_pre-2.ll
test/MC/ARM/basic-arm-instructions.s

index 85e3f1a82f2e0e4b3368177a18982d3e68725172..0b049e911368a4c7497ec42a4f2a7c328c1c48a2 100644 (file)
@@ -136,6 +136,8 @@ class ARMAsmParser : public MCTargetAsmParser {
 
   bool validateInstruction(MCInst &Inst,
                            const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
+  void processInstruction(MCInst &Inst,
+                          const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
 
 public:
   ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
@@ -2856,6 +2858,30 @@ validateInstruction(MCInst &Inst,
   return false;
 }
 
+void ARMAsmParser::
+processInstruction(MCInst &Inst,
+                   const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+  switch (Inst.getOpcode()) {
+  case ARM::LDMIA_UPD:
+    // If this is a load of a single register via a 'pop', then we should use
+    // a post-indexed LDR instruction instead, per the ARM ARM.
+    if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" &&
+        Inst.getNumOperands() == 5) {
+      MCInst TmpInst;
+      TmpInst.setOpcode(ARM::LDR_POST_IMM);
+      TmpInst.addOperand(Inst.getOperand(4)); // Rt
+      TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
+      TmpInst.addOperand(Inst.getOperand(1)); // Rn
+      TmpInst.addOperand(MCOperand::CreateReg(0));  // am2offset
+      TmpInst.addOperand(MCOperand::CreateImm(4));
+      TmpInst.addOperand(Inst.getOperand(2)); // CondCode
+      TmpInst.addOperand(Inst.getOperand(3));
+      Inst = TmpInst;
+    }
+    break;
+  }
+}
+
 bool ARMAsmParser::
 MatchAndEmitInstruction(SMLoc IDLoc,
                         SmallVectorImpl<MCParsedAsmOperand*> &Operands,
@@ -2871,6 +2897,10 @@ MatchAndEmitInstruction(SMLoc IDLoc,
     if (validateInstruction(Inst, Operands))
       return true;
 
+    // Some instructions need post-processing to, for example, tweak which
+    // encoding is selected.
+    processInstruction(Inst, Operands);
+
     Out.EmitInstruction(Inst);
     return false;
   case Match_MissingFeature:
index ef4069913407c8a2b8704b4ea33db5cbcd2ceb43..a8008faa84036319efb1c38ff89a15b1d3add1d4 100644 (file)
@@ -100,6 +100,14 @@ void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O) {
     printRegisterList(MI, 4, O);
     return;
   }
+  if (Opcode == ARM::LDR_POST_IMM && MI->getOperand(2).getReg() == ARM::SP &&
+      MI->getOperand(4).getImm() == 4) {
+    O << '\t' << "pop";
+    printPredicateOperand(MI, 5, O);
+    O << "\t{" << getRegisterName(MI->getOperand(0).getReg()) << "}";
+    return;
+  }
+
 
   // A8.6.355 VPUSH
   if ((Opcode == ARM::VSTMSDB_UPD || Opcode == ARM::VSTMDDB_UPD) &&
index b24f75a6e2b80ec5e0ca2ad4189c24a8a1f5f794..8d0c7a5fe16fd6d576fe5433d9271e55a43bb18c 100644 (file)
@@ -8,7 +8,7 @@
 define i64 @t(i64 %a) nounwind readonly {
 entry:
 ; CHECK: str lr, [sp, #-4]!
-; CHECK: ldr lr, [sp], #4
+; CHECK: pop {lr}
        %0 = load i64** @b, align 4
        %1 = load i64* %0, align 4
        %2 = mul i64 %1, %a
index c99c4353c0e7ad9c36ccaa7325aa559ea2b22ffc..adcecb5b38293b7cdd0b74c077fbf113219adf07 100644 (file)
@@ -664,9 +664,6 @@ Lforward:
 @ CHECK: ldmda r2!, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0x32,0xe8]
 @ CHECK: ldmdb r2!, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0x32,0xe9]
 
-@------------------------------------------------------------------------------
-@ FIXME: LDR*
-@------------------------------------------------------------------------------
 
 @------------------------------------------------------------------------------
 @ LDREX/LDREXB/LDREXH/LDREXD
@@ -1064,8 +1061,7 @@ Lforward:
         pop {r7}
         pop {r7, r8, r9, r10}
 
-@ FIXME: pop of a single register should encode as "ldr r7, [sp], #4"
-@ CHECK-FIXME: pop     {r7}                    @ encoding: [0x04,0x70,0x9d,0xe4]
+@ CHECK: pop   {r7}                    @ encoding: [0x04,0x70,0x9d,0xe4]
 @ CHECK: pop   {r7, r8, r9, r10}       @ encoding: [0x80,0x07,0xbd,0xe8]