@@ -16452,9 +16452,16 @@ bool RISCV::CC_RISCV(const DataLayout &DL, RISCVABI::ABI ABI, unsigned ValNo,
16452
16452
return false;
16453
16453
}
16454
16454
LocVT = MVT::i32;
16455
- if (!State.AllocateReg(ArgGPRs))
16456
- State.AllocateStack(4, Align(4));
16457
- State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
16455
+ State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
16456
+ Register HiReg = State.AllocateReg(ArgGPRs);
16457
+ if (HiReg) {
16458
+ State.addLoc(
16459
+ CCValAssign::getCustomReg(ValNo, ValVT, HiReg, LocVT, LocInfo));
16460
+ } else {
16461
+ unsigned StackOffset = State.AllocateStack(4, Align(4));
16462
+ State.addLoc(
16463
+ CCValAssign::getCustomMem(ValNo, ValVT, StackOffset, LocVT, LocInfo));
16464
+ }
16458
16465
return false;
16459
16466
}
16460
16467
@@ -16763,7 +16770,9 @@ static SDValue unpackFromMemLoc(SelectionDAG &DAG, SDValue Chain,
16763
16770
}
16764
16771
16765
16772
static SDValue unpackF64OnRV32DSoftABI(SelectionDAG &DAG, SDValue Chain,
16766
- const CCValAssign &VA, const SDLoc &DL) {
16773
+ const CCValAssign &VA,
16774
+ const CCValAssign &HiVA,
16775
+ const SDLoc &DL) {
16767
16776
assert(VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64 &&
16768
16777
"Unexpected VA");
16769
16778
MachineFunction &MF = DAG.getMachineFunction();
@@ -16776,16 +16785,17 @@ static SDValue unpackF64OnRV32DSoftABI(SelectionDAG &DAG, SDValue Chain,
16776
16785
RegInfo.addLiveIn(VA.getLocReg(), LoVReg);
16777
16786
SDValue Lo = DAG.getCopyFromReg(Chain, DL, LoVReg, MVT::i32);
16778
16787
SDValue Hi;
16779
- if (VA.getLocReg() == RISCV::X17 ) {
16788
+ if (HiVA.isMemLoc() ) {
16780
16789
// Second half of f64 is passed on the stack.
16781
- int FI = MFI.CreateFixedObject(4, 0, /*IsImmutable=*/true);
16790
+ int FI = MFI.CreateFixedObject(4, HiVA.getLocMemOffset(),
16791
+ /*IsImmutable=*/true);
16782
16792
SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
16783
16793
Hi = DAG.getLoad(MVT::i32, DL, Chain, FIN,
16784
16794
MachinePointerInfo::getFixedStack(MF, FI));
16785
16795
} else {
16786
16796
// Second half of f64 is passed in another GPR.
16787
16797
Register HiVReg = RegInfo.createVirtualRegister(&RISCV::GPRRegClass);
16788
- RegInfo.addLiveIn(VA .getLocReg() + 1 , HiVReg);
16798
+ RegInfo.addLiveIn(HiVA .getLocReg(), HiVReg);
16789
16799
Hi = DAG.getCopyFromReg(Chain, DL, HiVReg, MVT::i32);
16790
16800
}
16791
16801
return DAG.getNode(RISCVISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
@@ -17028,15 +17038,16 @@ SDValue RISCVTargetLowering::LowerFormalArguments(
17028
17038
CallConv == CallingConv::Fast ? RISCV::CC_RISCV_FastCC
17029
17039
: RISCV::CC_RISCV);
17030
17040
17031
- for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
17041
+ for (unsigned i = 0, e = ArgLocs.size(), InsIdx = 0 ; i != e; ++i, ++InsIdx ) {
17032
17042
CCValAssign &VA = ArgLocs[i];
17033
17043
SDValue ArgValue;
17034
17044
// Passing f64 on RV32D with a soft float ABI must be handled as a special
17035
17045
// case.
17036
- if (VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64)
17037
- ArgValue = unpackF64OnRV32DSoftABI(DAG, Chain, VA, DL);
17038
- else if (VA.isRegLoc())
17039
- ArgValue = unpackFromRegLoc(DAG, Chain, VA, DL, Ins[i], *this);
17046
+ if (VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64) {
17047
+ assert(VA.needsCustom());
17048
+ ArgValue = unpackF64OnRV32DSoftABI(DAG, Chain, VA, ArgLocs[++i], DL);
17049
+ } else if (VA.isRegLoc())
17050
+ ArgValue = unpackFromRegLoc(DAG, Chain, VA, DL, Ins[InsIdx], *this);
17040
17051
else
17041
17052
ArgValue = unpackFromMemLoc(DAG, Chain, VA, DL);
17042
17053
@@ -17048,19 +17059,20 @@ SDValue RISCVTargetLowering::LowerFormalArguments(
17048
17059
// stores are relative to that.
17049
17060
InVals.push_back(DAG.getLoad(VA.getValVT(), DL, Chain, ArgValue,
17050
17061
MachinePointerInfo()));
17051
- unsigned ArgIndex = Ins[i ].OrigArgIndex;
17052
- unsigned ArgPartOffset = Ins[i ].PartOffset;
17062
+ unsigned ArgIndex = Ins[InsIdx ].OrigArgIndex;
17063
+ unsigned ArgPartOffset = Ins[InsIdx ].PartOffset;
17053
17064
assert(VA.getValVT().isVector() || ArgPartOffset == 0);
17054
- while (i + 1 != e && Ins[i + 1].OrigArgIndex == ArgIndex) {
17065
+ while (i + 1 != e && Ins[InsIdx + 1].OrigArgIndex == ArgIndex) {
17055
17066
CCValAssign &PartVA = ArgLocs[i + 1];
17056
- unsigned PartOffset = Ins[i + 1].PartOffset - ArgPartOffset;
17067
+ unsigned PartOffset = Ins[InsIdx + 1].PartOffset - ArgPartOffset;
17057
17068
SDValue Offset = DAG.getIntPtrConstant(PartOffset, DL);
17058
17069
if (PartVA.getValVT().isScalableVector())
17059
17070
Offset = DAG.getNode(ISD::VSCALE, DL, XLenVT, Offset);
17060
17071
SDValue Address = DAG.getNode(ISD::ADD, DL, PtrVT, ArgValue, Offset);
17061
17072
InVals.push_back(DAG.getLoad(PartVA.getValVT(), DL, Chain, Address,
17062
17073
MachinePointerInfo()));
17063
17074
++i;
17075
+ ++InsIdx;
17064
17076
}
17065
17077
continue;
17066
17078
}
@@ -17276,14 +17288,16 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
17276
17288
SmallVector<std::pair<Register, SDValue>, 8> RegsToPass;
17277
17289
SmallVector<SDValue, 8> MemOpChains;
17278
17290
SDValue StackPtr;
17279
- for (unsigned i = 0, j = 0, e = ArgLocs.size(); i != e; ++i) {
17291
+ for (unsigned i = 0, j = 0, e = ArgLocs.size(), OutIdx = 0; i != e;
17292
+ ++i, ++OutIdx) {
17280
17293
CCValAssign &VA = ArgLocs[i];
17281
- SDValue ArgValue = OutVals[i ];
17282
- ISD::ArgFlagsTy Flags = Outs[i ].Flags;
17294
+ SDValue ArgValue = OutVals[OutIdx ];
17295
+ ISD::ArgFlagsTy Flags = Outs[OutIdx ].Flags;
17283
17296
17284
17297
// Handle passing f64 on RV32D with a soft float ABI as a special case.
17285
17298
if (VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64) {
17286
17299
assert(VA.isRegLoc() && "Expected register VA assignment");
17300
+ assert(VA.needsCustom());
17287
17301
SDValue SplitF64 = DAG.getNode(
17288
17302
RISCVISD::SplitF64, DL, DAG.getVTList(MVT::i32, MVT::i32), ArgValue);
17289
17303
SDValue Lo = SplitF64.getValue(0);
@@ -17292,18 +17306,22 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
17292
17306
Register RegLo = VA.getLocReg();
17293
17307
RegsToPass.push_back(std::make_pair(RegLo, Lo));
17294
17308
17295
- if (RegLo == RISCV::X17) {
17309
+ // Get the CCValAssign for the Hi part.
17310
+ CCValAssign &HiVA = ArgLocs[++i];
17311
+
17312
+ if (HiVA.isMemLoc()) {
17296
17313
// Second half of f64 is passed on the stack.
17297
- // Work out the address of the stack slot.
17298
17314
if (!StackPtr.getNode())
17299
17315
StackPtr = DAG.getCopyFromReg(Chain, DL, RISCV::X2, PtrVT);
17316
+ SDValue Address =
17317
+ DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr,
17318
+ DAG.getIntPtrConstant(HiVA.getLocMemOffset(), DL));
17300
17319
// Emit the store.
17301
17320
MemOpChains.push_back(
17302
- DAG.getStore(Chain, DL, Hi, StackPtr , MachinePointerInfo()));
17321
+ DAG.getStore(Chain, DL, Hi, Address , MachinePointerInfo()));
17303
17322
} else {
17304
17323
// Second half of f64 is passed in another GPR.
17305
- assert(RegLo < RISCV::X31 && "Invalid register pair");
17306
- Register RegHigh = RegLo + 1;
17324
+ Register RegHigh = HiVA.getLocReg();
17307
17325
RegsToPass.push_back(std::make_pair(RegHigh, Hi));
17308
17326
}
17309
17327
continue;
@@ -17314,24 +17332,24 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
17314
17332
if (VA.getLocInfo() == CCValAssign::Indirect) {
17315
17333
// Store the argument in a stack slot and pass its address.
17316
17334
Align StackAlign =
17317
- std::max(getPrefTypeAlign(Outs[i ].ArgVT, DAG),
17335
+ std::max(getPrefTypeAlign(Outs[OutIdx ].ArgVT, DAG),
17318
17336
getPrefTypeAlign(ArgValue.getValueType(), DAG));
17319
17337
TypeSize StoredSize = ArgValue.getValueType().getStoreSize();
17320
17338
// If the original argument was split (e.g. i128), we need
17321
17339
// to store the required parts of it here (and pass just one address).
17322
17340
// Vectors may be partly split to registers and partly to the stack, in
17323
17341
// which case the base address is partly offset and subsequent stores are
17324
17342
// relative to that.
17325
- unsigned ArgIndex = Outs[i ].OrigArgIndex;
17326
- unsigned ArgPartOffset = Outs[i ].PartOffset;
17343
+ unsigned ArgIndex = Outs[OutIdx ].OrigArgIndex;
17344
+ unsigned ArgPartOffset = Outs[OutIdx ].PartOffset;
17327
17345
assert(VA.getValVT().isVector() || ArgPartOffset == 0);
17328
17346
// Calculate the total size to store. We don't have access to what we're
17329
17347
// actually storing other than performing the loop and collecting the
17330
17348
// info.
17331
17349
SmallVector<std::pair<SDValue, SDValue>> Parts;
17332
- while (i + 1 != e && Outs[i + 1].OrigArgIndex == ArgIndex) {
17333
- SDValue PartValue = OutVals[i + 1];
17334
- unsigned PartOffset = Outs[i + 1].PartOffset - ArgPartOffset;
17350
+ while (i + 1 != e && Outs[OutIdx + 1].OrigArgIndex == ArgIndex) {
17351
+ SDValue PartValue = OutVals[OutIdx + 1];
17352
+ unsigned PartOffset = Outs[OutIdx + 1].PartOffset - ArgPartOffset;
17335
17353
SDValue Offset = DAG.getIntPtrConstant(PartOffset, DL);
17336
17354
EVT PartVT = PartValue.getValueType();
17337
17355
if (PartVT.isScalableVector())
@@ -17340,6 +17358,7 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
17340
17358
StackAlign = std::max(StackAlign, getPrefTypeAlign(PartVT, DAG));
17341
17359
Parts.push_back(std::make_pair(PartValue, Offset));
17342
17360
++i;
17361
+ ++OutIdx;
17343
17362
}
17344
17363
SDValue SpillSlot = DAG.CreateStackTemporary(StoredSize, StackAlign);
17345
17364
int FI = cast<FrameIndexSDNode>(SpillSlot)->getIndex();
@@ -17481,7 +17500,8 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
17481
17500
analyzeInputArgs(MF, RetCCInfo, Ins, /*IsRet=*/true, RISCV::CC_RISCV);
17482
17501
17483
17502
// Copy all of the result registers out of their specified physreg.
17484
- for (auto &VA : RVLocs) {
17503
+ for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) {
17504
+ auto &VA = RVLocs[i];
17485
17505
// Copy the value out
17486
17506
SDValue RetValue =
17487
17507
DAG.getCopyFromReg(Chain, DL, VA.getLocReg(), VA.getLocVT(), Glue);
@@ -17490,9 +17510,9 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
17490
17510
Glue = RetValue.getValue(2);
17491
17511
17492
17512
if (VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64) {
17493
- assert(VA.getLocReg() == ArgGPRs[0] && "Unexpected reg assignment" );
17494
- SDValue RetValue2 =
17495
- DAG.getCopyFromReg(Chain, DL, ArgGPRs[1], MVT::i32, Glue);
17513
+ assert(VA.needsCustom() );
17514
+ SDValue RetValue2 = DAG.getCopyFromReg(Chain, DL, RVLocs[++i].getLocReg(),
17515
+ MVT::i32, Glue);
17496
17516
Chain = RetValue2.getValue(1);
17497
17517
Glue = RetValue2.getValue(2);
17498
17518
RetValue = DAG.getNode(RISCVISD::BuildPairF64, DL, MVT::f64, RetValue,
@@ -17555,21 +17575,21 @@ RISCVTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
17555
17575
SmallVector<SDValue, 4> RetOps(1, Chain);
17556
17576
17557
17577
// Copy the result values into the output registers.
17558
- for (unsigned i = 0, e = RVLocs.size(); i < e; ++i) {
17559
- SDValue Val = OutVals[i ];
17578
+ for (unsigned i = 0, e = RVLocs.size(), OutIdx = 0 ; i < e; ++i, ++OutIdx ) {
17579
+ SDValue Val = OutVals[OutIdx ];
17560
17580
CCValAssign &VA = RVLocs[i];
17561
17581
assert(VA.isRegLoc() && "Can only return in registers!");
17562
17582
17563
17583
if (VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64) {
17564
17584
// Handle returning f64 on RV32D with a soft float ABI.
17565
17585
assert(VA.isRegLoc() && "Expected return via registers");
17586
+ assert(VA.needsCustom());
17566
17587
SDValue SplitF64 = DAG.getNode(RISCVISD::SplitF64, DL,
17567
17588
DAG.getVTList(MVT::i32, MVT::i32), Val);
17568
17589
SDValue Lo = SplitF64.getValue(0);
17569
17590
SDValue Hi = SplitF64.getValue(1);
17570
17591
Register RegLo = VA.getLocReg();
17571
- assert(RegLo < RISCV::X31 && "Invalid register pair");
17572
- Register RegHi = RegLo + 1;
17592
+ Register RegHi = RVLocs[++i].getLocReg();
17573
17593
17574
17594
if (STI.isRegisterReservedByUser(RegLo) ||
17575
17595
STI.isRegisterReservedByUser(RegHi))
0 commit comments