From 8ba76c6d5cee9cb8d38cb0ed374c53bc93451a4e Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Thu, 11 Aug 2011 17:35:48 +0000 Subject: [PATCH] ARM pop of a single register encodes as post-indexed LDR. Per the ARM ARM, a 'pop' of a single register encodes as an LDR, not an LDM. llvm-svn: 137316 --- .../lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 30 +++++++++++++++++++ .../Target/ARM/InstPrinter/ARMInstPrinter.cpp | 8 +++++ llvm/test/CodeGen/ARM/str_pre-2.ll | 2 +- llvm/test/MC/ARM/basic-arm-instructions.s | 6 +--- 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 85e3f1a82f2e..0b049e911368 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -136,6 +136,8 @@ class ARMAsmParser : public MCTargetAsmParser { bool validateInstruction(MCInst &Inst, const SmallVectorImpl &Ops); + void processInstruction(MCInst &Inst, + const SmallVectorImpl &Ops); public: ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) @@ -2856,6 +2858,30 @@ validateInstruction(MCInst &Inst, return false; } +void ARMAsmParser:: +processInstruction(MCInst &Inst, + const SmallVectorImpl &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(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 &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: diff --git a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp index ef4069913407..a8008faa8403 100644 --- a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp +++ b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp @@ -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) && diff --git a/llvm/test/CodeGen/ARM/str_pre-2.ll b/llvm/test/CodeGen/ARM/str_pre-2.ll index b24f75a6e2b8..8d0c7a5fe16f 100644 --- a/llvm/test/CodeGen/ARM/str_pre-2.ll +++ b/llvm/test/CodeGen/ARM/str_pre-2.ll @@ -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 diff --git a/llvm/test/MC/ARM/basic-arm-instructions.s b/llvm/test/MC/ARM/basic-arm-instructions.s index c99c4353c0e7..adcecb5b3829 100644 --- a/llvm/test/MC/ARM/basic-arm-instructions.s +++ b/llvm/test/MC/ARM/basic-arm-instructions.s @@ -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]