[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