diff options
Diffstat (limited to 'lib/Target/AVR/AVRFrameLowering.cpp')
| -rw-r--r-- | lib/Target/AVR/AVRFrameLowering.cpp | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/lib/Target/AVR/AVRFrameLowering.cpp b/lib/Target/AVR/AVRFrameLowering.cpp index ab42a7aa99011..25232d2e47e13 100644 --- a/lib/Target/AVR/AVRFrameLowering.cpp +++ b/lib/Target/AVR/AVRFrameLowering.cpp @@ -57,6 +57,7 @@ void AVRFrameLowering::emitPrologue(MachineFunction &MF, DebugLoc DL = (MBBI != MBB.end()) ? MBBI->getDebugLoc() : DebugLoc(); const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>(); const AVRInstrInfo &TII = *STI.getInstrInfo(); + bool HasFP = hasFP(MF); // Interrupt handlers re-enable interrupts in function entry. if (CallConv == CallingConv::AVR_INTR) { @@ -65,6 +66,13 @@ void AVRFrameLowering::emitPrologue(MachineFunction &MF, .setMIFlag(MachineInstr::FrameSetup); } + // Save the frame pointer if we have one. + if (HasFP) { + BuildMI(MBB, MBBI, DL, TII.get(AVR::PUSHWRr)) + .addReg(AVR::R29R28, RegState::Kill) + .setMIFlag(MachineInstr::FrameSetup); + } + // Emit special prologue code to save R1, R0 and SREG in interrupt/signal // handlers before saving any other registers. if (CallConv == CallingConv::AVR_INTR || @@ -72,6 +80,7 @@ void AVRFrameLowering::emitPrologue(MachineFunction &MF, BuildMI(MBB, MBBI, DL, TII.get(AVR::PUSHWRr)) .addReg(AVR::R1R0, RegState::Kill) .setMIFlag(MachineInstr::FrameSetup); + BuildMI(MBB, MBBI, DL, TII.get(AVR::INRdA), AVR::R0) .addImm(0x3f) .setMIFlag(MachineInstr::FrameSetup); @@ -86,7 +95,7 @@ void AVRFrameLowering::emitPrologue(MachineFunction &MF, } // Early exit if the frame pointer is not needed in this function. - if (!hasFP(MF)) { + if (!HasFP) { return; } @@ -165,6 +174,9 @@ void AVRFrameLowering::emitEpilogue(MachineFunction &MF, BuildMI(MBB, MBBI, DL, TII.get(AVR::POPWRd), AVR::R1R0); } + if (hasFP(MF)) + BuildMI(MBB, MBBI, DL, TII.get(AVR::POPWRd), AVR::R29R28); + // Early exit if there is no need to restore the frame pointer. if (!FrameSize) { return; @@ -216,8 +228,9 @@ void AVRFrameLowering::emitEpilogue(MachineFunction &MF, bool AVRFrameLowering::hasFP(const MachineFunction &MF) const { const AVRMachineFunctionInfo *FuncInfo = MF.getInfo<AVRMachineFunctionInfo>(); - return (FuncInfo->getHasSpills() || FuncInfo->getHasAllocas() || - FuncInfo->getHasStackArgs()); + // TODO: We do not always need a frame pointer. + // This can be optimised. + return true; } bool AVRFrameLowering::spillCalleeSavedRegisters( @@ -407,12 +420,9 @@ void AVRFrameLowering::determineCalleeSaves(MachineFunction &MF, RegScavenger *RS) const { TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); - // Spill register Y when it is used as the frame pointer. - if (hasFP(MF)) { - SavedRegs.set(AVR::R29R28); - SavedRegs.set(AVR::R29); - SavedRegs.set(AVR::R28); - } + // If we have a frame pointer, the Y register needs to be saved as well. + // We don't do that here however - the prologue and epilogue generation + // code will handle it specially. } /// The frame analyzer pass. /// |
