diff options
Diffstat (limited to 'contrib/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp')
| -rw-r--r-- | contrib/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp | 51 |
1 files changed, 43 insertions, 8 deletions
diff --git a/contrib/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp b/contrib/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp index 5776a92cab91..3ed1dec434ce 100644 --- a/contrib/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp +++ b/contrib/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp @@ -33,6 +33,13 @@ RISCVRegisterInfo::RISCVRegisterInfo(unsigned HwMode) const MCPhysReg * RISCVRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { + if (MF->getFunction().hasFnAttribute("interrupt")) { + if (MF->getSubtarget<RISCVSubtarget>().hasStdExtD()) + return CSR_XLEN_F64_Interrupt_SaveList; + if (MF->getSubtarget<RISCVSubtarget>().hasStdExtF()) + return CSR_XLEN_F32_Interrupt_SaveList; + return CSR_Interrupt_SaveList; + } return CSR_SaveList; } @@ -50,6 +57,10 @@ BitVector RISCVRegisterInfo::getReservedRegs(const MachineFunction &MF) const { return Reserved; } +bool RISCVRegisterInfo::isConstantPhysReg(unsigned PhysReg) const { + return PhysReg == RISCV::X0; +} + const uint32_t *RISCVRegisterInfo::getNoPreservedMask() const { return CSR_NoRegs_RegMask; } @@ -61,6 +72,8 @@ void RISCVRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, MachineInstr &MI = *II; MachineFunction &MF = *MI.getParent()->getParent(); + MachineRegisterInfo &MRI = MF.getRegInfo(); + const RISCVInstrInfo *TII = MF.getSubtarget<RISCVSubtarget>().getInstrInfo(); DebugLoc DL = MI.getDebugLoc(); int FrameIndex = MI.getOperand(FIOperandNum).getIndex(); @@ -69,25 +82,47 @@ void RISCVRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, getFrameLowering(MF)->getFrameIndexReference(MF, FrameIndex, FrameReg) + MI.getOperand(FIOperandNum + 1).getImm(); - assert(MF.getSubtarget().getFrameLowering()->hasFP(MF) && - "eliminateFrameIndex currently requires hasFP"); + if (!isInt<32>(Offset)) { + report_fatal_error( + "Frame offsets outside of the signed 32-bit range not supported"); + } + + MachineBasicBlock &MBB = *MI.getParent(); + bool FrameRegIsKill = false; - // Offsets must be directly encoded in a 12-bit immediate field if (!isInt<12>(Offset)) { - report_fatal_error( - "Frame offsets outside of the signed 12-bit range not supported"); + assert(isInt<32>(Offset) && "Int32 expected"); + // The offset won't fit in an immediate, so use a scratch register instead + // Modify Offset and FrameReg appropriately + unsigned ScratchReg = MRI.createVirtualRegister(&RISCV::GPRRegClass); + TII->movImm32(MBB, II, DL, ScratchReg, Offset); + BuildMI(MBB, II, DL, TII->get(RISCV::ADD), ScratchReg) + .addReg(FrameReg) + .addReg(ScratchReg, RegState::Kill); + Offset = 0; + FrameReg = ScratchReg; + FrameRegIsKill = true; } - MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false); + MI.getOperand(FIOperandNum) + .ChangeToRegister(FrameReg, false, false, FrameRegIsKill); MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset); } unsigned RISCVRegisterInfo::getFrameRegister(const MachineFunction &MF) const { - return RISCV::X8; + const TargetFrameLowering *TFI = getFrameLowering(MF); + return TFI->hasFP(MF) ? RISCV::X8 : RISCV::X2; } const uint32_t * -RISCVRegisterInfo::getCallPreservedMask(const MachineFunction & /*MF*/, +RISCVRegisterInfo::getCallPreservedMask(const MachineFunction & MF, CallingConv::ID /*CC*/) const { + if (MF.getFunction().hasFnAttribute("interrupt")) { + if (MF.getSubtarget<RISCVSubtarget>().hasStdExtD()) + return CSR_XLEN_F64_Interrupt_RegMask; + if (MF.getSubtarget<RISCVSubtarget>().hasStdExtF()) + return CSR_XLEN_F32_Interrupt_RegMask; + return CSR_Interrupt_RegMask; + } return CSR_RegMask; } |
