@@ -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 ;
@@ -609,10 +652,24 @@ bool llvm::CC_RISCV_FastCC(unsigned ValNo, MVT ValVT, MVT LocVT,
609652 }
610653 }
611654
655+ // Check if there is an available GPRF16 before hitting the stack.
656+ if (LocVT == MVT::f16 && Subtarget.hasStdExtZhinxmin ()) {
657+ if (MCRegister Reg = State.AllocateReg (getFastCCArgGPRF16s (ABI))) {
658+ State.addLoc (CCValAssign::getReg (ValNo, ValVT, Reg, LocVT, LocInfo));
659+ return false ;
660+ }
661+ }
662+
663+ // Check if there is an available GPRF32 before hitting the stack.
664+ if (LocVT == MVT::f32 && Subtarget.hasStdExtZfinx ()) {
665+ if (MCRegister Reg = State.AllocateReg (getFastCCArgGPRF32s (ABI))) {
666+ State.addLoc (CCValAssign::getReg (ValNo, ValVT, Reg, LocVT, LocInfo));
667+ return false ;
668+ }
669+ }
670+
612671 // Check if there is an available GPR before hitting the stack.
613- if ((LocVT == MVT::f32 && Subtarget.hasStdExtZfinx ()) ||
614- (LocVT == MVT::f64 && Subtarget.is64Bit () &&
615- Subtarget.hasStdExtZdinx ())) {
672+ if (LocVT == MVT::f64 && Subtarget.is64Bit () && Subtarget.hasStdExtZdinx ()) {
616673 if (MCRegister Reg = State.AllocateReg (getFastCCArgGPRs (ABI))) {
617674 if (LocVT.getSizeInBits () != Subtarget.getXLen ()) {
618675 LocVT = Subtarget.getXLenVT ();
@@ -625,14 +682,6 @@ bool llvm::CC_RISCV_FastCC(unsigned ValNo, MVT ValVT, MVT LocVT,
625682 }
626683 }
627684
628- // Check if there is an available GPRF16 before hitting the stack.
629- if ((LocVT == MVT::f16 && Subtarget.hasStdExtZhinxmin ())) {
630- if (MCRegister Reg = State.AllocateReg (getFastCCArgGPRF16s (ABI))) {
631- State.addLoc (CCValAssign::getReg (ValNo, ValVT, Reg, LocVT, LocInfo));
632- return false ;
633- }
634- }
635-
636685 if (LocVT == MVT::f16 || LocVT == MVT::bf16 ) {
637686 int64_t Offset2 = State.AllocateStack (2 , Align (2 ));
638687 State.addLoc (CCValAssign::getMem (ValNo, ValVT, Offset2, LocVT, LocInfo));
@@ -739,6 +788,17 @@ bool llvm::CC_RISCV_GHC(unsigned ValNo, MVT ValVT, MVT LocVT,
739788 }
740789 }
741790
791+ if (LocVT == MVT::f32 && Subtarget.hasStdExtZfinx ()) {
792+ static const MCPhysReg GPR32List[] = {
793+ RISCV::X9_W, RISCV::X18_W, RISCV::X19_W, RISCV::X20_W,
794+ RISCV::X21_W, RISCV::X22_W, RISCV::X23_W, RISCV::X24_W,
795+ RISCV::X25_W, RISCV::X26_W, RISCV::X27_W};
796+ if (MCRegister Reg = State.AllocateReg (GPR32List)) {
797+ State.addLoc (CCValAssign::getReg (ValNo, ValVT, Reg, LocVT, LocInfo));
798+ return false ;
799+ }
800+ }
801+
742802 if ((LocVT == MVT::f32 && Subtarget.hasStdExtZfinx ()) ||
743803 (LocVT == MVT::f64 && Subtarget.hasStdExtZdinx () &&
744804 Subtarget.is64Bit ())) {
0 commit comments