X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FXCore%2FXCoreRegisterInfo.cpp;h=1cfb57dc3af3073f604bb96686f113476fb3fbf3;hb=1422e1f158810323cfbe06d9242ba35c3f674921;hp=856ae36ed3992e500b55bf4531c583ceb093cbe7;hpb=2e9919a5e5fe76f4b1e3290103c4bfd149ebba9c;p=oota-llvm.git diff --git a/lib/Target/XCore/XCoreRegisterInfo.cpp b/lib/Target/XCore/XCoreRegisterInfo.cpp index 856ae36ed39..1cfb57dc3af 100644 --- a/lib/Target/XCore/XCoreRegisterInfo.cpp +++ b/lib/Target/XCore/XCoreRegisterInfo.cpp @@ -1,4 +1,4 @@ -//===- XCoreRegisterInfo.cpp - XCore Register Information -------*- C++ -*-===// +//===-- XCoreRegisterInfo.cpp - XCore Register Information ----------------===// // // The LLVM Compiler Infrastructure // @@ -12,32 +12,37 @@ //===----------------------------------------------------------------------===// #include "XCoreRegisterInfo.h" -#include "XCoreMachineFunctionInfo.h" #include "XCore.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/MachineFunction.h" +#include "XCoreInstrInfo.h" +#include "XCoreMachineFunctionInfo.h" +#include "XCoreSubtarget.h" +#include "llvm/ADT/BitVector.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/CodeGen/MachineFrameInfo.h" -#include "llvm/CodeGen/MachineLocation.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/RegisterScavenging.h" -#include "llvm/Target/TargetFrameInfo.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetOptions.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Type.h" -#include "llvm/Function.h" -#include "llvm/ADT/BitVector.h" -#include "llvm/ADT/STLExtras.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Type.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Target/TargetFrameLowering.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetOptions.h" using namespace llvm; -XCoreRegisterInfo::XCoreRegisterInfo(const TargetInstrInfo &tii) - : XCoreGenRegisterInfo(XCore::ADJCALLSTACKDOWN, XCore::ADJCALLSTACKUP), - TII(tii) { +#define DEBUG_TYPE "xcore-reg-info" + +#define GET_REGINFO_TARGET_DESC +#include "XCoreGenRegisterInfo.inc" + +XCoreRegisterInfo::XCoreRegisterInfo() + : XCoreGenRegisterInfo(XCore::LR) { } // helper functions @@ -53,58 +58,185 @@ static inline bool isImmU16(unsigned val) { return val < (1 << 16); } -static const unsigned XCore_ArgRegs[] = { - XCore::R0, XCore::R1, XCore::R2, XCore::R3 -}; -const unsigned * XCoreRegisterInfo::getArgRegs(const MachineFunction *MF) -{ - return XCore_ArgRegs; +static void InsertFPImmInst(MachineBasicBlock::iterator II, + const XCoreInstrInfo &TII, + unsigned Reg, unsigned FrameReg, int Offset ) { + MachineInstr &MI = *II; + MachineBasicBlock &MBB = *MI.getParent(); + DebugLoc dl = MI.getDebugLoc(); + + switch (MI.getOpcode()) { + case XCore::LDWFI: + BuildMI(MBB, II, dl, TII.get(XCore::LDW_2rus), Reg) + .addReg(FrameReg) + .addImm(Offset) + .addMemOperand(*MI.memoperands_begin()); + break; + case XCore::STWFI: + BuildMI(MBB, II, dl, TII.get(XCore::STW_2rus)) + .addReg(Reg, getKillRegState(MI.getOperand(0).isKill())) + .addReg(FrameReg) + .addImm(Offset) + .addMemOperand(*MI.memoperands_begin()); + break; + case XCore::LDAWFI: + BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l2rus), Reg) + .addReg(FrameReg) + .addImm(Offset); + break; + default: + llvm_unreachable("Unexpected Opcode"); + } } -unsigned XCoreRegisterInfo::getNumArgRegs(const MachineFunction *MF) -{ - return array_lengthof(XCore_ArgRegs); +static void InsertFPConstInst(MachineBasicBlock::iterator II, + const XCoreInstrInfo &TII, + unsigned Reg, unsigned FrameReg, + int Offset, RegScavenger *RS ) { + assert(RS && "requiresRegisterScavenging failed"); + MachineInstr &MI = *II; + MachineBasicBlock &MBB = *MI.getParent(); + DebugLoc dl = MI.getDebugLoc(); + unsigned ScratchOffset = RS->scavengeRegister(&XCore::GRRegsRegClass, II, 0); + RS->setRegUsed(ScratchOffset); + TII.loadImmediate(MBB, II, ScratchOffset, Offset); + + switch (MI.getOpcode()) { + case XCore::LDWFI: + BuildMI(MBB, II, dl, TII.get(XCore::LDW_3r), Reg) + .addReg(FrameReg) + .addReg(ScratchOffset, RegState::Kill) + .addMemOperand(*MI.memoperands_begin()); + break; + case XCore::STWFI: + BuildMI(MBB, II, dl, TII.get(XCore::STW_l3r)) + .addReg(Reg, getKillRegState(MI.getOperand(0).isKill())) + .addReg(FrameReg) + .addReg(ScratchOffset, RegState::Kill) + .addMemOperand(*MI.memoperands_begin()); + break; + case XCore::LDAWFI: + BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l3r), Reg) + .addReg(FrameReg) + .addReg(ScratchOffset, RegState::Kill); + break; + default: + llvm_unreachable("Unexpected Opcode"); + } } -bool XCoreRegisterInfo::needsFrameMoves(const MachineFunction &MF) -{ - const MachineFrameInfo *MFI = MF.getFrameInfo(); - MachineModuleInfo *MMI = MFI->getMachineModuleInfo(); - return (MMI && MMI->hasDebugInfo()) || - !MF.getFunction()->doesNotThrow() || - UnwindTablesMandatory; +static void InsertSPImmInst(MachineBasicBlock::iterator II, + const XCoreInstrInfo &TII, + unsigned Reg, int Offset) { + MachineInstr &MI = *II; + MachineBasicBlock &MBB = *MI.getParent(); + DebugLoc dl = MI.getDebugLoc(); + bool isU6 = isImmU6(Offset); + + switch (MI.getOpcode()) { + int NewOpcode; + case XCore::LDWFI: + NewOpcode = (isU6) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6; + BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg) + .addImm(Offset) + .addMemOperand(*MI.memoperands_begin()); + break; + case XCore::STWFI: + NewOpcode = (isU6) ? XCore::STWSP_ru6 : XCore::STWSP_lru6; + BuildMI(MBB, II, dl, TII.get(NewOpcode)) + .addReg(Reg, getKillRegState(MI.getOperand(0).isKill())) + .addImm(Offset) + .addMemOperand(*MI.memoperands_begin()); + break; + case XCore::LDAWFI: + NewOpcode = (isU6) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6; + BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg) + .addImm(Offset); + break; + default: + llvm_unreachable("Unexpected Opcode"); + } } -const unsigned* XCoreRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) - const { - static const unsigned CalleeSavedRegs[] = { +static void InsertSPConstInst(MachineBasicBlock::iterator II, + const XCoreInstrInfo &TII, + unsigned Reg, int Offset, RegScavenger *RS ) { + assert(RS && "requiresRegisterScavenging failed"); + MachineInstr &MI = *II; + MachineBasicBlock &MBB = *MI.getParent(); + DebugLoc dl = MI.getDebugLoc(); + unsigned OpCode = MI.getOpcode(); + + unsigned ScratchBase; + if (OpCode==XCore::STWFI) { + ScratchBase = RS->scavengeRegister(&XCore::GRRegsRegClass, II, 0); + RS->setRegUsed(ScratchBase); + } else + ScratchBase = Reg; + BuildMI(MBB, II, dl, TII.get(XCore::LDAWSP_ru6), ScratchBase).addImm(0); + unsigned ScratchOffset = RS->scavengeRegister(&XCore::GRRegsRegClass, II, 0); + RS->setRegUsed(ScratchOffset); + TII.loadImmediate(MBB, II, ScratchOffset, Offset); + + switch (OpCode) { + case XCore::LDWFI: + BuildMI(MBB, II, dl, TII.get(XCore::LDW_3r), Reg) + .addReg(ScratchBase, RegState::Kill) + .addReg(ScratchOffset, RegState::Kill) + .addMemOperand(*MI.memoperands_begin()); + break; + case XCore::STWFI: + BuildMI(MBB, II, dl, TII.get(XCore::STW_l3r)) + .addReg(Reg, getKillRegState(MI.getOperand(0).isKill())) + .addReg(ScratchBase, RegState::Kill) + .addReg(ScratchOffset, RegState::Kill) + .addMemOperand(*MI.memoperands_begin()); + break; + case XCore::LDAWFI: + BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l3r), Reg) + .addReg(ScratchBase, RegState::Kill) + .addReg(ScratchOffset, RegState::Kill); + break; + default: + llvm_unreachable("Unexpected Opcode"); + } +} + +bool XCoreRegisterInfo::needsFrameMoves(const MachineFunction &MF) { + return MF.getMMI().hasDebugInfo() || + MF.getFunction()->needsUnwindTableEntry(); +} + +const MCPhysReg * +XCoreRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { + // The callee saved registers LR & FP are explicitly handled during + // emitPrologue & emitEpilogue and related functions. + static const MCPhysReg CalleeSavedRegs[] = { XCore::R4, XCore::R5, XCore::R6, XCore::R7, - XCore::R8, XCore::R9, XCore::R10, XCore::LR, + XCore::R8, XCore::R9, XCore::R10, 0 }; - return CalleeSavedRegs; -} - -const TargetRegisterClass* const* -XCoreRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const { - static const TargetRegisterClass * const CalleeSavedRegClasses[] = { - XCore::GRRegsRegisterClass, XCore::GRRegsRegisterClass, - XCore::GRRegsRegisterClass, XCore::GRRegsRegisterClass, - XCore::GRRegsRegisterClass, XCore::GRRegsRegisterClass, - XCore::GRRegsRegisterClass, XCore::RRegsRegisterClass, + static const MCPhysReg CalleeSavedRegsFP[] = { + XCore::R4, XCore::R5, XCore::R6, XCore::R7, + XCore::R8, XCore::R9, 0 }; - return CalleeSavedRegClasses; + const XCoreFrameLowering *TFI = getFrameLowering(*MF); + if (TFI->hasFP(*MF)) + return CalleeSavedRegsFP; + return CalleeSavedRegs; } BitVector XCoreRegisterInfo::getReservedRegs(const MachineFunction &MF) const { BitVector Reserved(getNumRegs()); + const XCoreFrameLowering *TFI = getFrameLowering(MF); + Reserved.set(XCore::CP); Reserved.set(XCore::DP); Reserved.set(XCore::SP); Reserved.set(XCore::LR); - if (hasFP(MF)) { + if (TFI->hasFP(MF)) { Reserved.set(XCore::R10); } return Reserved; @@ -112,89 +244,39 @@ BitVector XCoreRegisterInfo::getReservedRegs(const MachineFunction &MF) const { bool XCoreRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const { - // TODO can we estimate stack size? - return hasFP(MF); + return true; } -bool XCoreRegisterInfo::hasFP(const MachineFunction &MF) const { - return NoFramePointerElim || MF.getFrameInfo()->hasVarSizedObjects(); +bool +XCoreRegisterInfo::trackLivenessAfterRegAlloc(const MachineFunction &MF) const { + return true; } -// This function eliminates ADJCALLSTACKDOWN, -// ADJCALLSTACKUP pseudo instructions -void XCoreRegisterInfo:: -eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, - MachineBasicBlock::iterator I) const { - if (!hasReservedCallFrame(MF)) { - // Turn the adjcallstackdown instruction into 'extsp ' and the - // adjcallstackup instruction into 'ldaw sp, sp[]' - MachineInstr *Old = I; - uint64_t Amount = Old->getOperand(0).getImm(); - if (Amount != 0) { - // We need to keep the stack aligned properly. To do this, we round the - // amount of space needed for the outgoing arguments up to the next - // alignment boundary. - unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); - Amount = (Amount+Align-1)/Align*Align; - - assert(Amount%4 == 0); - Amount /= 4; - - bool isU6 = isImmU6(Amount); - - if (!isU6 && !isImmU16(Amount)) { - // FIX could emit multiple instructions in this case. -#ifndef NDEBUG - errs() << "eliminateCallFramePseudoInstr size too big: " - << Amount << "\n"; -#endif - llvm_unreachable(0); - } - - MachineInstr *New; - if (Old->getOpcode() == XCore::ADJCALLSTACKDOWN) { - int Opcode = isU6 ? XCore::EXTSP_u6 : XCore::EXTSP_lu6; - New=BuildMI(MF, Old->getDebugLoc(), TII.get(Opcode)) - .addImm(Amount); - } else { - assert(Old->getOpcode() == XCore::ADJCALLSTACKUP); - int Opcode = isU6 ? XCore::LDAWSP_ru6_RRegs : XCore::LDAWSP_lru6_RRegs; - New=BuildMI(MF, Old->getDebugLoc(), TII.get(Opcode), XCore::SP) - .addImm(Amount); - } - - // Replace the pseudo instruction with a new instruction... - MBB.insert(I, New); - } - } - - MBB.erase(I); +bool +XCoreRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const { + return false; } -unsigned +void XCoreRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, - int SPAdj, FrameIndexValue *Value, + int SPAdj, unsigned FIOperandNum, RegScavenger *RS) const { assert(SPAdj == 0 && "Unexpected"); MachineInstr &MI = *II; - DebugLoc dl = MI.getDebugLoc(); - unsigned i = 0; - - while (!MI.getOperand(i).isFI()) { - ++i; - assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); - } - - MachineOperand &FrameOp = MI.getOperand(i); + MachineOperand &FrameOp = MI.getOperand(FIOperandNum); int FrameIndex = FrameOp.getIndex(); MachineFunction &MF = *MI.getParent()->getParent(); + const XCoreInstrInfo &TII = + *static_cast(MF.getSubtarget().getInstrInfo()); + + const XCoreFrameLowering *TFI = getFrameLowering(MF); int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex); int StackSize = MF.getFrameInfo()->getStackSize(); #ifndef NDEBUG DEBUG(errs() << "\nFunction : " - << MF.getFunction()->getName() << "\n"); + << MF.getName() << "\n"); DEBUG(errs() << "<--------->\n"); DEBUG(MI.print(errs())); DEBUG(errs() << "FrameIndex : " << FrameIndex << "\n"); @@ -203,414 +285,46 @@ XCoreRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, #endif Offset += StackSize; - + + unsigned FrameReg = getFrameRegister(MF); + + // Special handling of DBG_VALUE instructions. + if (MI.isDebugValue()) { + MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false /*isDef*/); + MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset); + return; + } + // fold constant into offset. - Offset += MI.getOperand(i + 1).getImm(); - MI.getOperand(i + 1).ChangeToImmediate(0); + Offset += MI.getOperand(FIOperandNum + 1).getImm(); + MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0); assert(Offset%4 == 0 && "Misaligned stack offset"); - DEBUG(errs() << "Offset : " << Offset << "\n" << "<--------->\n"); - Offset/=4; - bool FP = hasFP(MF); - unsigned Reg = MI.getOperand(0).getReg(); - bool isKill = MI.getOpcode() == XCore::STWFI && MI.getOperand(0).isKill(); + assert(XCore::GRRegsRegClass.contains(Reg) && "Unexpected register operand"); - assert(XCore::GRRegsRegisterClass->contains(Reg) && - "Unexpected register operand"); - - MachineBasicBlock &MBB = *MI.getParent(); - - if (FP) { - bool isUs = isImmUs(Offset); - unsigned FramePtr = XCore::R10; - - if (!isUs) { - if (!RS) { - std::string msg; - raw_string_ostream Msg(msg); - Msg << "eliminateFrameIndex Frame size too big: " << Offset; - llvm_report_error(Msg.str()); - } - unsigned ScratchReg = RS->scavengeRegister(XCore::GRRegsRegisterClass, II, - SPAdj); - loadConstant(MBB, II, ScratchReg, Offset, dl); - switch (MI.getOpcode()) { - case XCore::LDWFI: - BuildMI(MBB, II, dl, TII.get(XCore::LDW_3r), Reg) - .addReg(FramePtr) - .addReg(ScratchReg, RegState::Kill); - break; - case XCore::STWFI: - BuildMI(MBB, II, dl, TII.get(XCore::STW_3r)) - .addReg(Reg, getKillRegState(isKill)) - .addReg(FramePtr) - .addReg(ScratchReg, RegState::Kill); - break; - case XCore::LDAWFI: - BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l3r), Reg) - .addReg(FramePtr) - .addReg(ScratchReg, RegState::Kill); - break; - default: - llvm_unreachable("Unexpected Opcode"); - } - } else { - switch (MI.getOpcode()) { - case XCore::LDWFI: - BuildMI(MBB, II, dl, TII.get(XCore::LDW_2rus), Reg) - .addReg(FramePtr) - .addImm(Offset); - break; - case XCore::STWFI: - BuildMI(MBB, II, dl, TII.get(XCore::STW_2rus)) - .addReg(Reg, getKillRegState(isKill)) - .addReg(FramePtr) - .addImm(Offset); - break; - case XCore::LDAWFI: - BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l2rus), Reg) - .addReg(FramePtr) - .addImm(Offset); - break; - default: - llvm_unreachable("Unexpected Opcode"); - } - } + if (TFI->hasFP(MF)) { + if (isImmUs(Offset)) + InsertFPImmInst(II, TII, Reg, FrameReg, Offset); + else + InsertFPConstInst(II, TII, Reg, FrameReg, Offset, RS); } else { - bool isU6 = isImmU6(Offset); - if (!isU6 && !isImmU16(Offset)) { - std::string msg; - raw_string_ostream Msg(msg); - Msg << "eliminateFrameIndex Frame size too big: " << Offset; - llvm_report_error(Msg.str()); - } - - switch (MI.getOpcode()) { - int NewOpcode; - case XCore::LDWFI: - NewOpcode = (isU6) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6; - BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg) - .addImm(Offset); - break; - case XCore::STWFI: - NewOpcode = (isU6) ? XCore::STWSP_ru6 : XCore::STWSP_lru6; - BuildMI(MBB, II, dl, TII.get(NewOpcode)) - .addReg(Reg, getKillRegState(isKill)) - .addImm(Offset); - break; - case XCore::LDAWFI: - NewOpcode = (isU6) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6; - BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg) - .addImm(Offset); - break; - default: - llvm_unreachable("Unexpected Opcode"); - } + if (isImmU16(Offset)) + InsertSPImmInst(II, TII, Reg, Offset); + else + InsertSPConstInst(II, TII, Reg, Offset, RS); } // Erase old instruction. + MachineBasicBlock &MBB = *MI.getParent(); MBB.erase(II); - return 0; -} - -void -XCoreRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, - RegScavenger *RS) const { - MachineFrameInfo *MFI = MF.getFrameInfo(); - bool LRUsed = MF.getRegInfo().isPhysRegUsed(XCore::LR); - const TargetRegisterClass *RC = XCore::GRRegsRegisterClass; - XCoreFunctionInfo *XFI = MF.getInfo(); - if (LRUsed) { - MF.getRegInfo().setPhysRegUnused(XCore::LR); - - bool isVarArg = MF.getFunction()->isVarArg(); - int FrameIdx; - if (! isVarArg) { - // A fixed offset of 0 allows us to save / restore LR using entsp / retsp. - FrameIdx = MFI->CreateFixedObject(RC->getSize(), 0, true, false); - } else { - FrameIdx = MFI->CreateStackObject(RC->getSize(), RC->getAlignment(), - false); - } - XFI->setUsesLR(FrameIdx); - XFI->setLRSpillSlot(FrameIdx); - } - if (requiresRegisterScavenging(MF)) { - // Reserve a slot close to SP or frame pointer. - RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), - RC->getAlignment(), - false)); - } - if (hasFP(MF)) { - // A callee save register is used to hold the FP. - // This needs saving / restoring in the epilogue / prologue. - XFI->setFPSpillSlot(MFI->CreateStackObject(RC->getSize(), - RC->getAlignment(), - false)); - } -} - -void XCoreRegisterInfo:: -processFunctionBeforeFrameFinalized(MachineFunction &MF) const { - -} - -void XCoreRegisterInfo:: -loadConstant(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, - unsigned DstReg, int64_t Value, DebugLoc dl) const { - // TODO use mkmsk if possible. - if (!isImmU16(Value)) { - // TODO use constant pool. - std::string msg; - raw_string_ostream Msg(msg); - Msg << "loadConstant value too big " << Value; - llvm_report_error(Msg.str()); - } - int Opcode = isImmU6(Value) ? XCore::LDC_ru6 : XCore::LDC_lru6; - BuildMI(MBB, I, dl, TII.get(Opcode), DstReg).addImm(Value); -} - -void XCoreRegisterInfo:: -storeToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, - unsigned SrcReg, int Offset, DebugLoc dl) const { - assert(Offset%4 == 0 && "Misaligned stack offset"); - Offset/=4; - bool isU6 = isImmU6(Offset); - if (!isU6 && !isImmU16(Offset)) { - std::string msg; - raw_string_ostream Msg(msg); - Msg << "storeToStack offset too big " << Offset; - llvm_report_error(Msg.str()); - } - int Opcode = isU6 ? XCore::STWSP_ru6 : XCore::STWSP_lru6; - BuildMI(MBB, I, dl, TII.get(Opcode)) - .addReg(SrcReg) - .addImm(Offset); -} - -void XCoreRegisterInfo:: -loadFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, - unsigned DstReg, int Offset, DebugLoc dl) const { - assert(Offset%4 == 0 && "Misaligned stack offset"); - Offset/=4; - bool isU6 = isImmU6(Offset); - if (!isU6 && !isImmU16(Offset)) { - std::string msg; - raw_string_ostream Msg(msg); - Msg << "loadFromStack offset too big " << Offset; - llvm_report_error(Msg.str()); - } - int Opcode = isU6 ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6; - BuildMI(MBB, I, dl, TII.get(Opcode), DstReg) - .addImm(Offset); -} - -void XCoreRegisterInfo::emitPrologue(MachineFunction &MF) const { - MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB - MachineBasicBlock::iterator MBBI = MBB.begin(); - MachineFrameInfo *MFI = MF.getFrameInfo(); - MachineModuleInfo *MMI = MFI->getMachineModuleInfo(); - XCoreFunctionInfo *XFI = MF.getInfo(); - DebugLoc dl = (MBBI != MBB.end() ? - MBBI->getDebugLoc() : DebugLoc::getUnknownLoc()); - - bool FP = hasFP(MF); - - // Work out frame sizes. - int FrameSize = MFI->getStackSize(); - - assert(FrameSize%4 == 0 && "Misaligned frame size"); - - FrameSize/=4; - - bool isU6 = isImmU6(FrameSize); - - if (!isU6 && !isImmU16(FrameSize)) { - // FIXME could emit multiple instructions. - std::string msg; - raw_string_ostream Msg(msg); - Msg << "emitPrologue Frame size too big: " << FrameSize; - llvm_report_error(Msg.str()); - } - bool emitFrameMoves = needsFrameMoves(MF); - - // Do we need to allocate space on the stack? - if (FrameSize) { - bool saveLR = XFI->getUsesLR(); - bool LRSavedOnEntry = false; - int Opcode; - if (saveLR && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0)) { - Opcode = (isU6) ? XCore::ENTSP_u6 : XCore::ENTSP_lu6; - MBB.addLiveIn(XCore::LR); - saveLR = false; - LRSavedOnEntry = true; - } else { - Opcode = (isU6) ? XCore::EXTSP_u6 : XCore::EXTSP_lu6; - } - BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(FrameSize); - - if (emitFrameMoves) { - std::vector &Moves = MMI->getFrameMoves(); - - // Show update of SP. - MCSymbol *FrameLabel = MMI->getLabelSym(MMI->NextLabelID()); - BuildMI(MBB, MBBI, dl, TII.get(XCore::DBG_LABEL)).addSym(FrameLabel); - - MachineLocation SPDst(MachineLocation::VirtualFP); - MachineLocation SPSrc(MachineLocation::VirtualFP, -FrameSize * 4); - Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc)); - - if (LRSavedOnEntry) { - MachineLocation CSDst(MachineLocation::VirtualFP, 0); - MachineLocation CSSrc(XCore::LR); - Moves.push_back(MachineMove(FrameLabel, CSDst, CSSrc)); - } - } - if (saveLR) { - int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot()); - storeToStack(MBB, MBBI, XCore::LR, LRSpillOffset + FrameSize*4, dl); - MBB.addLiveIn(XCore::LR); - - if (emitFrameMoves) { - MCSymbol *SaveLRLabel = MMI->getLabelSym(MMI->NextLabelID()); - BuildMI(MBB, MBBI, dl, TII.get(XCore::DBG_LABEL)).addSym(SaveLRLabel); - MachineLocation CSDst(MachineLocation::VirtualFP, LRSpillOffset); - MachineLocation CSSrc(XCore::LR); - MMI->getFrameMoves().push_back(MachineMove(SaveLRLabel, CSDst, CSSrc)); - } - } - } - - if (FP) { - // Save R10 to the stack. - int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot()); - storeToStack(MBB, MBBI, XCore::R10, FPSpillOffset + FrameSize*4, dl); - // R10 is live-in. It is killed at the spill. - MBB.addLiveIn(XCore::R10); - if (emitFrameMoves) { - MCSymbol *SaveR10Label = MMI->getLabelSym(MMI->NextLabelID()); - BuildMI(MBB, MBBI, dl, TII.get(XCore::DBG_LABEL)).addSym(SaveR10Label); - MachineLocation CSDst(MachineLocation::VirtualFP, FPSpillOffset); - MachineLocation CSSrc(XCore::R10); - MMI->getFrameMoves().push_back(MachineMove(SaveR10Label, CSDst, CSSrc)); - } - // Set the FP from the SP. - unsigned FramePtr = XCore::R10; - BuildMI(MBB, MBBI, dl, TII.get(XCore::LDAWSP_ru6), FramePtr) - .addImm(0); - if (emitFrameMoves) { - // Show FP is now valid. - MCSymbol *FrameLabel = MMI->getLabelSym(MMI->NextLabelID()); - BuildMI(MBB, MBBI, dl, TII.get(XCore::DBG_LABEL)).addSym(FrameLabel); - MachineLocation SPDst(FramePtr); - MachineLocation SPSrc(MachineLocation::VirtualFP); - MMI->getFrameMoves().push_back(MachineMove(FrameLabel, SPDst, SPSrc)); - } - } - - if (emitFrameMoves) { - // Frame moves for callee saved. - std::vector &Moves = MMI->getFrameMoves(); - std::vector >&SpillLabels = - XFI->getSpillLabels(); - for (unsigned I = 0, E = SpillLabels.size(); I != E; ++I) { - MCSymbol *SpillLabel = SpillLabels[I].first; - CalleeSavedInfo &CSI = SpillLabels[I].second; - int Offset = MFI->getObjectOffset(CSI.getFrameIdx()); - unsigned Reg = CSI.getReg(); - MachineLocation CSDst(MachineLocation::VirtualFP, Offset); - MachineLocation CSSrc(Reg); - Moves.push_back(MachineMove(SpillLabel, CSDst, CSSrc)); - } - } } -void XCoreRegisterInfo::emitEpilogue(MachineFunction &MF, - MachineBasicBlock &MBB) const { - MachineFrameInfo *MFI = MF.getFrameInfo(); - MachineBasicBlock::iterator MBBI = prior(MBB.end()); - DebugLoc dl = MBBI->getDebugLoc(); - - bool FP = hasFP(MF); - - if (FP) { - // Restore the stack pointer. - unsigned FramePtr = XCore::R10; - BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)) - .addReg(FramePtr); - } - - // Work out frame sizes. - int FrameSize = MFI->getStackSize(); - - assert(FrameSize%4 == 0 && "Misaligned frame size"); - - FrameSize/=4; - - bool isU6 = isImmU6(FrameSize); - - if (!isU6 && !isImmU16(FrameSize)) { - // FIXME could emit multiple instructions. - std::string msg; - raw_string_ostream Msg(msg); - Msg << "emitEpilogue Frame size too big: " << FrameSize; - llvm_report_error(Msg.str()); - } - - if (FrameSize) { - XCoreFunctionInfo *XFI = MF.getInfo(); - - if (FP) { - // Restore R10 - int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot()); - FPSpillOffset += FrameSize*4; - loadFromStack(MBB, MBBI, XCore::R10, FPSpillOffset, dl); - } - bool restoreLR = XFI->getUsesLR(); - if (restoreLR && MFI->getObjectOffset(XFI->getLRSpillSlot()) != 0) { - int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot()); - LRSpillOffset += FrameSize*4; - loadFromStack(MBB, MBBI, XCore::LR, LRSpillOffset, dl); - restoreLR = false; - } - if (restoreLR) { - // Fold prologue into return instruction - assert(MBBI->getOpcode() == XCore::RETSP_u6 - || MBBI->getOpcode() == XCore::RETSP_lu6); - int Opcode = (isU6) ? XCore::RETSP_u6 : XCore::RETSP_lu6; - BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(FrameSize); - MBB.erase(MBBI); - } else { - int Opcode = (isU6) ? XCore::LDAWSP_ru6_RRegs : XCore::LDAWSP_lru6_RRegs; - BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(FrameSize); - } - } -} - -int XCoreRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const { - return XCoreGenRegisterInfo::getDwarfRegNumFull(RegNum, 0); -} unsigned XCoreRegisterInfo::getFrameRegister(const MachineFunction &MF) const { - bool FP = hasFP(MF); - - return FP ? XCore::R10 : XCore::SP; -} - -unsigned XCoreRegisterInfo::getRARegister() const { - return XCore::LR; -} + const XCoreFrameLowering *TFI = getFrameLowering(MF); -void XCoreRegisterInfo::getInitialFrameState(std::vector &Moves) - const { - // Initial state of the frame pointer is SP. - MachineLocation Dst(MachineLocation::VirtualFP); - MachineLocation Src(XCore::SP, 0); - Moves.push_back(MachineMove(0, Dst, Src)); + return TFI->hasFP(MF) ? XCore::R10 : XCore::SP; } - -#include "XCoreGenRegisterInfo.inc" -