@@ -216,13 +216,10 @@ class RISCVAsmParser : public MCTargetAsmParser {
216216 ParseStatus parseGPRPair (OperandVector &Operands, bool IsRV64Inst);
217217 ParseStatus parseFRMArg (OperandVector &Operands);
218218 ParseStatus parseFenceArg (OperandVector &Operands);
219- ParseStatus parseRegList (OperandVector &Operands) {
220- return parseRegListCommon (Operands, /* MustIncludeS0=*/ false );
221- }
219+ ParseStatus parseRegList (OperandVector &Operands, bool MustIncludeS0 = false );
222220 ParseStatus parseRegListS0 (OperandVector &Operands) {
223- return parseRegListCommon (Operands, /* MustIncludeS0=*/ true );
221+ return parseRegList (Operands, /* MustIncludeS0=*/ true );
224222 }
225- ParseStatus parseRegListCommon (OperandVector &Operands, bool MustIncludeS0);
226223
227224 ParseStatus parseRegReg (OperandVector &Operands);
228225 ParseStatus parseRetval (OperandVector &Operands);
@@ -2636,96 +2633,95 @@ ParseStatus RISCVAsmParser::parseRegReg(OperandVector &Operands) {
26362633 return ParseStatus::Success;
26372634}
26382635
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]]]}
26482638
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) {
26492645 if (getTok ().isNot (AsmToken::LCurly))
26502646 return ParseStatus::NoMatch;
26512647
26522648 SMLoc S = getLoc ();
2649+
26532650 Lex ();
26542651
2655- bool IsRVE = isRVE ();
2652+ bool UsesXRegs;
2653+ MCRegister RegEnd;
2654+ do {
2655+ if (getTok ().isNot (AsmToken::Identifier))
2656+ return Error (getLoc (), " invalid register" );
26562657
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" );
26592662
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+ }
26652677
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;
26782679
2679- // parse case like -s1
2680+ Lex ();
2681+
2682+ SMLoc MinusLoc = getLoc ();
26802683 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" );
26892687
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" );
26962690
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)
26992694 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 ();
27182714 }
2719- }
2715+ } while ( parseOptionalToken (AsmToken::Comma));
27202716
2721- if (parseToken (AsmToken::RCurly, " register list must end with '}'" ))
2717+ if (parseToken (AsmToken::RCurly, " expected ',' or '}'" ))
27222718 return ParseStatus::Failure;
27232719
27242720 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" );
27272723
2728- auto Encode = RISCVZC::encodeRegList (RegEnd, IsRVE );
2724+ auto Encode = RISCVZC::encodeRegList (RegEnd, isRVE () );
27292725 assert (Encode != RISCVZC::INVALID_RLIST);
27302726
27312727 if (MustIncludeS0 && Encode == RISCVZC::RA)
0 commit comments