MipsFrameLowering.cpp revision 8a8d479214745c82ef00f08d4e4f1c173b5f9ce2
14552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//=======- MipsFrameLowering.cpp - Mips Frame Information ------*- C++ -*-====// 233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// The LLVM Compiler Infrastructure 433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// This file is distributed under the University of Illinois Open Source 633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// License. See LICENSE.TXT for details. 733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 84552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===// 933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 1016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov// This file contains the Mips implementation of TargetFrameLowering class. 1133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 124552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===// 1333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 1416c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov#include "MipsFrameLowering.h" 1533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "MipsInstrInfo.h" 1633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "MipsMachineFunction.h" 1747b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes#include "MCTargetDesc/MipsBaseInfo.h" 1833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/Function.h" 1933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineFrameInfo.h" 2033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineFunction.h" 2133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineInstrBuilder.h" 2233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineModuleInfo.h" 2333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineRegisterInfo.h" 2433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/Target/TargetData.h" 2533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/Target/TargetOptions.h" 2633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/Support/CommandLine.h" 2733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 2833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovusing namespace llvm; 2933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 3033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 314552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===// 3233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 3333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// Stack Frame Processing methods 3433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// +----------------------------+ 3533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 3633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// The stack is allocated decrementing the stack pointer on 3733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// the first instruction of a function prologue. Once decremented, 3833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// all stack references are done thought a positive offset 3933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// from the stack/frame pointer, so the stack is considering 4033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// to grow up! Otherwise terrible hacks would have to be made 4133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// to get this stack ABI compliant :) 4233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 4333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// The stack frame required by the ABI (after call): 4433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// Offset 4533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 4633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 0 ---------- 4733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 4 Args to pass 4833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// . saved $GP (used in PIC) 4933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// . Alloca allocations 5033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// . Local Area 5133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// . CPU "Callee Saved" Registers 5233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// . saved FP 5333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// . saved RA 5433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// . FPU "Callee Saved" Registers 5533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// StackSize ----------- 5633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 5733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// Offset - offset from sp after stack allocation on function prologue 5833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 5933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// The sp is the stack pointer subtracted/added from the stack size 6033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// at the Prologue/Epilogue 6133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 6233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// References to the previous stack (to obtain arguments) are done 6333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// with offsets that exceeds the stack size: (stacksize+(4*(num_arg-1)) 6433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 6533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// Examples: 6633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// - reference to the actual stack frame 6733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// for any local area var there is smt like : FI >= 0, StackOffset: 4 6833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// sw REGX, 4(SP) 6933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 7033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// - reference to previous stack frame 7133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// suppose there's a load to the 5th arguments : FI < 0, StackOffset: 16. 7233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// The emitted instruction will be something like: 7333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// lw REGX, 16+StackSize(SP) 7433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 7533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// Since the total stack size is unknown on LowerFormalArguments, all 7633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// stack references (ObjectOffset) created to reference the function 7733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// arguments, are negative numbers. This way, on eliminateFrameIndex it's 7833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// possible to detect those references and the offsets are adjusted to 7933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// their real location. 8033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 814552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===// 8233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 83d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov// hasFP - Return true if the specified function should have a dedicated frame 844552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka// pointer register. This is true if the function has variable sized allocas or 854552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka// if frame pointer elimination is disabled. 8616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovbool MipsFrameLowering::hasFP(const MachineFunction &MF) const { 87d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov const MachineFrameInfo *MFI = MF.getFrameInfo(); 888a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky return MF.getTarget().Options.DisableFramePointerElim(MF) || 898a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky MFI->hasVarSizedObjects() || MFI->isFrameAddressTaken(); 90d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov} 91d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 9269c19f7316ed8e545c7339421b910543eb8e9eefAkira Hatanakabool MipsFrameLowering::targetHandlesStackFrameRounding() const { 9369c19f7316ed8e545c7339421b910543eb8e9eefAkira Hatanaka return true; 9433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 9533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 9669c19f7316ed8e545c7339421b910543eb8e9eefAkira Hatanakastatic unsigned AlignOffset(unsigned Offset, unsigned Align) { 9769c19f7316ed8e545c7339421b910543eb8e9eefAkira Hatanaka return (Offset + Align - 1) / Align * Align; 9869c19f7316ed8e545c7339421b910543eb8e9eefAkira Hatanaka} 994552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka 1000bf3dfbef60e36827df9c7e12b62503f1e345cd0Akira Hatanaka// expand pair of register and immediate if the immediate doesn't fit in the 1010bf3dfbef60e36827df9c7e12b62503f1e345cd0Akira Hatanaka// 16-bit offset field. 10299027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes// e.g. 10399027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes// if OrigImm = 0x10000, OrigReg = $sp: 10499027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes// generate the following sequence of instrs: 10599027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes// lui $at, hi(0x10000) 10699027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes// addu $at, $sp, $at 10799027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes// 10899027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes// (NewReg, NewImm) = ($at, lo(Ox10000)) 10999027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes// return true 11099027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopesstatic bool expandRegLargeImmPair(unsigned OrigReg, int OrigImm, 11199027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes unsigned& NewReg, int& NewImm, 1120bf3dfbef60e36827df9c7e12b62503f1e345cd0Akira Hatanaka MachineBasicBlock& MBB, 1130bf3dfbef60e36827df9c7e12b62503f1e345cd0Akira Hatanaka MachineBasicBlock::iterator I) { 11499027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes // OrigImm fits in the 16-bit field 11599027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes if (OrigImm < 0x8000 && OrigImm >= -0x8000) { 11699027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes NewReg = OrigReg; 11799027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes NewImm = OrigImm; 11899027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes return false; 11999027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes } 12099027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes 12199027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes MachineFunction* MF = MBB.getParent(); 12299027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes const TargetInstrInfo *TII = MF->getTarget().getInstrInfo(); 12399027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes DebugLoc DL = I->getDebugLoc(); 124ce98deb9f512070fe82518594550dd030b26dd96Akira Hatanaka int ImmLo = (short)(OrigImm & 0xffff); 1254552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka int ImmHi = (((unsigned)OrigImm & 0xffff0000) >> 16) + 1260bf3dfbef60e36827df9c7e12b62503f1e345cd0Akira Hatanaka ((OrigImm & 0x8000) != 0); 12799027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes 12899027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes // FIXME: change this when mips goes MC". 12999027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes BuildMI(MBB, I, DL, TII->get(Mips::NOAT)); 13099027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes BuildMI(MBB, I, DL, TII->get(Mips::LUi), Mips::AT).addImm(ImmHi); 1310bf3dfbef60e36827df9c7e12b62503f1e345cd0Akira Hatanaka BuildMI(MBB, I, DL, TII->get(Mips::ADDu), Mips::AT).addReg(OrigReg) 1320bf3dfbef60e36827df9c7e12b62503f1e345cd0Akira Hatanaka .addReg(Mips::AT); 13399027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes NewReg = Mips::AT; 13499027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes NewImm = ImmLo; 13599027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes 13699027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes return true; 13799027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes} 13899027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes 13916c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid MipsFrameLowering::emitPrologue(MachineFunction &MF) const { 14033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock &MBB = MF.front(); 14133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 14233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); 14333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const MipsRegisterInfo *RegInfo = 14433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); 14533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const MipsInstrInfo &TII = 14633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *static_cast<const MipsInstrInfo*>(MF.getTarget().getInstrInfo()); 14733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator MBBI = MBB.begin(); 14833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 14933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool isPIC = (MF.getTarget().getRelocationModel() == Reloc::PIC_); 15099027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes unsigned NewReg = 0; 15199027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes int NewImm = 0; 15299027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes bool ATUsed; 153a1fa08f66a5e92ccf5bc0b565c045be14108dae4Akira Hatanaka unsigned GP = STI.isABI_N64() ? Mips::GP_64 : Mips::GP; 154a1fa08f66a5e92ccf5bc0b565c045be14108dae4Akira Hatanaka unsigned T9 = STI.isABI_N64() ? Mips::T9_64 : Mips::T9; 1551b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; 1561b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; 1571b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO; 158a1fa08f66a5e92ccf5bc0b565c045be14108dae4Akira Hatanaka unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu; 159a1fa08f66a5e92ccf5bc0b565c045be14108dae4Akira Hatanaka unsigned ADDiu = STI.isABI_N64() ? Mips::DADDiu : Mips::ADDiu; 160a1fa08f66a5e92ccf5bc0b565c045be14108dae4Akira Hatanaka unsigned LUi = STI.isABI_N64() ? Mips::LUi64 : Mips::LUi; 16133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 16269c19f7316ed8e545c7339421b910543eb8e9eefAkira Hatanaka // First, compute final stack size. 16369c19f7316ed8e545c7339421b910543eb8e9eefAkira Hatanaka unsigned RegSize = STI.isGP32bit() ? 4 : 8; 16469c19f7316ed8e545c7339421b910543eb8e9eefAkira Hatanaka unsigned StackAlign = getStackAlignment(); 16569c19f7316ed8e545c7339421b910543eb8e9eefAkira Hatanaka unsigned LocalVarAreaOffset = MipsFI->needGPSaveRestore() ? 16669c19f7316ed8e545c7339421b910543eb8e9eefAkira Hatanaka (MFI->getObjectOffset(MipsFI->getGPFI()) + RegSize) : 167f15f49850768f5889c2e12aeb273e158597a1223Akira Hatanaka MipsFI->getMaxCallFrameSize(); 16869c19f7316ed8e545c7339421b910543eb8e9eefAkira Hatanaka unsigned StackSize = AlignOffset(LocalVarAreaOffset, StackAlign) + 16969c19f7316ed8e545c7339421b910543eb8e9eefAkira Hatanaka AlignOffset(MFI->getStackSize(), StackAlign); 17069c19f7316ed8e545c7339421b910543eb8e9eefAkira Hatanaka 17169c19f7316ed8e545c7339421b910543eb8e9eefAkira Hatanaka // Update stack size 17269c19f7316ed8e545c7339421b910543eb8e9eefAkira Hatanaka MFI->setStackSize(StackSize); 17369c19f7316ed8e545c7339421b910543eb8e9eefAkira Hatanaka 17433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(Mips::NOREORDER)); 175ac20aad81c8444b3f3901d805d62627df5b8caccAkira Hatanaka BuildMI(MBB, MBBI, dl, TII.get(Mips::NOMACRO)); 17633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 177a1fa08f66a5e92ccf5bc0b565c045be14108dae4Akira Hatanaka // Emit instructions that set $gp using the the value of $t9. 178a1fa08f66a5e92ccf5bc0b565c045be14108dae4Akira Hatanaka // O32 uses the directive .cpload while N32/64 requires three instructions to 179a1fa08f66a5e92ccf5bc0b565c045be14108dae4Akira Hatanaka // do this. 180a1fa08f66a5e92ccf5bc0b565c045be14108dae4Akira Hatanaka // TODO: Do not emit these instructions if no instructions use $gp. 18133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (isPIC && STI.isABI_O32()) 182ac20aad81c8444b3f3901d805d62627df5b8caccAkira Hatanaka BuildMI(MBB, llvm::prior(MBBI), dl, TII.get(Mips::CPLOAD)) 18333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(RegInfo->getPICCallReg()); 184a1fa08f66a5e92ccf5bc0b565c045be14108dae4Akira Hatanaka else if (STI.isABI_N64() || (isPIC && STI.isABI_N32())) { 185a1fa08f66a5e92ccf5bc0b565c045be14108dae4Akira Hatanaka // lui $28,%hi(%neg(%gp_rel(fname))) 186a1fa08f66a5e92ccf5bc0b565c045be14108dae4Akira Hatanaka // addu $28,$28,$25 187a1fa08f66a5e92ccf5bc0b565c045be14108dae4Akira Hatanaka // addiu $28,$28,%lo(%neg(%gp_rel(fname))) 188a1fa08f66a5e92ccf5bc0b565c045be14108dae4Akira Hatanaka const GlobalValue *FName = MF.getFunction(); 189a1fa08f66a5e92ccf5bc0b565c045be14108dae4Akira Hatanaka BuildMI(MBB, MBBI, dl, TII.get(LUi), GP) 190a1fa08f66a5e92ccf5bc0b565c045be14108dae4Akira Hatanaka .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI); 191a1fa08f66a5e92ccf5bc0b565c045be14108dae4Akira Hatanaka BuildMI(MBB, MBBI, dl, TII.get(ADDu), GP).addReg(GP).addReg(T9); 192a1fa08f66a5e92ccf5bc0b565c045be14108dae4Akira Hatanaka BuildMI(MBB, MBBI, dl, TII.get(ADDiu), GP).addReg(GP) 193a1fa08f66a5e92ccf5bc0b565c045be14108dae4Akira Hatanaka .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO); 194a1fa08f66a5e92ccf5bc0b565c045be14108dae4Akira Hatanaka } 195a1fa08f66a5e92ccf5bc0b565c045be14108dae4Akira Hatanaka 196f346c695309a6e3bbe80c0339387f334c07d9ab6Akira Hatanaka // No need to allocate space on the stack. 197f346c695309a6e3bbe80c0339387f334c07d9ab6Akira Hatanaka if (StackSize == 0 && !MFI->adjustsStack()) return; 198f346c695309a6e3bbe80c0339387f334c07d9ab6Akira Hatanaka 1998464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka MachineModuleInfo &MMI = MF.getMMI(); 2008464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka std::vector<MachineMove> &Moves = MMI.getFrameMoves(); 2018464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka MachineLocation DstML, SrcML; 2028464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka 20333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Adjust stack : addi sp, sp, (-imm) 2041b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka ATUsed = expandRegLargeImmPair(SP, -StackSize, NewReg, NewImm, MBB, MBBI); 2051b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka BuildMI(MBB, MBBI, dl, TII.get(ADDiu), SP).addReg(NewReg).addImm(NewImm); 20699027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes 20799027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes // FIXME: change this when mips goes MC". 20899027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes if (ATUsed) 20999027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes BuildMI(MBB, MBBI, dl, TII.get(Mips::ATMACRO)); 21033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 2118464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka // emit ".cfi_def_cfa_offset StackSize" 2128464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka MCSymbol *AdjustSPLabel = MMI.getContext().CreateTempSymbol(); 2138464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka BuildMI(MBB, MBBI, dl, 2148464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka TII.get(TargetOpcode::PROLOG_LABEL)).addSym(AdjustSPLabel); 2158464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka DstML = MachineLocation(MachineLocation::VirtualFP); 2168464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka SrcML = MachineLocation(MachineLocation::VirtualFP, -StackSize); 2178464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka Moves.push_back(MachineMove(AdjustSPLabel, DstML, SrcML)); 2188464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka 219cf0cd8005c81853ddea3ce26b71491c48dc4984eAkira Hatanaka const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 2208464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka 2218464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka if (CSI.size()) { 2220f843821385213b33116eaecf0c13e987139f6a5Akira Hatanaka // Find the instruction past the last instruction that saves a callee-saved 2230f843821385213b33116eaecf0c13e987139f6a5Akira Hatanaka // register to the stack. 2248464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka for (unsigned i = 0; i < CSI.size(); ++i) 2258464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka ++MBBI; 226f346c695309a6e3bbe80c0339387f334c07d9ab6Akira Hatanaka 2270f843821385213b33116eaecf0c13e987139f6a5Akira Hatanaka // Iterate over list of callee-saved registers and emit .cfi_offset 2280f843821385213b33116eaecf0c13e987139f6a5Akira Hatanaka // directives. 2298464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka MCSymbol *CSLabel = MMI.getContext().CreateTempSymbol(); 2308464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka BuildMI(MBB, MBBI, dl, 2318464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel); 2328464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka 2338464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(), 2348464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka E = CSI.end(); I != E; ++I) { 2358464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka int64_t Offset = MFI->getObjectOffset(I->getFrameIdx()); 2368464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka unsigned Reg = I->getReg(); 2378464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka 2388464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka // If Reg is a double precision register, emit two cfa_offsets, 2398464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka // one for each of the paired single precision registers. 2408464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka if (Mips::AFGR64RegisterClass->contains(Reg)) { 2418464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka const unsigned *SubRegs = RegInfo->getSubRegisters(Reg); 2428464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka MachineLocation DstML0(MachineLocation::VirtualFP, Offset); 2438464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka MachineLocation DstML1(MachineLocation::VirtualFP, Offset + 4); 2448464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka MachineLocation SrcML0(*SubRegs); 2458464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka MachineLocation SrcML1(*(SubRegs + 1)); 2468464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka 2478464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka if (!STI.isLittle()) 2488464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka std::swap(SrcML0, SrcML1); 2498464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka 2508464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka Moves.push_back(MachineMove(CSLabel, DstML0, SrcML0)); 2518464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka Moves.push_back(MachineMove(CSLabel, DstML1, SrcML1)); 2528464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka } 2538464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka else { 2548464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka // Reg is either in CPURegs or FGR32. 2558464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka DstML = MachineLocation(MachineLocation::VirtualFP, Offset); 2568464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka SrcML = MachineLocation(Reg); 2578464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka Moves.push_back(MachineMove(CSLabel, DstML, SrcML)); 2588464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka } 2598464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka } 2608464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka } 2618464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka 262cf0cd8005c81853ddea3ce26b71491c48dc4984eAkira Hatanaka // if framepointer enabled, set it to point to the stack pointer. 2638464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka if (hasFP(MF)) { 264f346c695309a6e3bbe80c0339387f334c07d9ab6Akira Hatanaka // Insert instruction "move $fp, $sp" at this location. 2651b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka BuildMI(MBB, MBBI, dl, TII.get(ADDu), FP).addReg(SP).addReg(ZERO); 26633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 2678464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka // emit ".cfi_def_cfa_register $fp" 2688464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka MCSymbol *SetFPLabel = MMI.getContext().CreateTempSymbol(); 2698464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka BuildMI(MBB, MBBI, dl, 2708464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka TII.get(TargetOpcode::PROLOG_LABEL)).addSym(SetFPLabel); 2711b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka DstML = MachineLocation(FP); 2728464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka SrcML = MachineLocation(MachineLocation::VirtualFP); 2738464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka Moves.push_back(MachineMove(SetFPLabel, DstML, SrcML)); 2748464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka } 2758464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka 27633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Restore GP from the saved stack location 2779029cf20e1158dbca9c95da72a646d467e871525Akira Hatanaka if (MipsFI->needGPSaveRestore()) { 2789029cf20e1158dbca9c95da72a646d467e871525Akira Hatanaka unsigned Offset = MFI->getObjectOffset(MipsFI->getGPFI()); 2799029cf20e1158dbca9c95da72a646d467e871525Akira Hatanaka BuildMI(MBB, MBBI, dl, TII.get(Mips::CPRESTORE)).addImm(Offset); 2809029cf20e1158dbca9c95da72a646d467e871525Akira Hatanaka 2819029cf20e1158dbca9c95da72a646d467e871525Akira Hatanaka if (Offset >= 0x8000) { 2829029cf20e1158dbca9c95da72a646d467e871525Akira Hatanaka BuildMI(MBB, llvm::prior(MBBI), dl, TII.get(Mips::MACRO)); 2839029cf20e1158dbca9c95da72a646d467e871525Akira Hatanaka BuildMI(MBB, MBBI, dl, TII.get(Mips::NOMACRO)); 2849029cf20e1158dbca9c95da72a646d467e871525Akira Hatanaka } 2859029cf20e1158dbca9c95da72a646d467e871525Akira Hatanaka } 28633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 28733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 28816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid MipsFrameLowering::emitEpilogue(MachineFunction &MF, 28933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock &MBB) const { 2904f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 29133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 29233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const MipsInstrInfo &TII = 29333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *static_cast<const MipsInstrInfo*>(MF.getTarget().getInstrInfo()); 29433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DebugLoc dl = MBBI->getDebugLoc(); 2951b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; 2961b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; 2971b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO; 2981b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu; 2991b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka unsigned ADDiu = STI.isABI_N64() ? Mips::DADDiu : Mips::ADDiu; 30033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 30133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get the number of bytes from FrameInfo 302f346c695309a6e3bbe80c0339387f334c07d9ab6Akira Hatanaka unsigned StackSize = MFI->getStackSize(); 30333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 30499027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes unsigned NewReg = 0; 30599027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes int NewImm = 0; 3060546f7396ab5dc4b78f887375a40cb5fda650ce6Bill Wendling bool ATUsed = false; 30799027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes 30817a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka // if framepointer enabled, restore the stack pointer. 309f346c695309a6e3bbe80c0339387f334c07d9ab6Akira Hatanaka if (hasFP(MF)) { 310f346c695309a6e3bbe80c0339387f334c07d9ab6Akira Hatanaka // Find the first instruction that restores a callee-saved register. 311f346c695309a6e3bbe80c0339387f334c07d9ab6Akira Hatanaka MachineBasicBlock::iterator I = MBBI; 312f346c695309a6e3bbe80c0339387f334c07d9ab6Akira Hatanaka 313f346c695309a6e3bbe80c0339387f334c07d9ab6Akira Hatanaka for (unsigned i = 0; i < MFI->getCalleeSavedInfo().size(); ++i) 314f346c695309a6e3bbe80c0339387f334c07d9ab6Akira Hatanaka --I; 315f346c695309a6e3bbe80c0339387f334c07d9ab6Akira Hatanaka 316f346c695309a6e3bbe80c0339387f334c07d9ab6Akira Hatanaka // Insert instruction "move $sp, $fp" at this location. 3171b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka BuildMI(MBB, I, dl, TII.get(ADDu), SP).addReg(FP).addReg(ZERO); 318f346c695309a6e3bbe80c0339387f334c07d9ab6Akira Hatanaka } 31933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 32033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // adjust stack : insert addi sp, sp, (imm) 321f346c695309a6e3bbe80c0339387f334c07d9ab6Akira Hatanaka if (StackSize) { 3221b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka ATUsed = expandRegLargeImmPair(SP, StackSize, NewReg, NewImm, MBB, MBBI); 3231b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka BuildMI(MBB, MBBI, dl, TII.get(ADDiu), SP).addReg(NewReg).addImm(NewImm); 32499027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes 32599027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes // FIXME: change this when mips goes MC". 32699027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes if (ATUsed) 32799027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes BuildMI(MBB, MBBI, dl, TII.get(Mips::ATMACRO)); 32833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 32933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 330fb67faa6614c2bf6e5a126ccdc712a64e4263797Bruno Cardoso Lopes 331fb67faa6614c2bf6e5a126ccdc712a64e4263797Bruno Cardoso Lopesvoid MipsFrameLowering:: 33217a1e8775119db75ece41e041eeb6480793696ffAkira HatanakaprocessFunctionBeforeCalleeSavedScan(MachineFunction &MF, 33317a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka RegScavenger *RS) const { 33417a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka MachineRegisterInfo& MRI = MF.getRegInfo(); 3351b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka unsigned RA = STI.isABI_N64() ? Mips::RA_64 : Mips::RA; 3361b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; 33717a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka 33817a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka // FIXME: remove this code if register allocator can correctly mark 33917a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka // $fp and $ra used or unused. 34017a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka 34117a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka // Mark $fp and $ra as used or unused. 34217a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka if (hasFP(MF)) 3431b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka MRI.setPhysRegUsed(FP); 34417a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka 34517a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka // The register allocator might determine $ra is used after seeing 34617a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka // instruction "jr $ra", but we do not want PrologEpilogInserter to insert 34717a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka // instructions to save/restore $ra unless there is a function call. 34817a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka // To correct this, $ra is explicitly marked unused if there is no 34917a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka // function call. 35033458fedb607e64c46af6797057fbf0b4973a6f6Akira Hatanaka if (MF.getFrameInfo()->hasCalls()) 3511b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka MRI.setPhysRegUsed(RA); 35217a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka else 3531b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka MRI.setPhysRegUnused(RA); 35417a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka} 355