@@ -215,13 +215,10 @@ class RISCVAsmParser : public MCTargetAsmParser {
215215 ParseStatus parseGPRPair (OperandVector &Operands, bool IsRV64Inst);
216216 ParseStatus parseFRMArg (OperandVector &Operands);
217217 ParseStatus parseFenceArg (OperandVector &Operands);
218- ParseStatus parseRegList (OperandVector &Operands) {
219- return parseRegListCommon (Operands, /* MustIncludeS0=*/ false );
220- }
218+ ParseStatus parseRegList (OperandVector &Operands, bool MustIncludeS0 = false );
221219 ParseStatus parseRegListS0 (OperandVector &Operands) {
222- return parseRegListCommon (Operands, /* MustIncludeS0=*/ true );
220+ return parseRegList (Operands, /* MustIncludeS0=*/ true );
223221 }
224- ParseStatus parseRegListCommon (OperandVector &Operands, bool MustIncludeS0);
225222
226223 ParseStatus parseRegReg (OperandVector &Operands);
227224 ParseStatus parseRetval (OperandVector &Operands);
@@ -2567,96 +2564,97 @@ ParseStatus RISCVAsmParser::parseRegReg(OperandVector &Operands) {
25672564 return ParseStatus::Success;
25682565}
25692566
2570- ParseStatus RISCVAsmParser::parseRegListCommon (OperandVector &Operands,
2571- bool MustIncludeS0) {
2572- // RegList: {ra [, s0[-sN]]}
2573- // XRegList: {x1 [, x8[-x9][, x18[-xN]]]}
2574-
2575- // When MustIncludeS0 = true (not the default) (used for `qc.cm.pushfp`) which
2576- // must include `fp`/`s0` in the list:
2577- // RegList: {ra, s0[-sN]}
2578- // XRegList: {x1, x8[-x9][, x18[-xN]]}
2567+ // RegList: {ra [, s0[-sN]]}
2568+ // XRegList: {x1 [, x8[-x9][, x18[-xN]]]}
25792569
2570+ // When MustIncludeS0 = true (not the default) (used for `qc.cm.pushfp`) which
2571+ // must include `fp`/`s0` in the list:
2572+ // RegList: {ra, s0[-sN]}
2573+ // XRegList: {x1, x8[-x9][, x18[-xN]]}
2574+ ParseStatus RISCVAsmParser::parseRegList (OperandVector &Operands,
2575+ bool MustIncludeS0) {
25802576 if (getTok ().isNot (AsmToken::LCurly))
25812577 return ParseStatus::NoMatch;
25822578
25832579 SMLoc S = getLoc ();
2580+
25842581 Lex ();
25852582
2586- bool IsRVE = isRVE ();
2583+ bool UsesXRegs;
2584+ MCRegister RegEnd;
2585+ do {
2586+ if (getTok ().isNot (AsmToken::Identifier) ||
2587+ (RegEnd == RISCV::X18 && isRVE ()))
2588+ return Error (getLoc (), " invalid register" );
25872589
2588- if (getLexer ().isNot (AsmToken::Identifier))
2589- return Error (getLoc (), " register list must start from 'ra' or 'x1'" );
2590+ StringRef RegName = getTok ().getIdentifier ();
2591+ MCRegister Reg = matchRegisterNameHelper (RegName);
2592+ if (!Reg)
2593+ return Error (getLoc (), " invalid register" );
25902594
2591- StringRef RegName = getLexer ().getTok ().getIdentifier ();
2592- MCRegister RegEnd = matchRegisterNameHelper (RegName);
2593- if (RegEnd != RISCV::X1)
2594- return Error (getLoc (), " register list must start from 'ra' or 'x1'" );
2595- getLexer ().Lex ();
2595+ if (!RegEnd) {
2596+ UsesXRegs = RegName[0 ] == ' x' ;
2597+ if (Reg != RISCV::X1)
2598+ return Error (getLoc (), " register list must start from 'ra' or 'x1'" );
2599+ } else if (RegEnd == RISCV::X1) {
2600+ if (Reg != RISCV::X8 || (UsesXRegs != (RegName[0 ] == ' x' )))
2601+ return Error (getLoc (), Twine (" register must be '" ) +
2602+ (UsesXRegs ? " x8" : " s0" ) + " '" );
2603+ } else if (RegEnd == RISCV::X9 && UsesXRegs) {
2604+ if (Reg != RISCV::X18 || (RegName[0 ] != ' x' ))
2605+ return Error (getLoc (), " register must be 'x18'" );
2606+ } else {
2607+ return Error (getLoc (), " too many register ranges" );
2608+ }
25962609
2597- // parse case like ,s0 (knowing the comma must be there if required)
2598- if (parseOptionalToken (AsmToken::Comma)) {
2599- if (getLexer ().isNot (AsmToken::Identifier))
2600- return Error (getLoc (), " invalid register" );
2601- StringRef RegName = getLexer ().getTok ().getIdentifier ();
2602- RegEnd = matchRegisterNameHelper (RegName);
2603- if (!RegEnd)
2604- return Error (getLoc (), " invalid register" );
2605- if (RegEnd != RISCV::X8)
2606- return Error (getLoc (),
2607- " continuous register list must start from 's0' or 'x8'" );
2608- getLexer ().Lex (); // eat reg
2610+ RegEnd = Reg;
26092611
2610- // parse case like -s1
2612+ Lex ();
2613+
2614+ SMLoc MinusLoc = getLoc ();
26112615 if (parseOptionalToken (AsmToken::Minus)) {
2612- StringRef EndName = getLexer ().getTok ().getIdentifier ();
2613- // FIXME: the register mapping and checks of RVE is wrong
2614- RegEnd = matchRegisterNameHelper (EndName);
2615- if (!(RegEnd == RISCV::X9 ||
2616- (RegEnd >= RISCV::X18 && RegEnd <= RISCV::X27)))
2617- return Error (getLoc (), " invalid register" );
2618- getLexer ().Lex ();
2619- }
2616+ if (RegEnd == RISCV::X1)
2617+ return Error (MinusLoc, Twine (" register '" ) + (UsesXRegs ? " x1" : " ra" ) +
2618+ " ' cannot start a multiple register range" );
26202619
2621- // parse extra part like ', x18[-x20]' for XRegList
2622- if (parseOptionalToken (AsmToken::Comma)) {
2623- if (RegEnd != RISCV::X9)
2624- return Error (
2625- getLoc (),
2626- " first contiguous registers pair of register list must be 'x8-x9'" );
2620+ if (getTok ().isNot (AsmToken::Identifier) ||
2621+ (RegEnd == RISCV::X18 && isRVE ()))
2622+ return Error (getLoc (), " invalid register" );
26272623
2628- // parse ', x18' for extra part
2629- if (getLexer ().isNot (AsmToken::Identifier) || IsRVE)
2624+ StringRef RegName = getTok ().getIdentifier ();
2625+ MCRegister Reg = matchRegisterNameHelper (RegName);
2626+ if (!Reg)
26302627 return Error (getLoc (), " invalid register" );
2631- StringRef EndName = getLexer ().getTok ().getIdentifier ();
2632- RegEnd = MatchRegisterName (EndName);
2633- if (RegEnd != RISCV::X18)
2634- return Error (getLoc (),
2635- " second contiguous registers pair of register list "
2636- " must start from 'x18'" );
2637- getLexer ().Lex ();
2638-
2639- // parse '-x20' for extra part
2640- if (parseOptionalToken (AsmToken::Minus)) {
2641- if (getLexer ().isNot (AsmToken::Identifier) || IsRVE)
2642- return Error (getLoc (), " invalid register" );
2643- EndName = getLexer ().getTok ().getIdentifier ();
2644- RegEnd = MatchRegisterName (EndName);
2645- if (!(RegEnd >= RISCV::X19 && RegEnd <= RISCV::X27))
2646- return Error (getLoc (), " invalid register" );
2647- getLexer ().Lex ();
2648- }
2628+
2629+ if (RegEnd == RISCV::X8) {
2630+ if ((Reg != RISCV::X9 &&
2631+ (UsesXRegs || Reg < RISCV::X18 || Reg > RISCV::X27)) ||
2632+ (UsesXRegs != (RegName[0 ] == ' x' ))) {
2633+ if (UsesXRegs)
2634+ return Error (getLoc (), " register must be 'x9'" );
2635+ return Error (getLoc (), " register must be in the range 's1' to 's11'" );
2636+ }
2637+ } else if (RegEnd == RISCV::X18) {
2638+ if (Reg < RISCV::X19 || Reg > RISCV::X27 || (RegName[0 ] != ' x' ))
2639+ return Error (getLoc (),
2640+ " register must be in the range 'x19' to 'x27'" );
2641+ } else
2642+ llvm_unreachable (" unexpected register" );
2643+
2644+ RegEnd = Reg;
2645+
2646+ Lex ();
26492647 }
2650- }
2648+ } while ( parseOptionalToken (AsmToken::Comma));
26512649
2652- if (parseToken (AsmToken::RCurly, " register list must end with '}'" ))
2650+ if (parseToken (AsmToken::RCurly, " expected ',' or '}'" ))
26532651 return ParseStatus::Failure;
26542652
26552653 if (RegEnd == RISCV::X26)
2656- return Error (S, " invalid register list, {ra, s0-s10} or {x1, x8-x9, "
2657- " x18-x26} is not supported" );
2654+ return Error (S, " invalid register list, ' {ra, s0-s10}' or ' {x1, x8-x9, "
2655+ " x18-x26}' is not supported" );
26582656
2659- auto Encode = RISCVZC::encodeRegList (RegEnd, IsRVE );
2657+ auto Encode = RISCVZC::encodeRegList (RegEnd, isRVE () );
26602658 assert (Encode != RISCVZC::INVALID_RLIST);
26612659
26622660 if (MustIncludeS0 && Encode == RISCVZC::RA)
0 commit comments