@@ -97,7 +97,6 @@ class RISCVAsmParser : public MCTargetAsmParser {
9797
9898 unsigned validateTargetOperandClass (MCParsedAsmOperand &Op,
9999 unsigned Kind) override ;
100- unsigned checkTargetMatchPredicate (MCInst &Inst) override ;
101100
102101 bool generateImmOutOfRangeError (OperandVector &Operands, uint64_t ErrorInfo,
103102 int64_t Lower, int64_t Upper,
@@ -209,6 +208,8 @@ class RISCVAsmParser : public MCTargetAsmParser {
209208 ParseStatus parseInsnDirectiveOpcode (OperandVector &Operands);
210209 ParseStatus parseInsnCDirectiveOpcode (OperandVector &Operands);
211210 ParseStatus parseGPRAsFPR (OperandVector &Operands);
211+ ParseStatus parseGPRAsFPR64 (OperandVector &Operands);
212+ ParseStatus parseGPRPairAsFPR64 (OperandVector &Operands);
212213 template <bool IsRV64Inst> ParseStatus parseGPRPair (OperandVector &Operands);
213214 ParseStatus parseGPRPair (OperandVector &Operands, bool IsRV64Inst);
214215 ParseStatus parseFRMArg (OperandVector &Operands);
@@ -280,7 +281,6 @@ class RISCVAsmParser : public MCTargetAsmParser {
280281public:
281282 enum RISCVMatchResultTy {
282283 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
283- Match_RequiresEvenGPRs,
284284#define GET_OPERAND_DIAGNOSTIC_TYPES
285285#include " RISCVGenAsmMatcher.inc"
286286#undef GET_OPERAND_DIAGNOSTIC_TYPES
@@ -481,6 +481,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
481481 }
482482
483483 bool isGPRAsFPR () const { return isGPR () && Reg.IsGPRAsFPR ; }
484+ bool isGPRPairAsFPR () const { return isGPRPair () && Reg.IsGPRAsFPR ; }
484485
485486 bool isGPRPair () const {
486487 return Kind == KindTy::Register &&
@@ -1341,6 +1342,16 @@ unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
13411342 Op.Reg .RegNum = convertFPR64ToFPR16 (Reg);
13421343 return Match_Success;
13431344 }
1345+
1346+ // There are some GPRF64AsFPR instructions that have no RV32 equivalent. We
1347+ // reject them at parsing thinking we should match as GPRPairAsFPR for RV32.
1348+ // So we explicitly accept them here for RV32 to allow the generic code to
1349+ // report that the instruction requires RV64.
1350+ if (RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains (Reg) &&
1351+ Kind == MCK_GPRF64AsFPR && STI->hasFeature (RISCV::FeatureStdExtZdinx) &&
1352+ !isRV64 ())
1353+ return Match_Success;
1354+
13441355 // As the parser couldn't differentiate an VRM2/VRM4/VRM8 from an VR, coerce
13451356 // the register from VR to VRM2/VRM4/VRM8 if necessary.
13461357 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
@@ -1352,27 +1363,6 @@ unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
13521363 return Match_InvalidOperand;
13531364}
13541365
1355- unsigned RISCVAsmParser::checkTargetMatchPredicate (MCInst &Inst) {
1356- const MCInstrDesc &MCID = MII.get (Inst.getOpcode ());
1357-
1358- for (unsigned I = 0 ; I < MCID.NumOperands ; ++I) {
1359- if (MCID.operands ()[I].RegClass == RISCV::GPRPairRegClassID) {
1360- const auto &Op = Inst.getOperand (I);
1361- assert (Op.isReg ());
1362-
1363- MCRegister Reg = Op.getReg ();
1364- if (RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].contains (Reg))
1365- continue ;
1366-
1367- // FIXME: We should form a paired register during parsing/matching.
1368- if (((Reg.id () - RISCV::X0) & 1 ) != 0 )
1369- return Match_RequiresEvenGPRs;
1370- }
1371- }
1372-
1373- return Match_Success;
1374- }
1375-
13761366bool RISCVAsmParser::generateImmOutOfRangeError (
13771367 SMLoc ErrorLoc, int64_t Lower, int64_t Upper,
13781368 const Twine &Msg = " immediate must be an integer in the range" ) {
@@ -1448,10 +1438,6 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
14481438 switch (Result) {
14491439 default :
14501440 break ;
1451- case Match_RequiresEvenGPRs:
1452- return Error (IDLoc,
1453- " double precision floating point operands must use even "
1454- " numbered X register" );
14551441 case Match_InvalidImmXLenLI:
14561442 if (isRV64 ()) {
14571443 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc ();
@@ -2318,6 +2304,13 @@ ParseStatus RISCVAsmParser::parseMaskReg(OperandVector &Operands) {
23182304 return ParseStatus::Success;
23192305}
23202306
2307+ ParseStatus RISCVAsmParser::parseGPRAsFPR64 (OperandVector &Operands) {
2308+ if (!isRV64 () || getSTI ().hasFeature (RISCV::FeatureStdExtF))
2309+ return ParseStatus::NoMatch;
2310+
2311+ return parseGPRAsFPR (Operands);
2312+ }
2313+
23212314ParseStatus RISCVAsmParser::parseGPRAsFPR (OperandVector &Operands) {
23222315 if (getLexer ().isNot (AsmToken::Identifier))
23232316 return ParseStatus::NoMatch;
@@ -2335,6 +2328,43 @@ ParseStatus RISCVAsmParser::parseGPRAsFPR(OperandVector &Operands) {
23352328 return ParseStatus::Success;
23362329}
23372330
2331+ ParseStatus RISCVAsmParser::parseGPRPairAsFPR64 (OperandVector &Operands) {
2332+ if (isRV64 () || getSTI ().hasFeature (RISCV::FeatureStdExtF))
2333+ return ParseStatus::NoMatch;
2334+
2335+ if (getLexer ().isNot (AsmToken::Identifier))
2336+ return ParseStatus::NoMatch;
2337+
2338+ StringRef Name = getLexer ().getTok ().getIdentifier ();
2339+ MCRegister Reg = matchRegisterNameHelper (Name);
2340+
2341+ if (!Reg)
2342+ return ParseStatus::NoMatch;
2343+
2344+ if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains (Reg))
2345+ return ParseStatus::NoMatch;
2346+
2347+ if ((Reg - RISCV::X0) & 1 ) {
2348+ // Only report the even register error if we have at least Zfinx so we know
2349+ // some FP is enabled. We already checked F earlier.
2350+ if (getSTI ().hasFeature (RISCV::FeatureStdExtZfinx))
2351+ return TokError (" double precision floating point operands must use even "
2352+ " numbered X register" );
2353+ return ParseStatus::NoMatch;
2354+ }
2355+
2356+ SMLoc S = getLoc ();
2357+ SMLoc E = SMLoc::getFromPointer (S.getPointer () + Name.size ());
2358+ getLexer ().Lex ();
2359+
2360+ const MCRegisterInfo *RI = getContext ().getRegisterInfo ();
2361+ MCRegister Pair = RI->getMatchingSuperReg (
2362+ Reg, RISCV::sub_gpr_even,
2363+ &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2364+ Operands.push_back (RISCVOperand::createReg (Pair, S, E, /* isGPRAsFPR=*/ true ));
2365+ return ParseStatus::Success;
2366+ }
2367+
23382368template <bool IsRV64>
23392369ParseStatus RISCVAsmParser::parseGPRPair (OperandVector &Operands) {
23402370 return parseGPRPair (Operands, IsRV64);
0 commit comments