@@ -49,8 +49,17 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
49
49
RISCVABI::ABI ABI = Subtarget.getTargetABI ();
50
50
assert (ABI != RISCVABI::ABI_Unknown && " Improperly initialised target ABI" );
51
51
52
- if (ABI != RISCVABI::ABI_ILP32 && ABI != RISCVABI::ABI_LP64)
52
+ switch (ABI) {
53
+ default :
53
54
report_fatal_error (" Don't know how to lower this ABI" );
55
+ case RISCVABI::ABI_ILP32:
56
+ case RISCVABI::ABI_ILP32F:
57
+ case RISCVABI::ABI_ILP32D:
58
+ case RISCVABI::ABI_LP64:
59
+ case RISCVABI::ABI_LP64F:
60
+ case RISCVABI::ABI_LP64D:
61
+ break ;
62
+ }
54
63
55
64
MVT XLenVT = Subtarget.getXLenVT ();
56
65
@@ -981,6 +990,14 @@ static const MCPhysReg ArgGPRs[] = {
981
990
RISCV::X10, RISCV::X11, RISCV::X12, RISCV::X13,
982
991
RISCV::X14, RISCV::X15, RISCV::X16, RISCV::X17
983
992
};
993
+ static const MCPhysReg ArgFPR32s[] = {
994
+ RISCV::F10_32, RISCV::F11_32, RISCV::F12_32, RISCV::F13_32,
995
+ RISCV::F14_32, RISCV::F15_32, RISCV::F16_32, RISCV::F17_32
996
+ };
997
+ static const MCPhysReg ArgFPR64s[] = {
998
+ RISCV::F10_64, RISCV::F11_64, RISCV::F12_64, RISCV::F13_64,
999
+ RISCV::F14_64, RISCV::F15_64, RISCV::F16_64, RISCV::F17_64
1000
+ };
984
1001
985
1002
// Pass a 2*XLEN argument that has been split into two XLEN values through
986
1003
// registers or the stack as necessary.
@@ -1021,9 +1038,10 @@ static bool CC_RISCVAssign2XLen(unsigned XLen, CCState &State, CCValAssign VA1,
1021
1038
}
1022
1039
1023
1040
// Implements the RISC-V calling convention. Returns true upon failure.
1024
- static bool CC_RISCV (const DataLayout &DL, unsigned ValNo, MVT ValVT, MVT LocVT,
1025
- CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags,
1026
- CCState &State, bool IsFixed, bool IsRet, Type *OrigTy) {
1041
+ static bool CC_RISCV (const DataLayout &DL, RISCVABI::ABI ABI, unsigned ValNo,
1042
+ MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo,
1043
+ ISD::ArgFlagsTy ArgFlags, CCState &State, bool IsFixed,
1044
+ bool IsRet, Type *OrigTy) {
1027
1045
unsigned XLen = DL.getLargestLegalIntTypeSizeInBits ();
1028
1046
assert (XLen == 32 || XLen == 64 );
1029
1047
MVT XLenVT = XLen == 32 ? MVT::i32 : MVT::i64;
@@ -1033,10 +1051,42 @@ static bool CC_RISCV(const DataLayout &DL, unsigned ValNo, MVT ValVT, MVT LocVT,
1033
1051
if (IsRet && ValNo > 1 )
1034
1052
return true ;
1035
1053
1036
- if (ValVT == MVT::f32) {
1054
+ // UseGPRForF32 if targeting one of the soft-float ABIs, if passing a
1055
+ // variadic argument, or if no F32 argument registers are available.
1056
+ bool UseGPRForF32 = true ;
1057
+ // UseGPRForF64 if targeting soft-float ABIs or an FLEN=32 ABI, if passing a
1058
+ // variadic argument, or if no F64 argument registers are available.
1059
+ bool UseGPRForF64 = true ;
1060
+
1061
+ switch (ABI) {
1062
+ default :
1063
+ llvm_unreachable (" Unexpected ABI" );
1064
+ case RISCVABI::ABI_ILP32:
1065
+ case RISCVABI::ABI_LP64:
1066
+ break ;
1067
+ case RISCVABI::ABI_ILP32F:
1068
+ case RISCVABI::ABI_LP64F:
1069
+ UseGPRForF32 = !IsFixed;
1070
+ break ;
1071
+ case RISCVABI::ABI_ILP32D:
1072
+ case RISCVABI::ABI_LP64D:
1073
+ UseGPRForF32 = !IsFixed;
1074
+ UseGPRForF64 = !IsFixed;
1075
+ break ;
1076
+ }
1077
+
1078
+ if (State.getFirstUnallocated (ArgFPR32s) == array_lengthof (ArgFPR32s))
1079
+ UseGPRForF32 = true ;
1080
+ if (State.getFirstUnallocated (ArgFPR64s) == array_lengthof (ArgFPR64s))
1081
+ UseGPRForF64 = true ;
1082
+
1083
+ // From this point on, rely on UseGPRForF32, UseGPRForF64 and similar local
1084
+ // variables rather than directly checking against the target ABI.
1085
+
1086
+ if (UseGPRForF32 && ValVT == MVT::f32) {
1037
1087
LocVT = XLenVT;
1038
1088
LocInfo = CCValAssign::BCvt;
1039
- } else if (XLen == 64 && ValVT == MVT::f64) {
1089
+ } else if (UseGPRForF64 && XLen == 64 && ValVT == MVT::f64) {
1040
1090
LocVT = MVT::i64;
1041
1091
LocInfo = CCValAssign::BCvt;
1042
1092
}
@@ -1064,8 +1114,9 @@ static bool CC_RISCV(const DataLayout &DL, unsigned ValNo, MVT ValVT, MVT LocVT,
1064
1114
assert (PendingLocs.size () == PendingArgFlags.size () &&
1065
1115
" PendingLocs and PendingArgFlags out of sync" );
1066
1116
1067
- // Handle passing f64 on RV32D with a soft float ABI.
1068
- if (XLen == 32 && ValVT == MVT::f64) {
1117
+ // Handle passing f64 on RV32D with a soft float ABI or when floating point
1118
+ // registers are exhausted.
1119
+ if (UseGPRForF64 && XLen == 32 && ValVT == MVT::f64) {
1069
1120
assert (!ArgFlags.isSplit () && PendingLocs.empty () &&
1070
1121
" Can't lower f64 if it is split" );
1071
1122
// Depending on available argument GPRS, f64 may be passed in a pair of
@@ -1114,7 +1165,13 @@ static bool CC_RISCV(const DataLayout &DL, unsigned ValNo, MVT ValVT, MVT LocVT,
1114
1165
}
1115
1166
1116
1167
// Allocate to a register if possible, or else a stack slot.
1117
- unsigned Reg = State.AllocateReg (ArgGPRs);
1168
+ unsigned Reg;
1169
+ if (ValVT == MVT::f32 && !UseGPRForF32)
1170
+ Reg = State.AllocateReg (ArgFPR32s, ArgFPR64s);
1171
+ else if (ValVT == MVT::f64 && !UseGPRForF64)
1172
+ Reg = State.AllocateReg (ArgFPR64s, ArgFPR32s);
1173
+ else
1174
+ Reg = Reg = State.AllocateReg (ArgGPRs);
1118
1175
unsigned StackOffset = Reg ? 0 : State.AllocateStack (XLen / 8 , XLen / 8 );
1119
1176
1120
1177
// If we reach this point and PendingLocs is non-empty, we must be at the
@@ -1135,7 +1192,8 @@ static bool CC_RISCV(const DataLayout &DL, unsigned ValNo, MVT ValVT, MVT LocVT,
1135
1192
return false ;
1136
1193
}
1137
1194
1138
- assert (LocVT == XLenVT && " Expected an XLenVT at this stage" );
1195
+ assert ((!UseGPRForF32 || !UseGPRForF64 || LocVT == XLenVT) &&
1196
+ " Expected an XLenVT at this stage" );
1139
1197
1140
1198
if (Reg) {
1141
1199
State.addLoc (CCValAssign::getReg (ValNo, ValVT, Reg, LocVT, LocInfo));
@@ -1167,7 +1225,8 @@ void RISCVTargetLowering::analyzeInputArgs(
1167
1225
else if (Ins[i].isOrigArg ())
1168
1226
ArgTy = FType->getParamType (Ins[i].getOrigArgIndex ());
1169
1227
1170
- if (CC_RISCV (MF.getDataLayout (), i, ArgVT, ArgVT, CCValAssign::Full,
1228
+ RISCVABI::ABI ABI = MF.getSubtarget <RISCVSubtarget>().getTargetABI ();
1229
+ if (CC_RISCV (MF.getDataLayout (), ABI, i, ArgVT, ArgVT, CCValAssign::Full,
1171
1230
ArgFlags, CCInfo, /* IsRet=*/ true , IsRet, ArgTy)) {
1172
1231
LLVM_DEBUG (dbgs () << " InputArg #" << i << " has unhandled type "
1173
1232
<< EVT (ArgVT).getEVTString () << ' \n ' );
@@ -1187,7 +1246,8 @@ void RISCVTargetLowering::analyzeOutputArgs(
1187
1246
ISD::ArgFlagsTy ArgFlags = Outs[i].Flags ;
1188
1247
Type *OrigTy = CLI ? CLI->getArgs ()[Outs[i].OrigArgIndex ].Ty : nullptr ;
1189
1248
1190
- if (CC_RISCV (MF.getDataLayout (), i, ArgVT, ArgVT, CCValAssign::Full,
1249
+ RISCVABI::ABI ABI = MF.getSubtarget <RISCVSubtarget>().getTargetABI ();
1250
+ if (CC_RISCV (MF.getDataLayout (), ABI, i, ArgVT, ArgVT, CCValAssign::Full,
1191
1251
ArgFlags, CCInfo, Outs[i].IsFixed , IsRet, OrigTy)) {
1192
1252
LLVM_DEBUG (dbgs () << " OutputArg #" << i << " has unhandled type "
1193
1253
<< EVT (ArgVT).getEVTString () << " \n " );
@@ -1224,8 +1284,24 @@ static SDValue unpackFromRegLoc(SelectionDAG &DAG, SDValue Chain,
1224
1284
MachineRegisterInfo &RegInfo = MF.getRegInfo ();
1225
1285
EVT LocVT = VA.getLocVT ();
1226
1286
SDValue Val;
1287
+ const TargetRegisterClass *RC;
1288
+
1289
+ switch (LocVT.getSimpleVT ().SimpleTy ) {
1290
+ default :
1291
+ llvm_unreachable (" Unexpected register type" );
1292
+ case MVT::i32:
1293
+ case MVT::i64:
1294
+ RC = &RISCV::GPRRegClass;
1295
+ break ;
1296
+ case MVT::f32:
1297
+ RC = &RISCV::FPR32RegClass;
1298
+ break ;
1299
+ case MVT::f64:
1300
+ RC = &RISCV::FPR64RegClass;
1301
+ break ;
1302
+ }
1227
1303
1228
- unsigned VReg = RegInfo.createVirtualRegister (&RISCV::GPRRegClass );
1304
+ unsigned VReg = RegInfo.createVirtualRegister (RC );
1229
1305
RegInfo.addLiveIn (VA.getLocReg (), VReg);
1230
1306
Val = DAG.getCopyFromReg (Chain, DL, VReg, LocVT);
1231
1307
@@ -1802,8 +1878,9 @@ bool RISCVTargetLowering::CanLowerReturn(
1802
1878
for (unsigned i = 0 , e = Outs.size (); i != e; ++i) {
1803
1879
MVT VT = Outs[i].VT ;
1804
1880
ISD::ArgFlagsTy ArgFlags = Outs[i].Flags ;
1805
- if (CC_RISCV (MF.getDataLayout (), i, VT, VT, CCValAssign::Full, ArgFlags,
1806
- CCInfo, /* IsFixed=*/ true , /* IsRet=*/ true , nullptr ))
1881
+ RISCVABI::ABI ABI = MF.getSubtarget <RISCVSubtarget>().getTargetABI ();
1882
+ if (CC_RISCV (MF.getDataLayout (), ABI, i, VT, VT, CCValAssign::Full,
1883
+ ArgFlags, CCInfo, /* IsFixed=*/ true , /* IsRet=*/ true , nullptr ))
1807
1884
return false ;
1808
1885
}
1809
1886
return true ;
0 commit comments