diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h index 185a5d8a9c9b2..886c23861841a 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -624,6 +624,15 @@ inline unsigned encodeRlist(MCRegister EndReg, bool IsRV32E = false) { } } +inline static unsigned encodeRlistNumRegs(unsigned NumRegs) { + assert(NumRegs > 0 && NumRegs < 14 && NumRegs != 12 && + "Unexpected number of registers"); + if (NumRegs == 13) + return RLISTENCODE::RA_S0_S11; + + return RLISTENCODE::RA + (NumRegs - 1); +} + inline static unsigned getStackAdjBase(unsigned RlistVal, bool IsRV64) { assert(RlistVal != RLISTENCODE::INVALID_RLIST && "{ra, s0-s10} is not supported, s11 must be included."); diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp index 4eccdc59d0c97..38dfd1e57f345 100644 --- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp @@ -332,51 +332,19 @@ getRestoreLibCallName(const MachineFunction &MF, return RestoreLibCalls[LibCallID]; } -// Return encoded value and register count for PUSH/POP instruction, -// representing registers to store/load. -static std::pair -getPushPopEncodingAndNum(const Register MaxReg) { - switch (MaxReg.id()) { - default: - llvm_unreachable("Unexpected Reg for Push/Pop Inst"); - case RISCV::X27: /*s11*/ - return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S11, 13); - case RISCV::X25: /*s9*/ - return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S9, 11); - case RISCV::X24: /*s8*/ - return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S8, 10); - case RISCV::X23: /*s7*/ - return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S7, 9); - case RISCV::X22: /*s6*/ - return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S6, 8); - case RISCV::X21: /*s5*/ - return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S5, 7); - case RISCV::X20: /*s4*/ - return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S4, 6); - case RISCV::X19: /*s3*/ - return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S3, 5); - case RISCV::X18: /*s2*/ - return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S2, 4); - case RISCV::X9: /*s1*/ - return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S1, 3); - case FPReg: /*s0*/ - return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0, 2); - case RAReg: /*ra*/ - return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA, 1); - } -} - // Get the max reg of Push/Pop for restoring callee saved registers. -static Register getMaxPushPopReg(const std::vector &CSI) { - MCRegister MaxPushPopReg; +static unsigned getNumPushPopRegs(const std::vector &CSI) { + unsigned NumPushPopRegs = 0; for (auto &CS : CSI) { - if (llvm::find_if(FixedCSRFIMap, [&](MCPhysReg P) { - return P == CS.getReg(); - }) != std::end(FixedCSRFIMap)) - MaxPushPopReg = std::max(MaxPushPopReg.id(), CS.getReg().id()); + auto *FII = llvm::find_if(FixedCSRFIMap, + [&](MCPhysReg P) { return P == CS.getReg(); }); + if (FII != std::end(FixedCSRFIMap)) { + unsigned RegNum = std::distance(std::begin(FixedCSRFIMap), FII); + NumPushPopRegs = std::max(NumPushPopRegs, RegNum + 1); + } } - assert(MaxPushPopReg != RISCV::X26 && "x26 requires x27 to also be pushed"); - return MaxPushPopReg; + assert(NumPushPopRegs != 12 && "x26 requires x27 to also be pushed"); + return NumPushPopRegs; } // Return true if the specified function should have a dedicated frame @@ -1790,14 +1758,10 @@ bool RISCVFrameLowering::assignCalleeSavedSpillSlots( if (RVFI->isPushable(MF)) { // Determine how many GPRs we need to push and save it to RVFI. - Register MaxReg = getMaxPushPopReg(CSI); - if (MaxReg != RISCV::NoRegister) { - auto [RegEnc, PushedRegNum] = getPushPopEncodingAndNum(MaxReg); + unsigned PushedRegNum = getNumPushPopRegs(CSI); + if (PushedRegNum) { RVFI->setRVPushRegs(PushedRegNum); RVFI->setRVPushStackSize(alignTo((STI.getXLen() / 8) * PushedRegNum, 16)); - - // Use encoded number to represent registers to spill. - RVFI->setRVPushRlist(RegEnc); } } @@ -1881,11 +1845,11 @@ bool RISCVFrameLowering::spillCalleeSavedRegisters( unsigned PushedRegNum = RVFI->getRVPushRegs(); if (PushedRegNum > 0) { // Use encoded number to represent registers to spill. - int RegEnc = RVFI->getRVPushRlist(); + unsigned RegEnc = RISCVZC::encodeRlistNumRegs(PushedRegNum); MachineInstrBuilder PushBuilder = BuildMI(MBB, MI, DL, TII.get(RISCV::CM_PUSH)) .setMIFlag(MachineInstr::FrameSetup); - PushBuilder.addImm((int64_t)RegEnc); + PushBuilder.addImm(RegEnc); PushBuilder.addImm(0); for (unsigned i = 0; i < PushedRegNum; i++) @@ -2034,8 +1998,9 @@ bool RISCVFrameLowering::restoreCalleeSavedRegisters( RISCVMachineFunctionInfo *RVFI = MF->getInfo(); if (RVFI->isPushable(*MF)) { - int RegEnc = RVFI->getRVPushRlist(); - if (RegEnc != llvm::RISCVZC::RLISTENCODE::INVALID_RLIST) { + unsigned PushedRegNum = RVFI->getRVPushRegs(); + if (PushedRegNum > 0) { + unsigned RegEnc = RISCVZC::encodeRlistNumRegs(PushedRegNum); MachineInstrBuilder PopBuilder = BuildMI(MBB, MI, DL, TII.get(RISCV::CM_POP)) .setMIFlag(MachineInstr::FrameDestroy); diff --git a/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h b/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h index 27a13bb7cace1..3f88439086e56 100644 --- a/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h +++ b/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h @@ -74,7 +74,6 @@ class RISCVMachineFunctionInfo : public MachineFunctionInfo { /// Size of stack frame for Zcmp PUSH/POP unsigned RVPushStackSize = 0; unsigned RVPushRegs = 0; - int RVPushRlist = llvm::RISCVZC::RLISTENCODE::INVALID_RLIST; int64_t StackProbeSize = 0; @@ -146,9 +145,6 @@ class RISCVMachineFunctionInfo : public MachineFunctionInfo { VarArgsSaveSize == 0; } - int getRVPushRlist() const { return RVPushRlist; } - void setRVPushRlist(int Rlist) { RVPushRlist = Rlist; } - unsigned getRVPushRegs() const { return RVPushRegs; } void setRVPushRegs(unsigned Regs) { RVPushRegs = Regs; }