@@ -216,13 +216,10 @@ class RISCVAsmParser : public MCTargetAsmParser {
216
216
ParseStatus parseGPRPair (OperandVector &Operands, bool IsRV64Inst);
217
217
ParseStatus parseFRMArg (OperandVector &Operands);
218
218
ParseStatus parseFenceArg (OperandVector &Operands);
219
- ParseStatus parseRegList (OperandVector &Operands) {
220
- return parseRegListCommon (Operands, /* MustIncludeS0=*/ false );
221
- }
219
+ ParseStatus parseRegList (OperandVector &Operands, bool MustIncludeS0 = false );
222
220
ParseStatus parseRegListS0 (OperandVector &Operands) {
223
- return parseRegListCommon (Operands, /* MustIncludeS0=*/ true );
221
+ return parseRegList (Operands, /* MustIncludeS0=*/ true );
224
222
}
225
- ParseStatus parseRegListCommon (OperandVector &Operands, bool MustIncludeS0);
226
223
227
224
ParseStatus parseRegReg (OperandVector &Operands);
228
225
ParseStatus parseRetval (OperandVector &Operands);
@@ -2636,96 +2633,95 @@ ParseStatus RISCVAsmParser::parseRegReg(OperandVector &Operands) {
2636
2633
return ParseStatus::Success;
2637
2634
}
2638
2635
2639
- ParseStatus RISCVAsmParser::parseRegListCommon (OperandVector &Operands,
2640
- bool MustIncludeS0) {
2641
- // RegList: {ra [, s0[-sN]]}
2642
- // XRegList: {x1 [, x8[-x9][, x18[-xN]]]}
2643
-
2644
- // When MustIncludeS0 = true (not the default) (used for `qc.cm.pushfp`) which
2645
- // must include `fp`/`s0` in the list:
2646
- // RegList: {ra, s0[-sN]}
2647
- // XRegList: {x1, x8[-x9][, x18[-xN]]}
2636
+ // RegList: {ra [, s0[-sN]]}
2637
+ // XRegList: {x1 [, x8[-x9][, x18[-xN]]]}
2648
2638
2639
+ // When MustIncludeS0 = true (not the default) (used for `qc.cm.pushfp`) which
2640
+ // must include `fp`/`s0` in the list:
2641
+ // RegList: {ra, s0[-sN]}
2642
+ // XRegList: {x1, x8[-x9][, x18[-xN]]}
2643
+ ParseStatus RISCVAsmParser::parseRegList (OperandVector &Operands,
2644
+ bool MustIncludeS0) {
2649
2645
if (getTok ().isNot (AsmToken::LCurly))
2650
2646
return ParseStatus::NoMatch;
2651
2647
2652
2648
SMLoc S = getLoc ();
2649
+
2653
2650
Lex ();
2654
2651
2655
- bool IsRVE = isRVE ();
2652
+ bool UsesXRegs;
2653
+ MCRegister RegEnd;
2654
+ do {
2655
+ if (getTok ().isNot (AsmToken::Identifier))
2656
+ return Error (getLoc (), " invalid register" );
2656
2657
2657
- if (getLexer ().isNot (AsmToken::Identifier))
2658
- return Error (getLoc (), " register list must start from 'ra' or 'x1'" );
2658
+ StringRef RegName = getTok ().getIdentifier ();
2659
+ MCRegister Reg = matchRegisterNameHelper (RegName);
2660
+ if (!Reg)
2661
+ return Error (getLoc (), " invalid register" );
2659
2662
2660
- StringRef RegName = getLexer ().getTok ().getIdentifier ();
2661
- MCRegister RegEnd = matchRegisterNameHelper (RegName);
2662
- if (RegEnd != RISCV::X1)
2663
- return Error (getLoc (), " register list must start from 'ra' or 'x1'" );
2664
- getLexer ().Lex ();
2663
+ if (!RegEnd) {
2664
+ UsesXRegs = RegName[0 ] == ' x' ;
2665
+ if (Reg != RISCV::X1)
2666
+ return Error (getLoc (), " register list must start from 'ra' or 'x1'" );
2667
+ } else if (RegEnd == RISCV::X1) {
2668
+ if (Reg != RISCV::X8 || (UsesXRegs != (RegName[0 ] == ' x' )))
2669
+ return Error (getLoc (), Twine (" register must be '" ) +
2670
+ (UsesXRegs ? " x8" : " s0" ) + " '" );
2671
+ } else if (RegEnd == RISCV::X9 && UsesXRegs) {
2672
+ if (Reg != RISCV::X18 || (RegName[0 ] != ' x' ))
2673
+ return Error (getLoc (), " register must be 'x18'" );
2674
+ } else {
2675
+ return Error (getLoc (), " too many register ranges" );
2676
+ }
2665
2677
2666
- // parse case like ,s0 (knowing the comma must be there if required)
2667
- if (parseOptionalToken (AsmToken::Comma)) {
2668
- if (getLexer ().isNot (AsmToken::Identifier))
2669
- return Error (getLoc (), " invalid register" );
2670
- StringRef RegName = getLexer ().getTok ().getIdentifier ();
2671
- RegEnd = matchRegisterNameHelper (RegName);
2672
- if (!RegEnd)
2673
- return Error (getLoc (), " invalid register" );
2674
- if (RegEnd != RISCV::X8)
2675
- return Error (getLoc (),
2676
- " continuous register list must start from 's0' or 'x8'" );
2677
- getLexer ().Lex (); // eat reg
2678
+ RegEnd = Reg;
2678
2679
2679
- // parse case like -s1
2680
+ Lex ();
2681
+
2682
+ SMLoc MinusLoc = getLoc ();
2680
2683
if (parseOptionalToken (AsmToken::Minus)) {
2681
- StringRef EndName = getLexer ().getTok ().getIdentifier ();
2682
- // FIXME: the register mapping and checks of RVE is wrong
2683
- RegEnd = matchRegisterNameHelper (EndName);
2684
- if (!(RegEnd == RISCV::X9 ||
2685
- (RegEnd >= RISCV::X18 && RegEnd <= RISCV::X27)))
2686
- return Error (getLoc (), " invalid register" );
2687
- getLexer ().Lex ();
2688
- }
2684
+ if (RegEnd == RISCV::X1)
2685
+ return Error (MinusLoc, Twine (" register '" ) + (UsesXRegs ? " x1" : " ra" ) +
2686
+ " ' cannot start a multiple register range" );
2689
2687
2690
- // parse extra part like ', x18[-x20]' for XRegList
2691
- if (parseOptionalToken (AsmToken::Comma)) {
2692
- if (RegEnd != RISCV::X9)
2693
- return Error (
2694
- getLoc (),
2695
- " first contiguous registers pair of register list must be 'x8-x9'" );
2688
+ if (getTok ().isNot (AsmToken::Identifier))
2689
+ return Error (getLoc (), " invalid register" );
2696
2690
2697
- // parse ', x18' for extra part
2698
- if (getLexer ().isNot (AsmToken::Identifier) || IsRVE)
2691
+ StringRef RegName = getTok ().getIdentifier ();
2692
+ MCRegister Reg = matchRegisterNameHelper (RegName);
2693
+ if (!Reg)
2699
2694
return Error (getLoc (), " invalid register" );
2700
- StringRef EndName = getLexer ().getTok ().getIdentifier ();
2701
- RegEnd = MatchRegisterName (EndName);
2702
- if (RegEnd != RISCV::X18)
2703
- return Error (getLoc (),
2704
- " second contiguous registers pair of register list "
2705
- " must start from 'x18'" );
2706
- getLexer ().Lex ();
2707
-
2708
- // parse '-x20' for extra part
2709
- if (parseOptionalToken (AsmToken::Minus)) {
2710
- if (getLexer ().isNot (AsmToken::Identifier) || IsRVE)
2711
- return Error (getLoc (), " invalid register" );
2712
- EndName = getLexer ().getTok ().getIdentifier ();
2713
- RegEnd = MatchRegisterName (EndName);
2714
- if (!(RegEnd >= RISCV::X19 && RegEnd <= RISCV::X27))
2715
- return Error (getLoc (), " invalid register" );
2716
- getLexer ().Lex ();
2717
- }
2695
+
2696
+ if (RegEnd == RISCV::X8) {
2697
+ if ((Reg != RISCV::X9 &&
2698
+ (UsesXRegs || Reg < RISCV::X18 || Reg > RISCV::X27)) ||
2699
+ (UsesXRegs != (RegName[0 ] == ' x' ))) {
2700
+ if (UsesXRegs)
2701
+ return Error (getLoc (), " register must be 'x9'" );
2702
+ return Error (getLoc (), " register must be in the range 's1' to 's11'" );
2703
+ }
2704
+ } else if (RegEnd == RISCV::X18) {
2705
+ if (Reg < RISCV::X19 || Reg > RISCV::X27 || (RegName[0 ] != ' x' ))
2706
+ return Error (getLoc (),
2707
+ " register must be in the range 'x19' to 'x27'" );
2708
+ } else
2709
+ llvm_unreachable (" unexpected register" );
2710
+
2711
+ RegEnd = Reg;
2712
+
2713
+ Lex ();
2718
2714
}
2719
- }
2715
+ } while ( parseOptionalToken (AsmToken::Comma));
2720
2716
2721
- if (parseToken (AsmToken::RCurly, " register list must end with '}'" ))
2717
+ if (parseToken (AsmToken::RCurly, " expected ',' or '}'" ))
2722
2718
return ParseStatus::Failure;
2723
2719
2724
2720
if (RegEnd == RISCV::X26)
2725
- return Error (S, " invalid register list, {ra, s0-s10} or {x1, x8-x9, "
2726
- " x18-x26} is not supported" );
2721
+ return Error (S, " invalid register list, ' {ra, s0-s10}' or ' {x1, x8-x9, "
2722
+ " x18-x26}' is not supported" );
2727
2723
2728
- auto Encode = RISCVZC::encodeRegList (RegEnd, IsRVE );
2724
+ auto Encode = RISCVZC::encodeRegList (RegEnd, isRVE () );
2729
2725
assert (Encode != RISCVZC::INVALID_RLIST);
2730
2726
2731
2727
if (MustIncludeS0 && Encode == RISCVZC::RA)
0 commit comments