1239310Sdim//===-- Mips16FrameLowering.cpp - Mips16 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 Mips16 implementation of TargetFrameLowering class. 11239310Sdim// 12239310Sdim//===----------------------------------------------------------------------===// 13239310Sdim 14239310Sdim#include "Mips16FrameLowering.h" 15249423Sdim#include "MCTargetDesc/MipsBaseInfo.h" 16249423Sdim#include "Mips16InstrInfo.h" 17239310Sdim#include "MipsInstrInfo.h" 18239310Sdim#include "llvm/CodeGen/MachineFrameInfo.h" 19239310Sdim#include "llvm/CodeGen/MachineFunction.h" 20239310Sdim#include "llvm/CodeGen/MachineInstrBuilder.h" 21239310Sdim#include "llvm/CodeGen/MachineModuleInfo.h" 22239310Sdim#include "llvm/CodeGen/MachineRegisterInfo.h" 23249423Sdim#include "llvm/IR/DataLayout.h" 24249423Sdim#include "llvm/IR/Function.h" 25249423Sdim#include "llvm/Support/CommandLine.h" 26239310Sdim#include "llvm/Target/TargetOptions.h" 27239310Sdim 28239310Sdimusing namespace llvm; 29239310Sdim 30239310Sdimvoid Mips16FrameLowering::emitPrologue(MachineFunction &MF) const { 31239310Sdim MachineBasicBlock &MBB = MF.front(); 32239310Sdim MachineFrameInfo *MFI = MF.getFrameInfo(); 33249423Sdim const Mips16InstrInfo &TII = 34249423Sdim *static_cast<const Mips16InstrInfo*>(MF.getTarget().getInstrInfo()); 35239310Sdim MachineBasicBlock::iterator MBBI = MBB.begin(); 36239310Sdim DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 37239310Sdim uint64_t StackSize = MFI->getStackSize(); 38239310Sdim 39239310Sdim // No need to allocate space on the stack. 40239310Sdim if (StackSize == 0 && !MFI->adjustsStack()) return; 41239310Sdim 42249423Sdim MachineModuleInfo &MMI = MF.getMMI(); 43263508Sdim const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo(); 44249423Sdim MachineLocation DstML, SrcML; 45249423Sdim 46239310Sdim // Adjust stack. 47249423Sdim TII.makeFrame(Mips::SP, StackSize, MBB, MBBI); 48243830Sdim 49249423Sdim // emit ".cfi_def_cfa_offset StackSize" 50249423Sdim MCSymbol *AdjustSPLabel = MMI.getContext().CreateTempSymbol(); 51249423Sdim BuildMI(MBB, MBBI, dl, 52249423Sdim TII.get(TargetOpcode::PROLOG_LABEL)).addSym(AdjustSPLabel); 53263508Sdim MMI.addFrameInst( 54263508Sdim MCCFIInstruction::createDefCfaOffset(AdjustSPLabel, -StackSize)); 55249423Sdim 56249423Sdim MCSymbol *CSLabel = MMI.getContext().CreateTempSymbol(); 57249423Sdim BuildMI(MBB, MBBI, dl, 58249423Sdim TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel); 59263508Sdim unsigned S2 = MRI->getDwarfRegNum(Mips::S2, true); 60263508Sdim MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, S2, -8)); 61249423Sdim 62263508Sdim unsigned S1 = MRI->getDwarfRegNum(Mips::S1, true); 63263508Sdim MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, S1, -12)); 64249423Sdim 65263508Sdim unsigned S0 = MRI->getDwarfRegNum(Mips::S0, true); 66263508Sdim MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, S0, -16)); 67249423Sdim 68263508Sdim unsigned RA = MRI->getDwarfRegNum(Mips::RA, true); 69263508Sdim MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, RA, -4)); 70263508Sdim 71243830Sdim if (hasFP(MF)) 72243830Sdim BuildMI(MBB, MBBI, dl, TII.get(Mips::MoveR3216), Mips::S0) 73243830Sdim .addReg(Mips::SP); 74243830Sdim 75239310Sdim} 76239310Sdim 77239310Sdimvoid Mips16FrameLowering::emitEpilogue(MachineFunction &MF, 78239310Sdim MachineBasicBlock &MBB) const { 79239310Sdim MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 80239310Sdim MachineFrameInfo *MFI = MF.getFrameInfo(); 81249423Sdim const Mips16InstrInfo &TII = 82249423Sdim *static_cast<const Mips16InstrInfo*>(MF.getTarget().getInstrInfo()); 83239310Sdim DebugLoc dl = MBBI->getDebugLoc(); 84239310Sdim uint64_t StackSize = MFI->getStackSize(); 85239310Sdim 86239310Sdim if (!StackSize) 87239310Sdim return; 88239310Sdim 89243830Sdim if (hasFP(MF)) 90243830Sdim BuildMI(MBB, MBBI, dl, TII.get(Mips::Move32R16), Mips::SP) 91243830Sdim .addReg(Mips::S0); 92243830Sdim 93239310Sdim // Adjust stack. 94249423Sdim // assumes stacksize multiple of 8 95249423Sdim TII.restoreFrame(Mips::SP, StackSize, MBB, MBBI); 96239310Sdim} 97239310Sdim 98239310Sdimbool Mips16FrameLowering:: 99239310SdimspillCalleeSavedRegisters(MachineBasicBlock &MBB, 100239310Sdim MachineBasicBlock::iterator MI, 101239310Sdim const std::vector<CalleeSavedInfo> &CSI, 102239310Sdim const TargetRegisterInfo *TRI) const { 103243830Sdim MachineFunction *MF = MBB.getParent(); 104243830Sdim MachineBasicBlock *EntryBlock = MF->begin(); 105243830Sdim 106243830Sdim // 107243830Sdim // Registers RA, S0,S1 are the callee saved registers and they 108243830Sdim // will be saved with the "save" instruction 109243830Sdim // during emitPrologue 110243830Sdim // 111243830Sdim for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 112243830Sdim // Add the callee-saved register as live-in. Do not add if the register is 113243830Sdim // RA and return address is taken, because it has already been added in 114243830Sdim // method MipsTargetLowering::LowerRETURNADDR. 115243830Sdim // It's killed at the spill, unless the register is RA and return address 116243830Sdim // is taken. 117243830Sdim unsigned Reg = CSI[i].getReg(); 118243830Sdim bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA) 119243830Sdim && MF->getFrameInfo()->isReturnAddressTaken(); 120243830Sdim if (!IsRAAndRetAddrIsTaken) 121243830Sdim EntryBlock->addLiveIn(Reg); 122243830Sdim } 123243830Sdim 124239310Sdim return true; 125239310Sdim} 126239310Sdim 127243830Sdimbool Mips16FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 128243830Sdim MachineBasicBlock::iterator MI, 129243830Sdim const std::vector<CalleeSavedInfo> &CSI, 130243830Sdim const TargetRegisterInfo *TRI) const { 131243830Sdim // 132243830Sdim // Registers RA,S0,S1 are the callee saved registers and they will be restored 133243830Sdim // with the restore instruction during emitEpilogue. 134243830Sdim // We need to override this virtual function, otherwise llvm will try and 135243830Sdim // restore the registers on it's on from the stack. 136243830Sdim // 137243830Sdim 138243830Sdim return true; 139243830Sdim} 140243830Sdim 141249423Sdim// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions 142249423Sdimvoid Mips16FrameLowering:: 143249423SdimeliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 144249423Sdim MachineBasicBlock::iterator I) const { 145249423Sdim if (!hasReservedCallFrame(MF)) { 146249423Sdim int64_t Amount = I->getOperand(0).getImm(); 147249423Sdim 148249423Sdim if (I->getOpcode() == Mips::ADJCALLSTACKDOWN) 149249423Sdim Amount = -Amount; 150249423Sdim 151249423Sdim const Mips16InstrInfo &TII = 152249423Sdim *static_cast<const Mips16InstrInfo*>(MF.getTarget().getInstrInfo()); 153249423Sdim 154249423Sdim TII.adjustStackPtr(Mips::SP, Amount, MBB, I); 155249423Sdim } 156249423Sdim 157249423Sdim MBB.erase(I); 158249423Sdim} 159249423Sdim 160239310Sdimbool 161239310SdimMips16FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 162243830Sdim const MachineFrameInfo *MFI = MF.getFrameInfo(); 163243830Sdim // Reserve call frame if the size of the maximum call frame fits into 15-bit 164243830Sdim // immediate field and there are no variable sized objects on the stack. 165243830Sdim return isInt<15>(MFI->getMaxCallFrameSize()) && !MFI->hasVarSizedObjects(); 166239310Sdim} 167239310Sdim 168239310Sdimvoid Mips16FrameLowering:: 169239310SdimprocessFunctionBeforeCalleeSavedScan(MachineFunction &MF, 170239310Sdim RegScavenger *RS) const { 171243830Sdim MF.getRegInfo().setPhysRegUsed(Mips::RA); 172243830Sdim MF.getRegInfo().setPhysRegUsed(Mips::S0); 173243830Sdim MF.getRegInfo().setPhysRegUsed(Mips::S1); 174263508Sdim MF.getRegInfo().setPhysRegUsed(Mips::S2); 175239310Sdim} 176239310Sdim 177239310Sdimconst MipsFrameLowering * 178239310Sdimllvm::createMips16FrameLowering(const MipsSubtarget &ST) { 179239310Sdim return new Mips16FrameLowering(ST); 180239310Sdim} 181