@@ -156,6 +156,23 @@ static ArrayRef<MCPhysReg> getArgGPR16s(const RISCVABI::ABI ABI) {
156156 return ArrayRef (ArgIGPRs);
157157}
158158
159+ static ArrayRef<MCPhysReg> getArgGPR32s (const RISCVABI::ABI ABI) {
160+ // The GPRs used for passing arguments in the ILP32* and LP64* ABIs, except
161+ // the ILP32E ABI.
162+ static const MCPhysReg ArgIGPRs[] = {RISCV::X10_W, RISCV::X11_W, RISCV::X12_W,
163+ RISCV::X13_W, RISCV::X14_W, RISCV::X15_W,
164+ RISCV::X16_W, RISCV::X17_W};
165+ // The GPRs used for passing arguments in the ILP32E/ILP64E ABI.
166+ static const MCPhysReg ArgEGPRs[] = {RISCV::X10_W, RISCV::X11_W,
167+ RISCV::X12_W, RISCV::X13_W,
168+ RISCV::X14_W, RISCV::X15_W};
169+
170+ if (ABI == RISCVABI::ABI_ILP32E || ABI == RISCVABI::ABI_LP64E)
171+ return ArrayRef (ArgEGPRs);
172+
173+ return ArrayRef (ArgIGPRs);
174+ }
175+
159176static ArrayRef<MCPhysReg> getFastCCArgGPRs (const RISCVABI::ABI ABI) {
160177 // The GPRs used for passing arguments in the FastCC, X5 and X6 might be used
161178 // for save-restore libcall, so we don't use them.
@@ -194,6 +211,26 @@ static ArrayRef<MCPhysReg> getFastCCArgGPRF16s(const RISCVABI::ABI ABI) {
194211 return ArrayRef (FastCCIGPRs);
195212}
196213
214+ static ArrayRef<MCPhysReg> getFastCCArgGPRF32s (const RISCVABI::ABI ABI) {
215+ // The GPRs used for passing arguments in the FastCC, X5 and X6 might be used
216+ // for save-restore libcall, so we don't use them.
217+ // Don't use X7 for fastcc, since Zicfilp uses X7 as the label register.
218+ static const MCPhysReg FastCCIGPRs[] = {
219+ RISCV::X10_W, RISCV::X11_W, RISCV::X12_W, RISCV::X13_W,
220+ RISCV::X14_W, RISCV::X15_W, RISCV::X16_W, RISCV::X17_W,
221+ RISCV::X28_W, RISCV::X29_W, RISCV::X30_W, RISCV::X31_W};
222+
223+ // The GPRs used for passing arguments in the FastCC when using ILP32E/ILP64E.
224+ static const MCPhysReg FastCCEGPRs[] = {RISCV::X10_W, RISCV::X11_W,
225+ RISCV::X12_W, RISCV::X13_W,
226+ RISCV::X14_W, RISCV::X15_W};
227+
228+ if (ABI == RISCVABI::ABI_ILP32E || ABI == RISCVABI::ABI_LP64E)
229+ return ArrayRef (FastCCEGPRs);
230+
231+ return ArrayRef (FastCCIGPRs);
232+ }
233+
197234// Pass a 2*XLEN argument that has been split into two XLEN values through
198235// registers or the stack as necessary.
199236static bool CC_RISCVAssign2XLen (unsigned XLen, CCState &State, CCValAssign VA1,
@@ -364,11 +401,17 @@ bool llvm::CC_RISCV(unsigned ValNo, MVT ValVT, MVT LocVT,
364401 }
365402 }
366403
404+ if ((ValVT == MVT::f32 && Subtarget.hasStdExtZfinx ())) {
405+ if (MCRegister Reg = State.AllocateReg (getArgGPR32s (ABI))) {
406+ State.addLoc (CCValAssign::getReg (ValNo, ValVT, Reg, LocVT, LocInfo));
407+ return false ;
408+ }
409+ }
410+
367411 ArrayRef<MCPhysReg> ArgGPRs = RISCV::getArgGPRs (ABI);
368412
369- // Zfinx/Zdinx use GPR without a bitcast when possible.
370- if ((LocVT == MVT::f32 && XLen == 32 && Subtarget.hasStdExtZfinx ()) ||
371- (LocVT == MVT::f64 && XLen == 64 && Subtarget.hasStdExtZdinx ())) {
413+ // Zdinx use GPR without a bitcast when possible.
414+ if (LocVT == MVT::f64 && XLen == 64 && Subtarget.hasStdExtZdinx ()) {
372415 if (MCRegister Reg = State.AllocateReg (ArgGPRs)) {
373416 State.addLoc (CCValAssign::getReg (ValNo, ValVT, Reg, LocVT, LocInfo));
374417 return false ;
@@ -616,10 +659,16 @@ bool llvm::CC_RISCV_FastCC(unsigned ValNo, MVT ValVT, MVT LocVT,
616659 }
617660 }
618661
662+ // Check if there is an available GPRF32 before hitting the stack.
663+ if (LocVT == MVT::f32 && Subtarget.hasStdExtZfinx ()) {
664+ if (MCRegister Reg = State.AllocateReg (getFastCCArgGPRF32s (ABI))) {
665+ State.addLoc (CCValAssign::getReg (ValNo, ValVT, Reg, LocVT, LocInfo));
666+ return false ;
667+ }
668+ }
669+
619670 // Check if there is an available GPR before hitting the stack.
620- if ((LocVT == MVT::f32 && Subtarget.hasStdExtZfinx ()) ||
621- (LocVT == MVT::f64 && Subtarget.is64Bit () &&
622- Subtarget.hasStdExtZdinx ())) {
671+ if (LocVT == MVT::f64 && Subtarget.is64Bit () && Subtarget.hasStdExtZdinx ()) {
623672 if (MCRegister Reg = State.AllocateReg (getFastCCArgGPRs (ABI))) {
624673 if (LocVT.getSizeInBits () != Subtarget.getXLen ()) {
625674 LocVT = XLenVT;
@@ -723,6 +772,17 @@ bool llvm::CC_RISCV_GHC(unsigned ValNo, MVT ValVT, MVT LocVT,
723772 }
724773 }
725774
775+ if (LocVT == MVT::f32 && Subtarget.hasStdExtZfinx ()) {
776+ static const MCPhysReg GPR32List[] = {
777+ RISCV::X9_W, RISCV::X18_W, RISCV::X19_W, RISCV::X20_W,
778+ RISCV::X21_W, RISCV::X22_W, RISCV::X23_W, RISCV::X24_W,
779+ RISCV::X25_W, RISCV::X26_W, RISCV::X27_W};
780+ if (MCRegister Reg = State.AllocateReg (GPR32List)) {
781+ State.addLoc (CCValAssign::getReg (ValNo, ValVT, Reg, LocVT, LocInfo));
782+ return false ;
783+ }
784+ }
785+
726786 if ((LocVT == MVT::f32 && Subtarget.hasStdExtZfinx ()) ||
727787 (LocVT == MVT::f64 && Subtarget.hasStdExtZdinx () &&
728788 Subtarget.is64Bit ())) {
0 commit comments