Mips16FrameLowering.cpp revision 25278aa26fa498e41830946b2138f01473269df2
19e49fb63d355446b91d20ff78ad78b297e89a50dcaryclark@google.com//===-- Mips16FrameLowering.cpp - Mips16 Frame Information ----------------===// 29e49fb63d355446b91d20ff78ad78b297e89a50dcaryclark@google.com// 39e49fb63d355446b91d20ff78ad78b297e89a50dcaryclark@google.com// The LLVM Compiler Infrastructure 49e49fb63d355446b91d20ff78ad78b297e89a50dcaryclark@google.com// 59e49fb63d355446b91d20ff78ad78b297e89a50dcaryclark@google.com// This file is distributed under the University of Illinois Open Source 69e49fb63d355446b91d20ff78ad78b297e89a50dcaryclark@google.com// License. See LICENSE.TXT for details. 79d5f99bc309a7d733e33a149bef295ae3c8b3ac1caryclark@google.com// 8639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com//===----------------------------------------------------------------------===// 9639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com// 10639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com// This file contains the Mips16 implementation of TargetFrameLowering class. 11639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com// 12d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com//===----------------------------------------------------------------------===// 13639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com 14639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com#include "Mips16FrameLowering.h" 15639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com#include "MCTargetDesc/MipsBaseInfo.h" 16639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com#include "Mips16InstrInfo.h" 17639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com#include "MipsInstrInfo.h" 18d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com#include "llvm/CodeGen/MachineFrameInfo.h" 19639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com#include "llvm/CodeGen/MachineFunction.h" 20639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com#include "llvm/CodeGen/MachineInstrBuilder.h" 21d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com#include "llvm/CodeGen/MachineModuleInfo.h" 22639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com#include "llvm/CodeGen/MachineRegisterInfo.h" 23639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com#include "llvm/IR/DataLayout.h" 24d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com#include "llvm/IR/Function.h" 25639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com#include "llvm/Support/CommandLine.h" 26d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com#include "llvm/Target/TargetOptions.h" 27639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com 28639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.comusing namespace llvm; 29639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com 30639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.comvoid Mips16FrameLowering::emitPrologue(MachineFunction &MF) const { 31639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com MachineBasicBlock &MBB = MF.front(); 32639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com MachineFrameInfo *MFI = MF.getFrameInfo(); 33639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com const Mips16InstrInfo &TII = 34639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com *static_cast<const Mips16InstrInfo*>(MF.getTarget().getInstrInfo()); 35639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com MachineBasicBlock::iterator MBBI = MBB.begin(); 36639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 37639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com uint64_t StackSize = MFI->getStackSize(); 38639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com 39639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com // No need to allocate space on the stack. 40639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com if (StackSize == 0 && !MFI->adjustsStack()) return; 41639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com 42639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com MachineModuleInfo &MMI = MF.getMMI(); 43639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo(); 44639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com MachineLocation DstML, SrcML; 45d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 46639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com // Adjust stack. 47d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com TII.makeFrame(Mips::SP, StackSize, MBB, MBBI); 48639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com 49639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com // emit ".cfi_def_cfa_offset StackSize" 50639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com MCSymbol *AdjustSPLabel = MMI.getContext().CreateTempSymbol(); 51639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com BuildMI(MBB, MBBI, dl, 52639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com TII.get(TargetOpcode::PROLOG_LABEL)).addSym(AdjustSPLabel); 53639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com MMI.addFrameInst( 54639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com MCCFIInstruction::createDefCfaOffset(AdjustSPLabel, -StackSize)); 55d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 56639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com MCSymbol *CSLabel = MMI.getContext().CreateTempSymbol(); 57639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com BuildMI(MBB, MBBI, dl, 58639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel); 59639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com unsigned S2 = MRI->getDwarfRegNum(Mips::S2, true); 60639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, S2, -8)); 61639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com 62639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com unsigned S1 = MRI->getDwarfRegNum(Mips::S1, true); 63639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, S1, -12)); 64639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com 65639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com unsigned S0 = MRI->getDwarfRegNum(Mips::S0, true); 66d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, S0, -16)); 67639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com 681304bb25aa3b0baa61fc2e2900fabcef88801b59caryclark@google.com unsigned RA = MRI->getDwarfRegNum(Mips::RA, true); 691304bb25aa3b0baa61fc2e2900fabcef88801b59caryclark@google.com MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, RA, -4)); 701304bb25aa3b0baa61fc2e2900fabcef88801b59caryclark@google.com 711304bb25aa3b0baa61fc2e2900fabcef88801b59caryclark@google.com if (hasFP(MF)) 721304bb25aa3b0baa61fc2e2900fabcef88801b59caryclark@google.com BuildMI(MBB, MBBI, dl, TII.get(Mips::MoveR3216), Mips::S0) 7303682beb8c1c5dfe714933e9419e1412b33c932dskia.committer@gmail.com .addReg(Mips::SP); 741304bb25aa3b0baa61fc2e2900fabcef88801b59caryclark@google.com 75639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com} 76639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com 77639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.comvoid Mips16FrameLowering::emitEpilogue(MachineFunction &MF, 78639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com MachineBasicBlock &MBB) const { 79639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 80639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com MachineFrameInfo *MFI = MF.getFrameInfo(); 81639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com const Mips16InstrInfo &TII = 82639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com *static_cast<const Mips16InstrInfo*>(MF.getTarget().getInstrInfo()); 83639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com DebugLoc dl = MBBI->getDebugLoc(); 84639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com uint64_t StackSize = MFI->getStackSize(); 85639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com 86639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com if (!StackSize) 87639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com return; 88639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com 89639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com if (hasFP(MF)) 90639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com BuildMI(MBB, MBBI, dl, TII.get(Mips::Move32R16), Mips::SP) 91639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com .addReg(Mips::S0); 92639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com 93c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com // Adjust stack. 94c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com // assumes stacksize multiple of 8 95c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com TII.restoreFrame(Mips::SP, StackSize, MBB, MBBI); 96c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com} 97c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com 98c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.combool Mips16FrameLowering:: 99c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.comspillCalleeSavedRegisters(MachineBasicBlock &MBB, 100c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com MachineBasicBlock::iterator MI, 101c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com const std::vector<CalleeSavedInfo> &CSI, 102c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com const TargetRegisterInfo *TRI) const { 103c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com MachineFunction *MF = MBB.getParent(); 104c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com MachineBasicBlock *EntryBlock = MF->begin(); 105c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com 106c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com // 107c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com // Registers RA, S0,S1 are the callee saved registers and they 108c83c70e911a38aea03db4af8dd9841d0d77bd129caryclark@google.com // will be saved with the "save" instruction 109639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com // during emitPrologue 110639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com // 111639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 112639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com // Add the callee-saved register as live-in. Do not add if the register is 113639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com // RA and return address is taken, because it has already been added in 114639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com // method MipsTargetLowering::LowerRETURNADDR. 115639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com // It's killed at the spill, unless the register is RA and return address 116639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com // is taken. 117639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com unsigned Reg = CSI[i].getReg(); 118639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA) 119639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com && MF->getFrameInfo()->isReturnAddressTaken(); 120639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com if (!IsRAAndRetAddrIsTaken) 121639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com EntryBlock->addLiveIn(Reg); 122639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com } 123639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com 124639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com return true; 125639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com} 126639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com 127639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.combool Mips16FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 128639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com MachineBasicBlock::iterator MI, 129639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com const std::vector<CalleeSavedInfo> &CSI, 1306d0032a8ec680221c2a704cac2391f2a2d77546fcaryclark@google.com const TargetRegisterInfo *TRI) const { 1316d0032a8ec680221c2a704cac2391f2a2d77546fcaryclark@google.com // 1326d0032a8ec680221c2a704cac2391f2a2d77546fcaryclark@google.com // Registers RA,S0,S1 are the callee saved registers and they will be restored 1336d0032a8ec680221c2a704cac2391f2a2d77546fcaryclark@google.com // with the restore instruction during emitEpilogue. 1346d0032a8ec680221c2a704cac2391f2a2d77546fcaryclark@google.com // We need to override this virtual function, otherwise llvm will try and 1356d0032a8ec680221c2a704cac2391f2a2d77546fcaryclark@google.com // restore the registers on it's on from the stack. 1366d0032a8ec680221c2a704cac2391f2a2d77546fcaryclark@google.com // 1376d0032a8ec680221c2a704cac2391f2a2d77546fcaryclark@google.com 1386d0032a8ec680221c2a704cac2391f2a2d77546fcaryclark@google.com return true; 1396d0032a8ec680221c2a704cac2391f2a2d77546fcaryclark@google.com} 1406d0032a8ec680221c2a704cac2391f2a2d77546fcaryclark@google.com 1416d0032a8ec680221c2a704cac2391f2a2d77546fcaryclark@google.com// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions 1426d0032a8ec680221c2a704cac2391f2a2d77546fcaryclark@google.comvoid Mips16FrameLowering:: 1436d0032a8ec680221c2a704cac2391f2a2d77546fcaryclark@google.comeliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 1446d0032a8ec680221c2a704cac2391f2a2d77546fcaryclark@google.com MachineBasicBlock::iterator I) const { 145639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com if (!hasReservedCallFrame(MF)) { 146639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com int64_t Amount = I->getOperand(0).getImm(); 147639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com 148 if (I->getOpcode() == Mips::ADJCALLSTACKDOWN) 149 Amount = -Amount; 150 151 const Mips16InstrInfo &TII = 152 *static_cast<const Mips16InstrInfo*>(MF.getTarget().getInstrInfo()); 153 154 TII.adjustStackPtr(Mips::SP, Amount, MBB, I); 155 } 156 157 MBB.erase(I); 158} 159 160bool 161Mips16FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 162 const MachineFrameInfo *MFI = MF.getFrameInfo(); 163 // Reserve call frame if the size of the maximum call frame fits into 15-bit 164 // immediate field and there are no variable sized objects on the stack. 165 return isInt<15>(MFI->getMaxCallFrameSize()) && !MFI->hasVarSizedObjects(); 166} 167 168void Mips16FrameLowering:: 169processFunctionBeforeCalleeSavedScan(MachineFunction &MF, 170 RegScavenger *RS) const { 171 MF.getRegInfo().setPhysRegUsed(Mips::RA); 172 MF.getRegInfo().setPhysRegUsed(Mips::S0); 173 MF.getRegInfo().setPhysRegUsed(Mips::S1); 174 MF.getRegInfo().setPhysRegUsed(Mips::S2); 175} 176 177const MipsFrameLowering * 178llvm::createMips16FrameLowering(const MipsSubtarget &ST) { 179 return new Mips16FrameLowering(ST); 180} 181