Mips16FrameLowering.cpp revision 243830
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" 15239310Sdim#include "MipsInstrInfo.h" 16239310Sdim#include "MCTargetDesc/MipsBaseInfo.h" 17239310Sdim#include "llvm/Function.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" 23243830Sdim#include "llvm/DataLayout.h" 24239310Sdim#include "llvm/Target/TargetOptions.h" 25239310Sdim#include "llvm/Support/CommandLine.h" 26239310Sdim 27239310Sdimusing namespace llvm; 28239310Sdim 29239310Sdimvoid Mips16FrameLowering::emitPrologue(MachineFunction &MF) const { 30239310Sdim MachineBasicBlock &MBB = MF.front(); 31239310Sdim MachineFrameInfo *MFI = MF.getFrameInfo(); 32239310Sdim const MipsInstrInfo &TII = 33239310Sdim *static_cast<const MipsInstrInfo*>(MF.getTarget().getInstrInfo()); 34239310Sdim MachineBasicBlock::iterator MBBI = MBB.begin(); 35239310Sdim DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 36239310Sdim uint64_t StackSize = MFI->getStackSize(); 37239310Sdim 38239310Sdim // No need to allocate space on the stack. 39239310Sdim if (StackSize == 0 && !MFI->adjustsStack()) return; 40239310Sdim 41239310Sdim // Adjust stack. 42239310Sdim if (isInt<16>(-StackSize)) 43239310Sdim BuildMI(MBB, MBBI, dl, TII.get(Mips::SaveRaF16)).addImm(StackSize); 44243830Sdim 45243830Sdim if (hasFP(MF)) 46243830Sdim BuildMI(MBB, MBBI, dl, TII.get(Mips::MoveR3216), Mips::S0) 47243830Sdim .addReg(Mips::SP); 48243830Sdim 49239310Sdim} 50239310Sdim 51239310Sdimvoid Mips16FrameLowering::emitEpilogue(MachineFunction &MF, 52239310Sdim MachineBasicBlock &MBB) const { 53239310Sdim MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 54239310Sdim MachineFrameInfo *MFI = MF.getFrameInfo(); 55239310Sdim const MipsInstrInfo &TII = 56239310Sdim *static_cast<const MipsInstrInfo*>(MF.getTarget().getInstrInfo()); 57239310Sdim DebugLoc dl = MBBI->getDebugLoc(); 58239310Sdim uint64_t StackSize = MFI->getStackSize(); 59239310Sdim 60239310Sdim if (!StackSize) 61239310Sdim return; 62239310Sdim 63243830Sdim if (hasFP(MF)) 64243830Sdim BuildMI(MBB, MBBI, dl, TII.get(Mips::Move32R16), Mips::SP) 65243830Sdim .addReg(Mips::S0); 66243830Sdim 67239310Sdim // Adjust stack. 68239310Sdim if (isInt<16>(StackSize)) 69239310Sdim // assumes stacksize multiple of 8 70239310Sdim BuildMI(MBB, MBBI, dl, TII.get(Mips::RestoreRaF16)).addImm(StackSize); 71239310Sdim} 72239310Sdim 73239310Sdimbool Mips16FrameLowering:: 74239310SdimspillCalleeSavedRegisters(MachineBasicBlock &MBB, 75239310Sdim MachineBasicBlock::iterator MI, 76239310Sdim const std::vector<CalleeSavedInfo> &CSI, 77239310Sdim const TargetRegisterInfo *TRI) const { 78243830Sdim MachineFunction *MF = MBB.getParent(); 79243830Sdim MachineBasicBlock *EntryBlock = MF->begin(); 80243830Sdim 81243830Sdim // 82243830Sdim // Registers RA, S0,S1 are the callee saved registers and they 83243830Sdim // will be saved with the "save" instruction 84243830Sdim // during emitPrologue 85243830Sdim // 86243830Sdim for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 87243830Sdim // Add the callee-saved register as live-in. Do not add if the register is 88243830Sdim // RA and return address is taken, because it has already been added in 89243830Sdim // method MipsTargetLowering::LowerRETURNADDR. 90243830Sdim // It's killed at the spill, unless the register is RA and return address 91243830Sdim // is taken. 92243830Sdim unsigned Reg = CSI[i].getReg(); 93243830Sdim bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA) 94243830Sdim && MF->getFrameInfo()->isReturnAddressTaken(); 95243830Sdim if (!IsRAAndRetAddrIsTaken) 96243830Sdim EntryBlock->addLiveIn(Reg); 97243830Sdim } 98243830Sdim 99239310Sdim return true; 100239310Sdim} 101239310Sdim 102243830Sdimbool Mips16FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 103243830Sdim MachineBasicBlock::iterator MI, 104243830Sdim const std::vector<CalleeSavedInfo> &CSI, 105243830Sdim const TargetRegisterInfo *TRI) const { 106243830Sdim // 107243830Sdim // Registers RA,S0,S1 are the callee saved registers and they will be restored 108243830Sdim // with the restore instruction during emitEpilogue. 109243830Sdim // We need to override this virtual function, otherwise llvm will try and 110243830Sdim // restore the registers on it's on from the stack. 111243830Sdim // 112243830Sdim 113243830Sdim return true; 114243830Sdim} 115243830Sdim 116239310Sdimbool 117239310SdimMips16FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 118243830Sdim const MachineFrameInfo *MFI = MF.getFrameInfo(); 119243830Sdim // Reserve call frame if the size of the maximum call frame fits into 15-bit 120243830Sdim // immediate field and there are no variable sized objects on the stack. 121243830Sdim return isInt<15>(MFI->getMaxCallFrameSize()) && !MFI->hasVarSizedObjects(); 122239310Sdim} 123239310Sdim 124239310Sdimvoid Mips16FrameLowering:: 125239310SdimprocessFunctionBeforeCalleeSavedScan(MachineFunction &MF, 126239310Sdim RegScavenger *RS) const { 127243830Sdim MF.getRegInfo().setPhysRegUsed(Mips::RA); 128243830Sdim MF.getRegInfo().setPhysRegUsed(Mips::S0); 129243830Sdim MF.getRegInfo().setPhysRegUsed(Mips::S1); 130239310Sdim} 131239310Sdim 132239310Sdimconst MipsFrameLowering * 133239310Sdimllvm::createMips16FrameLowering(const MipsSubtarget &ST) { 134239310Sdim return new Mips16FrameLowering(ST); 135239310Sdim} 136