From ce45d30fa1922d19745f7307cf1bb712c5814b9a Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Sun, 3 May 2009 13:11:20 +0000 Subject: [PATCH] Add prologue/epilogue emission. Fix frame pointer handling. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@70740 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/MSP430/MSP430RegisterInfo.cpp | 140 +++++++++++++++++++++- lib/Target/MSP430/MSP430RegisterInfo.h | 2 + lib/Target/MSP430/MSP430TargetMachine.cpp | 2 +- 3 files changed, 138 insertions(+), 6 deletions(-) diff --git a/lib/Target/MSP430/MSP430RegisterInfo.cpp b/lib/Target/MSP430/MSP430RegisterInfo.cpp index 1506515d97a..ebd09fb78e5 100644 --- a/lib/Target/MSP430/MSP430RegisterInfo.cpp +++ b/lib/Target/MSP430/MSP430RegisterInfo.cpp @@ -14,6 +14,7 @@ #define DEBUG_TYPE "msp430-reg-info" #include "MSP430.h" +#include "MSP430MachineFunctionInfo.h" #include "MSP430RegisterInfo.h" #include "MSP430TargetMachine.h" #include "llvm/CodeGen/MachineFrameInfo.h" @@ -165,12 +166,14 @@ MSP430RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, unsigned BasePtr = (hasFP(MF) ? MSP430::FPW : MSP430::SPW); int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex); - if (!hasFP(MF)) - Offset += MF.getFrameInfo()->getStackSize(); - // Skip the saved PC Offset += 2; + if (!hasFP(MF)) + Offset += MF.getFrameInfo()->getStackSize(); + else + Offset += 2; // Skip the saved FPW + // Fold imm into offset Offset += MI.getOperand(i+1).getImm(); @@ -201,13 +204,140 @@ MSP430RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, MI.getOperand(i+1).ChangeToImmediate(Offset); } +void +MSP430RegisterInfo::processFunctionBeforeFrameFinalized(MachineFunction &MF) + const { + // Create a frame entry for the FPW register that must be saved. + if (hasFP(MF)) { + int FrameIdx = MF.getFrameInfo()->CreateFixedObject(2, -4); + assert(FrameIdx == MF.getFrameInfo()->getObjectIndexBegin() && + "Slot for FPW register must be last in order to be found!"); + FrameIdx = 0; + } +} + + void MSP430RegisterInfo::emitPrologue(MachineFunction &MF) const { - // Nothing here yet + MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB + MachineFrameInfo *MFI = MF.getFrameInfo(); + MSP430MachineFunctionInfo *MSP430FI = MF.getInfo(); + MachineBasicBlock::iterator MBBI = MBB.begin(); + DebugLoc DL = (MBBI != MBB.end() ? MBBI->getDebugLoc() : + DebugLoc::getUnknownLoc()); + + // Get the number of bytes to allocate from the FrameInfo. + uint64_t StackSize = MFI->getStackSize(); + + uint64_t NumBytes = 0; + if (hasFP(MF)) { + // Calculate required stack adjustment + uint64_t FrameSize = StackSize - 2; + NumBytes = FrameSize - MSP430FI->getCalleeSavedFrameSize(); + + // Get the offset of the stack slot for the EBP register... which is + // guaranteed to be the last slot by processFunctionBeforeFrameFinalized. + // Update the frame offset adjustment. + MFI->setOffsetAdjustment(-NumBytes); + + // Save FPW into the appropriate stack slot... + BuildMI(MBB, MBBI, DL, TII.get(MSP430::PUSH16r)) + .addReg(MSP430::FPW, /*isDef=*/false, /*isImp=*/false, /*isKill=*/true); + + // Update FPW with the new base value... + BuildMI(MBB, MBBI, DL, TII.get(MSP430::MOV16rr), MSP430::FPW) + .addReg(MSP430::SPW); + + // Mark the FramePtr as live-in in every block except the entry. + for (MachineFunction::iterator I = next(MF.begin()), E = MF.end(); + I != E; ++I) + I->addLiveIn(MSP430::FPW); + + } else + NumBytes = StackSize - MSP430FI->getCalleeSavedFrameSize(); + + // Skip the callee-saved push instructions. + while (MBBI != MBB.end() && (MBBI->getOpcode() == MSP430::PUSH16r)) + ++MBBI; + + if (MBBI != MBB.end()) + DL = MBBI->getDebugLoc(); + + if (NumBytes) { // adjust stack pointer: SPW -= numbytes + // If there is an SUB16ri of SPW immediately before this instruction, merge + // the two. + //NumBytes -= mergeSPUpdates(MBB, MBBI, true); + // If there is an ADD16ri or SUB16ri of SPW immediately after this + // instruction, merge the two instructions. + // mergeSPUpdatesDown(MBB, MBBI, &NumBytes); + + if (NumBytes) { + MachineInstr *MI = + BuildMI(MBB, MBBI, DL, TII.get(MSP430::SUB16ri), MSP430::SPW) + .addReg(MSP430::SPW).addImm(NumBytes); + // The SRW implicit def is dead. + MI->getOperand(3).setIsDead(); + } + } } void MSP430RegisterInfo::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const { - // Nothing here yet + const MachineFrameInfo *MFI = MF.getFrameInfo(); + MSP430MachineFunctionInfo *MSP430FI = MF.getInfo(); + MachineBasicBlock::iterator MBBI = prior(MBB.end()); + unsigned RetOpcode = MBBI->getOpcode(); + DebugLoc DL = MBBI->getDebugLoc(); + + switch (RetOpcode) { + case MSP430::RET: break; // These are ok + default: + assert(0 && "Can only insert epilog into returning blocks"); + } + + // Get the number of bytes to allocate from the FrameInfo + uint64_t StackSize = MFI->getStackSize(); + unsigned CSSize = MSP430FI->getCalleeSavedFrameSize(); + uint64_t NumBytes = 0; + + if (hasFP(MF)) { + // Calculate required stack adjustment + uint64_t FrameSize = StackSize - 2; + NumBytes = FrameSize - CSSize; + + // pop FPW. + BuildMI(MBB, MBBI, DL, TII.get(MSP430::POP16r), MSP430::FPW); + } else + NumBytes = StackSize - CSSize; + + // Skip the callee-saved pop instructions. + MachineBasicBlock::iterator LastCSPop = MBBI; + while (MBBI != MBB.begin()) { + MachineBasicBlock::iterator PI = prior(MBBI); + unsigned Opc = PI->getOpcode(); + if (Opc != MSP430::POP16r && !PI->getDesc().isTerminator()) + break; + --MBBI; + } + + DL = MBBI->getDebugLoc(); + + // If there is an ADD16ri or SUB16ri of SPW immediately before this + // instruction, merge the two instructions. + //if (NumBytes || MFI->hasVarSizedObjects()) + // mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes); + + if (MFI->hasVarSizedObjects()) { + assert(0 && "Not implemented yet!"); + } else { + // adjust stack pointer back: SPW += numbytes + if (NumBytes) { + MachineInstr *MI = + BuildMI(MBB, MBBI, DL, TII.get(MSP430::ADD16ri), MSP430::SPW) + .addReg(MSP430::SPW).addImm(NumBytes); + // The SRW implicit def is dead. + MI->getOperand(3).setIsDead(); + } + } } unsigned MSP430RegisterInfo::getRARegister() const { diff --git a/lib/Target/MSP430/MSP430RegisterInfo.h b/lib/Target/MSP430/MSP430RegisterInfo.h index 6038af3d08d..a210e36e001 100644 --- a/lib/Target/MSP430/MSP430RegisterInfo.h +++ b/lib/Target/MSP430/MSP430RegisterInfo.h @@ -55,6 +55,8 @@ public: void emitPrologue(MachineFunction &MF) const; void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const; + void processFunctionBeforeFrameFinalized(MachineFunction &MF) const; + // Debug information queries. unsigned getRARegister() const; unsigned getFrameRegister(MachineFunction &MF) const; diff --git a/lib/Target/MSP430/MSP430TargetMachine.cpp b/lib/Target/MSP430/MSP430TargetMachine.cpp index 90819cff999..155f8c2bac3 100644 --- a/lib/Target/MSP430/MSP430TargetMachine.cpp +++ b/lib/Target/MSP430/MSP430TargetMachine.cpp @@ -41,7 +41,7 @@ MSP430TargetMachine::MSP430TargetMachine(const Module &M, // FIXME: Check TargetData string. DataLayout("e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8"), InstrInfo(*this), TLInfo(*this), - FrameInfo(TargetFrameInfo::StackGrowsDown, 8, 0) { } + FrameInfo(TargetFrameInfo::StackGrowsDown, 2, -2) { } const TargetAsmInfo *MSP430TargetMachine::createTargetAsmInfo() const { return new MSP430TargetAsmInfo(*this);