================ @@ -17134,30 +17133,64 @@ static const MCPhysReg ArgVRM4s[] = {RISCV::V8M4, RISCV::V12M4, RISCV::V16M4, RISCV::V20M4}; static const MCPhysReg ArgVRM8s[] = {RISCV::V8M8, RISCV::V16M8}; -ArrayRef<MCPhysReg> RISCV::getArgGPRs() { - static const MCPhysReg ArgGPRs[] = {RISCV::X10, RISCV::X11, RISCV::X12, - RISCV::X13, RISCV::X14, RISCV::X15, - RISCV::X16, RISCV::X17}; +ArrayRef<MCPhysReg> RISCV::getArgGPRs(const RISCVABI::ABI ABI) { + // The GPRs used for passing arguments in the ILP32* and LP64* ABIs, except + // the ILP32E ABI. + static const MCPhysReg ArgIGPRs[] = {RISCV::X10, RISCV::X11, RISCV::X12, + RISCV::X13, RISCV::X14, RISCV::X15, + RISCV::X16, RISCV::X17}; + // The GPRs used for passing arguments in the ILP32E/ILP64E ABI. + static const MCPhysReg ArgEGPRs[] = {RISCV::X10, RISCV::X11, RISCV::X12, + RISCV::X13, RISCV::X14, RISCV::X15}; + + if (ABI == RISCVABI::ABI_ILP32E || ABI == RISCVABI::ABI_LP64E) + return ArrayRef(ArgEGPRs); + + return ArrayRef(ArgIGPRs); +} + +static ArrayRef<MCPhysReg> getFastCCArgGPRs(const RISCVABI::ABI ABI) { + // The GPRs used for passing arguments in the FastCC, X5 and X6 might be used + // for save-restore libcall, so we don't use them. + static const MCPhysReg FastCCIGPRs[] = { + RISCV::X10, RISCV::X11, RISCV::X12, RISCV::X13, RISCV::X14, + RISCV::X15, RISCV::X16, RISCV::X17, RISCV::X7, RISCV::X28, + RISCV::X29, RISCV::X30, RISCV::X31}; + + // The GPRs used for passing arguments in the FastCC when using ILP32E/ILP64E. + static const MCPhysReg FastCCEGPRs[] = {RISCV::X10, RISCV::X11, RISCV::X12, + RISCV::X13, RISCV::X14, RISCV::X15, + RISCV::X7}; - return ArrayRef(ArgGPRs); + if (ABI == RISCVABI::ABI_ILP32E || ABI == RISCVABI::ABI_LP64E) + return ArrayRef(FastCCEGPRs); + + return ArrayRef(FastCCIGPRs); } // Pass a 2*XLEN argument that has been split into two XLEN values through // registers or the stack as necessary. static bool CC_RISCVAssign2XLen(unsigned XLen, CCState &State, CCValAssign VA1, ISD::ArgFlagsTy ArgFlags1, unsigned ValNo2, MVT ValVT2, MVT LocVT2, - ISD::ArgFlagsTy ArgFlags2) { + ISD::ArgFlagsTy ArgFlags2, bool EABI) { unsigned XLenInBytes = XLen / 8; - ArrayRef<MCPhysReg> ArgGPRs = RISCV::getArgGPRs(); + const RISCVSubtarget &STI = + State.getMachineFunction().getSubtarget<RISCVSubtarget>(); + ArrayRef<MCPhysReg> ArgGPRs = RISCV::getArgGPRs(STI.getTargetABI()); + if (Register Reg = State.AllocateReg(ArgGPRs)) { // At least one half can be passed via register. State.addLoc(CCValAssign::getReg(VA1.getValNo(), VA1.getValVT(), Reg, VA1.getLocVT(), CCValAssign::Full)); } else { // Both halves must be passed on the stack, with proper alignment. + // TODO: To be compatible with GCC's behaviors, we force them to have 4-byte + // alignment. This behavior may be changed when RV32E/ILP32E is ratified. Align StackAlign = - std::max(Align(XLenInBytes), ArgFlags1.getNonZeroOrigAlign()); + EABI && XLen == 32 ---------------- topperc wrote:
``` Align StackAlign(XLenInBytes); if (!EABI || XLen != 32) StackAlign = std::max(StackAlign, ArgFlags1.getNonZeroOrigAlign()); ``` https://github.com/llvm/llvm-project/pull/76777 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits