diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:38:04 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:38:11 +0000 |
| commit | e3b557809604d036af6e00c60f012c2025b59a5e (patch) | |
| tree | 8a11ba2269a3b669601e2fd41145b174008f4da8 /llvm/lib/Target/AVR/AVRFrameLowering.cpp | |
| parent | 08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff) | |
Diffstat (limited to 'llvm/lib/Target/AVR/AVRFrameLowering.cpp')
| -rw-r--r-- | llvm/lib/Target/AVR/AVRFrameLowering.cpp | 44 |
1 files changed, 28 insertions, 16 deletions
diff --git a/llvm/lib/Target/AVR/AVRFrameLowering.cpp b/llvm/lib/Target/AVR/AVRFrameLowering.cpp index ec8b74e435ce..904cdf8420eb 100644 --- a/llvm/lib/Target/AVR/AVRFrameLowering.cpp +++ b/llvm/lib/Target/AVR/AVRFrameLowering.cpp @@ -56,6 +56,7 @@ void AVRFrameLowering::emitPrologue(MachineFunction &MF, const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>(); const AVRInstrInfo &TII = *STI.getInstrInfo(); const AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>(); + const MachineRegisterInfo &MRI = MF.getRegInfo(); bool HasFP = hasFP(MF); // Interrupt handlers re-enable interrupts in function entry. @@ -68,21 +69,26 @@ void AVRFrameLowering::emitPrologue(MachineFunction &MF, // Emit special prologue code to save R1, R0 and SREG in interrupt/signal // handlers before saving any other registers. if (AFI->isInterruptOrSignalHandler()) { - BuildMI(MBB, MBBI, DL, TII.get(AVR::PUSHWRr)) - .addReg(AVR::R1R0, RegState::Kill) + BuildMI(MBB, MBBI, DL, TII.get(AVR::PUSHRr)) + .addReg(STI.getTmpRegister(), RegState::Kill) .setMIFlag(MachineInstr::FrameSetup); - BuildMI(MBB, MBBI, DL, TII.get(AVR::INRdA), AVR::R0) + BuildMI(MBB, MBBI, DL, TII.get(AVR::INRdA), STI.getTmpRegister()) .addImm(STI.getIORegSREG()) .setMIFlag(MachineInstr::FrameSetup); BuildMI(MBB, MBBI, DL, TII.get(AVR::PUSHRr)) - .addReg(AVR::R0, RegState::Kill) - .setMIFlag(MachineInstr::FrameSetup); - BuildMI(MBB, MBBI, DL, TII.get(AVR::EORRdRr)) - .addReg(AVR::R1, RegState::Define) - .addReg(AVR::R1, RegState::Kill) - .addReg(AVR::R1, RegState::Kill) + .addReg(STI.getTmpRegister(), RegState::Kill) .setMIFlag(MachineInstr::FrameSetup); + if (!MRI.reg_empty(STI.getZeroRegister())) { + BuildMI(MBB, MBBI, DL, TII.get(AVR::PUSHRr)) + .addReg(STI.getZeroRegister(), RegState::Kill) + .setMIFlag(MachineInstr::FrameSetup); + BuildMI(MBB, MBBI, DL, TII.get(AVR::EORRdRr)) + .addReg(STI.getZeroRegister(), RegState::Define) + .addReg(STI.getZeroRegister(), RegState::Kill) + .addReg(STI.getZeroRegister(), RegState::Kill) + .setMIFlag(MachineInstr::FrameSetup); + } } // Early exit if the frame pointer is not needed in this function. @@ -115,7 +121,8 @@ void AVRFrameLowering::emitPrologue(MachineFunction &MF, } // Reserve the necessary frame memory by doing FP -= <size>. - unsigned Opcode = (isUInt<6>(FrameSize)) ? AVR::SBIWRdK : AVR::SUBIWRdK; + unsigned Opcode = (isUInt<6>(FrameSize) && STI.hasADDSUBIW()) ? AVR::SBIWRdK + : AVR::SUBIWRdK; MachineInstr *MI = BuildMI(MBB, MBBI, DL, TII.get(Opcode), AVR::R29R28) .addReg(AVR::R29R28, RegState::Kill) @@ -132,6 +139,7 @@ void AVRFrameLowering::emitPrologue(MachineFunction &MF, static void restoreStatusRegister(MachineFunction &MF, MachineBasicBlock &MBB) { const AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>(); + const MachineRegisterInfo &MRI = MF.getRegInfo(); MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); @@ -142,11 +150,14 @@ static void restoreStatusRegister(MachineFunction &MF, MachineBasicBlock &MBB) { // Emit special epilogue code to restore R1, R0 and SREG in interrupt/signal // handlers at the very end of the function, just before reti. if (AFI->isInterruptOrSignalHandler()) { - BuildMI(MBB, MBBI, DL, TII.get(AVR::POPRd), AVR::R0); + if (!MRI.reg_empty(STI.getZeroRegister())) { + BuildMI(MBB, MBBI, DL, TII.get(AVR::POPRd), STI.getZeroRegister()); + } + BuildMI(MBB, MBBI, DL, TII.get(AVR::POPRd), STI.getTmpRegister()); BuildMI(MBB, MBBI, DL, TII.get(AVR::OUTARr)) .addImm(STI.getIORegSREG()) - .addReg(AVR::R0, RegState::Kill); - BuildMI(MBB, MBBI, DL, TII.get(AVR::POPWRd), AVR::R1R0); + .addReg(STI.getTmpRegister(), RegState::Kill); + BuildMI(MBB, MBBI, DL, TII.get(AVR::POPRd), STI.getTmpRegister()); } } @@ -192,7 +203,7 @@ void AVRFrameLowering::emitEpilogue(MachineFunction &MF, unsigned Opcode; // Select the optimal opcode depending on how big it is. - if (isUInt<6>(FrameSize)) { + if (isUInt<6>(FrameSize) && STI.hasADDSUBIW()) { Opcode = AVR::ADIWRdK; } else { Opcode = AVR::SUBIWRdK; @@ -374,7 +385,7 @@ MachineBasicBlock::iterator AVRFrameLowering::eliminateCallFramePseudoInstr( // Select the best opcode to adjust SP based on the offset size. unsigned AddOpcode; - if (isUInt<6>(Amount)) { + if (isUInt<6>(Amount) && STI.hasADDSUBIW()) { AddOpcode = AVR::ADIWRdK; } else { AddOpcode = AVR::SUBIWRdK; @@ -447,7 +458,8 @@ struct AVRFrameAnalyzer : public MachineFunctionPass { int Opcode = MI.getOpcode(); if ((Opcode != AVR::LDDRdPtrQ) && (Opcode != AVR::LDDWRdPtrQ) && - (Opcode != AVR::STDPtrQRr) && (Opcode != AVR::STDWPtrQRr)) { + (Opcode != AVR::STDPtrQRr) && (Opcode != AVR::STDWPtrQRr) && + (Opcode != AVR::FRMIDX)) { continue; } |
