MipsFrameLowering.cpp revision 79aa3417eb6f58d668aadfedf075240a41d35a26
1c5707112e7635d1dd2f2cc9c4f42e79a51302ccaJia Liu//===-- MipsFrameLowering.cpp - Mips Frame Information --------------------===// 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" 1579aa3417eb6f58d668aadfedf075240a41d35a26Craig Topper#include "MipsAnalyzeImmediate.h" 1633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "MipsInstrInfo.h" 1733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "MipsMachineFunction.h" 1847b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes#include "MCTargetDesc/MipsBaseInfo.h" 1933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/Function.h" 2033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineFrameInfo.h" 2133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineFunction.h" 2233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineInstrBuilder.h" 2333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineModuleInfo.h" 2433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineRegisterInfo.h" 2533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/Target/TargetData.h" 2633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/Target/TargetOptions.h" 2733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/Support/CommandLine.h" 2833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 2933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovusing namespace llvm; 3033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 3133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 324552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===// 3333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 3433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// Stack Frame Processing methods 3533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// +----------------------------+ 3633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 3733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// The stack is allocated decrementing the stack pointer on 3833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// the first instruction of a function prologue. Once decremented, 3933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// all stack references are done thought a positive offset 4033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// from the stack/frame pointer, so the stack is considering 4133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// to grow up! Otherwise terrible hacks would have to be made 4233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// to get this stack ABI compliant :) 4333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 4433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// The stack frame required by the ABI (after call): 4533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// Offset 4633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 4733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 0 ---------- 4833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 4 Args to pass 4933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// . saved $GP (used in PIC) 5033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// . Alloca allocations 5133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// . Local Area 5233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// . CPU "Callee Saved" Registers 5333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// . saved FP 5433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// . saved RA 5533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// . FPU "Callee Saved" Registers 5633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// StackSize ----------- 5733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 5833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// Offset - offset from sp after stack allocation on function prologue 5933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 6033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// The sp is the stack pointer subtracted/added from the stack size 6133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// at the Prologue/Epilogue 6233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 6333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// References to the previous stack (to obtain arguments) are done 6433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// with offsets that exceeds the stack size: (stacksize+(4*(num_arg-1)) 6533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 6633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// Examples: 6733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// - reference to the actual stack frame 6833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// for any local area var there is smt like : FI >= 0, StackOffset: 4 6933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// sw REGX, 4(SP) 7033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 7133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// - reference to previous stack frame 7233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// suppose there's a load to the 5th arguments : FI < 0, StackOffset: 16. 7333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// The emitted instruction will be something like: 7433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// lw REGX, 16+StackSize(SP) 7533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 7633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// Since the total stack size is unknown on LowerFormalArguments, all 7733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// stack references (ObjectOffset) created to reference the function 7833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// arguments, are negative numbers. This way, on eliminateFrameIndex it's 7933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// possible to detect those references and the offsets are adjusted to 8033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// their real location. 8133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 824552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===// 8333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 84d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov// hasFP - Return true if the specified function should have a dedicated frame 854552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka// pointer register. This is true if the function has variable sized allocas or 864552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka// if frame pointer elimination is disabled. 8716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovbool MipsFrameLowering::hasFP(const MachineFunction &MF) const { 88d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov const MachineFrameInfo *MFI = MF.getFrameInfo(); 898a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky return MF.getTarget().Options.DisableFramePointerElim(MF) || 908a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky MFI->hasVarSizedObjects() || MFI->isFrameAddressTaken(); 91d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov} 92d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 9369c19f7316ed8e545c7339421b910543eb8e9eefAkira Hatanakabool MipsFrameLowering::targetHandlesStackFrameRounding() const { 9469c19f7316ed8e545c7339421b910543eb8e9eefAkira Hatanaka return true; 9533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 9633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 97de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka// Build an instruction sequence to load an immediate that is too large to fit 98de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka// in 16-bit and add the result to Reg. 99de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanakastatic void expandLargeImm(unsigned Reg, int64_t Imm, bool IsN64, 100de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka const MipsInstrInfo &TII, MachineBasicBlock& MBB, 101de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka MachineBasicBlock::iterator II, DebugLoc DL) { 102de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka unsigned LUi = IsN64 ? Mips::LUi64 : Mips::LUi; 103de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka unsigned ADDu = IsN64 ? Mips::DADDu : Mips::ADDu; 104bb481f882093fb738d2bb15610c79364bada5496Jia Liu unsigned ZEROReg = IsN64 ? Mips::ZERO_64 : Mips::ZERO; 105de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka unsigned ATReg = IsN64 ? Mips::AT_64 : Mips::AT; 106de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka MipsAnalyzeImmediate AnalyzeImm; 107de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka const MipsAnalyzeImmediate::InstSeq &Seq = 108de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka AnalyzeImm.Analyze(Imm, IsN64 ? 64 : 32, false /* LastInstrIsADDiu */); 109de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka MipsAnalyzeImmediate::InstSeq::const_iterator Inst = Seq.begin(); 11099027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes 11199027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes // FIXME: change this when mips goes MC". 112de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka BuildMI(MBB, II, DL, TII.get(Mips::NOAT)); 113de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka 114de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka // The first instruction can be a LUi, which is different from other 115de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka // instructions (ADDiu, ORI and SLL) in that it does not have a register 116de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka // operand. 117de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka if (Inst->Opc == LUi) 118de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka BuildMI(MBB, II, DL, TII.get(LUi), ATReg) 119de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka .addImm(SignExtend64<16>(Inst->ImmOpnd)); 120de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka else 121de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka BuildMI(MBB, II, DL, TII.get(Inst->Opc), ATReg).addReg(ZEROReg) 122de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka .addImm(SignExtend64<16>(Inst->ImmOpnd)); 12399027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes 124de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka // Build the remaining instructions in Seq. 125de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka for (++Inst; Inst != Seq.end(); ++Inst) 126de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka BuildMI(MBB, II, DL, TII.get(Inst->Opc), ATReg).addReg(ATReg) 127de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka .addImm(SignExtend64<16>(Inst->ImmOpnd)); 128bb481f882093fb738d2bb15610c79364bada5496Jia Liu 129de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka BuildMI(MBB, II, DL, TII.get(ADDu), Reg).addReg(Reg).addReg(ATReg); 130de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka BuildMI(MBB, II, DL, TII.get(Mips::ATMACRO)); 13199027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes} 13299027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes 13316c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid MipsFrameLowering::emitPrologue(MachineFunction &MF) const { 13433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock &MBB = MF.front(); 13533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 13633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); 13733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const MipsRegisterInfo *RegInfo = 13833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); 13933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const MipsInstrInfo &TII = 14033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *static_cast<const MipsInstrInfo*>(MF.getTarget().getInstrInfo()); 14133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator MBBI = MBB.begin(); 14233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 14333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov bool isPIC = (MF.getTarget().getRelocationModel() == Reloc::PIC_); 1441b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; 1451b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; 1461b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO; 147a1fa08f66a5e92ccf5bc0b565c045be14108dae4Akira Hatanaka unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu; 148a1fa08f66a5e92ccf5bc0b565c045be14108dae4Akira Hatanaka unsigned ADDiu = STI.isABI_N64() ? Mips::DADDiu : Mips::ADDiu; 14933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 15069c19f7316ed8e545c7339421b910543eb8e9eefAkira Hatanaka // First, compute final stack size. 15169c19f7316ed8e545c7339421b910543eb8e9eefAkira Hatanaka unsigned RegSize = STI.isGP32bit() ? 4 : 8; 15269c19f7316ed8e545c7339421b910543eb8e9eefAkira Hatanaka unsigned StackAlign = getStackAlignment(); 153bb481f882093fb738d2bb15610c79364bada5496Jia Liu unsigned LocalVarAreaOffset = MipsFI->needGPSaveRestore() ? 15469c19f7316ed8e545c7339421b910543eb8e9eefAkira Hatanaka (MFI->getObjectOffset(MipsFI->getGPFI()) + RegSize) : 155f15f49850768f5889c2e12aeb273e158597a1223Akira Hatanaka MipsFI->getMaxCallFrameSize(); 156de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka uint64_t StackSize = RoundUpToAlignment(LocalVarAreaOffset, StackAlign) + 157de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka RoundUpToAlignment(MFI->getStackSize(), StackAlign); 15869c19f7316ed8e545c7339421b910543eb8e9eefAkira Hatanaka 15969c19f7316ed8e545c7339421b910543eb8e9eefAkira Hatanaka // Update stack size 160bb481f882093fb738d2bb15610c79364bada5496Jia Liu MFI->setStackSize(StackSize); 161bb481f882093fb738d2bb15610c79364bada5496Jia Liu 16233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, dl, TII.get(Mips::NOREORDER)); 163de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka BuildMI(MBB, MBBI, dl, TII.get(Mips::NOMACRO)); 164a1fa08f66a5e92ccf5bc0b565c045be14108dae4Akira Hatanaka 165648f00c2f0eb29c0ae2a333fa0bfa55970059f08Akira Hatanaka // Emit instructions that set the global base register if the target ABI is 166648f00c2f0eb29c0ae2a333fa0bfa55970059f08Akira Hatanaka // O32. 167648f00c2f0eb29c0ae2a333fa0bfa55970059f08Akira Hatanaka if (isPIC && MipsFI->globalBaseRegSet() && STI.isABI_O32()) { 168648f00c2f0eb29c0ae2a333fa0bfa55970059f08Akira Hatanaka if (MipsFI->globalBaseRegFixed()) 169648f00c2f0eb29c0ae2a333fa0bfa55970059f08Akira Hatanaka BuildMI(MBB, llvm::prior(MBBI), dl, TII.get(Mips::CPLOAD)) 170648f00c2f0eb29c0ae2a333fa0bfa55970059f08Akira Hatanaka .addReg(RegInfo->getPICCallReg()); 171648f00c2f0eb29c0ae2a333fa0bfa55970059f08Akira Hatanaka else 172648f00c2f0eb29c0ae2a333fa0bfa55970059f08Akira Hatanaka // See MipsInstrInfo.td for explanation. 173648f00c2f0eb29c0ae2a333fa0bfa55970059f08Akira Hatanaka BuildMI(MBB, MBBI, dl, TII.get(Mips:: SETGP01), Mips::V0); 174648f00c2f0eb29c0ae2a333fa0bfa55970059f08Akira Hatanaka } 175648f00c2f0eb29c0ae2a333fa0bfa55970059f08Akira Hatanaka 176f346c695309a6e3bbe80c0339387f334c07d9ab6Akira Hatanaka // No need to allocate space on the stack. 177f346c695309a6e3bbe80c0339387f334c07d9ab6Akira Hatanaka if (StackSize == 0 && !MFI->adjustsStack()) return; 178f346c695309a6e3bbe80c0339387f334c07d9ab6Akira Hatanaka 1798464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka MachineModuleInfo &MMI = MF.getMMI(); 1808464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka std::vector<MachineMove> &Moves = MMI.getFrameMoves(); 1818464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka MachineLocation DstML, SrcML; 1828464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka 183de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka // Adjust stack. 184de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka if (isInt<16>(-StackSize)) // addi sp, sp, (-stacksize) 185de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka BuildMI(MBB, MBBI, dl, TII.get(ADDiu), SP).addReg(SP).addImm(-StackSize); 186de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka else // Expand immediate that doesn't fit in 16-bit. 187de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka expandLargeImm(SP, -StackSize, STI.isABI_N64(), TII, MBB, MBBI, dl); 18833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 1898464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka // emit ".cfi_def_cfa_offset StackSize" 1908464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka MCSymbol *AdjustSPLabel = MMI.getContext().CreateTempSymbol(); 1918464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka BuildMI(MBB, MBBI, dl, 1928464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka TII.get(TargetOpcode::PROLOG_LABEL)).addSym(AdjustSPLabel); 1938464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka DstML = MachineLocation(MachineLocation::VirtualFP); 1948464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka SrcML = MachineLocation(MachineLocation::VirtualFP, -StackSize); 1958464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka Moves.push_back(MachineMove(AdjustSPLabel, DstML, SrcML)); 1968464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka 197cf0cd8005c81853ddea3ce26b71491c48dc4984eAkira Hatanaka const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 1988464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka 1998464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka if (CSI.size()) { 2000f843821385213b33116eaecf0c13e987139f6a5Akira Hatanaka // Find the instruction past the last instruction that saves a callee-saved 2010f843821385213b33116eaecf0c13e987139f6a5Akira Hatanaka // register to the stack. 2028464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka for (unsigned i = 0; i < CSI.size(); ++i) 2038464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka ++MBBI; 204bb481f882093fb738d2bb15610c79364bada5496Jia Liu 2050f843821385213b33116eaecf0c13e987139f6a5Akira Hatanaka // Iterate over list of callee-saved registers and emit .cfi_offset 2060f843821385213b33116eaecf0c13e987139f6a5Akira Hatanaka // directives. 2078464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka MCSymbol *CSLabel = MMI.getContext().CreateTempSymbol(); 2088464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka BuildMI(MBB, MBBI, dl, 2098464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel); 210bb481f882093fb738d2bb15610c79364bada5496Jia Liu 2118464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(), 2128464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka E = CSI.end(); I != E; ++I) { 2138464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka int64_t Offset = MFI->getObjectOffset(I->getFrameIdx()); 2148464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka unsigned Reg = I->getReg(); 2158464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka 2168464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka // If Reg is a double precision register, emit two cfa_offsets, 2178464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka // one for each of the paired single precision registers. 2188464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka if (Mips::AFGR64RegisterClass->contains(Reg)) { 2199ebfbf8b9fd5f982e0db9293808bd32168615ba9Craig Topper const uint16_t *SubRegs = RegInfo->getSubRegisters(Reg); 2208464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka MachineLocation DstML0(MachineLocation::VirtualFP, Offset); 2218464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka MachineLocation DstML1(MachineLocation::VirtualFP, Offset + 4); 2228464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka MachineLocation SrcML0(*SubRegs); 2238464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka MachineLocation SrcML1(*(SubRegs + 1)); 2248464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka 2258464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka if (!STI.isLittle()) 2268464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka std::swap(SrcML0, SrcML1); 2278464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka 2288464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka Moves.push_back(MachineMove(CSLabel, DstML0, SrcML0)); 2298464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka Moves.push_back(MachineMove(CSLabel, DstML1, SrcML1)); 2308464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka } 2318464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka else { 2328464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka // Reg is either in CPURegs or FGR32. 2338464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka DstML = MachineLocation(MachineLocation::VirtualFP, Offset); 2348464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka SrcML = MachineLocation(Reg); 2358464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka Moves.push_back(MachineMove(CSLabel, DstML, SrcML)); 2368464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka } 2378464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka } 238bb481f882093fb738d2bb15610c79364bada5496Jia Liu } 2398464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka 240cf0cd8005c81853ddea3ce26b71491c48dc4984eAkira Hatanaka // if framepointer enabled, set it to point to the stack pointer. 2418464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka if (hasFP(MF)) { 242bb481f882093fb738d2bb15610c79364bada5496Jia Liu // Insert instruction "move $fp, $sp" at this location. 2431b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka BuildMI(MBB, MBBI, dl, TII.get(ADDu), FP).addReg(SP).addReg(ZERO); 24433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 245bb481f882093fb738d2bb15610c79364bada5496Jia Liu // emit ".cfi_def_cfa_register $fp" 2468464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka MCSymbol *SetFPLabel = MMI.getContext().CreateTempSymbol(); 2478464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka BuildMI(MBB, MBBI, dl, 2488464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka TII.get(TargetOpcode::PROLOG_LABEL)).addSym(SetFPLabel); 2491b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka DstML = MachineLocation(FP); 2508464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka SrcML = MachineLocation(MachineLocation::VirtualFP); 2518464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka Moves.push_back(MachineMove(SetFPLabel, DstML, SrcML)); 2528464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka } 2538464fff30b16d39227444985bb7c8cc7fd12d66dAkira Hatanaka 25433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Restore GP from the saved stack location 2559029cf20e1158dbca9c95da72a646d467e871525Akira Hatanaka if (MipsFI->needGPSaveRestore()) { 2569029cf20e1158dbca9c95da72a646d467e871525Akira Hatanaka unsigned Offset = MFI->getObjectOffset(MipsFI->getGPFI()); 2579029cf20e1158dbca9c95da72a646d467e871525Akira Hatanaka BuildMI(MBB, MBBI, dl, TII.get(Mips::CPRESTORE)).addImm(Offset); 2589029cf20e1158dbca9c95da72a646d467e871525Akira Hatanaka 2599029cf20e1158dbca9c95da72a646d467e871525Akira Hatanaka if (Offset >= 0x8000) { 2609029cf20e1158dbca9c95da72a646d467e871525Akira Hatanaka BuildMI(MBB, llvm::prior(MBBI), dl, TII.get(Mips::MACRO)); 2619029cf20e1158dbca9c95da72a646d467e871525Akira Hatanaka BuildMI(MBB, MBBI, dl, TII.get(Mips::NOMACRO)); 2629029cf20e1158dbca9c95da72a646d467e871525Akira Hatanaka } 2639029cf20e1158dbca9c95da72a646d467e871525Akira Hatanaka } 26433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 26533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 26616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid MipsFrameLowering::emitEpilogue(MachineFunction &MF, 26733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock &MBB) const { 2684f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 26933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 27033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const MipsInstrInfo &TII = 27133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *static_cast<const MipsInstrInfo*>(MF.getTarget().getInstrInfo()); 27233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DebugLoc dl = MBBI->getDebugLoc(); 2731b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; 2741b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; 2751b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO; 2761b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu; 2771b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka unsigned ADDiu = STI.isABI_N64() ? Mips::DADDiu : Mips::ADDiu; 27833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 27917a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka // if framepointer enabled, restore the stack pointer. 280f346c695309a6e3bbe80c0339387f334c07d9ab6Akira Hatanaka if (hasFP(MF)) { 281f346c695309a6e3bbe80c0339387f334c07d9ab6Akira Hatanaka // Find the first instruction that restores a callee-saved register. 282f346c695309a6e3bbe80c0339387f334c07d9ab6Akira Hatanaka MachineBasicBlock::iterator I = MBBI; 283bb481f882093fb738d2bb15610c79364bada5496Jia Liu 284f346c695309a6e3bbe80c0339387f334c07d9ab6Akira Hatanaka for (unsigned i = 0; i < MFI->getCalleeSavedInfo().size(); ++i) 285f346c695309a6e3bbe80c0339387f334c07d9ab6Akira Hatanaka --I; 286f346c695309a6e3bbe80c0339387f334c07d9ab6Akira Hatanaka 287f346c695309a6e3bbe80c0339387f334c07d9ab6Akira Hatanaka // Insert instruction "move $sp, $fp" at this location. 2881b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka BuildMI(MBB, I, dl, TII.get(ADDu), SP).addReg(FP).addReg(ZERO); 289f346c695309a6e3bbe80c0339387f334c07d9ab6Akira Hatanaka } 29033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 291de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka // Get the number of bytes from FrameInfo 292de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka uint64_t StackSize = MFI->getStackSize(); 293de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka 294de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka if (!StackSize) 295de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka return; 29699027d76f31d0a9f9c86a08114545dca8b3d2dc1Bruno Cardoso Lopes 297de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka // Adjust stack. 298de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka if (isInt<16>(StackSize)) // addi sp, sp, (-stacksize) 299de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka BuildMI(MBB, MBBI, dl, TII.get(ADDiu), SP).addReg(SP).addImm(StackSize); 300de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka else // Expand immediate that doesn't fit in 16-bit. 301de5a0b65c27cc82300d3046fb9c119b8b524aa81Akira Hatanaka expandLargeImm(SP, StackSize, STI.isABI_N64(), TII, MBB, MBBI, dl); 30233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 303fb67faa6614c2bf6e5a126ccdc712a64e4263797Bruno Cardoso Lopes 304fb67faa6614c2bf6e5a126ccdc712a64e4263797Bruno Cardoso Lopesvoid MipsFrameLowering:: 30517a1e8775119db75ece41e041eeb6480793696ffAkira HatanakaprocessFunctionBeforeCalleeSavedScan(MachineFunction &MF, 30617a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka RegScavenger *RS) const { 30717a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka MachineRegisterInfo& MRI = MF.getRegInfo(); 3081b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; 30917a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka 31017a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka // FIXME: remove this code if register allocator can correctly mark 31117a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka // $fp and $ra used or unused. 31217a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka 31317a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka // Mark $fp and $ra as used or unused. 31417a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka if (hasFP(MF)) 3151b71950812a7595916d85b03d9ec8413ba8c13f1Akira Hatanaka MRI.setPhysRegUsed(FP); 31617a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka 317bb481f882093fb738d2bb15610c79364bada5496Jia Liu // The register allocator might determine $ra is used after seeing 31817a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka // instruction "jr $ra", but we do not want PrologEpilogInserter to insert 31917a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka // instructions to save/restore $ra unless there is a function call. 32017a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka // To correct this, $ra is explicitly marked unused if there is no 32117a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka // function call. 32233458fedb607e64c46af6797057fbf0b4973a6f6Akira Hatanaka if (MF.getFrameInfo()->hasCalls()) 3234bd73cac6abf8afa291f0e37e2240835fc1d08f0Akira Hatanaka MRI.setPhysRegUsed(Mips::RA); 3244bd73cac6abf8afa291f0e37e2240835fc1d08f0Akira Hatanaka else { 3254bd73cac6abf8afa291f0e37e2240835fc1d08f0Akira Hatanaka MRI.setPhysRegUnused(Mips::RA); 3264bd73cac6abf8afa291f0e37e2240835fc1d08f0Akira Hatanaka MRI.setPhysRegUnused(Mips::RA_64); 3274bd73cac6abf8afa291f0e37e2240835fc1d08f0Akira Hatanaka } 32817a1e8775119db75ece41e041eeb6480793696ffAkira Hatanaka} 329