//===-- Mips16FrameLowering.cpp - Mips16 Frame Information ----------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file contains the Mips16 implementation of TargetFrameLowering class. // //===----------------------------------------------------------------------===// #include "Mips16FrameLowering.h" #include "MipsInstrInfo.h" #include "MCTargetDesc/MipsBaseInfo.h" #include "llvm/Function.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/DataLayout.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Support/CommandLine.h" using namespace llvm; void Mips16FrameLowering::emitPrologue(MachineFunction &MF) const { MachineBasicBlock &MBB = MF.front(); MachineFrameInfo *MFI = MF.getFrameInfo(); const MipsInstrInfo &TII = *static_cast(MF.getTarget().getInstrInfo()); MachineBasicBlock::iterator MBBI = MBB.begin(); DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); uint64_t StackSize = MFI->getStackSize(); // No need to allocate space on the stack. if (StackSize == 0 && !MFI->adjustsStack()) return; // Adjust stack. if (isInt<16>(-StackSize)) BuildMI(MBB, MBBI, dl, TII.get(Mips::SaveRaF16)).addImm(StackSize); if (hasFP(MF)) BuildMI(MBB, MBBI, dl, TII.get(Mips::MoveR3216), Mips::S0) .addReg(Mips::SP); } void Mips16FrameLowering::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const { MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); MachineFrameInfo *MFI = MF.getFrameInfo(); const MipsInstrInfo &TII = *static_cast(MF.getTarget().getInstrInfo()); DebugLoc dl = MBBI->getDebugLoc(); uint64_t StackSize = MFI->getStackSize(); if (!StackSize) return; if (hasFP(MF)) BuildMI(MBB, MBBI, dl, TII.get(Mips::Move32R16), Mips::SP) .addReg(Mips::S0); // Adjust stack. if (isInt<16>(StackSize)) // assumes stacksize multiple of 8 BuildMI(MBB, MBBI, dl, TII.get(Mips::RestoreRaF16)).addImm(StackSize); } bool Mips16FrameLowering:: spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector &CSI, const TargetRegisterInfo *TRI) const { MachineFunction *MF = MBB.getParent(); MachineBasicBlock *EntryBlock = MF->begin(); // // Registers RA, S0,S1 are the callee saved registers and they // will be saved with the "save" instruction // during emitPrologue // for (unsigned i = 0, e = CSI.size(); i != e; ++i) { // Add the callee-saved register as live-in. Do not add if the register is // RA and return address is taken, because it has already been added in // method MipsTargetLowering::LowerRETURNADDR. // It's killed at the spill, unless the register is RA and return address // is taken. unsigned Reg = CSI[i].getReg(); bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA) && MF->getFrameInfo()->isReturnAddressTaken(); if (!IsRAAndRetAddrIsTaken) EntryBlock->addLiveIn(Reg); } return true; } bool Mips16FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector &CSI, const TargetRegisterInfo *TRI) const { // // Registers RA,S0,S1 are the callee saved registers and they will be restored // with the restore instruction during emitEpilogue. // We need to override this virtual function, otherwise llvm will try and // restore the registers on it's on from the stack. // return true; } bool Mips16FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { const MachineFrameInfo *MFI = MF.getFrameInfo(); // Reserve call frame if the size of the maximum call frame fits into 15-bit // immediate field and there are no variable sized objects on the stack. return isInt<15>(MFI->getMaxCallFrameSize()) && !MFI->hasVarSizedObjects(); } void Mips16FrameLowering:: processFunctionBeforeCalleeSavedScan(MachineFunction &MF, RegScavenger *RS) const { MF.getRegInfo().setPhysRegUsed(Mips::RA); MF.getRegInfo().setPhysRegUsed(Mips::S0); MF.getRegInfo().setPhysRegUsed(Mips::S1); } const MipsFrameLowering * llvm::createMips16FrameLowering(const MipsSubtarget &ST) { return new Mips16FrameLowering(ST); }