1//===-- MipsSEFrameLowering.cpp - Mips32/64 Frame Information -------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file contains the Mips32/64 implementation of TargetFrameLowering class. 11// 12//===----------------------------------------------------------------------===// 13 14#include "MipsSEFrameLowering.h" 15#include "MCTargetDesc/MipsBaseInfo.h" 16#include "MipsAnalyzeImmediate.h" 17#include "MipsMachineFunction.h" 18#include "MipsSEInstrInfo.h" 19#include "llvm/CodeGen/MachineFrameInfo.h" 20#include "llvm/CodeGen/MachineFunction.h" 21#include "llvm/CodeGen/MachineInstrBuilder.h" 22#include "llvm/CodeGen/MachineModuleInfo.h" 23#include "llvm/CodeGen/MachineRegisterInfo.h" 24#include "llvm/CodeGen/RegisterScavenging.h" 25#include "llvm/IR/DataLayout.h" 26#include "llvm/IR/Function.h" 27#include "llvm/Support/CommandLine.h" 28#include "llvm/Target/TargetOptions.h" 29 30using namespace llvm; 31 32unsigned MipsSEFrameLowering::ehDataReg(unsigned I) const { 33 static const unsigned EhDataReg[] = { 34 Mips::A0, Mips::A1, Mips::A2, Mips::A3 35 }; 36 static const unsigned EhDataReg64[] = { 37 Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64 38 }; 39 40 return STI.isABI_N64() ? EhDataReg64[I] : EhDataReg[I]; 41} 42 43void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const { 44 MachineBasicBlock &MBB = MF.front(); 45 MachineFrameInfo *MFI = MF.getFrameInfo(); 46 MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); 47 const MipsRegisterInfo *RegInfo = 48 static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); 49 const MipsSEInstrInfo &TII = 50 *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); 51 MachineBasicBlock::iterator MBBI = MBB.begin(); 52 DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 53 unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; 54 unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; 55 unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO; 56 unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu; 57 58 // First, compute final stack size. 59 uint64_t StackSize = MFI->getStackSize(); 60 61 // No need to allocate space on the stack. 62 if (StackSize == 0 && !MFI->adjustsStack()) return; 63 64 MachineModuleInfo &MMI = MF.getMMI(); 65 std::vector<MachineMove> &Moves = MMI.getFrameMoves(); 66 MachineLocation DstML, SrcML; 67 68 // Adjust stack. 69 TII.adjustStackPtr(SP, -StackSize, MBB, MBBI); 70 71 // emit ".cfi_def_cfa_offset StackSize" 72 MCSymbol *AdjustSPLabel = MMI.getContext().CreateTempSymbol(); 73 BuildMI(MBB, MBBI, dl, 74 TII.get(TargetOpcode::PROLOG_LABEL)).addSym(AdjustSPLabel); 75 DstML = MachineLocation(MachineLocation::VirtualFP); 76 SrcML = MachineLocation(MachineLocation::VirtualFP, -StackSize); 77 Moves.push_back(MachineMove(AdjustSPLabel, DstML, SrcML)); 78 79 const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 80 81 if (CSI.size()) { 82 // Find the instruction past the last instruction that saves a callee-saved 83 // register to the stack. 84 for (unsigned i = 0; i < CSI.size(); ++i) 85 ++MBBI; 86 87 // Iterate over list of callee-saved registers and emit .cfi_offset 88 // directives. 89 MCSymbol *CSLabel = MMI.getContext().CreateTempSymbol(); 90 BuildMI(MBB, MBBI, dl, 91 TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel); 92 93 for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(), 94 E = CSI.end(); I != E; ++I) { 95 int64_t Offset = MFI->getObjectOffset(I->getFrameIdx()); 96 unsigned Reg = I->getReg(); 97 98 // If Reg is a double precision register, emit two cfa_offsets, 99 // one for each of the paired single precision registers. 100 if (Mips::AFGR64RegClass.contains(Reg)) { 101 MachineLocation DstML0(MachineLocation::VirtualFP, Offset); 102 MachineLocation DstML1(MachineLocation::VirtualFP, Offset + 4); 103 MachineLocation SrcML0(RegInfo->getSubReg(Reg, Mips::sub_fpeven)); 104 MachineLocation SrcML1(RegInfo->getSubReg(Reg, Mips::sub_fpodd)); 105 106 if (!STI.isLittle()) 107 std::swap(SrcML0, SrcML1); 108 109 Moves.push_back(MachineMove(CSLabel, DstML0, SrcML0)); 110 Moves.push_back(MachineMove(CSLabel, DstML1, SrcML1)); 111 } else { 112 // Reg is either in CPURegs or FGR32. 113 DstML = MachineLocation(MachineLocation::VirtualFP, Offset); 114 SrcML = MachineLocation(Reg); 115 Moves.push_back(MachineMove(CSLabel, DstML, SrcML)); 116 } 117 } 118 } 119 120 if (MipsFI->callsEhReturn()) { 121 const TargetRegisterClass *RC = STI.isABI_N64() ? 122 &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass; 123 124 // Insert instructions that spill eh data registers. 125 for (int I = 0; I < 4; ++I) { 126 if (!MBB.isLiveIn(ehDataReg(I))) 127 MBB.addLiveIn(ehDataReg(I)); 128 TII.storeRegToStackSlot(MBB, MBBI, ehDataReg(I), false, 129 MipsFI->getEhDataRegFI(I), RC, RegInfo); 130 } 131 132 // Emit .cfi_offset directives for eh data registers. 133 MCSymbol *CSLabel2 = MMI.getContext().CreateTempSymbol(); 134 BuildMI(MBB, MBBI, dl, 135 TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel2); 136 for (int I = 0; I < 4; ++I) { 137 int64_t Offset = MFI->getObjectOffset(MipsFI->getEhDataRegFI(I)); 138 DstML = MachineLocation(MachineLocation::VirtualFP, Offset); 139 SrcML = MachineLocation(ehDataReg(I)); 140 Moves.push_back(MachineMove(CSLabel2, DstML, SrcML)); 141 } 142 } 143 144 // if framepointer enabled, set it to point to the stack pointer. 145 if (hasFP(MF)) { 146 // Insert instruction "move $fp, $sp" at this location. 147 BuildMI(MBB, MBBI, dl, TII.get(ADDu), FP).addReg(SP).addReg(ZERO); 148 149 // emit ".cfi_def_cfa_register $fp" 150 MCSymbol *SetFPLabel = MMI.getContext().CreateTempSymbol(); 151 BuildMI(MBB, MBBI, dl, 152 TII.get(TargetOpcode::PROLOG_LABEL)).addSym(SetFPLabel); 153 DstML = MachineLocation(FP); 154 SrcML = MachineLocation(MachineLocation::VirtualFP); 155 Moves.push_back(MachineMove(SetFPLabel, DstML, SrcML)); 156 } 157} 158 159void MipsSEFrameLowering::emitEpilogue(MachineFunction &MF, 160 MachineBasicBlock &MBB) const { 161 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 162 MachineFrameInfo *MFI = MF.getFrameInfo(); 163 MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); 164 const MipsRegisterInfo *RegInfo = 165 static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); 166 const MipsSEInstrInfo &TII = 167 *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); 168 DebugLoc dl = MBBI->getDebugLoc(); 169 unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; 170 unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; 171 unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO; 172 unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu; 173 174 // if framepointer enabled, restore the stack pointer. 175 if (hasFP(MF)) { 176 // Find the first instruction that restores a callee-saved register. 177 MachineBasicBlock::iterator I = MBBI; 178 179 for (unsigned i = 0; i < MFI->getCalleeSavedInfo().size(); ++i) 180 --I; 181 182 // Insert instruction "move $sp, $fp" at this location. 183 BuildMI(MBB, I, dl, TII.get(ADDu), SP).addReg(FP).addReg(ZERO); 184 } 185 186 if (MipsFI->callsEhReturn()) { 187 const TargetRegisterClass *RC = STI.isABI_N64() ? 188 &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass; 189 190 // Find first instruction that restores a callee-saved register. 191 MachineBasicBlock::iterator I = MBBI; 192 for (unsigned i = 0; i < MFI->getCalleeSavedInfo().size(); ++i) 193 --I; 194 195 // Insert instructions that restore eh data registers. 196 for (int J = 0; J < 4; ++J) { 197 TII.loadRegFromStackSlot(MBB, I, ehDataReg(J), MipsFI->getEhDataRegFI(J), 198 RC, RegInfo); 199 } 200 } 201 202 // Get the number of bytes from FrameInfo 203 uint64_t StackSize = MFI->getStackSize(); 204 205 if (!StackSize) 206 return; 207 208 // Adjust stack. 209 TII.adjustStackPtr(SP, StackSize, MBB, MBBI); 210} 211 212bool MipsSEFrameLowering:: 213spillCalleeSavedRegisters(MachineBasicBlock &MBB, 214 MachineBasicBlock::iterator MI, 215 const std::vector<CalleeSavedInfo> &CSI, 216 const TargetRegisterInfo *TRI) const { 217 MachineFunction *MF = MBB.getParent(); 218 MachineBasicBlock *EntryBlock = MF->begin(); 219 const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo(); 220 221 for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 222 // Add the callee-saved register as live-in. Do not add if the register is 223 // RA and return address is taken, because it has already been added in 224 // method MipsTargetLowering::LowerRETURNADDR. 225 // It's killed at the spill, unless the register is RA and return address 226 // is taken. 227 unsigned Reg = CSI[i].getReg(); 228 bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA || Reg == Mips::RA_64) 229 && MF->getFrameInfo()->isReturnAddressTaken(); 230 if (!IsRAAndRetAddrIsTaken) 231 EntryBlock->addLiveIn(Reg); 232 233 // Insert the spill to the stack frame. 234 bool IsKill = !IsRAAndRetAddrIsTaken; 235 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 236 TII.storeRegToStackSlot(*EntryBlock, MI, Reg, IsKill, 237 CSI[i].getFrameIdx(), RC, TRI); 238 } 239 240 return true; 241} 242 243bool 244MipsSEFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 245 const MachineFrameInfo *MFI = MF.getFrameInfo(); 246 247 // Reserve call frame if the size of the maximum call frame fits into 16-bit 248 // immediate field and there are no variable sized objects on the stack. 249 return isInt<16>(MFI->getMaxCallFrameSize()) && !MFI->hasVarSizedObjects(); 250} 251 252// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions 253void MipsSEFrameLowering:: 254eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 255 MachineBasicBlock::iterator I) const { 256 const MipsSEInstrInfo &TII = 257 *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); 258 259 if (!hasReservedCallFrame(MF)) { 260 int64_t Amount = I->getOperand(0).getImm(); 261 262 if (I->getOpcode() == Mips::ADJCALLSTACKDOWN) 263 Amount = -Amount; 264 265 unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; 266 TII.adjustStackPtr(SP, Amount, MBB, I); 267 } 268 269 MBB.erase(I); 270} 271 272void MipsSEFrameLowering:: 273processFunctionBeforeCalleeSavedScan(MachineFunction &MF, 274 RegScavenger *RS) const { 275 MachineRegisterInfo &MRI = MF.getRegInfo(); 276 MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); 277 unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; 278 279 // Mark $fp as used if function has dedicated frame pointer. 280 if (hasFP(MF)) 281 MRI.setPhysRegUsed(FP); 282 283 // Create spill slots for eh data registers if function calls eh_return. 284 if (MipsFI->callsEhReturn()) 285 MipsFI->createEhDataRegsFI(); 286 287 // Set scavenging frame index if necessary. 288 uint64_t MaxSPOffset = MF.getInfo<MipsFunctionInfo>()->getIncomingArgSize() + 289 estimateStackSize(MF); 290 291 if (isInt<16>(MaxSPOffset)) 292 return; 293 294 const TargetRegisterClass *RC = STI.isABI_N64() ? 295 &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass; 296 int FI = MF.getFrameInfo()->CreateStackObject(RC->getSize(), 297 RC->getAlignment(), false); 298 RS->setScavengingFrameIndex(FI); 299} 300 301const MipsFrameLowering * 302llvm::createMipsSEFrameLowering(const MipsSubtarget &ST) { 303 return new MipsSEFrameLowering(ST); 304} 305