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 35263508Sdimstatic std::pair<unsigned, unsigned> getMFHiLoOpc(unsigned Src) { 36263508Sdim if (Mips::ACC64RegClass.contains(Src)) 37263508Sdim return std::make_pair((unsigned)Mips::PseudoMFHI, 38263508Sdim (unsigned)Mips::PseudoMFLO); 39263508Sdim 40263508Sdim if (Mips::ACC64DSPRegClass.contains(Src)) 41263508Sdim return std::make_pair((unsigned)Mips::MFHI_DSP, (unsigned)Mips::MFLO_DSP); 42263508Sdim 43263508Sdim if (Mips::ACC128RegClass.contains(Src)) 44263508Sdim return std::make_pair((unsigned)Mips::PseudoMFHI64, 45263508Sdim (unsigned)Mips::PseudoMFLO64); 46263508Sdim 47263508Sdim return std::make_pair(0, 0); 48263508Sdim} 49263508Sdim 50251662Sdim/// Helper class to expand pseudos. 51251662Sdimclass ExpandPseudo { 52249423Sdimpublic: 53251662Sdim ExpandPseudo(MachineFunction &MF); 54249423Sdim bool expand(); 55249423Sdim 56249423Sdimprivate: 57249423Sdim bool expandInstr(MachineBasicBlock &MBB, Iter I); 58251662Sdim void expandLoadCCond(MachineBasicBlock &MBB, Iter I); 59251662Sdim void expandStoreCCond(MachineBasicBlock &MBB, Iter I); 60251662Sdim void expandLoadACC(MachineBasicBlock &MBB, Iter I, unsigned RegSize); 61263508Sdim void expandStoreACC(MachineBasicBlock &MBB, Iter I, unsigned MFHiOpc, 62263508Sdim unsigned MFLoOpc, unsigned RegSize); 63251662Sdim bool expandCopy(MachineBasicBlock &MBB, Iter I); 64263508Sdim bool expandCopyACC(MachineBasicBlock &MBB, Iter I, unsigned MFHiOpc, 65263508Sdim unsigned MFLoOpc); 66249423Sdim 67249423Sdim MachineFunction &MF; 68249423Sdim MachineRegisterInfo &MRI; 69249423Sdim}; 70249423Sdim} 71249423Sdim 72251662SdimExpandPseudo::ExpandPseudo(MachineFunction &MF_) 73263508Sdim : MF(MF_), MRI(MF.getRegInfo()) {} 74249423Sdim 75251662Sdimbool ExpandPseudo::expand() { 76249423Sdim bool Expanded = false; 77249423Sdim 78249423Sdim for (MachineFunction::iterator BB = MF.begin(), BBEnd = MF.end(); 79249423Sdim BB != BBEnd; ++BB) 80249423Sdim for (Iter I = BB->begin(), End = BB->end(); I != End;) 81249423Sdim Expanded |= expandInstr(*BB, I++); 82249423Sdim 83249423Sdim return Expanded; 84249423Sdim} 85249423Sdim 86251662Sdimbool ExpandPseudo::expandInstr(MachineBasicBlock &MBB, Iter I) { 87249423Sdim switch(I->getOpcode()) { 88251662Sdim case Mips::LOAD_CCOND_DSP: 89251662Sdim expandLoadCCond(MBB, I); 90251662Sdim break; 91251662Sdim case Mips::STORE_CCOND_DSP: 92251662Sdim expandStoreCCond(MBB, I); 93251662Sdim break; 94263508Sdim case Mips::LOAD_ACC64: 95263508Sdim case Mips::LOAD_ACC64DSP: 96251662Sdim expandLoadACC(MBB, I, 4); 97249423Sdim break; 98263508Sdim case Mips::LOAD_ACC128: 99251662Sdim expandLoadACC(MBB, I, 8); 100249423Sdim break; 101263508Sdim case Mips::STORE_ACC64: 102263508Sdim expandStoreACC(MBB, I, Mips::PseudoMFHI, Mips::PseudoMFLO, 4); 103249423Sdim break; 104263508Sdim case Mips::STORE_ACC64DSP: 105263508Sdim expandStoreACC(MBB, I, Mips::MFHI_DSP, Mips::MFLO_DSP, 4); 106249423Sdim break; 107263508Sdim case Mips::STORE_ACC128: 108263508Sdim expandStoreACC(MBB, I, Mips::PseudoMFHI64, Mips::PseudoMFLO64, 8); 109263508Sdim break; 110251662Sdim case TargetOpcode::COPY: 111251662Sdim if (!expandCopy(MBB, I)) 112251662Sdim return false; 113249423Sdim break; 114249423Sdim default: 115249423Sdim return false; 116249423Sdim } 117249423Sdim 118249423Sdim MBB.erase(I); 119249423Sdim return true; 120249423Sdim} 121249423Sdim 122251662Sdimvoid ExpandPseudo::expandLoadCCond(MachineBasicBlock &MBB, Iter I) { 123251662Sdim // load $vr, FI 124251662Sdim // copy ccond, $vr 125251662Sdim 126251662Sdim assert(I->getOperand(0).isReg() && I->getOperand(1).isFI()); 127251662Sdim 128263508Sdim const MipsSEInstrInfo &TII = 129263508Sdim *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); 130263508Sdim const MipsRegisterInfo &RegInfo = 131263508Sdim *static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); 132263508Sdim 133251662Sdim const TargetRegisterClass *RC = RegInfo.intRegClass(4); 134251662Sdim unsigned VR = MRI.createVirtualRegister(RC); 135251662Sdim unsigned Dst = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex(); 136251662Sdim 137251662Sdim TII.loadRegFromStack(MBB, I, VR, FI, RC, &RegInfo, 0); 138251662Sdim BuildMI(MBB, I, I->getDebugLoc(), TII.get(TargetOpcode::COPY), Dst) 139251662Sdim .addReg(VR, RegState::Kill); 140251662Sdim} 141251662Sdim 142251662Sdimvoid ExpandPseudo::expandStoreCCond(MachineBasicBlock &MBB, Iter I) { 143251662Sdim // copy $vr, ccond 144251662Sdim // store $vr, FI 145251662Sdim 146251662Sdim assert(I->getOperand(0).isReg() && I->getOperand(1).isFI()); 147251662Sdim 148263508Sdim const MipsSEInstrInfo &TII = 149263508Sdim *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); 150263508Sdim const MipsRegisterInfo &RegInfo = 151263508Sdim *static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); 152263508Sdim 153251662Sdim const TargetRegisterClass *RC = RegInfo.intRegClass(4); 154251662Sdim unsigned VR = MRI.createVirtualRegister(RC); 155251662Sdim unsigned Src = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex(); 156251662Sdim 157251662Sdim BuildMI(MBB, I, I->getDebugLoc(), TII.get(TargetOpcode::COPY), VR) 158251662Sdim .addReg(Src, getKillRegState(I->getOperand(0).isKill())); 159251662Sdim TII.storeRegToStack(MBB, I, VR, true, FI, RC, &RegInfo, 0); 160251662Sdim} 161251662Sdim 162251662Sdimvoid ExpandPseudo::expandLoadACC(MachineBasicBlock &MBB, Iter I, 163249423Sdim unsigned RegSize) { 164249423Sdim // load $vr0, FI 165249423Sdim // copy lo, $vr0 166249423Sdim // load $vr1, FI + 4 167249423Sdim // copy hi, $vr1 168249423Sdim 169249423Sdim assert(I->getOperand(0).isReg() && I->getOperand(1).isFI()); 170249423Sdim 171263508Sdim const MipsSEInstrInfo &TII = 172263508Sdim *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); 173263508Sdim const MipsRegisterInfo &RegInfo = 174263508Sdim *static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); 175263508Sdim 176249423Sdim const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize); 177249423Sdim unsigned VR0 = MRI.createVirtualRegister(RC); 178249423Sdim unsigned VR1 = MRI.createVirtualRegister(RC); 179249423Sdim unsigned Dst = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex(); 180249423Sdim unsigned Lo = RegInfo.getSubReg(Dst, Mips::sub_lo); 181249423Sdim unsigned Hi = RegInfo.getSubReg(Dst, Mips::sub_hi); 182249423Sdim DebugLoc DL = I->getDebugLoc(); 183249423Sdim const MCInstrDesc &Desc = TII.get(TargetOpcode::COPY); 184249423Sdim 185249423Sdim TII.loadRegFromStack(MBB, I, VR0, FI, RC, &RegInfo, 0); 186249423Sdim BuildMI(MBB, I, DL, Desc, Lo).addReg(VR0, RegState::Kill); 187249423Sdim TII.loadRegFromStack(MBB, I, VR1, FI, RC, &RegInfo, RegSize); 188249423Sdim BuildMI(MBB, I, DL, Desc, Hi).addReg(VR1, RegState::Kill); 189249423Sdim} 190249423Sdim 191251662Sdimvoid ExpandPseudo::expandStoreACC(MachineBasicBlock &MBB, Iter I, 192263508Sdim unsigned MFHiOpc, unsigned MFLoOpc, 193249423Sdim unsigned RegSize) { 194263508Sdim // mflo $vr0, src 195249423Sdim // store $vr0, FI 196263508Sdim // mfhi $vr1, src 197249423Sdim // store $vr1, FI + 4 198249423Sdim 199249423Sdim assert(I->getOperand(0).isReg() && I->getOperand(1).isFI()); 200249423Sdim 201263508Sdim const MipsSEInstrInfo &TII = 202263508Sdim *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); 203263508Sdim const MipsRegisterInfo &RegInfo = 204263508Sdim *static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); 205263508Sdim 206249423Sdim const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize); 207249423Sdim unsigned VR0 = MRI.createVirtualRegister(RC); 208249423Sdim unsigned VR1 = MRI.createVirtualRegister(RC); 209249423Sdim unsigned Src = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex(); 210249423Sdim unsigned SrcKill = getKillRegState(I->getOperand(0).isKill()); 211249423Sdim DebugLoc DL = I->getDebugLoc(); 212249423Sdim 213263508Sdim BuildMI(MBB, I, DL, TII.get(MFLoOpc), VR0).addReg(Src); 214249423Sdim TII.storeRegToStack(MBB, I, VR0, true, FI, RC, &RegInfo, 0); 215263508Sdim BuildMI(MBB, I, DL, TII.get(MFHiOpc), VR1).addReg(Src, SrcKill); 216249423Sdim TII.storeRegToStack(MBB, I, VR1, true, FI, RC, &RegInfo, RegSize); 217249423Sdim} 218249423Sdim 219251662Sdimbool ExpandPseudo::expandCopy(MachineBasicBlock &MBB, Iter I) { 220263508Sdim unsigned Src = I->getOperand(1).getReg(); 221263508Sdim std::pair<unsigned, unsigned> Opcodes = getMFHiLoOpc(Src); 222251662Sdim 223263508Sdim if (!Opcodes.first) 224263508Sdim return false; 225251662Sdim 226263508Sdim return expandCopyACC(MBB, I, Opcodes.first, Opcodes.second); 227251662Sdim} 228251662Sdim 229263508Sdimbool ExpandPseudo::expandCopyACC(MachineBasicBlock &MBB, Iter I, 230263508Sdim unsigned MFHiOpc, unsigned MFLoOpc) { 231263508Sdim // mflo $vr0, src 232249423Sdim // copy dst_lo, $vr0 233263508Sdim // mfhi $vr1, src 234249423Sdim // copy dst_hi, $vr1 235249423Sdim 236263508Sdim const MipsSEInstrInfo &TII = 237263508Sdim *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); 238263508Sdim const MipsRegisterInfo &RegInfo = 239263508Sdim *static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); 240263508Sdim 241263508Sdim unsigned Dst = I->getOperand(0).getReg(), Src = I->getOperand(1).getReg(); 242263508Sdim unsigned VRegSize = RegInfo.getMinimalPhysRegClass(Dst)->getSize() / 2; 243263508Sdim const TargetRegisterClass *RC = RegInfo.intRegClass(VRegSize); 244249423Sdim unsigned VR0 = MRI.createVirtualRegister(RC); 245249423Sdim unsigned VR1 = MRI.createVirtualRegister(RC); 246249423Sdim unsigned SrcKill = getKillRegState(I->getOperand(1).isKill()); 247249423Sdim unsigned DstLo = RegInfo.getSubReg(Dst, Mips::sub_lo); 248249423Sdim unsigned DstHi = RegInfo.getSubReg(Dst, Mips::sub_hi); 249249423Sdim DebugLoc DL = I->getDebugLoc(); 250249423Sdim 251263508Sdim BuildMI(MBB, I, DL, TII.get(MFLoOpc), VR0).addReg(Src); 252249423Sdim BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), DstLo) 253249423Sdim .addReg(VR0, RegState::Kill); 254263508Sdim BuildMI(MBB, I, DL, TII.get(MFHiOpc), VR1).addReg(Src, SrcKill); 255249423Sdim BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), DstHi) 256249423Sdim .addReg(VR1, RegState::Kill); 257251662Sdim return true; 258249423Sdim} 259249423Sdim 260249423Sdimunsigned MipsSEFrameLowering::ehDataReg(unsigned I) const { 261249423Sdim static const unsigned EhDataReg[] = { 262249423Sdim Mips::A0, Mips::A1, Mips::A2, Mips::A3 263249423Sdim }; 264249423Sdim static const unsigned EhDataReg64[] = { 265249423Sdim Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64 266249423Sdim }; 267249423Sdim 268249423Sdim return STI.isABI_N64() ? EhDataReg64[I] : EhDataReg[I]; 269249423Sdim} 270249423Sdim 271239310Sdimvoid MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const { 272239310Sdim MachineBasicBlock &MBB = MF.front(); 273239310Sdim MachineFrameInfo *MFI = MF.getFrameInfo(); 274249423Sdim MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); 275263508Sdim 276239310Sdim const MipsSEInstrInfo &TII = 277239310Sdim *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); 278263508Sdim const MipsRegisterInfo &RegInfo = 279263508Sdim *static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); 280263508Sdim 281239310Sdim MachineBasicBlock::iterator MBBI = MBB.begin(); 282239310Sdim DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 283239310Sdim unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; 284239310Sdim unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; 285239310Sdim unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO; 286239310Sdim unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu; 287239310Sdim 288239310Sdim // First, compute final stack size. 289239310Sdim uint64_t StackSize = MFI->getStackSize(); 290239310Sdim 291239310Sdim // No need to allocate space on the stack. 292239310Sdim if (StackSize == 0 && !MFI->adjustsStack()) return; 293239310Sdim 294239310Sdim MachineModuleInfo &MMI = MF.getMMI(); 295263508Sdim const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo(); 296239310Sdim MachineLocation DstML, SrcML; 297239310Sdim 298239310Sdim // Adjust stack. 299239310Sdim TII.adjustStackPtr(SP, -StackSize, MBB, MBBI); 300239310Sdim 301239310Sdim // emit ".cfi_def_cfa_offset StackSize" 302239310Sdim MCSymbol *AdjustSPLabel = MMI.getContext().CreateTempSymbol(); 303239310Sdim BuildMI(MBB, MBBI, dl, 304239310Sdim TII.get(TargetOpcode::PROLOG_LABEL)).addSym(AdjustSPLabel); 305263508Sdim MMI.addFrameInst( 306263508Sdim MCCFIInstruction::createDefCfaOffset(AdjustSPLabel, -StackSize)); 307239310Sdim 308239310Sdim const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 309239310Sdim 310239310Sdim if (CSI.size()) { 311239310Sdim // Find the instruction past the last instruction that saves a callee-saved 312239310Sdim // register to the stack. 313239310Sdim for (unsigned i = 0; i < CSI.size(); ++i) 314239310Sdim ++MBBI; 315239310Sdim 316239310Sdim // Iterate over list of callee-saved registers and emit .cfi_offset 317239310Sdim // directives. 318239310Sdim MCSymbol *CSLabel = MMI.getContext().CreateTempSymbol(); 319239310Sdim BuildMI(MBB, MBBI, dl, 320239310Sdim TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel); 321239310Sdim 322239310Sdim for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(), 323239310Sdim E = CSI.end(); I != E; ++I) { 324239310Sdim int64_t Offset = MFI->getObjectOffset(I->getFrameIdx()); 325239310Sdim unsigned Reg = I->getReg(); 326239310Sdim 327239310Sdim // If Reg is a double precision register, emit two cfa_offsets, 328239310Sdim // one for each of the paired single precision registers. 329239310Sdim if (Mips::AFGR64RegClass.contains(Reg)) { 330263508Sdim unsigned Reg0 = 331263508Sdim MRI->getDwarfRegNum(RegInfo.getSubReg(Reg, Mips::sub_lo), true); 332263508Sdim unsigned Reg1 = 333263508Sdim MRI->getDwarfRegNum(RegInfo.getSubReg(Reg, Mips::sub_hi), true); 334239310Sdim 335239310Sdim if (!STI.isLittle()) 336263508Sdim std::swap(Reg0, Reg1); 337239310Sdim 338263508Sdim MMI.addFrameInst( 339263508Sdim MCCFIInstruction::createOffset(CSLabel, Reg0, Offset)); 340263508Sdim MMI.addFrameInst( 341263508Sdim MCCFIInstruction::createOffset(CSLabel, Reg1, Offset + 4)); 342239310Sdim } else { 343263508Sdim // Reg is either in GPR32 or FGR32. 344263508Sdim MMI.addFrameInst(MCCFIInstruction::createOffset( 345263508Sdim CSLabel, MRI->getDwarfRegNum(Reg, 1), Offset)); 346239310Sdim } 347239310Sdim } 348239310Sdim } 349239310Sdim 350249423Sdim if (MipsFI->callsEhReturn()) { 351249423Sdim const TargetRegisterClass *RC = STI.isABI_N64() ? 352263508Sdim &Mips::GPR64RegClass : &Mips::GPR32RegClass; 353249423Sdim 354249423Sdim // Insert instructions that spill eh data registers. 355249423Sdim for (int I = 0; I < 4; ++I) { 356249423Sdim if (!MBB.isLiveIn(ehDataReg(I))) 357249423Sdim MBB.addLiveIn(ehDataReg(I)); 358249423Sdim TII.storeRegToStackSlot(MBB, MBBI, ehDataReg(I), false, 359263508Sdim MipsFI->getEhDataRegFI(I), RC, &RegInfo); 360249423Sdim } 361249423Sdim 362249423Sdim // Emit .cfi_offset directives for eh data registers. 363249423Sdim MCSymbol *CSLabel2 = MMI.getContext().CreateTempSymbol(); 364249423Sdim BuildMI(MBB, MBBI, dl, 365249423Sdim TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel2); 366249423Sdim for (int I = 0; I < 4; ++I) { 367249423Sdim int64_t Offset = MFI->getObjectOffset(MipsFI->getEhDataRegFI(I)); 368263508Sdim unsigned Reg = MRI->getDwarfRegNum(ehDataReg(I), true); 369263508Sdim MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel2, Reg, Offset)); 370249423Sdim } 371249423Sdim } 372249423Sdim 373239310Sdim // if framepointer enabled, set it to point to the stack pointer. 374239310Sdim if (hasFP(MF)) { 375239310Sdim // Insert instruction "move $fp, $sp" at this location. 376239310Sdim BuildMI(MBB, MBBI, dl, TII.get(ADDu), FP).addReg(SP).addReg(ZERO); 377239310Sdim 378239310Sdim // emit ".cfi_def_cfa_register $fp" 379239310Sdim MCSymbol *SetFPLabel = MMI.getContext().CreateTempSymbol(); 380239310Sdim BuildMI(MBB, MBBI, dl, 381239310Sdim TII.get(TargetOpcode::PROLOG_LABEL)).addSym(SetFPLabel); 382263508Sdim MMI.addFrameInst(MCCFIInstruction::createDefCfaRegister( 383263508Sdim SetFPLabel, MRI->getDwarfRegNum(FP, true))); 384239310Sdim } 385239310Sdim} 386239310Sdim 387239310Sdimvoid MipsSEFrameLowering::emitEpilogue(MachineFunction &MF, 388239310Sdim MachineBasicBlock &MBB) const { 389239310Sdim MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 390239310Sdim MachineFrameInfo *MFI = MF.getFrameInfo(); 391249423Sdim MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); 392263508Sdim 393239310Sdim const MipsSEInstrInfo &TII = 394239310Sdim *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); 395263508Sdim const MipsRegisterInfo &RegInfo = 396263508Sdim *static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); 397263508Sdim 398239310Sdim DebugLoc dl = MBBI->getDebugLoc(); 399239310Sdim unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; 400239310Sdim unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; 401239310Sdim unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO; 402239310Sdim unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu; 403239310Sdim 404239310Sdim // if framepointer enabled, restore the stack pointer. 405239310Sdim if (hasFP(MF)) { 406239310Sdim // Find the first instruction that restores a callee-saved register. 407239310Sdim MachineBasicBlock::iterator I = MBBI; 408239310Sdim 409239310Sdim for (unsigned i = 0; i < MFI->getCalleeSavedInfo().size(); ++i) 410239310Sdim --I; 411239310Sdim 412239310Sdim // Insert instruction "move $sp, $fp" at this location. 413239310Sdim BuildMI(MBB, I, dl, TII.get(ADDu), SP).addReg(FP).addReg(ZERO); 414239310Sdim } 415239310Sdim 416249423Sdim if (MipsFI->callsEhReturn()) { 417249423Sdim const TargetRegisterClass *RC = STI.isABI_N64() ? 418263508Sdim &Mips::GPR64RegClass : &Mips::GPR32RegClass; 419249423Sdim 420249423Sdim // Find first instruction that restores a callee-saved register. 421249423Sdim MachineBasicBlock::iterator I = MBBI; 422249423Sdim for (unsigned i = 0; i < MFI->getCalleeSavedInfo().size(); ++i) 423249423Sdim --I; 424249423Sdim 425249423Sdim // Insert instructions that restore eh data registers. 426249423Sdim for (int J = 0; J < 4; ++J) { 427249423Sdim TII.loadRegFromStackSlot(MBB, I, ehDataReg(J), MipsFI->getEhDataRegFI(J), 428263508Sdim RC, &RegInfo); 429249423Sdim } 430249423Sdim } 431249423Sdim 432239310Sdim // Get the number of bytes from FrameInfo 433239310Sdim uint64_t StackSize = MFI->getStackSize(); 434239310Sdim 435239310Sdim if (!StackSize) 436239310Sdim return; 437239310Sdim 438239310Sdim // Adjust stack. 439239310Sdim TII.adjustStackPtr(SP, StackSize, MBB, MBBI); 440239310Sdim} 441239310Sdim 442239310Sdimbool MipsSEFrameLowering:: 443239310SdimspillCalleeSavedRegisters(MachineBasicBlock &MBB, 444239310Sdim MachineBasicBlock::iterator MI, 445239310Sdim const std::vector<CalleeSavedInfo> &CSI, 446239310Sdim const TargetRegisterInfo *TRI) const { 447239310Sdim MachineFunction *MF = MBB.getParent(); 448239310Sdim MachineBasicBlock *EntryBlock = MF->begin(); 449239310Sdim const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo(); 450239310Sdim 451239310Sdim for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 452239310Sdim // Add the callee-saved register as live-in. Do not add if the register is 453239310Sdim // RA and return address is taken, because it has already been added in 454239310Sdim // method MipsTargetLowering::LowerRETURNADDR. 455239310Sdim // It's killed at the spill, unless the register is RA and return address 456239310Sdim // is taken. 457239310Sdim unsigned Reg = CSI[i].getReg(); 458239310Sdim bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA || Reg == Mips::RA_64) 459239310Sdim && MF->getFrameInfo()->isReturnAddressTaken(); 460239310Sdim if (!IsRAAndRetAddrIsTaken) 461239310Sdim EntryBlock->addLiveIn(Reg); 462239310Sdim 463239310Sdim // Insert the spill to the stack frame. 464239310Sdim bool IsKill = !IsRAAndRetAddrIsTaken; 465239310Sdim const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 466239310Sdim TII.storeRegToStackSlot(*EntryBlock, MI, Reg, IsKill, 467239310Sdim CSI[i].getFrameIdx(), RC, TRI); 468239310Sdim } 469239310Sdim 470239310Sdim return true; 471239310Sdim} 472239310Sdim 473239310Sdimbool 474239310SdimMipsSEFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 475239310Sdim const MachineFrameInfo *MFI = MF.getFrameInfo(); 476239310Sdim 477239310Sdim // Reserve call frame if the size of the maximum call frame fits into 16-bit 478239310Sdim // immediate field and there are no variable sized objects on the stack. 479249423Sdim // Make sure the second register scavenger spill slot can be accessed with one 480249423Sdim // instruction. 481249423Sdim return isInt<16>(MFI->getMaxCallFrameSize() + getStackAlignment()) && 482249423Sdim !MFI->hasVarSizedObjects(); 483239310Sdim} 484239310Sdim 485249423Sdim// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions 486239310Sdimvoid MipsSEFrameLowering:: 487249423SdimeliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 488249423Sdim MachineBasicBlock::iterator I) const { 489249423Sdim const MipsSEInstrInfo &TII = 490249423Sdim *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); 491249423Sdim 492249423Sdim if (!hasReservedCallFrame(MF)) { 493249423Sdim int64_t Amount = I->getOperand(0).getImm(); 494249423Sdim 495249423Sdim if (I->getOpcode() == Mips::ADJCALLSTACKDOWN) 496249423Sdim Amount = -Amount; 497249423Sdim 498249423Sdim unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; 499249423Sdim TII.adjustStackPtr(SP, Amount, MBB, I); 500249423Sdim } 501249423Sdim 502249423Sdim MBB.erase(I); 503249423Sdim} 504249423Sdim 505249423Sdimvoid MipsSEFrameLowering:: 506239310SdimprocessFunctionBeforeCalleeSavedScan(MachineFunction &MF, 507239310Sdim RegScavenger *RS) const { 508239310Sdim MachineRegisterInfo &MRI = MF.getRegInfo(); 509249423Sdim MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); 510239310Sdim unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; 511239310Sdim 512239310Sdim // Mark $fp as used if function has dedicated frame pointer. 513239310Sdim if (hasFP(MF)) 514239310Sdim MRI.setPhysRegUsed(FP); 515243830Sdim 516249423Sdim // Create spill slots for eh data registers if function calls eh_return. 517249423Sdim if (MipsFI->callsEhReturn()) 518249423Sdim MipsFI->createEhDataRegsFI(); 519249423Sdim 520249423Sdim // Expand pseudo instructions which load, store or copy accumulators. 521249423Sdim // Add an emergency spill slot if a pseudo was expanded. 522251662Sdim if (ExpandPseudo(MF).expand()) { 523249423Sdim // The spill slot should be half the size of the accumulator. If target is 524249423Sdim // mips64, it should be 64-bit, otherwise it should be 32-bt. 525249423Sdim const TargetRegisterClass *RC = STI.hasMips64() ? 526263508Sdim &Mips::GPR64RegClass : &Mips::GPR32RegClass; 527249423Sdim int FI = MF.getFrameInfo()->CreateStackObject(RC->getSize(), 528249423Sdim RC->getAlignment(), false); 529249423Sdim RS->addScavengingFrameIndex(FI); 530249423Sdim } 531249423Sdim 532243830Sdim // Set scavenging frame index if necessary. 533243830Sdim uint64_t MaxSPOffset = MF.getInfo<MipsFunctionInfo>()->getIncomingArgSize() + 534243830Sdim estimateStackSize(MF); 535243830Sdim 536243830Sdim if (isInt<16>(MaxSPOffset)) 537243830Sdim return; 538243830Sdim 539243830Sdim const TargetRegisterClass *RC = STI.isABI_N64() ? 540263508Sdim &Mips::GPR64RegClass : &Mips::GPR32RegClass; 541243830Sdim int FI = MF.getFrameInfo()->CreateStackObject(RC->getSize(), 542243830Sdim RC->getAlignment(), false); 543249423Sdim RS->addScavengingFrameIndex(FI); 544239310Sdim} 545239310Sdim 546239310Sdimconst MipsFrameLowering * 547239310Sdimllvm::createMipsSEFrameLowering(const MipsSubtarget &ST) { 548239310Sdim return new MipsSEFrameLowering(ST); 549239310Sdim} 550