[PATCH] Fix return sequence on armv4 thumb
Jon Roelofs
jonathan at codesourcery.com
Thu Jul 31 15:51:02 PDT 2014
Hi t.p.northover,
http://reviews.llvm.org/D4748
Files:
llvm/lib/Target/ARM/Thumb1FrameLowering.cpp
Index: llvm/lib/Target/ARM/Thumb1FrameLowering.cpp
===================================================================
--- llvm/lib/Target/ARM/Thumb1FrameLowering.cpp
+++ llvm/lib/Target/ARM/Thumb1FrameLowering.cpp
@@ -463,13 +463,17 @@
MachineInstrBuilder MIB = BuildMI(MF, DL, TII.get(ARM::tPOP));
AddDefaultPred(MIB);
+ bool IsReturn = false;
bool NumRegs = false;
for (unsigned i = CSI.size(); i != 0; --i) {
unsigned Reg = CSI[i-1].getReg();
if (Reg == ARM::LR) {
// Special epilogue for vararg functions. See emitEpilogue
if (isVarArg)
continue;
+ IsReturn = true;
+ if (STI.hasV4TOps() && !STI.hasV5TOps())
+ continue;
Reg = ARM::PC;
(*MIB).setDesc(TII.get(ARM::tPOP_RET));
MIB.copyImplicitOps(&*MI);
@@ -485,5 +489,27 @@
else
MF.DeleteMachineInstr(MIB);
+ // On armv4, popping into PC will not change arm/thumb state,
+ // so instead we have to emit that as:
+ // POP {r3}
+ // BX r3
+ if (IsReturn && STI.hasV4TOps() && !STI.hasV5TOps()) {
+ // Get the last instruction, tBX_RET
+ MI = MBB.getLastNonDebugInstr();
+ assert (MI->getOpcode() == ARM::tBX_RET);
+ DebugLoc dl = MI->getDebugLoc();
+ // Epilogue: pop LR to R3 and branch off it.
+ AddDefaultPred(BuildMI(MBB, MI, dl, TII.get(ARM::tPOP)))
+ .addReg(ARM::R3, RegState::Define);
+
+ MachineInstrBuilder MIB =
+ BuildMI(MBB, MI, dl, TII.get(ARM::tBX))
+ .addReg(ARM::R3, RegState::Kill);
+ AddDefaultPred(MIB);
+ MIB.copyImplicitOps(&*MI);
+ // erase the old tBX_RET instruction
+ MBB.erase(MI);
+ }
+
return true;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D4748.12088.patch
Type: text/x-patch
Size: 1641 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140731/93cab4ad/attachment.bin>
More information about the llvm-commits
mailing list