@@ -199,6 +199,8 @@ class RISCVAsmParser : public MCTargetAsmParser {
199
199
ParseStatus parseInsnDirectiveOpcode (OperandVector &Operands);
200
200
ParseStatus parseInsnCDirectiveOpcode (OperandVector &Operands);
201
201
ParseStatus parseGPRAsFPR (OperandVector &Operands);
202
+ template <bool IsRV64Inst> ParseStatus parseGPRPair (OperandVector &Operands);
203
+ ParseStatus parseGPRPair (OperandVector &Operands, bool IsRV64Inst);
202
204
ParseStatus parseFRMArg (OperandVector &Operands);
203
205
ParseStatus parseFenceArg (OperandVector &Operands);
204
206
ParseStatus parseReglist (OperandVector &Operands);
@@ -466,6 +468,12 @@ struct RISCVOperand final : public MCParsedAsmOperand {
466
468
467
469
bool isGPRAsFPR () const { return isGPR () && Reg.IsGPRAsFPR ; }
468
470
471
+ bool isGPRPair () const {
472
+ return Kind == KindTy::Register &&
473
+ RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].contains (
474
+ Reg.RegNum );
475
+ }
476
+
469
477
static bool evaluateConstantImm (const MCExpr *Expr, int64_t &Imm,
470
478
RISCVMCExpr::VariantKind &VK) {
471
479
if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) {
@@ -1300,6 +1308,10 @@ unsigned RISCVAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1300
1308
assert (Op.isReg ());
1301
1309
1302
1310
MCRegister Reg = Op.getReg ();
1311
+ if (RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].contains (Reg))
1312
+ continue ;
1313
+
1314
+ // FIXME: We should form a paired register during parsing/matching.
1303
1315
if (((Reg.id () - RISCV::X0) & 1 ) != 0 )
1304
1316
return Match_RequiresEvenGPRs;
1305
1317
}
@@ -2222,6 +2234,48 @@ ParseStatus RISCVAsmParser::parseGPRAsFPR(OperandVector &Operands) {
2222
2234
return ParseStatus::Success;
2223
2235
}
2224
2236
2237
+ template <bool IsRV64>
2238
+ ParseStatus RISCVAsmParser::parseGPRPair (OperandVector &Operands) {
2239
+ return parseGPRPair (Operands, IsRV64);
2240
+ }
2241
+
2242
+ ParseStatus RISCVAsmParser::parseGPRPair (OperandVector &Operands,
2243
+ bool IsRV64Inst) {
2244
+ // If this is not an RV64 GPRPair instruction, don't parse as a GPRPair on
2245
+ // RV64 as it will prevent matching the RV64 version of the same instruction
2246
+ // that doesn't use a GPRPair.
2247
+ // If this is an RV64 GPRPair instruction, there is no RV32 version so we can
2248
+ // still parse as a pair.
2249
+ if (!IsRV64Inst && isRV64 ())
2250
+ return ParseStatus::NoMatch;
2251
+
2252
+ if (getLexer ().isNot (AsmToken::Identifier))
2253
+ return ParseStatus::NoMatch;
2254
+
2255
+ StringRef Name = getLexer ().getTok ().getIdentifier ();
2256
+ MCRegister RegNo = matchRegisterNameHelper (isRVE (), Name);
2257
+
2258
+ if (!RegNo)
2259
+ return ParseStatus::NoMatch;
2260
+
2261
+ if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains (RegNo))
2262
+ return ParseStatus::NoMatch;
2263
+
2264
+ if ((RegNo - RISCV::X0) & 1 )
2265
+ return TokError (" register must be even" );
2266
+
2267
+ SMLoc S = getLoc ();
2268
+ SMLoc E = SMLoc::getFromPointer (S.getPointer () + Name.size ());
2269
+ getLexer ().Lex ();
2270
+
2271
+ const MCRegisterInfo *RI = getContext ().getRegisterInfo ();
2272
+ unsigned Pair = RI->getMatchingSuperReg (
2273
+ RegNo, RISCV::sub_gpr_even,
2274
+ &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2275
+ Operands.push_back (RISCVOperand::createReg (Pair, S, E));
2276
+ return ParseStatus::Success;
2277
+ }
2278
+
2225
2279
ParseStatus RISCVAsmParser::parseFRMArg (OperandVector &Operands) {
2226
2280
if (getLexer ().isNot (AsmToken::Identifier))
2227
2281
return TokError (
@@ -3335,27 +3389,6 @@ bool RISCVAsmParser::validateInstruction(MCInst &Inst,
3335
3389
return Error (Loc, " Operand must be constant 4." );
3336
3390
}
3337
3391
3338
- bool IsAMOCAS_D = Opcode == RISCV::AMOCAS_D || Opcode == RISCV::AMOCAS_D_AQ ||
3339
- Opcode == RISCV::AMOCAS_D_RL ||
3340
- Opcode == RISCV::AMOCAS_D_AQ_RL;
3341
- bool IsAMOCAS_Q = Opcode == RISCV::AMOCAS_Q || Opcode == RISCV::AMOCAS_Q_AQ ||
3342
- Opcode == RISCV::AMOCAS_Q_RL ||
3343
- Opcode == RISCV::AMOCAS_Q_AQ_RL;
3344
- if ((!isRV64 () && IsAMOCAS_D) || IsAMOCAS_Q) {
3345
- unsigned Rd = Inst.getOperand (0 ).getReg ();
3346
- unsigned Rs2 = Inst.getOperand (2 ).getReg ();
3347
- assert (Rd >= RISCV::X0 && Rd <= RISCV::X31);
3348
- if ((Rd - RISCV::X0) % 2 != 0 ) {
3349
- SMLoc Loc = Operands[1 ]->getStartLoc ();
3350
- return Error (Loc, " The destination register must be even." );
3351
- }
3352
- assert (Rs2 >= RISCV::X0 && Rs2 <= RISCV::X31);
3353
- if ((Rs2 - RISCV::X0) % 2 != 0 ) {
3354
- SMLoc Loc = Operands[2 ]->getStartLoc ();
3355
- return Error (Loc, " The source register must be even." );
3356
- }
3357
- }
3358
-
3359
3392
const MCInstrDesc &MCID = MII.get (Opcode);
3360
3393
if (!(MCID.TSFlags & RISCVII::ConstraintMask))
3361
3394
return false ;
0 commit comments