@@ -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[] = {
@@ -296,6 +298,11 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
296298 setCondCodeAction(ISD::SETLE, XLenVT, Expand);
297299 }
298300
301+ if (Subtarget.isRV64())
302+ setOperationAction(ISD::BITCAST, MVT::i128, Custom);
303+ else if (Subtarget.isRV32())
304+ setOperationAction(ISD::BITCAST, MVT::i64, Custom);
305+
299306 setOperationAction({ISD::STACKSAVE, ISD::STACKRESTORE}, MVT::Other, Expand);
300307
301308 setOperationAction(ISD::VASTART, MVT::Other, Custom);
@@ -2216,6 +2223,17 @@ bool RISCVTargetLowering::isExtractSubvectorCheap(EVT ResVT, EVT SrcVT,
22162223 return Index == 0 || Index == ResElts;
22172224}
22182225
2226+ EVT RISCVTargetLowering::getAsmOperandValueType(const DataLayout &DL, Type *Ty,
2227+ bool AllowUnknown) const {
2228+ if (Subtarget.isRV32() && Ty->isIntegerTy(64))
2229+ return MVT::riscv_i32_pair;
2230+
2231+ if (Subtarget.isRV64() && Ty->isIntegerTy(128))
2232+ return MVT::riscv_i64_pair;
2233+
2234+ return TargetLowering::getAsmOperandValueType(DL, Ty, AllowUnknown);
2235+ }
2236+
22192237MVT RISCVTargetLowering::getRegisterTypeForCallingConv(LLVMContext &Context,
22202238 CallingConv::ID CC,
22212239 EVT VT) const {
@@ -6405,6 +6423,13 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
64056423 std::tie(Lo, Hi) = DAG.SplitScalar(Op0, DL, MVT::i32, MVT::i32);
64066424 return DAG.getNode(RISCVISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
64076425 }
6426+ if (VT == Subtarget.getXLenPairVT() && Op0VT.isScalarInteger() &&
6427+ Op0VT.getSizeInBits() == 2 * Subtarget.getXLen()) {
6428+ SDValue Lo, Hi;
6429+ std::tie(Lo, Hi) = DAG.SplitScalar(Op0, DL, XLenVT, XLenVT);
6430+ return DAG.getNode(RISCVISD::BuildGPRPair, DL, Subtarget.getXLenPairVT(),
6431+ Lo, Hi);
6432+ }
64086433
64096434 // Consider other scalar<->scalar casts as legal if the types are legal.
64106435 // Otherwise expand them.
@@ -12846,6 +12871,14 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
1284612871 SDValue RetReg = DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64,
1284712872 NewReg.getValue(0), NewReg.getValue(1));
1284812873 Results.push_back(RetReg);
12874+ } else if (VT.isInteger() &&
12875+ VT.getSizeInBits() == 2 * Subtarget.getXLen() &&
12876+ Op0VT == Subtarget.getXLenPairVT()) {
12877+ SDValue NewReg = DAG.getNode(RISCVISD::SplitGPRPair, DL,
12878+ DAG.getVTList(XLenVT, XLenVT), Op0);
12879+ SDValue RetReg = DAG.getNode(ISD::BUILD_PAIR, DL, VT, NewReg.getValue(0),
12880+ NewReg.getValue(1));
12881+ Results.push_back(RetReg);
1284912882 } else if (!VT.isVector() && Op0VT.isFixedLengthVector() &&
1285012883 isTypeLegal(Op0VT)) {
1285112884 // Custom-legalize bitcasts from fixed-length vector types to illegal
@@ -20090,6 +20123,8 @@ const char *RISCVTargetLowering::getTargetNodeName(unsigned Opcode) const {
2009020123 NODE_NAME_CASE(TAIL)
2009120124 NODE_NAME_CASE(SELECT_CC)
2009220125 NODE_NAME_CASE(BR_CC)
20126+ NODE_NAME_CASE(BuildGPRPair)
20127+ NODE_NAME_CASE(SplitGPRPair)
2009320128 NODE_NAME_CASE(BuildPairF64)
2009420129 NODE_NAME_CASE(SplitF64)
2009520130 NODE_NAME_CASE(ADD_LO)
@@ -20368,6 +20403,8 @@ RISCVTargetLowering::getConstraintType(StringRef Constraint) const {
2036820403 return C_RegisterClass;
2036920404 if (Constraint == "cr" || Constraint == "cf")
2037020405 return C_RegisterClass;
20406+ if (Constraint == "Pr")
20407+ return C_RegisterClass;
2037120408 }
2037220409 return TargetLowering::getConstraintType(Constraint);
2037320410}
@@ -20389,7 +20426,7 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
2038920426 if (VT == MVT::f32 && Subtarget.hasStdExtZfinx())
2039020427 return std::make_pair(0U, &RISCV::GPRF32NoX0RegClass);
2039120428 if (VT == MVT::f64 && Subtarget.hasStdExtZdinx() && !Subtarget.is64Bit())
20392- return std::make_pair(0U, &RISCV::GPRPairNoX0RegClass );
20429+ return std::make_pair(0U, &RISCV::GPRF64PairNoX0RegClass );
2039320430 return std::make_pair(0U, &RISCV::GPRNoX0RegClass);
2039420431 case 'f':
2039520432 if (VT == MVT::f16) {
@@ -20406,7 +20443,7 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
2040620443 if (Subtarget.hasStdExtD())
2040720444 return std::make_pair(0U, &RISCV::FPR64RegClass);
2040820445 if (Subtarget.hasStdExtZdinx() && !Subtarget.is64Bit())
20409- return std::make_pair(0U, &RISCV::GPRPairNoX0RegClass );
20446+ return std::make_pair(0U, &RISCV::GPRF64PairNoX0RegClass );
2041020447 if (Subtarget.hasStdExtZdinx() && Subtarget.is64Bit())
2041120448 return std::make_pair(0U, &RISCV::GPRNoX0RegClass);
2041220449 }
@@ -20448,7 +20485,7 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
2044820485 if (VT == MVT::f32 && Subtarget.hasStdExtZfinx())
2044920486 return std::make_pair(0U, &RISCV::GPRF32CRegClass);
2045020487 if (VT == MVT::f64 && Subtarget.hasStdExtZdinx() && !Subtarget.is64Bit())
20451- return std::make_pair(0U, &RISCV::GPRPairCRegClass );
20488+ return std::make_pair(0U, &RISCV::GPRF64PairCRegClass );
2045220489 if (!VT.isVector())
2045320490 return std::make_pair(0U, &RISCV::GPRCRegClass);
2045420491 } else if (Constraint == "cf") {
@@ -20466,10 +20503,12 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
2046620503 if (Subtarget.hasStdExtD())
2046720504 return std::make_pair(0U, &RISCV::FPR64CRegClass);
2046820505 if (Subtarget.hasStdExtZdinx() && !Subtarget.is64Bit())
20469- return std::make_pair(0U, &RISCV::GPRPairCRegClass );
20506+ return std::make_pair(0U, &RISCV::GPRF64PairCRegClass );
2047020507 if (Subtarget.hasStdExtZdinx() && Subtarget.is64Bit())
2047120508 return std::make_pair(0U, &RISCV::GPRCRegClass);
2047220509 }
20510+ } else if (Constraint == "Pr") {
20511+ return std::make_pair(0U, &RISCV::GPRPairNoX0RegClass);
2047320512 }
2047420513
2047520514 // Clang will correctly decode the usage of register name aliases into their
@@ -20630,7 +20669,7 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
2063020669 // Subtarget into account.
2063120670 if (Res.second == &RISCV::GPRF16RegClass ||
2063220671 Res.second == &RISCV::GPRF32RegClass ||
20633- Res.second == &RISCV::GPRPairRegClass )
20672+ Res.second == &RISCV::GPRF64PairRegClass )
2063420673 return std::make_pair(Res.first, &RISCV::GPRRegClass);
2063520674
2063620675 return Res;
0 commit comments