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" 15252723Sdim#include "MCTargetDesc/MipsBaseInfo.h" 16252723Sdim#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" 23252723Sdim#include "llvm/IR/DataLayout.h" 24252723Sdim#include "llvm/IR/Function.h" 25252723Sdim#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(); 33252723Sdim const Mips16InstrInfo &TII = 34252723Sdim *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 42252723Sdim MachineModuleInfo &MMI = MF.getMMI(); 43263509Sdim const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo(); 44252723Sdim MachineLocation DstML, SrcML; 45252723Sdim 46239310Sdim // Adjust stack. 47252723Sdim TII.makeFrame(Mips::SP, StackSize, MBB, MBBI); 48245431Sdim 49252723Sdim // emit ".cfi_def_cfa_offset StackSize" 50252723Sdim MCSymbol *AdjustSPLabel = MMI.getContext().CreateTempSymbol(); 51252723Sdim BuildMI(MBB, MBBI, dl, 52252723Sdim TII.get(TargetOpcode::PROLOG_LABEL)).addSym(AdjustSPLabel); 53263509Sdim MMI.addFrameInst( 54263509Sdim MCCFIInstruction::createDefCfaOffset(AdjustSPLabel, -StackSize)); 55252723Sdim 56252723Sdim MCSymbol *CSLabel = MMI.getContext().CreateTempSymbol(); 57252723Sdim BuildMI(MBB, MBBI, dl, 58252723Sdim TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel); 59263509Sdim unsigned S2 = MRI->getDwarfRegNum(Mips::S2, true); 60263509Sdim MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, S2, -8)); 61252723Sdim 62263509Sdim unsigned S1 = MRI->getDwarfRegNum(Mips::S1, true); 63263509Sdim MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, S1, -12)); 64252723Sdim 65263509Sdim unsigned S0 = MRI->getDwarfRegNum(Mips::S0, true); 66263509Sdim MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, S0, -16)); 67252723Sdim 68263509Sdim unsigned RA = MRI->getDwarfRegNum(Mips::RA, true); 69263509Sdim MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, RA, -4)); 70263509Sdim 71245431Sdim if (hasFP(MF)) 72245431Sdim BuildMI(MBB, MBBI, dl, TII.get(Mips::MoveR3216), Mips::S0) 73245431Sdim .addReg(Mips::SP); 74245431Sdim 75239310Sdim} 76239310Sdim 77239310Sdimvoid Mips16FrameLowering::emitEpilogue(MachineFunction &MF, 78239310Sdim MachineBasicBlock &MBB) const { 79239310Sdim MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 80239310Sdim MachineFrameInfo *MFI = MF.getFrameInfo(); 81252723Sdim const Mips16InstrInfo &TII = 82252723Sdim *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 89245431Sdim if (hasFP(MF)) 90245431Sdim BuildMI(MBB, MBBI, dl, TII.get(Mips::Move32R16), Mips::SP) 91245431Sdim .addReg(Mips::S0); 92245431Sdim 93239310Sdim // Adjust stack. 94252723Sdim // assumes stacksize multiple of 8 95252723Sdim 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 { 103245431Sdim MachineFunction *MF = MBB.getParent(); 104245431Sdim MachineBasicBlock *EntryBlock = MF->begin(); 105245431Sdim 106245431Sdim // 107245431Sdim // Registers RA, S0,S1 are the callee saved registers and they 108245431Sdim // will be saved with the "save" instruction 109245431Sdim // during emitPrologue 110245431Sdim // 111245431Sdim for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 112245431Sdim // Add the callee-saved register as live-in. Do not add if the register is 113245431Sdim // RA and return address is taken, because it has already been added in 114245431Sdim // method MipsTargetLowering::LowerRETURNADDR. 115245431Sdim // It's killed at the spill, unless the register is RA and return address 116245431Sdim // is taken. 117245431Sdim unsigned Reg = CSI[i].getReg(); 118245431Sdim bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA) 119245431Sdim && MF->getFrameInfo()->isReturnAddressTaken(); 120245431Sdim if (!IsRAAndRetAddrIsTaken) 121245431Sdim EntryBlock->addLiveIn(Reg); 122245431Sdim } 123245431Sdim 124239310Sdim return true; 125239310Sdim} 126239310Sdim 127245431Sdimbool Mips16FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 128245431Sdim MachineBasicBlock::iterator MI, 129245431Sdim const std::vector<CalleeSavedInfo> &CSI, 130245431Sdim const TargetRegisterInfo *TRI) const { 131245431Sdim // 132245431Sdim // Registers RA,S0,S1 are the callee saved registers and they will be restored 133245431Sdim // with the restore instruction during emitEpilogue. 134245431Sdim // We need to override this virtual function, otherwise llvm will try and 135245431Sdim // restore the registers on it's on from the stack. 136245431Sdim // 137245431Sdim 138245431Sdim return true; 139245431Sdim} 140245431Sdim 141252723Sdim// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions 142252723Sdimvoid Mips16FrameLowering:: 143252723SdimeliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 144252723Sdim MachineBasicBlock::iterator I) const { 145252723Sdim if (!hasReservedCallFrame(MF)) { 146252723Sdim int64_t Amount = I->getOperand(0).getImm(); 147252723Sdim 148252723Sdim if (I->getOpcode() == Mips::ADJCALLSTACKDOWN) 149252723Sdim Amount = -Amount; 150252723Sdim 151252723Sdim const Mips16InstrInfo &TII = 152252723Sdim *static_cast<const Mips16InstrInfo*>(MF.getTarget().getInstrInfo()); 153252723Sdim 154252723Sdim TII.adjustStackPtr(Mips::SP, Amount, MBB, I); 155252723Sdim } 156252723Sdim 157252723Sdim MBB.erase(I); 158252723Sdim} 159252723Sdim 160239310Sdimbool 161239310SdimMips16FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 162245431Sdim const MachineFrameInfo *MFI = MF.getFrameInfo(); 163245431Sdim // Reserve call frame if the size of the maximum call frame fits into 15-bit 164245431Sdim // immediate field and there are no variable sized objects on the stack. 165245431Sdim return isInt<15>(MFI->getMaxCallFrameSize()) && !MFI->hasVarSizedObjects(); 166239310Sdim} 167239310Sdim 168239310Sdimvoid Mips16FrameLowering:: 169239310SdimprocessFunctionBeforeCalleeSavedScan(MachineFunction &MF, 170239310Sdim RegScavenger *RS) const { 171245431Sdim MF.getRegInfo().setPhysRegUsed(Mips::RA); 172245431Sdim MF.getRegInfo().setPhysRegUsed(Mips::S0); 173245431Sdim MF.getRegInfo().setPhysRegUsed(Mips::S1); 174263509Sdim MF.getRegInfo().setPhysRegUsed(Mips::S2); 175239310Sdim} 176239310Sdim 177239310Sdimconst MipsFrameLowering * 178239310Sdimllvm::createMips16FrameLowering(const MipsSubtarget &ST) { 179239310Sdim return new Mips16FrameLowering(ST); 180239310Sdim} 181