From 544cc21cf4807116251a699d8b1d3d4bace21597 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Wed, 30 Jan 2013 00:26:49 +0000 Subject: [mips] Lower EH_RETURN. Patch by Sasa Stankovic. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173862 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsSEFrameLowering.cpp | 60 +++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'lib/Target/Mips/MipsSEFrameLowering.cpp') diff --git a/lib/Target/Mips/MipsSEFrameLowering.cpp b/lib/Target/Mips/MipsSEFrameLowering.cpp index 60b1233..e5ecf2c 100644 --- a/lib/Target/Mips/MipsSEFrameLowering.cpp +++ b/lib/Target/Mips/MipsSEFrameLowering.cpp @@ -29,9 +29,21 @@ using namespace llvm; +unsigned MipsSEFrameLowering::ehDataReg(unsigned I) const { + static const unsigned EhDataReg[] = { + Mips::A0, Mips::A1, Mips::A2, Mips::A3 + }; + static const unsigned EhDataReg64[] = { + Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64 + }; + + return STI.isABI_N64() ? EhDataReg64[I] : EhDataReg[I]; +} + void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const { MachineBasicBlock &MBB = MF.front(); MachineFrameInfo *MFI = MF.getFrameInfo(); + MipsFunctionInfo *MipsFI = MF.getInfo(); const MipsRegisterInfo *RegInfo = static_cast(MF.getTarget().getRegisterInfo()); const MipsSEInstrInfo &TII = @@ -105,6 +117,30 @@ void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const { } } + if (MipsFI->callsEhReturn()) { + const TargetRegisterClass *RC = STI.isABI_N64() ? + &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass; + + // Insert instructions that spill eh data registers. + for (int I = 0; I < 4; ++I) { + if (!MBB.isLiveIn(ehDataReg(I))) + MBB.addLiveIn(ehDataReg(I)); + TII.storeRegToStackSlot(MBB, MBBI, ehDataReg(I), false, + MipsFI->getEhDataRegFI(I), RC, RegInfo); + } + + // Emit .cfi_offset directives for eh data registers. + MCSymbol *CSLabel2 = MMI.getContext().CreateTempSymbol(); + BuildMI(MBB, MBBI, dl, + TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel2); + for (int I = 0; I < 4; ++I) { + int64_t Offset = MFI->getObjectOffset(MipsFI->getEhDataRegFI(I)); + DstML = MachineLocation(MachineLocation::VirtualFP, Offset); + SrcML = MachineLocation(ehDataReg(I)); + Moves.push_back(MachineMove(CSLabel2, DstML, SrcML)); + } + } + // if framepointer enabled, set it to point to the stack pointer. if (hasFP(MF)) { // Insert instruction "move $fp, $sp" at this location. @@ -124,6 +160,9 @@ void MipsSEFrameLowering::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const { MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); MachineFrameInfo *MFI = MF.getFrameInfo(); + MipsFunctionInfo *MipsFI = MF.getInfo(); + const MipsRegisterInfo *RegInfo = + static_cast(MF.getTarget().getRegisterInfo()); const MipsSEInstrInfo &TII = *static_cast(MF.getTarget().getInstrInfo()); DebugLoc dl = MBBI->getDebugLoc(); @@ -144,6 +183,22 @@ void MipsSEFrameLowering::emitEpilogue(MachineFunction &MF, BuildMI(MBB, I, dl, TII.get(ADDu), SP).addReg(FP).addReg(ZERO); } + if (MipsFI->callsEhReturn()) { + const TargetRegisterClass *RC = STI.isABI_N64() ? + &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass; + + // Find first instruction that restores a callee-saved register. + MachineBasicBlock::iterator I = MBBI; + for (unsigned i = 0; i < MFI->getCalleeSavedInfo().size(); ++i) + --I; + + // Insert instructions that restore eh data registers. + for (int J = 0; J < 4; ++J) { + TII.loadRegFromStackSlot(MBB, I, ehDataReg(J), MipsFI->getEhDataRegFI(J), + RC, RegInfo); + } + } + // Get the number of bytes from FrameInfo uint64_t StackSize = MFI->getStackSize(); @@ -198,12 +253,17 @@ void MipsSEFrameLowering:: processFunctionBeforeCalleeSavedScan(MachineFunction &MF, RegScavenger *RS) const { MachineRegisterInfo &MRI = MF.getRegInfo(); + MipsFunctionInfo *MipsFI = MF.getInfo(); unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; // Mark $fp as used if function has dedicated frame pointer. if (hasFP(MF)) MRI.setPhysRegUsed(FP); + // Create spill slots for eh data registers if function calls eh_return. + if (MipsFI->callsEhReturn()) + MipsFI->createEhDataRegsFI(); + // Set scavenging frame index if necessary. uint64_t MaxSPOffset = MF.getInfo()->getIncomingArgSize() + estimateStackSize(MF); -- cgit v1.1 From 700ed80d3da5e98e05ceb90e9bfb66058581a6db Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Thu, 21 Feb 2013 20:05:00 +0000 Subject: Move the eliminateCallFramePseudoInstr method from TargetRegisterInfo to TargetFrameLowering, where it belongs. Incidentally, this allows us to delete some duplicated (and slightly different!) code in TRI. There are potentially other layering problems that can be cleaned up as a result, or in a similar manner. The refactoring was OK'd by Anton Korobeynikov on llvmdev. Note: this touches the target interfaces, so out-of-tree targets may be affected. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175788 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsSEFrameLowering.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'lib/Target/Mips/MipsSEFrameLowering.cpp') diff --git a/lib/Target/Mips/MipsSEFrameLowering.cpp b/lib/Target/Mips/MipsSEFrameLowering.cpp index e5ecf2c..0dd6713 100644 --- a/lib/Target/Mips/MipsSEFrameLowering.cpp +++ b/lib/Target/Mips/MipsSEFrameLowering.cpp @@ -249,6 +249,26 @@ MipsSEFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { return isInt<16>(MFI->getMaxCallFrameSize()) && !MFI->hasVarSizedObjects(); } +// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions +void MipsSEFrameLowering:: +eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, + MachineBasicBlock::iterator I) const { + const MipsSEInstrInfo &TII = + *static_cast(MF.getTarget().getInstrInfo()); + + if (!hasReservedCallFrame(MF)) { + int64_t Amount = I->getOperand(0).getImm(); + + if (I->getOpcode() == Mips::ADJCALLSTACKDOWN) + Amount = -Amount; + + unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; + TII.adjustStackPtr(SP, Amount, MBB, I); + } + + MBB.erase(I); +} + void MipsSEFrameLowering:: processFunctionBeforeCalleeSavedScan(MachineFunction &MF, RegScavenger *RS) const { -- cgit v1.1