@@ -139,6 +139,23 @@ ArrayRef<MCPhysReg> RISCV::getArgGPRs(const RISCVABI::ABI ABI) {
139139 return ArrayRef (ArgIGPRs);
140140}
141141
142+ static ArrayRef<MCPhysReg> getArgGPR16s (const RISCVABI::ABI ABI) {
143+ // The GPRs used for passing arguments in the ILP32* and LP64* ABIs, except
144+ // the ILP32E ABI.
145+ static const MCPhysReg ArgIGPRs[] = {RISCV::X10_H, RISCV::X11_H, RISCV::X12_H,
146+ RISCV::X13_H, RISCV::X14_H, RISCV::X15_H,
147+ RISCV::X16_H, RISCV::X17_H};
148+ // The GPRs used for passing arguments in the ILP32E/LP64E ABI.
149+ static const MCPhysReg ArgEGPRs[] = {RISCV::X10_H, RISCV::X11_H,
150+ RISCV::X12_H, RISCV::X13_H,
151+ RISCV::X14_H, RISCV::X15_H};
152+
153+ if (ABI == RISCVABI::ABI_ILP32E || ABI == RISCVABI::ABI_LP64E)
154+ return ArrayRef (ArgEGPRs);
155+
156+ return ArrayRef (ArgIGPRs);
157+ }
158+
142159static ArrayRef<MCPhysReg> getFastCCArgGPRs (const RISCVABI::ABI ABI) {
143160 // The GPRs used for passing arguments in the FastCC, X5 and X6 might be used
144161 // for save-restore libcall, so we don't use them.
@@ -157,6 +174,26 @@ static ArrayRef<MCPhysReg> getFastCCArgGPRs(const RISCVABI::ABI ABI) {
157174 return ArrayRef (FastCCIGPRs);
158175}
159176
177+ static ArrayRef<MCPhysReg> getFastCCArgGPRF16s (const RISCVABI::ABI ABI) {
178+ // The GPRs used for passing arguments in the FastCC, X5 and X6 might be used
179+ // for save-restore libcall, so we don't use them.
180+ // Don't use X7 for fastcc, since Zicfilp uses X7 as the label register.
181+ static const MCPhysReg FastCCIGPRs[] = {
182+ RISCV::X10_H, RISCV::X11_H, RISCV::X12_H, RISCV::X13_H,
183+ RISCV::X14_H, RISCV::X15_H, RISCV::X16_H, RISCV::X17_H,
184+ RISCV::X28_H, RISCV::X29_H, RISCV::X30_H, RISCV::X31_H};
185+
186+ // The GPRs used for passing arguments in the FastCC when using ILP32E/LP64E.
187+ static const MCPhysReg FastCCEGPRs[] = {RISCV::X10_H, RISCV::X11_H,
188+ RISCV::X12_H, RISCV::X13_H,
189+ RISCV::X14_H, RISCV::X15_H};
190+
191+ if (ABI == RISCVABI::ABI_ILP32E || ABI == RISCVABI::ABI_LP64E)
192+ return ArrayRef (FastCCEGPRs);
193+
194+ return ArrayRef (FastCCIGPRs);
195+ }
196+
160197// Pass a 2*XLEN argument that has been split into two XLEN values through
161198// registers or the stack as necessary.
162199static bool CC_RISCVAssign2XLen (unsigned XLen, CCState &State, CCValAssign VA1,
@@ -320,6 +357,13 @@ bool llvm::CC_RISCV(unsigned ValNo, MVT ValVT, MVT LocVT,
320357 }
321358 }
322359
360+ if ((ValVT == MVT::f16 && Subtarget.hasStdExtZhinxmin ())) {
361+ if (MCRegister Reg = State.AllocateReg (getArgGPR16s (ABI))) {
362+ State.addLoc (CCValAssign::getReg (ValNo, ValVT, Reg, LocVT, LocInfo));
363+ return false ;
364+ }
365+ }
366+
323367 ArrayRef<MCPhysReg> ArgGPRs = RISCV::getArgGPRs (ABI);
324368
325369 // Zfinx/Zdinx use GPR without a bitcast when possible.
@@ -564,9 +608,16 @@ bool llvm::CC_RISCV_FastCC(unsigned ValNo, MVT ValVT, MVT LocVT,
564608
565609 MVT XLenVT = Subtarget.getXLenVT ();
566610
611+ // Check if there is an available GPRF16 before hitting the stack.
612+ if ((LocVT == MVT::f16 && Subtarget.hasStdExtZhinxmin ())) {
613+ if (MCRegister Reg = State.AllocateReg (getFastCCArgGPRF16s (ABI))) {
614+ State.addLoc (CCValAssign::getReg (ValNo, ValVT, Reg, LocVT, LocInfo));
615+ return false ;
616+ }
617+ }
618+
567619 // Check if there is an available GPR before hitting the stack.
568- if ((LocVT == MVT::f16 && Subtarget.hasStdExtZhinxmin ()) ||
569- (LocVT == MVT::f32 && Subtarget.hasStdExtZfinx ()) ||
620+ if ((LocVT == MVT::f32 && Subtarget.hasStdExtZfinx ()) ||
570621 (LocVT == MVT::f64 && Subtarget.is64Bit () &&
571622 Subtarget.hasStdExtZdinx ())) {
572623 if (MCRegister Reg = State.AllocateReg (getFastCCArgGPRs (ABI))) {
0 commit comments