@@ -183,6 +183,9 @@ class RISCVAsmParser : public MCTargetAsmParser {
183
183
OperandMatchResultTy parseGPRAsFPR (OperandVector &Operands);
184
184
OperandMatchResultTy parseFRMArg (OperandVector &Operands);
185
185
OperandMatchResultTy parseFenceArg (OperandVector &Operands);
186
+ OperandMatchResultTy parseReglist (OperandVector &Operands);
187
+ OperandMatchResultTy parseRetval (OperandVector &Operands);
188
+ OperandMatchResultTy parseZcmpSpimm (OperandVector &Operands);
186
189
187
190
bool parseOperand (OperandVector &Operands, StringRef Mnemonic);
188
191
@@ -293,6 +296,8 @@ struct RISCVOperand final : public MCParsedAsmOperand {
293
296
VType,
294
297
FRM,
295
298
Fence,
299
+ Rlist,
300
+ Spimm,
296
301
} Kind;
297
302
298
303
struct RegOp {
@@ -329,6 +334,14 @@ struct RISCVOperand final : public MCParsedAsmOperand {
329
334
unsigned Val;
330
335
};
331
336
337
+ struct RlistOp {
338
+ unsigned Val;
339
+ };
340
+
341
+ struct SpimmOp {
342
+ unsigned Val;
343
+ };
344
+
332
345
SMLoc StartLoc, EndLoc;
333
346
union {
334
347
StringRef Tok;
@@ -339,6 +352,8 @@ struct RISCVOperand final : public MCParsedAsmOperand {
339
352
struct VTypeOp VType;
340
353
struct FRMOp FRM;
341
354
struct FenceOp Fence;
355
+ struct RlistOp Rlist;
356
+ struct SpimmOp Spimm;
342
357
};
343
358
344
359
RISCVOperand (KindTy K) : Kind(K) {}
@@ -373,6 +388,12 @@ struct RISCVOperand final : public MCParsedAsmOperand {
373
388
case KindTy::Fence:
374
389
Fence = o.Fence ;
375
390
break ;
391
+ case KindTy::Rlist:
392
+ Rlist = o.Rlist ;
393
+ break ;
394
+ case KindTy::Spimm:
395
+ Spimm = o.Spimm ;
396
+ break ;
376
397
}
377
398
}
378
399
@@ -397,6 +418,8 @@ struct RISCVOperand final : public MCParsedAsmOperand {
397
418
bool isImm () const override { return Kind == KindTy::Immediate; }
398
419
bool isMem () const override { return false ; }
399
420
bool isSystemRegister () const { return Kind == KindTy::SystemRegister; }
421
+ bool isRlist () const { return Kind == KindTy::Rlist; }
422
+ bool isSpimm () const { return Kind == KindTy::Spimm; }
400
423
401
424
bool isGPR () const {
402
425
return Kind == KindTy::Register &&
@@ -949,6 +972,16 @@ struct RISCVOperand final : public MCParsedAsmOperand {
949
972
OS << getFence ();
950
973
OS << ' >' ;
951
974
break ;
975
+ case KindTy::Rlist:
976
+ OS << " <rlist: " ;
977
+ RISCVZC::printRlist (Rlist.Val , OS);
978
+ OS << ' >' ;
979
+ break ;
980
+ case KindTy::Spimm:
981
+ OS << " <Spimm: " ;
982
+ RISCVZC::printSpimm (Spimm.Val , OS);
983
+ OS << ' >' ;
984
+ break ;
952
985
}
953
986
}
954
987
@@ -1024,6 +1057,21 @@ struct RISCVOperand final : public MCParsedAsmOperand {
1024
1057
return Op;
1025
1058
}
1026
1059
1060
+ static std::unique_ptr<RISCVOperand> createRlist (unsigned RlistEncode,
1061
+ SMLoc S) {
1062
+ auto Op = std::make_unique<RISCVOperand>(KindTy::Rlist);
1063
+ Op->Rlist .Val = RlistEncode;
1064
+ Op->StartLoc = S;
1065
+ return Op;
1066
+ }
1067
+
1068
+ static std::unique_ptr<RISCVOperand> createSpimm (unsigned Spimm, SMLoc S) {
1069
+ auto Op = std::make_unique<RISCVOperand>(KindTy::Spimm);
1070
+ Op->Spimm .Val = Spimm;
1071
+ Op->StartLoc = S;
1072
+ return Op;
1073
+ }
1074
+
1027
1075
static void addExpr (MCInst &Inst, const MCExpr *Expr, bool IsRV64Imm) {
1028
1076
assert (Expr && " Expr shouldn't be null!" );
1029
1077
int64_t Imm = 0 ;
@@ -1087,6 +1135,16 @@ struct RISCVOperand final : public MCParsedAsmOperand {
1087
1135
Inst.addOperand (MCOperand::createImm (Imm));
1088
1136
}
1089
1137
1138
+ void addRlistOperands (MCInst &Inst, unsigned N) const {
1139
+ assert (N == 1 && " Invalid number of operands!" );
1140
+ Inst.addOperand (MCOperand::createImm (Rlist.Val ));
1141
+ }
1142
+
1143
+ void addSpimmOperands (MCInst &Inst, unsigned N) const {
1144
+ assert (N == 1 && " Invalid number of operands!" );
1145
+ Inst.addOperand (MCOperand::createImm (Spimm.Val ));
1146
+ }
1147
+
1090
1148
void addFRMArgOperands (MCInst &Inst, unsigned N) const {
1091
1149
assert (N == 1 && " Invalid number of operands!" );
1092
1150
Inst.addOperand (MCOperand::createImm (getFRM ()));
@@ -1422,6 +1480,19 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1422
1480
(1 << 4 ),
1423
1481
" immediate must be in the range" );
1424
1482
}
1483
+ case Match_InvalidRlist: {
1484
+ SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc ();
1485
+ return Error (
1486
+ ErrorLoc,
1487
+ " operand must be {ra [, s0[-sN]]} or {x1 [, x8[-x9][, x18[-xN]]]}" );
1488
+ }
1489
+ case Match_InvalidSpimm: {
1490
+ SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc ();
1491
+ return Error (
1492
+ ErrorLoc,
1493
+ " stack adjustment is invalid for this instruction and register list; "
1494
+ " refer to Zc spec for a detailed range of stack adjustment" );
1495
+ }
1425
1496
case Match_InvalidRnumArg: {
1426
1497
return generateImmOutOfRangeError (Operands, ErrorInfo, 0 , 10 );
1427
1498
}
@@ -2243,6 +2314,147 @@ RISCVAsmParser::parseZeroOffsetMemOp(OperandVector &Operands) {
2243
2314
return MatchOperand_Success;
2244
2315
}
2245
2316
2317
+ OperandMatchResultTy RISCVAsmParser::parseReglist (OperandVector &Operands) {
2318
+ // Rlist: {ra [, s0[-sN]]}
2319
+ // XRlist: {x1 [, x8[-x9][, x18[-xN]]]}
2320
+ SMLoc S = getLoc ();
2321
+ if (getLexer ().isNot (AsmToken::LCurly)) {
2322
+ Error (getLoc (), " register list must start with '{'" );
2323
+ return MatchOperand_ParseFail;
2324
+ }
2325
+ getLexer ().Lex (); // eat '{'
2326
+ bool IsEABI = isRVE ();
2327
+
2328
+ MCRegister RegStart = RISCV::NoRegister;
2329
+ MCRegister RegEnd = RISCV::NoRegister;
2330
+ StringRef RegName = getLexer ().getTok ().getIdentifier ();
2331
+ matchRegisterNameHelper (IsEABI, RegStart, RegName);
2332
+ if (RegStart != RISCV::X1) {
2333
+ Error (getLoc (), " register list must start from 'ra' or 'x1'" );
2334
+ return MatchOperand_ParseFail;
2335
+ }
2336
+ getLexer ().Lex ();
2337
+
2338
+ // parse case like ,s0
2339
+ if (getLexer ().is (AsmToken::Comma)) {
2340
+ getLexer ().Lex ();
2341
+ if (getLexer ().isNot (AsmToken::Identifier)) {
2342
+ Error (getLoc (), " invalid register" );
2343
+ return MatchOperand_ParseFail;
2344
+ }
2345
+ StringRef RegName = getLexer ().getTok ().getIdentifier ();
2346
+ if (matchRegisterNameHelper (IsEABI, RegStart, RegName)) {
2347
+ Error (getLoc (), " invalid register" );
2348
+ return MatchOperand_ParseFail;
2349
+ }
2350
+ if (RegStart != RISCV::X8) {
2351
+ Error (getLoc (), " continuous register list must start from 's0' or 'x8'" );
2352
+ return MatchOperand_ParseFail;
2353
+ }
2354
+ getLexer ().Lex (); // eat reg
2355
+ }
2356
+
2357
+ // parse case like -s1
2358
+ if (getLexer ().is (AsmToken::Minus)) {
2359
+ getLexer ().Lex ();
2360
+ StringRef EndName = getLexer ().getTok ().getIdentifier ();
2361
+ // FIXME: the register mapping and checks of EABI is wrong
2362
+ if (matchRegisterNameHelper (IsEABI, RegEnd, EndName)) {
2363
+ Error (getLoc (), " invalid register" );
2364
+ return MatchOperand_ParseFail;
2365
+ }
2366
+ if (IsEABI && RegEnd != RISCV::X9) {
2367
+ Error (getLoc (), " contiguous register list of EABI can only be 's0-s1' or "
2368
+ " 'x8-x9' pair" );
2369
+ return MatchOperand_ParseFail;
2370
+ }
2371
+ getLexer ().Lex ();
2372
+ }
2373
+
2374
+ if (!IsEABI) {
2375
+ // parse extra part like ', x18[-x20]' for XRegList
2376
+ if (getLexer ().is (AsmToken::Comma)) {
2377
+ if (RegEnd != RISCV::X9) {
2378
+ Error (
2379
+ getLoc (),
2380
+ " first contiguous registers pair of register list must be 'x8-x9'" );
2381
+ return MatchOperand_ParseFail;
2382
+ }
2383
+
2384
+ // parse ', x18' for extra part
2385
+ getLexer ().Lex ();
2386
+ if (getLexer ().isNot (AsmToken::Identifier)) {
2387
+ Error (getLoc (), " invalid register" );
2388
+ return MatchOperand_ParseFail;
2389
+ }
2390
+ StringRef EndName = getLexer ().getTok ().getIdentifier ();
2391
+ if (MatchRegisterName (EndName) != RISCV::X18) {
2392
+ Error (getLoc (), " second contiguous registers pair of register list "
2393
+ " must start from 'x18'" );
2394
+ return MatchOperand_ParseFail;
2395
+ }
2396
+ getLexer ().Lex ();
2397
+
2398
+ // parse '-x20' for extra part
2399
+ if (getLexer ().is (AsmToken::Minus)) {
2400
+ getLexer ().Lex ();
2401
+ if (getLexer ().isNot (AsmToken::Identifier)) {
2402
+ Error (getLoc (), " invalid register" );
2403
+ return MatchOperand_ParseFail;
2404
+ }
2405
+ EndName = getLexer ().getTok ().getIdentifier ();
2406
+ if (MatchRegisterName (EndName) == RISCV::NoRegister) {
2407
+ Error (getLoc (), " invalid register" );
2408
+ return MatchOperand_ParseFail;
2409
+ }
2410
+ getLexer ().Lex ();
2411
+ }
2412
+ RegEnd = MatchRegisterName (EndName);
2413
+ }
2414
+ }
2415
+
2416
+ if (RegEnd == RISCV::X26) {
2417
+ Error (getLoc (), " invalid register list, {ra, s0-s10} or {x1, x8-x9, "
2418
+ " x18-x26} is not supported" );
2419
+ return MatchOperand_ParseFail;
2420
+ }
2421
+
2422
+ if (getLexer ().isNot (AsmToken::RCurly)) {
2423
+ Error (getLoc (), " register list must end with '}'" );
2424
+ return MatchOperand_ParseFail;
2425
+ }
2426
+ getLexer ().Lex (); // eat '}'
2427
+
2428
+ if (RegEnd == RISCV::NoRegister)
2429
+ RegEnd = RegStart;
2430
+
2431
+ auto Encode = RISCVZC::encodeRlist (RegEnd, IsEABI);
2432
+ if (Encode == 16 ) {
2433
+ Error (S, " invalid register list" );
2434
+ return MatchOperand_ParseFail;
2435
+ }
2436
+ Operands.push_back (RISCVOperand::createRlist (Encode, S));
2437
+
2438
+ return MatchOperand_Success;
2439
+ }
2440
+
2441
+ OperandMatchResultTy RISCVAsmParser::parseZcmpSpimm (OperandVector &Operands) {
2442
+ if (getLexer ().is (AsmToken::Minus))
2443
+ getLexer ().Lex ();
2444
+
2445
+ SMLoc S = getLoc ();
2446
+ int64_t StackAdjustment = getLexer ().getTok ().getIntVal ();
2447
+ unsigned Spimm = 0 ;
2448
+ unsigned RlistVal = static_cast <RISCVOperand *>(Operands[1 ].get ())->Rlist .Val ;
2449
+
2450
+ bool IsEABI = isRVE ();
2451
+ if (!RISCVZC::getSpimm (RlistVal, Spimm, StackAdjustment, isRV64 (), IsEABI))
2452
+ return MatchOperand_NoMatch;
2453
+ Operands.push_back (RISCVOperand::createSpimm (Spimm << 4 , S));
2454
+ getLexer ().Lex ();
2455
+ return MatchOperand_Success;
2456
+ }
2457
+
2246
2458
// / Looks at a token type and creates the relevant operand from this
2247
2459
// / information, adding to Operands. If operand was parsed, returns false, else
2248
2460
// / true.
@@ -2925,6 +3137,15 @@ bool RISCVAsmParser::validateInstruction(MCInst &Inst,
2925
3137
}
2926
3138
}
2927
3139
3140
+ if (Opcode == RISCV::CM_MVSA01) {
3141
+ unsigned Rd1 = Inst.getOperand (0 ).getReg ();
3142
+ unsigned Rd2 = Inst.getOperand (1 ).getReg ();
3143
+ if (Rd1 == Rd2) {
3144
+ SMLoc Loc = Operands[1 ]->getStartLoc ();
3145
+ return Error (Loc, " 'rs1' and 'rs2' must be different." );
3146
+ }
3147
+ }
3148
+
2928
3149
bool IsTHeadMemPair32 = (Opcode == RISCV::TH_LWD ||
2929
3150
Opcode == RISCV::TH_LWUD || Opcode == RISCV::TH_SWD);
2930
3151
bool IsTHeadMemPair64 = (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_SDD);
0 commit comments