@@ -114,9 +114,11 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
114114 }
115115
116116 MVT XLenVT = Subtarget.getXLenVT();
117+ MVT XLenPairVT = Subtarget.getXLenPairVT();
117118
118119 // Set up the register classes.
119120 addRegisterClass(XLenVT, &RISCV::GPRRegClass);
121+ addRegisterClass(XLenPairVT, &RISCV::GPRPairRegClass);
120122
121123 if (Subtarget.hasStdExtZfhmin())
122124 addRegisterClass(MVT::f16, &RISCV::FPR16RegClass);
@@ -134,7 +136,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
134136 if (Subtarget.is64Bit())
135137 addRegisterClass(MVT::f64, &RISCV::GPRRegClass);
136138 else
137- addRegisterClass(MVT::f64, &RISCV::GPRPairRegClass );
139+ addRegisterClass(MVT::f64, &RISCV::GPRF64PairRegClass );
138140 }
139141
140142 static const MVT::SimpleValueType BoolVecVTs[] = {
@@ -2216,6 +2218,17 @@ bool RISCVTargetLowering::isExtractSubvectorCheap(EVT ResVT, EVT SrcVT,
22162218 return Index == 0 || Index == ResElts;
22172219}
22182220
2221+ EVT RISCVTargetLowering::getAsmOperandValueType(const DataLayout &DL, Type *Ty,
2222+ bool AllowUnknown) const {
2223+ if (Subtarget.isRV32() && Ty->isIntegerTy(64))
2224+ return MVT::riscv_i32_pair;
2225+
2226+ if (Subtarget.isRV64() && Ty->isIntegerTy(128))
2227+ return MVT::riscv_i64_pair;
2228+
2229+ return TargetLowering::getAsmOperandValueType(DL, Ty, AllowUnknown);
2230+ }
2231+
22192232MVT RISCVTargetLowering::getRegisterTypeForCallingConv(LLVMContext &Context,
22202233 CallingConv::ID CC,
22212234 EVT VT) const {
@@ -20087,11 +20100,13 @@ const char *RISCVTargetLowering::getTargetNodeName(unsigned Opcode) const {
2008720100 NODE_NAME_CASE(SRET_GLUE)
2008820101 NODE_NAME_CASE(MRET_GLUE)
2008920102 NODE_NAME_CASE(CALL)
20103+ NODE_NAME_CASE(TAIL)
2009020104 NODE_NAME_CASE(SELECT_CC)
2009120105 NODE_NAME_CASE(BR_CC)
20106+ NODE_NAME_CASE(BuildXLenPair)
20107+ NODE_NAME_CASE(SplitXLenPair)
2009220108 NODE_NAME_CASE(BuildPairF64)
2009320109 NODE_NAME_CASE(SplitF64)
20094- NODE_NAME_CASE(TAIL)
2009520110 NODE_NAME_CASE(ADD_LO)
2009620111 NODE_NAME_CASE(HI)
2009720112 NODE_NAME_CASE(LLA)
@@ -20368,6 +20383,8 @@ RISCVTargetLowering::getConstraintType(StringRef Constraint) const {
2036820383 return C_RegisterClass;
2036920384 if (Constraint == "cr" || Constraint == "cf")
2037020385 return C_RegisterClass;
20386+ if (Constraint == "Pr")
20387+ return C_RegisterClass;
2037120388 }
2037220389 return TargetLowering::getConstraintType(Constraint);
2037320390}
@@ -20389,7 +20406,7 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
2038920406 if (VT == MVT::f32 && Subtarget.hasStdExtZfinx())
2039020407 return std::make_pair(0U, &RISCV::GPRF32NoX0RegClass);
2039120408 if (VT == MVT::f64 && Subtarget.hasStdExtZdinx() && !Subtarget.is64Bit())
20392- return std::make_pair(0U, &RISCV::GPRPairNoX0RegClass );
20409+ return std::make_pair(0U, &RISCV::GPRF64PairNoX0RegClass );
2039320410 return std::make_pair(0U, &RISCV::GPRNoX0RegClass);
2039420411 case 'f':
2039520412 if (VT == MVT::f16) {
@@ -20406,7 +20423,7 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
2040620423 if (Subtarget.hasStdExtD())
2040720424 return std::make_pair(0U, &RISCV::FPR64RegClass);
2040820425 if (Subtarget.hasStdExtZdinx() && !Subtarget.is64Bit())
20409- return std::make_pair(0U, &RISCV::GPRPairNoX0RegClass );
20426+ return std::make_pair(0U, &RISCV::GPRF64PairNoX0RegClass );
2041020427 if (Subtarget.hasStdExtZdinx() && Subtarget.is64Bit())
2041120428 return std::make_pair(0U, &RISCV::GPRNoX0RegClass);
2041220429 }
@@ -20448,7 +20465,7 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
2044820465 if (VT == MVT::f32 && Subtarget.hasStdExtZfinx())
2044920466 return std::make_pair(0U, &RISCV::GPRF32CRegClass);
2045020467 if (VT == MVT::f64 && Subtarget.hasStdExtZdinx() && !Subtarget.is64Bit())
20451- return std::make_pair(0U, &RISCV::GPRPairCRegClass );
20468+ return std::make_pair(0U, &RISCV::GPRF64PairCRegClass );
2045220469 if (!VT.isVector())
2045320470 return std::make_pair(0U, &RISCV::GPRCRegClass);
2045420471 } else if (Constraint == "cf") {
@@ -20466,10 +20483,12 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
2046620483 if (Subtarget.hasStdExtD())
2046720484 return std::make_pair(0U, &RISCV::FPR64CRegClass);
2046820485 if (Subtarget.hasStdExtZdinx() && !Subtarget.is64Bit())
20469- return std::make_pair(0U, &RISCV::GPRPairCRegClass );
20486+ return std::make_pair(0U, &RISCV::GPRF64PairCRegClass );
2047020487 if (Subtarget.hasStdExtZdinx() && Subtarget.is64Bit())
2047120488 return std::make_pair(0U, &RISCV::GPRCRegClass);
2047220489 }
20490+ } else if (Constraint == "Pr") {
20491+ return std::make_pair(0U, &RISCV::GPRPairNoX0RegClass);
2047320492 }
2047420493
2047520494 // Clang will correctly decode the usage of register name aliases into their
@@ -20630,7 +20649,7 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
2063020649 // Subtarget into account.
2063120650 if (Res.second == &RISCV::GPRF16RegClass ||
2063220651 Res.second == &RISCV::GPRF32RegClass ||
20633- Res.second == &RISCV::GPRPairRegClass )
20652+ Res.second == &RISCV::GPRF64PairRegClass )
2063420653 return std::make_pair(Res.first, &RISCV::GPRRegClass);
2063520654
2063620655 return Res;
@@ -21269,6 +21288,24 @@ bool RISCVTargetLowering::splitValueIntoRegisterParts(
2126921288 return true;
2127021289 }
2127121290
21291+ if (NumParts == 1 && ValueVT == MVT::i128 && PartVT == MVT::riscv_i64_pair) {
21292+ // Used on inputs *to* inline assembly.
21293+ SDValue Lo, Hi;
21294+ std::tie(Lo, Hi) = DAG.SplitScalar(Val, DL, MVT::i64, MVT::i64);
21295+ Parts[0] = DAG.getNode(RISCVISD::BuildXLenPair, DL, PartVT, Lo, Hi);
21296+ return true;
21297+ }
21298+
21299+ if (NumParts == 1 && ValueVT == MVT::i64 && PartVT == MVT::riscv_i32_pair) {
21300+ // Used on inputs *to* inline assembly.
21301+ SDValue Lo, Hi;
21302+ std::tie(Lo, Hi) = DAG.SplitScalar(Val, DL, MVT::i32, MVT::i32);
21303+ Parts[0] = DAG.getNode(RISCVISD::BuildXLenPair, DL, PartVT, Lo, Hi);
21304+ return true;
21305+ }
21306+
21307+ // || (ValueVT == MVT::i64 && PartVT == MVT::riscv_i32_pair)
21308+
2127221309 if (ValueVT.isScalableVector() && PartVT.isScalableVector()) {
2127321310 LLVMContext &Context = *DAG.getContext();
2127421311 EVT ValueEltVT = ValueVT.getVectorElementType();
@@ -21338,6 +21375,16 @@ SDValue RISCVTargetLowering::joinRegisterPartsIntoValue(
2133821375 return Val;
2133921376 }
2134021377
21378+ // if (/*ValueVT == MVT::riscv_i64_pair &&*/ PartVT == MVT::riscv_i64_pair) {
21379+ // // Used on outputs *from* inline assembly.
21380+ // SDValue Val = Parts[0];
21381+ // SDValue Pair = DAG.getNode(RISCVISD::SplitXLenPair, DL, {MVT::i64,
21382+ // MVT::i64}, Val); return DAG.getNode(ISD::BUILD_PAIR, DL, ValueVT,
21383+ // Pair.getValue(0), Pair.getValue(1));
21384+ // }
21385+
21386+ // (PartVT == MVT::i64 && ValueVT == MVT::riscv_i32_pair)
21387+
2134121388 if (ValueVT.isScalableVector() && PartVT.isScalableVector()) {
2134221389 LLVMContext &Context = *DAG.getContext();
2134321390 SDValue Val = Parts[0];
0 commit comments