@@ -8426,6 +8426,10 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
84268426 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Lo.getValue(1),
84278427 Hi.getValue(1));
84288428
8429+ // For big-endian, swap the order of Lo and Hi.
8430+ if (!Subtarget.isLittleEndian())
8431+ std::swap(Lo, Hi);
8432+
84298433 SDValue Pair = DAG.getNode(RISCVISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
84308434 return DAG.getMergeValues({Pair, Chain}, DL);
84318435 }
@@ -8498,15 +8502,21 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
84988502 SDValue Split = DAG.getNode(RISCVISD::SplitF64, DL,
84998503 DAG.getVTList(MVT::i32, MVT::i32), StoredVal);
85008504
8501- SDValue Lo = DAG.getStore(Chain, DL, Split.getValue(0), BasePtr,
8502- Store->getPointerInfo(), Store->getBaseAlign(),
8503- Store->getMemOperand()->getFlags());
8505+ SDValue Lo = Split.getValue(0);
8506+ SDValue Hi = Split.getValue(1);
8507+
8508+ // For big-endian, swap the order of Lo and Hi before storing.
8509+ if (!Subtarget.isLittleEndian())
8510+ std::swap(Lo, Hi);
8511+
8512+ SDValue LoStore = DAG.getStore(
8513+ Chain, DL, Lo, BasePtr, Store->getPointerInfo(),
8514+ Store->getBaseAlign(), Store->getMemOperand()->getFlags());
85048515 BasePtr = DAG.getObjectPtrOffset(DL, BasePtr, TypeSize::getFixed(4));
8505- SDValue Hi = DAG.getStore(Chain, DL, Split.getValue(1), BasePtr,
8506- Store->getPointerInfo().getWithOffset(4),
8507- Store->getBaseAlign(),
8508- Store->getMemOperand()->getFlags());
8509- return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Lo, Hi);
8516+ SDValue HiStore = DAG.getStore(
8517+ Chain, DL, Hi, BasePtr, Store->getPointerInfo().getWithOffset(4),
8518+ Store->getBaseAlign(), Store->getMemOperand()->getFlags());
8519+ return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, LoStore, HiStore);
85108520 }
85118521 if (VT == MVT::i64) {
85128522 assert(Subtarget.hasStdExtZilsd() && !Subtarget.is64Bit() &&
@@ -15231,8 +15241,12 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
1523115241 Subtarget.hasStdExtDOrZdinx()) {
1523215242 SDValue NewReg = DAG.getNode(RISCVISD::SplitF64, DL,
1523315243 DAG.getVTList(MVT::i32, MVT::i32), Op0);
15234- SDValue RetReg = DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64,
15235- NewReg.getValue(0), NewReg.getValue(1));
15244+ SDValue Lo = NewReg.getValue(0);
15245+ SDValue Hi = NewReg.getValue(1);
15246+ // For big-endian, swap the order when building the i64 pair.
15247+ if (!Subtarget.isLittleEndian())
15248+ std::swap(Lo, Hi);
15249+ SDValue RetReg = DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Lo, Hi);
1523615250 Results.push_back(RetReg);
1523715251 } else if (!VT.isVector() && Op0VT.isFixedLengthVector() &&
1523815252 isTypeLegal(Op0VT)) {
@@ -22676,6 +22690,11 @@ static MachineBasicBlock *emitSplitF64Pseudo(MachineInstr &MI,
2267622690 MF.getMachineMemOperand(MPI, MachineMemOperand::MOLoad, 4, Align(8));
2267722691 MachineMemOperand *MMOHi = MF.getMachineMemOperand(
2267822692 MPI.getWithOffset(4), MachineMemOperand::MOLoad, 4, Align(8));
22693+
22694+ // For big-endian, the high part is at offset 0 and the low part at offset 4.
22695+ if (!Subtarget.isLittleEndian())
22696+ std::swap(LoReg, HiReg);
22697+
2267922698 BuildMI(*BB, MI, DL, TII.get(RISCV::LW), LoReg)
2268022699 .addFrameIndex(FI)
2268122700 .addImm(0)
@@ -22700,6 +22719,8 @@ static MachineBasicBlock *emitBuildPairF64Pseudo(MachineInstr &MI,
2270022719 Register DstReg = MI.getOperand(0).getReg();
2270122720 Register LoReg = MI.getOperand(1).getReg();
2270222721 Register HiReg = MI.getOperand(2).getReg();
22722+ bool KillLo = MI.getOperand(1).isKill();
22723+ bool KillHi = MI.getOperand(2).isKill();
2270322724
2270422725 const TargetRegisterClass *DstRC = &RISCV::FPR64RegClass;
2270522726 int FI = MF.getInfo<RISCVMachineFunctionInfo>()->getMoveF64FrameIndex(MF);
@@ -22709,13 +22730,21 @@ static MachineBasicBlock *emitBuildPairF64Pseudo(MachineInstr &MI,
2270922730 MF.getMachineMemOperand(MPI, MachineMemOperand::MOStore, 4, Align(8));
2271022731 MachineMemOperand *MMOHi = MF.getMachineMemOperand(
2271122732 MPI.getWithOffset(4), MachineMemOperand::MOStore, 4, Align(8));
22733+
22734+ // For big-endian, store the high part at offset 0 and the low part at
22735+ // offset 4.
22736+ if (!Subtarget.isLittleEndian()) {
22737+ std::swap(LoReg, HiReg);
22738+ std::swap(KillLo, KillHi);
22739+ }
22740+
2271222741 BuildMI(*BB, MI, DL, TII.get(RISCV::SW))
22713- .addReg(LoReg, getKillRegState(MI.getOperand(1).isKill() ))
22742+ .addReg(LoReg, getKillRegState(KillLo ))
2271422743 .addFrameIndex(FI)
2271522744 .addImm(0)
2271622745 .addMemOperand(MMOLo);
2271722746 BuildMI(*BB, MI, DL, TII.get(RISCV::SW))
22718- .addReg(HiReg, getKillRegState(MI.getOperand(2).isKill() ))
22747+ .addReg(HiReg, getKillRegState(KillHi ))
2271922748 .addFrameIndex(FI)
2272022749 .addImm(4)
2272122750 .addMemOperand(MMOHi);
@@ -23545,6 +23574,12 @@ static SDValue unpackF64OnRV32DSoftABI(SelectionDAG &DAG, SDValue Chain,
2354523574 RegInfo.addLiveIn(HiVA.getLocReg(), HiVReg);
2354623575 Hi = DAG.getCopyFromReg(Chain, DL, HiVReg, MVT::i32);
2354723576 }
23577+
23578+ // For big-endian, swap the order of Lo and Hi when building the pair.
23579+ const RISCVSubtarget &Subtarget = DAG.getSubtarget<RISCVSubtarget>();
23580+ if (!Subtarget.isLittleEndian())
23581+ std::swap(Lo, Hi);
23582+
2354823583 return DAG.getNode(RISCVISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
2354923584}
2355023585
@@ -23916,6 +23951,10 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
2391623951 SDValue Lo = SplitF64.getValue(0);
2391723952 SDValue Hi = SplitF64.getValue(1);
2391823953
23954+ // For big-endian, swap the order of Lo and Hi when passing.
23955+ if (!Subtarget.isLittleEndian())
23956+ std::swap(Lo, Hi);
23957+
2391923958 Register RegLo = VA.getLocReg();
2392023959 RegsToPass.push_back(std::make_pair(RegLo, Lo));
2392123960
@@ -24143,8 +24182,14 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
2414324182 MVT::i32, Glue);
2414424183 Chain = RetValue2.getValue(1);
2414524184 Glue = RetValue2.getValue(2);
24146- RetValue = DAG.getNode(RISCVISD::BuildPairF64, DL, MVT::f64, RetValue,
24147- RetValue2);
24185+
24186+ // For big-endian, swap the order when building the pair.
24187+ SDValue Lo = RetValue;
24188+ SDValue Hi = RetValue2;
24189+ if (!Subtarget.isLittleEndian())
24190+ std::swap(Lo, Hi);
24191+
24192+ RetValue = DAG.getNode(RISCVISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
2414824193 } else
2414924194 RetValue = convertLocVTToValVT(DAG, RetValue, VA, DL, Subtarget);
2415024195
@@ -24209,6 +24254,11 @@ RISCVTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
2420924254 DAG.getVTList(MVT::i32, MVT::i32), Val);
2421024255 SDValue Lo = SplitF64.getValue(0);
2421124256 SDValue Hi = SplitF64.getValue(1);
24257+
24258+ // For big-endian, swap the order of Lo and Hi when returning.
24259+ if (!Subtarget.isLittleEndian())
24260+ std::swap(Lo, Hi);
24261+
2421224262 Register RegLo = VA.getLocReg();
2421324263 Register RegHi = RVLocs[++i].getLocReg();
2421424264
0 commit comments