@@ -97,7 +97,6 @@ class RISCVAsmParser : public MCTargetAsmParser {
97
97
98
98
unsigned validateTargetOperandClass (MCParsedAsmOperand &Op,
99
99
unsigned Kind) override ;
100
- unsigned checkTargetMatchPredicate (MCInst &Inst) override ;
101
100
102
101
bool generateImmOutOfRangeError (OperandVector &Operands, uint64_t ErrorInfo,
103
102
int64_t Lower, int64_t Upper,
@@ -209,6 +208,8 @@ class RISCVAsmParser : public MCTargetAsmParser {
209
208
ParseStatus parseInsnDirectiveOpcode (OperandVector &Operands);
210
209
ParseStatus parseInsnCDirectiveOpcode (OperandVector &Operands);
211
210
ParseStatus parseGPRAsFPR (OperandVector &Operands);
211
+ ParseStatus parseGPRAsFPR64 (OperandVector &Operands);
212
+ ParseStatus parseGPRPairAsFPR64 (OperandVector &Operands);
212
213
template <bool IsRV64Inst> ParseStatus parseGPRPair (OperandVector &Operands);
213
214
ParseStatus parseGPRPair (OperandVector &Operands, bool IsRV64Inst);
214
215
ParseStatus parseFRMArg (OperandVector &Operands);
@@ -280,7 +281,6 @@ class RISCVAsmParser : public MCTargetAsmParser {
280
281
public:
281
282
enum RISCVMatchResultTy {
282
283
Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
283
- Match_RequiresEvenGPRs,
284
284
#define GET_OPERAND_DIAGNOSTIC_TYPES
285
285
#include " RISCVGenAsmMatcher.inc"
286
286
#undef GET_OPERAND_DIAGNOSTIC_TYPES
@@ -481,6 +481,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
481
481
}
482
482
483
483
bool isGPRAsFPR () const { return isGPR () && Reg.IsGPRAsFPR ; }
484
+ bool isGPRPairAsFPR () const { return isGPRPair () && Reg.IsGPRAsFPR ; }
484
485
485
486
bool isGPRPair () const {
486
487
return Kind == KindTy::Register &&
@@ -1341,6 +1342,16 @@ unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
1341
1342
Op.Reg .RegNum = convertFPR64ToFPR16 (Reg);
1342
1343
return Match_Success;
1343
1344
}
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
+
1344
1355
// As the parser couldn't differentiate an VRM2/VRM4/VRM8 from an VR, coerce
1345
1356
// the register from VR to VRM2/VRM4/VRM8 if necessary.
1346
1357
if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
@@ -1352,27 +1363,6 @@ unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
1352
1363
return Match_InvalidOperand;
1353
1364
}
1354
1365
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
-
1376
1366
bool RISCVAsmParser::generateImmOutOfRangeError (
1377
1367
SMLoc ErrorLoc, int64_t Lower, int64_t Upper,
1378
1368
const Twine &Msg = " immediate must be an integer in the range" ) {
@@ -1448,10 +1438,6 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1448
1438
switch (Result) {
1449
1439
default :
1450
1440
break ;
1451
- case Match_RequiresEvenGPRs:
1452
- return Error (IDLoc,
1453
- " double precision floating point operands must use even "
1454
- " numbered X register" );
1455
1441
case Match_InvalidImmXLenLI:
1456
1442
if (isRV64 ()) {
1457
1443
SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc ();
@@ -2318,6 +2304,13 @@ ParseStatus RISCVAsmParser::parseMaskReg(OperandVector &Operands) {
2318
2304
return ParseStatus::Success;
2319
2305
}
2320
2306
2307
+ ParseStatus RISCVAsmParser::parseGPRAsFPR64 (OperandVector &Operands) {
2308
+ if (!isRV64 () || getSTI ().hasFeature (RISCV::FeatureStdExtF))
2309
+ return ParseStatus::NoMatch;
2310
+
2311
+ return parseGPRAsFPR (Operands);
2312
+ }
2313
+
2321
2314
ParseStatus RISCVAsmParser::parseGPRAsFPR (OperandVector &Operands) {
2322
2315
if (getLexer ().isNot (AsmToken::Identifier))
2323
2316
return ParseStatus::NoMatch;
@@ -2335,6 +2328,43 @@ ParseStatus RISCVAsmParser::parseGPRAsFPR(OperandVector &Operands) {
2335
2328
return ParseStatus::Success;
2336
2329
}
2337
2330
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
+
2338
2368
template <bool IsRV64>
2339
2369
ParseStatus RISCVAsmParser::parseGPRPair (OperandVector &Operands) {
2340
2370
return parseGPRPair (Operands, IsRV64);
0 commit comments