diff options
author | Wesley Peck <peckw@wesleypeck.com> | 2010-12-15 20:27:28 +0000 |
---|---|---|
committer | Wesley Peck <peckw@wesleypeck.com> | 2010-12-15 20:27:28 +0000 |
commit | dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6 (patch) | |
tree | 9a0d05ded0bb7ff2af598470da17b2c731f49d0c /lib | |
parent | d364acd3d7b0dd78bc92e168af268a56ff7141d4 (diff) | |
download | external_llvm-dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6.zip external_llvm-dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6.tar.gz external_llvm-dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6.tar.bz2 |
Lower the MBlaze target specific calling conventions for "interrupt_handler"
and "save_volatiles" correctly. This completes the custom calling convention
functionality changes for the MBlaze backend that were started in 121888.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121891 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/MBlaze/MBlazeFrameInfo.cpp | 103 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlazeISelLowering.cpp | 17 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlazeISelLowering.h | 7 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlazeInstrInfo.td | 4 |
4 files changed, 119 insertions, 12 deletions
diff --git a/lib/Target/MBlaze/MBlazeFrameInfo.cpp b/lib/Target/MBlaze/MBlazeFrameInfo.cpp index 7789723..3b5023d 100644 --- a/lib/Target/MBlaze/MBlazeFrameInfo.cpp +++ b/lib/Target/MBlaze/MBlazeFrameInfo.cpp @@ -132,6 +132,92 @@ static void analyzeFrameIndexes(MachineFunction &MF) { MBlazeFI->setStackAdjust(StackAdjust); } +static void interruptFrameLayout(MachineFunction &MF) { + const Function *F = MF.getFunction(); + llvm::CallingConv::ID CallConv = F->getCallingConv(); + + // If this function is not using either the interrupt_handler + // calling convention or the save_volatiles calling convention + // then we don't need to do any additional frame layout. + if (CallConv != llvm::CallingConv::MBLAZE_INTR && + CallConv != llvm::CallingConv::MBLAZE_SVOL) + return; + + MachineFrameInfo *MFI = MF.getFrameInfo(); + const MachineRegisterInfo &MRI = MF.getRegInfo(); + const MBlazeInstrInfo &TII = + *static_cast<const MBlazeInstrInfo*>(MF.getTarget().getInstrInfo()); + + // Determine if the calling convention is the interrupt_handler + // calling convention. Some pieces of the prologue and epilogue + // only need to be emitted if we are lowering and interrupt handler. + bool isIntr = CallConv == llvm::CallingConv::MBLAZE_INTR; + + // Determine where to put prologue and epilogue additions + MachineBasicBlock &MENT = MF.front(); + MachineBasicBlock &MEXT = MF.back(); + + MachineBasicBlock::iterator MENTI = MENT.begin(); + MachineBasicBlock::iterator MEXTI = prior(MEXT.end()); + + DebugLoc ENTDL = MENTI != MENT.end() ? MENTI->getDebugLoc() : DebugLoc(); + DebugLoc EXTDL = MEXTI != MEXT.end() ? MEXTI->getDebugLoc() : DebugLoc(); + + // Store the frame indexes generated during prologue additions for use + // when we are generating the epilogue additions. + SmallVector<int, 10> VFI; + + // Build the prologue SWI for R3 - R12 if needed. Note that R11 must + // always have a SWI because it is used when processing RMSR. + for (unsigned r = MBlaze::R3; r <= MBlaze::R12; ++r) { + if (!MRI.isPhysRegUsed(r) && !(isIntr && r == MBlaze::R11)) continue; + + int FI = MFI->CreateStackObject(4,4,false,false); + VFI.push_back(FI); + + BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), r) + .addFrameIndex(FI).addImm(0); + } + + // Build the prologue SWI for R17, R18 + int R17FI = MFI->CreateStackObject(4,4,false,false); + int R18FI = MFI->CreateStackObject(4,4,false,false); + + BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), MBlaze::R17) + .addFrameIndex(R17FI).addImm(0); + + BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), MBlaze::R18) + .addFrameIndex(R18FI).addImm(0); + + // Buid the prologue SWI and the epilogue LWI for RMSR if needed + if (isIntr) { + int MSRFI = MFI->CreateStackObject(4,4,false,false); + BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::MFS), MBlaze::R11) + .addReg(MBlaze::RMSR); + BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), MBlaze::R11) + .addFrameIndex(MSRFI).addImm(0); + + BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), MBlaze::R11) + .addFrameIndex(MSRFI).addImm(0); + BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::MTS), MBlaze::RMSR) + .addReg(MBlaze::R11); + } + + // Build the epilogue LWI for R17, R18 + BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), MBlaze::R18) + .addFrameIndex(R18FI).addImm(0); + + BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), MBlaze::R17) + .addFrameIndex(R17FI).addImm(0); + + // Build the epilogue LWI for R3 - R12 if needed + for (unsigned r = MBlaze::R12, i = VFI.size(); r >= MBlaze::R3; --r) { + if (!MRI.isPhysRegUsed(r)) continue; + BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), r) + .addFrameIndex(VFI[--i]).addImm(0); + } +} + static void determineFrameLayout(MachineFunction &MF) { MachineFrameInfo *MFI = MF.getFrameInfo(); MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>(); @@ -174,6 +260,9 @@ void MBlazeFrameInfo::emitPrologue(MachineFunction &MF) const { MachineBasicBlock::iterator MBBI = MBB.begin(); DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); + llvm::CallingConv::ID CallConv = MF.getFunction()->getCallingConv(); + bool requiresRA = CallConv == llvm::CallingConv::MBLAZE_INTR; + // Determine the correct frame layout determineFrameLayout(MF); @@ -181,7 +270,7 @@ void MBlazeFrameInfo::emitPrologue(MachineFunction &MF) const { unsigned StackSize = MFI->getStackSize(); // No need to allocate space on the stack. - if (StackSize == 0 && !MFI->adjustsStack()) return; + if (StackSize == 0 && !MFI->adjustsStack() && !requiresRA) return; int FPOffset = MBlazeFI->getFPStackOffset(); int RAOffset = MBlazeFI->getRAStackOffset(); @@ -191,7 +280,7 @@ void MBlazeFrameInfo::emitPrologue(MachineFunction &MF) const { .addReg(MBlaze::R1).addImm(-StackSize); // swi R15, R1, stack_loc - if (MFI->adjustsStack()) { + if (MFI->adjustsStack() || requiresRA) { BuildMI(MBB, MBBI, DL, TII.get(MBlaze::SWI)) .addReg(MBlaze::R15).addReg(MBlaze::R1).addImm(RAOffset); } @@ -217,6 +306,9 @@ void MBlazeFrameInfo::emitEpilogue(MachineFunction &MF, DebugLoc dl = MBBI->getDebugLoc(); + llvm::CallingConv::ID CallConv = MF.getFunction()->getCallingConv(); + bool requiresRA = CallConv == llvm::CallingConv::MBLAZE_INTR; + // Get the FI's where RA and FP are saved. int FPOffset = MBlazeFI->getFPStackOffset(); int RAOffset = MBlazeFI->getRAStackOffset(); @@ -232,7 +324,7 @@ void MBlazeFrameInfo::emitEpilogue(MachineFunction &MF, } // lwi R15, R1, stack_loc - if (MFI->adjustsStack()) { + if (MFI->adjustsStack() || requiresRA) { BuildMI(MBB, MBBI, dl, TII.get(MBlaze::LWI), MBlaze::R15) .addReg(MBlaze::R1).addImm(RAOffset); } @@ -251,8 +343,10 @@ void MBlazeFrameInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, const { MachineFrameInfo *MFI = MF.getFrameInfo(); MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>(); + llvm::CallingConv::ID CallConv = MF.getFunction()->getCallingConv(); + bool requiresRA = CallConv == llvm::CallingConv::MBLAZE_INTR; - if (MFI->adjustsStack()) { + if (MFI->adjustsStack() || requiresRA) { MBlazeFI->setRAStackOffset(0); MFI->CreateFixedObject(4,0,true); } @@ -262,5 +356,6 @@ void MBlazeFrameInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, MFI->CreateFixedObject(4,4,true); } + interruptFrameLayout(MF); analyzeFrameIndexes(MF); } diff --git a/lib/Target/MBlaze/MBlazeISelLowering.cpp b/lib/Target/MBlaze/MBlazeISelLowering.cpp index ad7222a..dc7cff8 100644 --- a/lib/Target/MBlaze/MBlazeISelLowering.cpp +++ b/lib/Target/MBlaze/MBlazeISelLowering.cpp @@ -864,13 +864,18 @@ LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, Flag = Chain.getValue(1); } - // Return on MBlaze is always a "rtsd R15, 8" + // If this function is using the interrupt_handler calling convention + // then use "rtid r14, 0" otherwise use "rtsd r15, 8" + unsigned Ret = (CallConv == llvm::CallingConv::MBLAZE_INTR) ? MBlazeISD::IRet + : MBlazeISD::Ret; + unsigned Reg = (CallConv == llvm::CallingConv::MBLAZE_INTR) ? MBlaze::R14 + : MBlaze::R15; + SDValue DReg = DAG.getRegister(Reg, MVT::i32); + if (Flag.getNode()) - return DAG.getNode(MBlazeISD::Ret, dl, MVT::Other, - Chain, DAG.getRegister(MBlaze::R15, MVT::i32), Flag); - else // Return Void - return DAG.getNode(MBlazeISD::Ret, dl, MVT::Other, - Chain, DAG.getRegister(MBlaze::R15, MVT::i32)); + return DAG.getNode(Ret, dl, MVT::Other, Chain, DReg, Flag); + + return DAG.getNode(Ret, dl, MVT::Other, Chain, DReg); } //===----------------------------------------------------------------------===// diff --git a/lib/Target/MBlaze/MBlazeISelLowering.h b/lib/Target/MBlaze/MBlazeISelLowering.h index 4f09851..aa1c9aa 100644 --- a/lib/Target/MBlaze/MBlazeISelLowering.h +++ b/lib/Target/MBlaze/MBlazeISelLowering.h @@ -78,8 +78,11 @@ namespace llvm { // Integer Compare ICmp, - // Return - Ret + // Return from subroutine + Ret, + + // Return from interrupt + IRet }; } diff --git a/lib/Target/MBlaze/MBlazeInstrInfo.td b/lib/Target/MBlaze/MBlazeInstrInfo.td index cf69efa..39ddd6a 100644 --- a/lib/Target/MBlaze/MBlazeInstrInfo.td +++ b/lib/Target/MBlaze/MBlazeInstrInfo.td @@ -18,6 +18,7 @@ include "MBlazeInstrFormats.td" // def SDTMBlazeSelectCC : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>]>; def SDT_MBlazeRet : SDTypeProfile<0, 1, [SDTCisInt<0>]>; +def SDT_MBlazeIRet : SDTypeProfile<0, 1, [SDTCisInt<0>]>; def SDT_MBlazeJmpLink : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>; def SDT_MBCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>]>; def SDT_MBCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>; @@ -28,6 +29,8 @@ def SDT_MBCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>; def MBlazeRet : SDNode<"MBlazeISD::Ret", SDT_MBlazeRet, [SDNPHasChain, SDNPOptInFlag]>; +def MBlazeIRet : SDNode<"MBlazeISD::IRet", SDT_MBlazeIRet, + [SDNPHasChain, SDNPOptInFlag]>; def MBlazeJmpLink : SDNode<"MBlazeISD::JmpLink",SDT_MBlazeJmpLink, [SDNPHasChain,SDNPOptInFlag,SDNPOutFlag]>; @@ -727,6 +730,7 @@ def : Pat<(selectcc (i32 GPR:$L), (i32 GPR:$R), // Ret instructions def : Pat<(MBlazeRet GPR:$target), (RTSD GPR:$target, 0x8)>; +def : Pat<(MBlazeIRet GPR:$target), (RTID GPR:$target, 0x0)>; // BR instructions def : Pat<(br bb:$T), (BRID bb:$T)>; |