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" 15249423Sdim#include "MCTargetDesc/MipsBaseInfo.h" 16239310Sdim#include "MipsAnalyzeImmediate.h" 17249423Sdim#include "MipsMachineFunction.h" 18239310Sdim#include "MipsSEInstrInfo.h" 19239310Sdim#include "llvm/CodeGen/MachineFrameInfo.h" 20239310Sdim#include "llvm/CodeGen/MachineFunction.h" 21239310Sdim#include "llvm/CodeGen/MachineInstrBuilder.h" 22239310Sdim#include "llvm/CodeGen/MachineModuleInfo.h" 23239310Sdim#include "llvm/CodeGen/MachineRegisterInfo.h" 24243830Sdim#include "llvm/CodeGen/RegisterScavenging.h" 25249423Sdim#include "llvm/IR/DataLayout.h" 26249423Sdim#include "llvm/IR/Function.h" 27249423Sdim#include "llvm/Support/CommandLine.h" 28239310Sdim#include "llvm/Target/TargetOptions.h" 29239310Sdim 30239310Sdimusing namespace llvm; 31239310Sdim 32249423Sdimnamespace { 33249423Sdimtypedef MachineBasicBlock::iterator Iter; 34249423Sdim 35251662Sdim/// Helper class to expand pseudos. 36251662Sdimclass ExpandPseudo { 37249423Sdimpublic: 38251662Sdim ExpandPseudo(MachineFunction &MF); 39249423Sdim bool expand(); 40249423Sdim 41249423Sdimprivate: 42249423Sdim bool expandInstr(MachineBasicBlock &MBB, Iter I); 43251662Sdim void expandLoadCCond(MachineBasicBlock &MBB, Iter I); 44251662Sdim void expandStoreCCond(MachineBasicBlock &MBB, Iter I); 45251662Sdim void expandLoadACC(MachineBasicBlock &MBB, Iter I, unsigned RegSize); 46251662Sdim void expandStoreACC(MachineBasicBlock &MBB, Iter I, unsigned RegSize); 47251662Sdim bool expandCopy(MachineBasicBlock &MBB, Iter I); 48251662Sdim bool expandCopyACC(MachineBasicBlock &MBB, Iter I, unsigned Dst, 49251662Sdim unsigned Src, unsigned RegSize); 50249423Sdim 51249423Sdim MachineFunction &MF; 52249423Sdim const MipsSEInstrInfo &TII; 53249423Sdim const MipsRegisterInfo &RegInfo; 54249423Sdim MachineRegisterInfo &MRI; 55249423Sdim}; 56249423Sdim} 57249423Sdim 58251662SdimExpandPseudo::ExpandPseudo(MachineFunction &MF_) 59249423Sdim : MF(MF_), 60249423Sdim TII(*static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo())), 61249423Sdim RegInfo(TII.getRegisterInfo()), MRI(MF.getRegInfo()) {} 62249423Sdim 63251662Sdimbool ExpandPseudo::expand() { 64249423Sdim bool Expanded = false; 65249423Sdim 66249423Sdim for (MachineFunction::iterator BB = MF.begin(), BBEnd = MF.end(); 67249423Sdim BB != BBEnd; ++BB) 68249423Sdim for (Iter I = BB->begin(), End = BB->end(); I != End;) 69249423Sdim Expanded |= expandInstr(*BB, I++); 70249423Sdim 71249423Sdim return Expanded; 72249423Sdim} 73249423Sdim 74251662Sdimbool ExpandPseudo::expandInstr(MachineBasicBlock &MBB, Iter I) { 75249423Sdim switch(I->getOpcode()) { 76251662Sdim case Mips::LOAD_CCOND_DSP: 77251662Sdim case Mips::LOAD_CCOND_DSP_P8: 78251662Sdim expandLoadCCond(MBB, I); 79251662Sdim break; 80251662Sdim case Mips::STORE_CCOND_DSP: 81251662Sdim case Mips::STORE_CCOND_DSP_P8: 82251662Sdim expandStoreCCond(MBB, I); 83251662Sdim break; 84249423Sdim case Mips::LOAD_AC64: 85249423Sdim case Mips::LOAD_AC64_P8: 86249423Sdim case Mips::LOAD_AC_DSP: 87249423Sdim case Mips::LOAD_AC_DSP_P8: 88251662Sdim expandLoadACC(MBB, I, 4); 89249423Sdim break; 90249423Sdim case Mips::LOAD_AC128: 91249423Sdim case Mips::LOAD_AC128_P8: 92251662Sdim expandLoadACC(MBB, I, 8); 93249423Sdim break; 94249423Sdim case Mips::STORE_AC64: 95249423Sdim case Mips::STORE_AC64_P8: 96249423Sdim case Mips::STORE_AC_DSP: 97249423Sdim case Mips::STORE_AC_DSP_P8: 98251662Sdim expandStoreACC(MBB, I, 4); 99249423Sdim break; 100249423Sdim case Mips::STORE_AC128: 101249423Sdim case Mips::STORE_AC128_P8: 102251662Sdim expandStoreACC(MBB, I, 8); 103249423Sdim break; 104251662Sdim case TargetOpcode::COPY: 105251662Sdim if (!expandCopy(MBB, I)) 106251662Sdim return false; 107249423Sdim break; 108249423Sdim default: 109249423Sdim return false; 110249423Sdim } 111249423Sdim 112249423Sdim MBB.erase(I); 113249423Sdim return true; 114249423Sdim} 115249423Sdim 116251662Sdimvoid ExpandPseudo::expandLoadCCond(MachineBasicBlock &MBB, Iter I) { 117251662Sdim // load $vr, FI 118251662Sdim // copy ccond, $vr 119251662Sdim 120251662Sdim assert(I->getOperand(0).isReg() && I->getOperand(1).isFI()); 121251662Sdim 122251662Sdim const TargetRegisterClass *RC = RegInfo.intRegClass(4); 123251662Sdim unsigned VR = MRI.createVirtualRegister(RC); 124251662Sdim unsigned Dst = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex(); 125251662Sdim 126251662Sdim TII.loadRegFromStack(MBB, I, VR, FI, RC, &RegInfo, 0); 127251662Sdim BuildMI(MBB, I, I->getDebugLoc(), TII.get(TargetOpcode::COPY), Dst) 128251662Sdim .addReg(VR, RegState::Kill); 129251662Sdim} 130251662Sdim 131251662Sdimvoid ExpandPseudo::expandStoreCCond(MachineBasicBlock &MBB, Iter I) { 132251662Sdim // copy $vr, ccond 133251662Sdim // store $vr, FI 134251662Sdim 135251662Sdim assert(I->getOperand(0).isReg() && I->getOperand(1).isFI()); 136251662Sdim 137251662Sdim const TargetRegisterClass *RC = RegInfo.intRegClass(4); 138251662Sdim unsigned VR = MRI.createVirtualRegister(RC); 139251662Sdim unsigned Src = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex(); 140251662Sdim 141251662Sdim BuildMI(MBB, I, I->getDebugLoc(), TII.get(TargetOpcode::COPY), VR) 142251662Sdim .addReg(Src, getKillRegState(I->getOperand(0).isKill())); 143251662Sdim TII.storeRegToStack(MBB, I, VR, true, FI, RC, &RegInfo, 0); 144251662Sdim} 145251662Sdim 146251662Sdimvoid ExpandPseudo::expandLoadACC(MachineBasicBlock &MBB, Iter I, 147249423Sdim unsigned RegSize) { 148249423Sdim // load $vr0, FI 149249423Sdim // copy lo, $vr0 150249423Sdim // load $vr1, FI + 4 151249423Sdim // copy hi, $vr1 152249423Sdim 153249423Sdim assert(I->getOperand(0).isReg() && I->getOperand(1).isFI()); 154249423Sdim 155249423Sdim const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize); 156249423Sdim unsigned VR0 = MRI.createVirtualRegister(RC); 157249423Sdim unsigned VR1 = MRI.createVirtualRegister(RC); 158249423Sdim unsigned Dst = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex(); 159249423Sdim unsigned Lo = RegInfo.getSubReg(Dst, Mips::sub_lo); 160249423Sdim unsigned Hi = RegInfo.getSubReg(Dst, Mips::sub_hi); 161249423Sdim DebugLoc DL = I->getDebugLoc(); 162249423Sdim const MCInstrDesc &Desc = TII.get(TargetOpcode::COPY); 163249423Sdim 164249423Sdim TII.loadRegFromStack(MBB, I, VR0, FI, RC, &RegInfo, 0); 165249423Sdim BuildMI(MBB, I, DL, Desc, Lo).addReg(VR0, RegState::Kill); 166249423Sdim TII.loadRegFromStack(MBB, I, VR1, FI, RC, &RegInfo, RegSize); 167249423Sdim BuildMI(MBB, I, DL, Desc, Hi).addReg(VR1, RegState::Kill); 168249423Sdim} 169249423Sdim 170251662Sdimvoid ExpandPseudo::expandStoreACC(MachineBasicBlock &MBB, Iter I, 171249423Sdim unsigned RegSize) { 172249423Sdim // copy $vr0, lo 173249423Sdim // store $vr0, FI 174249423Sdim // copy $vr1, hi 175249423Sdim // store $vr1, FI + 4 176249423Sdim 177249423Sdim assert(I->getOperand(0).isReg() && I->getOperand(1).isFI()); 178249423Sdim 179249423Sdim const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize); 180249423Sdim unsigned VR0 = MRI.createVirtualRegister(RC); 181249423Sdim unsigned VR1 = MRI.createVirtualRegister(RC); 182249423Sdim unsigned Src = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex(); 183249423Sdim unsigned SrcKill = getKillRegState(I->getOperand(0).isKill()); 184249423Sdim unsigned Lo = RegInfo.getSubReg(Src, Mips::sub_lo); 185249423Sdim unsigned Hi = RegInfo.getSubReg(Src, Mips::sub_hi); 186249423Sdim DebugLoc DL = I->getDebugLoc(); 187249423Sdim 188249423Sdim BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), VR0).addReg(Lo, SrcKill); 189249423Sdim TII.storeRegToStack(MBB, I, VR0, true, FI, RC, &RegInfo, 0); 190249423Sdim BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), VR1).addReg(Hi, SrcKill); 191249423Sdim TII.storeRegToStack(MBB, I, VR1, true, FI, RC, &RegInfo, RegSize); 192249423Sdim} 193249423Sdim 194251662Sdimbool ExpandPseudo::expandCopy(MachineBasicBlock &MBB, Iter I) { 195251662Sdim unsigned Dst = I->getOperand(0).getReg(), Src = I->getOperand(1).getReg(); 196251662Sdim 197251662Sdim if (Mips::ACRegsDSPRegClass.contains(Dst, Src)) 198251662Sdim return expandCopyACC(MBB, I, Dst, Src, 4); 199251662Sdim 200251662Sdim if (Mips::ACRegs128RegClass.contains(Dst, Src)) 201251662Sdim return expandCopyACC(MBB, I, Dst, Src, 8); 202251662Sdim 203251662Sdim return false; 204251662Sdim} 205251662Sdim 206251662Sdimbool ExpandPseudo::expandCopyACC(MachineBasicBlock &MBB, Iter I, unsigned Dst, 207251662Sdim unsigned Src, unsigned RegSize) { 208249423Sdim // copy $vr0, src_lo 209249423Sdim // copy dst_lo, $vr0 210249423Sdim // copy $vr1, src_hi 211249423Sdim // copy dst_hi, $vr1 212249423Sdim 213249423Sdim const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize); 214249423Sdim unsigned VR0 = MRI.createVirtualRegister(RC); 215249423Sdim unsigned VR1 = MRI.createVirtualRegister(RC); 216249423Sdim unsigned SrcKill = getKillRegState(I->getOperand(1).isKill()); 217249423Sdim unsigned DstLo = RegInfo.getSubReg(Dst, Mips::sub_lo); 218249423Sdim unsigned DstHi = RegInfo.getSubReg(Dst, Mips::sub_hi); 219249423Sdim unsigned SrcLo = RegInfo.getSubReg(Src, Mips::sub_lo); 220249423Sdim unsigned SrcHi = RegInfo.getSubReg(Src, Mips::sub_hi); 221249423Sdim DebugLoc DL = I->getDebugLoc(); 222249423Sdim 223249423Sdim BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), VR0).addReg(SrcLo, SrcKill); 224249423Sdim BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), DstLo) 225249423Sdim .addReg(VR0, RegState::Kill); 226249423Sdim BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), VR1).addReg(SrcHi, SrcKill); 227249423Sdim BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), DstHi) 228249423Sdim .addReg(VR1, RegState::Kill); 229251662Sdim return true; 230249423Sdim} 231249423Sdim 232249423Sdimunsigned MipsSEFrameLowering::ehDataReg(unsigned I) const { 233249423Sdim static const unsigned EhDataReg[] = { 234249423Sdim Mips::A0, Mips::A1, Mips::A2, Mips::A3 235249423Sdim }; 236249423Sdim static const unsigned EhDataReg64[] = { 237249423Sdim Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64 238249423Sdim }; 239249423Sdim 240249423Sdim return STI.isABI_N64() ? EhDataReg64[I] : EhDataReg[I]; 241249423Sdim} 242249423Sdim 243239310Sdimvoid MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const { 244239310Sdim MachineBasicBlock &MBB = MF.front(); 245239310Sdim MachineFrameInfo *MFI = MF.getFrameInfo(); 246249423Sdim MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); 247239310Sdim const MipsRegisterInfo *RegInfo = 248239310Sdim static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); 249239310Sdim const MipsSEInstrInfo &TII = 250239310Sdim *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); 251239310Sdim MachineBasicBlock::iterator MBBI = MBB.begin(); 252239310Sdim DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 253239310Sdim unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; 254239310Sdim unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; 255239310Sdim unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO; 256239310Sdim unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu; 257239310Sdim 258239310Sdim // First, compute final stack size. 259239310Sdim uint64_t StackSize = MFI->getStackSize(); 260239310Sdim 261239310Sdim // No need to allocate space on the stack. 262239310Sdim if (StackSize == 0 && !MFI->adjustsStack()) return; 263239310Sdim 264239310Sdim MachineModuleInfo &MMI = MF.getMMI(); 265239310Sdim std::vector<MachineMove> &Moves = MMI.getFrameMoves(); 266239310Sdim MachineLocation DstML, SrcML; 267239310Sdim 268239310Sdim // Adjust stack. 269239310Sdim TII.adjustStackPtr(SP, -StackSize, MBB, MBBI); 270239310Sdim 271239310Sdim // emit ".cfi_def_cfa_offset StackSize" 272239310Sdim MCSymbol *AdjustSPLabel = MMI.getContext().CreateTempSymbol(); 273239310Sdim BuildMI(MBB, MBBI, dl, 274239310Sdim TII.get(TargetOpcode::PROLOG_LABEL)).addSym(AdjustSPLabel); 275239310Sdim DstML = MachineLocation(MachineLocation::VirtualFP); 276239310Sdim SrcML = MachineLocation(MachineLocation::VirtualFP, -StackSize); 277239310Sdim Moves.push_back(MachineMove(AdjustSPLabel, DstML, SrcML)); 278239310Sdim 279239310Sdim const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 280239310Sdim 281239310Sdim if (CSI.size()) { 282239310Sdim // Find the instruction past the last instruction that saves a callee-saved 283239310Sdim // register to the stack. 284239310Sdim for (unsigned i = 0; i < CSI.size(); ++i) 285239310Sdim ++MBBI; 286239310Sdim 287239310Sdim // Iterate over list of callee-saved registers and emit .cfi_offset 288239310Sdim // directives. 289239310Sdim MCSymbol *CSLabel = MMI.getContext().CreateTempSymbol(); 290239310Sdim BuildMI(MBB, MBBI, dl, 291239310Sdim TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel); 292239310Sdim 293239310Sdim for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(), 294239310Sdim E = CSI.end(); I != E; ++I) { 295239310Sdim int64_t Offset = MFI->getObjectOffset(I->getFrameIdx()); 296239310Sdim unsigned Reg = I->getReg(); 297239310Sdim 298239310Sdim // If Reg is a double precision register, emit two cfa_offsets, 299239310Sdim // one for each of the paired single precision registers. 300239310Sdim if (Mips::AFGR64RegClass.contains(Reg)) { 301239310Sdim MachineLocation DstML0(MachineLocation::VirtualFP, Offset); 302239310Sdim MachineLocation DstML1(MachineLocation::VirtualFP, Offset + 4); 303239310Sdim MachineLocation SrcML0(RegInfo->getSubReg(Reg, Mips::sub_fpeven)); 304239310Sdim MachineLocation SrcML1(RegInfo->getSubReg(Reg, Mips::sub_fpodd)); 305239310Sdim 306239310Sdim if (!STI.isLittle()) 307239310Sdim std::swap(SrcML0, SrcML1); 308239310Sdim 309239310Sdim Moves.push_back(MachineMove(CSLabel, DstML0, SrcML0)); 310239310Sdim Moves.push_back(MachineMove(CSLabel, DstML1, SrcML1)); 311239310Sdim } else { 312239310Sdim // Reg is either in CPURegs or FGR32. 313239310Sdim DstML = MachineLocation(MachineLocation::VirtualFP, Offset); 314239310Sdim SrcML = MachineLocation(Reg); 315239310Sdim Moves.push_back(MachineMove(CSLabel, DstML, SrcML)); 316239310Sdim } 317239310Sdim } 318239310Sdim } 319239310Sdim 320249423Sdim if (MipsFI->callsEhReturn()) { 321249423Sdim const TargetRegisterClass *RC = STI.isABI_N64() ? 322249423Sdim &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass; 323249423Sdim 324249423Sdim // Insert instructions that spill eh data registers. 325249423Sdim for (int I = 0; I < 4; ++I) { 326249423Sdim if (!MBB.isLiveIn(ehDataReg(I))) 327249423Sdim MBB.addLiveIn(ehDataReg(I)); 328249423Sdim TII.storeRegToStackSlot(MBB, MBBI, ehDataReg(I), false, 329249423Sdim MipsFI->getEhDataRegFI(I), RC, RegInfo); 330249423Sdim } 331249423Sdim 332249423Sdim // Emit .cfi_offset directives for eh data registers. 333249423Sdim MCSymbol *CSLabel2 = MMI.getContext().CreateTempSymbol(); 334249423Sdim BuildMI(MBB, MBBI, dl, 335249423Sdim TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel2); 336249423Sdim for (int I = 0; I < 4; ++I) { 337249423Sdim int64_t Offset = MFI->getObjectOffset(MipsFI->getEhDataRegFI(I)); 338249423Sdim DstML = MachineLocation(MachineLocation::VirtualFP, Offset); 339249423Sdim SrcML = MachineLocation(ehDataReg(I)); 340249423Sdim Moves.push_back(MachineMove(CSLabel2, DstML, SrcML)); 341249423Sdim } 342249423Sdim } 343249423Sdim 344239310Sdim // if framepointer enabled, set it to point to the stack pointer. 345239310Sdim if (hasFP(MF)) { 346239310Sdim // Insert instruction "move $fp, $sp" at this location. 347239310Sdim BuildMI(MBB, MBBI, dl, TII.get(ADDu), FP).addReg(SP).addReg(ZERO); 348239310Sdim 349239310Sdim // emit ".cfi_def_cfa_register $fp" 350239310Sdim MCSymbol *SetFPLabel = MMI.getContext().CreateTempSymbol(); 351239310Sdim BuildMI(MBB, MBBI, dl, 352239310Sdim TII.get(TargetOpcode::PROLOG_LABEL)).addSym(SetFPLabel); 353239310Sdim DstML = MachineLocation(FP); 354239310Sdim SrcML = MachineLocation(MachineLocation::VirtualFP); 355239310Sdim Moves.push_back(MachineMove(SetFPLabel, DstML, SrcML)); 356239310Sdim } 357239310Sdim} 358239310Sdim 359239310Sdimvoid MipsSEFrameLowering::emitEpilogue(MachineFunction &MF, 360239310Sdim MachineBasicBlock &MBB) const { 361239310Sdim MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 362239310Sdim MachineFrameInfo *MFI = MF.getFrameInfo(); 363249423Sdim MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); 364249423Sdim const MipsRegisterInfo *RegInfo = 365249423Sdim static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); 366239310Sdim const MipsSEInstrInfo &TII = 367239310Sdim *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); 368239310Sdim DebugLoc dl = MBBI->getDebugLoc(); 369239310Sdim unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; 370239310Sdim unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; 371239310Sdim unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO; 372239310Sdim unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu; 373239310Sdim 374239310Sdim // if framepointer enabled, restore the stack pointer. 375239310Sdim if (hasFP(MF)) { 376239310Sdim // Find the first instruction that restores a callee-saved register. 377239310Sdim MachineBasicBlock::iterator I = MBBI; 378239310Sdim 379239310Sdim for (unsigned i = 0; i < MFI->getCalleeSavedInfo().size(); ++i) 380239310Sdim --I; 381239310Sdim 382239310Sdim // Insert instruction "move $sp, $fp" at this location. 383239310Sdim BuildMI(MBB, I, dl, TII.get(ADDu), SP).addReg(FP).addReg(ZERO); 384239310Sdim } 385239310Sdim 386249423Sdim if (MipsFI->callsEhReturn()) { 387249423Sdim const TargetRegisterClass *RC = STI.isABI_N64() ? 388249423Sdim &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass; 389249423Sdim 390249423Sdim // Find first instruction that restores a callee-saved register. 391249423Sdim MachineBasicBlock::iterator I = MBBI; 392249423Sdim for (unsigned i = 0; i < MFI->getCalleeSavedInfo().size(); ++i) 393249423Sdim --I; 394249423Sdim 395249423Sdim // Insert instructions that restore eh data registers. 396249423Sdim for (int J = 0; J < 4; ++J) { 397249423Sdim TII.loadRegFromStackSlot(MBB, I, ehDataReg(J), MipsFI->getEhDataRegFI(J), 398249423Sdim RC, RegInfo); 399249423Sdim } 400249423Sdim } 401249423Sdim 402239310Sdim // Get the number of bytes from FrameInfo 403239310Sdim uint64_t StackSize = MFI->getStackSize(); 404239310Sdim 405239310Sdim if (!StackSize) 406239310Sdim return; 407239310Sdim 408239310Sdim // Adjust stack. 409239310Sdim TII.adjustStackPtr(SP, StackSize, MBB, MBBI); 410239310Sdim} 411239310Sdim 412239310Sdimbool MipsSEFrameLowering:: 413239310SdimspillCalleeSavedRegisters(MachineBasicBlock &MBB, 414239310Sdim MachineBasicBlock::iterator MI, 415239310Sdim const std::vector<CalleeSavedInfo> &CSI, 416239310Sdim const TargetRegisterInfo *TRI) const { 417239310Sdim MachineFunction *MF = MBB.getParent(); 418239310Sdim MachineBasicBlock *EntryBlock = MF->begin(); 419239310Sdim const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo(); 420239310Sdim 421239310Sdim for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 422239310Sdim // Add the callee-saved register as live-in. Do not add if the register is 423239310Sdim // RA and return address is taken, because it has already been added in 424239310Sdim // method MipsTargetLowering::LowerRETURNADDR. 425239310Sdim // It's killed at the spill, unless the register is RA and return address 426239310Sdim // is taken. 427239310Sdim unsigned Reg = CSI[i].getReg(); 428239310Sdim bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA || Reg == Mips::RA_64) 429239310Sdim && MF->getFrameInfo()->isReturnAddressTaken(); 430239310Sdim if (!IsRAAndRetAddrIsTaken) 431239310Sdim EntryBlock->addLiveIn(Reg); 432239310Sdim 433239310Sdim // Insert the spill to the stack frame. 434239310Sdim bool IsKill = !IsRAAndRetAddrIsTaken; 435239310Sdim const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 436239310Sdim TII.storeRegToStackSlot(*EntryBlock, MI, Reg, IsKill, 437239310Sdim CSI[i].getFrameIdx(), RC, TRI); 438239310Sdim } 439239310Sdim 440239310Sdim return true; 441239310Sdim} 442239310Sdim 443239310Sdimbool 444239310SdimMipsSEFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 445239310Sdim const MachineFrameInfo *MFI = MF.getFrameInfo(); 446239310Sdim 447239310Sdim // Reserve call frame if the size of the maximum call frame fits into 16-bit 448239310Sdim // immediate field and there are no variable sized objects on the stack. 449249423Sdim // Make sure the second register scavenger spill slot can be accessed with one 450249423Sdim // instruction. 451249423Sdim return isInt<16>(MFI->getMaxCallFrameSize() + getStackAlignment()) && 452249423Sdim !MFI->hasVarSizedObjects(); 453239310Sdim} 454239310Sdim 455249423Sdim// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions 456239310Sdimvoid MipsSEFrameLowering:: 457249423SdimeliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 458249423Sdim MachineBasicBlock::iterator I) const { 459249423Sdim const MipsSEInstrInfo &TII = 460249423Sdim *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); 461249423Sdim 462249423Sdim if (!hasReservedCallFrame(MF)) { 463249423Sdim int64_t Amount = I->getOperand(0).getImm(); 464249423Sdim 465249423Sdim if (I->getOpcode() == Mips::ADJCALLSTACKDOWN) 466249423Sdim Amount = -Amount; 467249423Sdim 468249423Sdim unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; 469249423Sdim TII.adjustStackPtr(SP, Amount, MBB, I); 470249423Sdim } 471249423Sdim 472249423Sdim MBB.erase(I); 473249423Sdim} 474249423Sdim 475249423Sdimvoid MipsSEFrameLowering:: 476239310SdimprocessFunctionBeforeCalleeSavedScan(MachineFunction &MF, 477239310Sdim RegScavenger *RS) const { 478239310Sdim MachineRegisterInfo &MRI = MF.getRegInfo(); 479249423Sdim MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); 480239310Sdim unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; 481239310Sdim 482239310Sdim // Mark $fp as used if function has dedicated frame pointer. 483239310Sdim if (hasFP(MF)) 484239310Sdim MRI.setPhysRegUsed(FP); 485243830Sdim 486249423Sdim // Create spill slots for eh data registers if function calls eh_return. 487249423Sdim if (MipsFI->callsEhReturn()) 488249423Sdim MipsFI->createEhDataRegsFI(); 489249423Sdim 490249423Sdim // Expand pseudo instructions which load, store or copy accumulators. 491249423Sdim // Add an emergency spill slot if a pseudo was expanded. 492251662Sdim if (ExpandPseudo(MF).expand()) { 493249423Sdim // The spill slot should be half the size of the accumulator. If target is 494249423Sdim // mips64, it should be 64-bit, otherwise it should be 32-bt. 495249423Sdim const TargetRegisterClass *RC = STI.hasMips64() ? 496249423Sdim &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass; 497249423Sdim int FI = MF.getFrameInfo()->CreateStackObject(RC->getSize(), 498249423Sdim RC->getAlignment(), false); 499249423Sdim RS->addScavengingFrameIndex(FI); 500249423Sdim } 501249423Sdim 502243830Sdim // Set scavenging frame index if necessary. 503243830Sdim uint64_t MaxSPOffset = MF.getInfo<MipsFunctionInfo>()->getIncomingArgSize() + 504243830Sdim estimateStackSize(MF); 505243830Sdim 506243830Sdim if (isInt<16>(MaxSPOffset)) 507243830Sdim return; 508243830Sdim 509243830Sdim const TargetRegisterClass *RC = STI.isABI_N64() ? 510243830Sdim &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass; 511243830Sdim int FI = MF.getFrameInfo()->CreateStackObject(RC->getSize(), 512243830Sdim RC->getAlignment(), false); 513249423Sdim RS->addScavengingFrameIndex(FI); 514239310Sdim} 515239310Sdim 516239310Sdimconst MipsFrameLowering * 517239310Sdimllvm::createMipsSEFrameLowering(const MipsSubtarget &ST) { 518239310Sdim return new MipsSEFrameLowering(ST); 519239310Sdim} 520