MipsSEFrameLowering.cpp revision 239310
1239310Sdim//===-- MipsSEFrameLowering.cpp - Mips32/64 Frame Information -------------===// 2239310Sdim// 3239310Sdim// The LLVM Compiler Infrastructure 4239310Sdim// 5239310Sdim// This file is distributed under the University of Illinois Open Source 6239310Sdim// License. See LICENSE.TXT for details. 7239310Sdim// 8239310Sdim//===----------------------------------------------------------------------===// 9239310Sdim// 10239310Sdim// This file contains the Mips32/64 implementation of TargetFrameLowering class. 11239310Sdim// 12239310Sdim//===----------------------------------------------------------------------===// 13239310Sdim 14239310Sdim#include "MipsSEFrameLowering.h" 15239310Sdim#include "MipsAnalyzeImmediate.h" 16239310Sdim#include "MipsSEInstrInfo.h" 17239310Sdim#include "MipsMachineFunction.h" 18239310Sdim#include "MCTargetDesc/MipsBaseInfo.h" 19239310Sdim#include "llvm/Function.h" 20239310Sdim#include "llvm/CodeGen/MachineFrameInfo.h" 21239310Sdim#include "llvm/CodeGen/MachineFunction.h" 22239310Sdim#include "llvm/CodeGen/MachineInstrBuilder.h" 23239310Sdim#include "llvm/CodeGen/MachineModuleInfo.h" 24239310Sdim#include "llvm/CodeGen/MachineRegisterInfo.h" 25239310Sdim#include "llvm/Target/TargetData.h" 26239310Sdim#include "llvm/Target/TargetOptions.h" 27239310Sdim#include "llvm/Support/CommandLine.h" 28239310Sdim 29239310Sdimusing namespace llvm; 30239310Sdim 31239310Sdimvoid MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const { 32239310Sdim MachineBasicBlock &MBB = MF.front(); 33239310Sdim MachineFrameInfo *MFI = MF.getFrameInfo(); 34239310Sdim const MipsRegisterInfo *RegInfo = 35239310Sdim static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); 36239310Sdim const MipsSEInstrInfo &TII = 37239310Sdim *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); 38239310Sdim MachineBasicBlock::iterator MBBI = MBB.begin(); 39239310Sdim DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 40239310Sdim unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; 41239310Sdim unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; 42239310Sdim unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO; 43239310Sdim unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu; 44239310Sdim 45239310Sdim // First, compute final stack size. 46239310Sdim uint64_t StackSize = MFI->getStackSize(); 47239310Sdim 48239310Sdim // No need to allocate space on the stack. 49239310Sdim if (StackSize == 0 && !MFI->adjustsStack()) return; 50239310Sdim 51239310Sdim MachineModuleInfo &MMI = MF.getMMI(); 52239310Sdim std::vector<MachineMove> &Moves = MMI.getFrameMoves(); 53239310Sdim MachineLocation DstML, SrcML; 54239310Sdim 55239310Sdim // Adjust stack. 56239310Sdim TII.adjustStackPtr(SP, -StackSize, MBB, MBBI); 57239310Sdim 58239310Sdim // emit ".cfi_def_cfa_offset StackSize" 59239310Sdim MCSymbol *AdjustSPLabel = MMI.getContext().CreateTempSymbol(); 60239310Sdim BuildMI(MBB, MBBI, dl, 61239310Sdim TII.get(TargetOpcode::PROLOG_LABEL)).addSym(AdjustSPLabel); 62239310Sdim DstML = MachineLocation(MachineLocation::VirtualFP); 63239310Sdim SrcML = MachineLocation(MachineLocation::VirtualFP, -StackSize); 64239310Sdim Moves.push_back(MachineMove(AdjustSPLabel, DstML, SrcML)); 65239310Sdim 66239310Sdim const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 67239310Sdim 68239310Sdim if (CSI.size()) { 69239310Sdim // Find the instruction past the last instruction that saves a callee-saved 70239310Sdim // register to the stack. 71239310Sdim for (unsigned i = 0; i < CSI.size(); ++i) 72239310Sdim ++MBBI; 73239310Sdim 74239310Sdim // Iterate over list of callee-saved registers and emit .cfi_offset 75239310Sdim // directives. 76239310Sdim MCSymbol *CSLabel = MMI.getContext().CreateTempSymbol(); 77239310Sdim BuildMI(MBB, MBBI, dl, 78239310Sdim TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel); 79239310Sdim 80239310Sdim for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(), 81239310Sdim E = CSI.end(); I != E; ++I) { 82239310Sdim int64_t Offset = MFI->getObjectOffset(I->getFrameIdx()); 83239310Sdim unsigned Reg = I->getReg(); 84239310Sdim 85239310Sdim // If Reg is a double precision register, emit two cfa_offsets, 86239310Sdim // one for each of the paired single precision registers. 87239310Sdim if (Mips::AFGR64RegClass.contains(Reg)) { 88239310Sdim MachineLocation DstML0(MachineLocation::VirtualFP, Offset); 89239310Sdim MachineLocation DstML1(MachineLocation::VirtualFP, Offset + 4); 90239310Sdim MachineLocation SrcML0(RegInfo->getSubReg(Reg, Mips::sub_fpeven)); 91239310Sdim MachineLocation SrcML1(RegInfo->getSubReg(Reg, Mips::sub_fpodd)); 92239310Sdim 93239310Sdim if (!STI.isLittle()) 94239310Sdim std::swap(SrcML0, SrcML1); 95239310Sdim 96239310Sdim Moves.push_back(MachineMove(CSLabel, DstML0, SrcML0)); 97239310Sdim Moves.push_back(MachineMove(CSLabel, DstML1, SrcML1)); 98239310Sdim } else { 99239310Sdim // Reg is either in CPURegs or FGR32. 100239310Sdim DstML = MachineLocation(MachineLocation::VirtualFP, Offset); 101239310Sdim SrcML = MachineLocation(Reg); 102239310Sdim Moves.push_back(MachineMove(CSLabel, DstML, SrcML)); 103239310Sdim } 104239310Sdim } 105239310Sdim } 106239310Sdim 107239310Sdim // if framepointer enabled, set it to point to the stack pointer. 108239310Sdim if (hasFP(MF)) { 109239310Sdim // Insert instruction "move $fp, $sp" at this location. 110239310Sdim BuildMI(MBB, MBBI, dl, TII.get(ADDu), FP).addReg(SP).addReg(ZERO); 111239310Sdim 112239310Sdim // emit ".cfi_def_cfa_register $fp" 113239310Sdim MCSymbol *SetFPLabel = MMI.getContext().CreateTempSymbol(); 114239310Sdim BuildMI(MBB, MBBI, dl, 115239310Sdim TII.get(TargetOpcode::PROLOG_LABEL)).addSym(SetFPLabel); 116239310Sdim DstML = MachineLocation(FP); 117239310Sdim SrcML = MachineLocation(MachineLocation::VirtualFP); 118239310Sdim Moves.push_back(MachineMove(SetFPLabel, DstML, SrcML)); 119239310Sdim } 120239310Sdim} 121239310Sdim 122239310Sdimvoid MipsSEFrameLowering::emitEpilogue(MachineFunction &MF, 123239310Sdim MachineBasicBlock &MBB) const { 124239310Sdim MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 125239310Sdim MachineFrameInfo *MFI = MF.getFrameInfo(); 126239310Sdim const MipsSEInstrInfo &TII = 127239310Sdim *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); 128239310Sdim DebugLoc dl = MBBI->getDebugLoc(); 129239310Sdim unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; 130239310Sdim unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; 131239310Sdim unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO; 132239310Sdim unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu; 133239310Sdim 134239310Sdim // if framepointer enabled, restore the stack pointer. 135239310Sdim if (hasFP(MF)) { 136239310Sdim // Find the first instruction that restores a callee-saved register. 137239310Sdim MachineBasicBlock::iterator I = MBBI; 138239310Sdim 139239310Sdim for (unsigned i = 0; i < MFI->getCalleeSavedInfo().size(); ++i) 140239310Sdim --I; 141239310Sdim 142239310Sdim // Insert instruction "move $sp, $fp" at this location. 143239310Sdim BuildMI(MBB, I, dl, TII.get(ADDu), SP).addReg(FP).addReg(ZERO); 144239310Sdim } 145239310Sdim 146239310Sdim // Get the number of bytes from FrameInfo 147239310Sdim uint64_t StackSize = MFI->getStackSize(); 148239310Sdim 149239310Sdim if (!StackSize) 150239310Sdim return; 151239310Sdim 152239310Sdim // Adjust stack. 153239310Sdim TII.adjustStackPtr(SP, StackSize, MBB, MBBI); 154239310Sdim} 155239310Sdim 156239310Sdimbool MipsSEFrameLowering:: 157239310SdimspillCalleeSavedRegisters(MachineBasicBlock &MBB, 158239310Sdim MachineBasicBlock::iterator MI, 159239310Sdim const std::vector<CalleeSavedInfo> &CSI, 160239310Sdim const TargetRegisterInfo *TRI) const { 161239310Sdim MachineFunction *MF = MBB.getParent(); 162239310Sdim MachineBasicBlock *EntryBlock = MF->begin(); 163239310Sdim const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo(); 164239310Sdim 165239310Sdim for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 166239310Sdim // Add the callee-saved register as live-in. Do not add if the register is 167239310Sdim // RA and return address is taken, because it has already been added in 168239310Sdim // method MipsTargetLowering::LowerRETURNADDR. 169239310Sdim // It's killed at the spill, unless the register is RA and return address 170239310Sdim // is taken. 171239310Sdim unsigned Reg = CSI[i].getReg(); 172239310Sdim bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA || Reg == Mips::RA_64) 173239310Sdim && MF->getFrameInfo()->isReturnAddressTaken(); 174239310Sdim if (!IsRAAndRetAddrIsTaken) 175239310Sdim EntryBlock->addLiveIn(Reg); 176239310Sdim 177239310Sdim // Insert the spill to the stack frame. 178239310Sdim bool IsKill = !IsRAAndRetAddrIsTaken; 179239310Sdim const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 180239310Sdim TII.storeRegToStackSlot(*EntryBlock, MI, Reg, IsKill, 181239310Sdim CSI[i].getFrameIdx(), RC, TRI); 182239310Sdim } 183239310Sdim 184239310Sdim return true; 185239310Sdim} 186239310Sdim 187239310Sdimbool 188239310SdimMipsSEFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 189239310Sdim const MachineFrameInfo *MFI = MF.getFrameInfo(); 190239310Sdim 191239310Sdim // Reserve call frame if the size of the maximum call frame fits into 16-bit 192239310Sdim // immediate field and there are no variable sized objects on the stack. 193239310Sdim return isInt<16>(MFI->getMaxCallFrameSize()) && !MFI->hasVarSizedObjects(); 194239310Sdim} 195239310Sdim 196239310Sdimvoid MipsSEFrameLowering:: 197239310SdimprocessFunctionBeforeCalleeSavedScan(MachineFunction &MF, 198239310Sdim RegScavenger *RS) const { 199239310Sdim MachineRegisterInfo &MRI = MF.getRegInfo(); 200239310Sdim unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; 201239310Sdim 202239310Sdim // Mark $fp as used if function has dedicated frame pointer. 203239310Sdim if (hasFP(MF)) 204239310Sdim MRI.setPhysRegUsed(FP); 205239310Sdim} 206239310Sdim 207239310Sdimconst MipsFrameLowering * 208239310Sdimllvm::createMipsSEFrameLowering(const MipsSubtarget &ST) { 209239310Sdim return new MipsSEFrameLowering(ST); 210239310Sdim} 211