aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp')
-rw-r--r--contrib/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp51
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;
}