[llvm] [RISCV] Refactor register list parsing and improve error messages. (PR #134938)
Sam Elliott via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 14 14:17:31 PDT 2025
================
@@ -2567,96 +2564,97 @@ ParseStatus RISCVAsmParser::parseRegReg(OperandVector &Operands) {
return ParseStatus::Success;
}
-ParseStatus RISCVAsmParser::parseRegListCommon(OperandVector &Operands,
- bool MustIncludeS0) {
- // RegList: {ra [, s0[-sN]]}
- // XRegList: {x1 [, x8[-x9][, x18[-xN]]]}
-
- // When MustIncludeS0 = true (not the default) (used for `qc.cm.pushfp`) which
- // must include `fp`/`s0` in the list:
- // RegList: {ra, s0[-sN]}
- // XRegList: {x1, x8[-x9][, x18[-xN]]}
+// RegList: {ra [, s0[-sN]]}
+// XRegList: {x1 [, x8[-x9][, x18[-xN]]]}
+// When MustIncludeS0 = true (not the default) (used for `qc.cm.pushfp`) which
+// must include `fp`/`s0` in the list:
+// RegList: {ra, s0[-sN]}
+// XRegList: {x1, x8[-x9][, x18[-xN]]}
+ParseStatus RISCVAsmParser::parseRegList(OperandVector &Operands,
+ bool MustIncludeS0) {
if (getTok().isNot(AsmToken::LCurly))
return ParseStatus::NoMatch;
SMLoc S = getLoc();
+
Lex();
- bool IsRVE = isRVE();
+ bool UsesXRegs;
+ MCRegister RegEnd;
+ do {
+ if (getTok().isNot(AsmToken::Identifier) ||
+ (RegEnd == RISCV::X18 && isRVE()))
+ return Error(getLoc(), "invalid register");
- if (getLexer().isNot(AsmToken::Identifier))
- return Error(getLoc(), "register list must start from 'ra' or 'x1'");
+ StringRef RegName = getTok().getIdentifier();
+ MCRegister Reg = matchRegisterNameHelper(RegName);
+ if (!Reg)
+ return Error(getLoc(), "invalid register");
- StringRef RegName = getLexer().getTok().getIdentifier();
- MCRegister RegEnd = matchRegisterNameHelper(RegName);
- if (RegEnd != RISCV::X1)
- return Error(getLoc(), "register list must start from 'ra' or 'x1'");
- getLexer().Lex();
+ if (!RegEnd) {
+ UsesXRegs = RegName[0] == 'x';
+ if (Reg != RISCV::X1)
+ return Error(getLoc(), "register list must start from 'ra' or 'x1'");
+ } else if (RegEnd == RISCV::X1) {
+ if (Reg != RISCV::X8 || (UsesXRegs != (RegName[0] == 'x')))
+ return Error(getLoc(), Twine("register must be '") +
+ (UsesXRegs ? "x8" : "s0") + "'");
+ } else if (RegEnd == RISCV::X9 && UsesXRegs) {
+ if (Reg != RISCV::X18 || (RegName[0] != 'x'))
+ return Error(getLoc(), "register must be 'x18'");
+ } else {
+ return Error(getLoc(), "too many register ranges");
+ }
- // parse case like ,s0 (knowing the comma must be there if required)
- if (parseOptionalToken(AsmToken::Comma)) {
- if (getLexer().isNot(AsmToken::Identifier))
- return Error(getLoc(), "invalid register");
- StringRef RegName = getLexer().getTok().getIdentifier();
- RegEnd = matchRegisterNameHelper(RegName);
- if (!RegEnd)
- return Error(getLoc(), "invalid register");
- if (RegEnd != RISCV::X8)
- return Error(getLoc(),
- "continuous register list must start from 's0' or 'x8'");
- getLexer().Lex(); // eat reg
+ RegEnd = Reg;
- // parse case like -s1
+ Lex();
+
+ SMLoc MinusLoc = getLoc();
if (parseOptionalToken(AsmToken::Minus)) {
- StringRef EndName = getLexer().getTok().getIdentifier();
- // FIXME: the register mapping and checks of RVE is wrong
- RegEnd = matchRegisterNameHelper(EndName);
- if (!(RegEnd == RISCV::X9 ||
- (RegEnd >= RISCV::X18 && RegEnd <= RISCV::X27)))
- return Error(getLoc(), "invalid register");
- getLexer().Lex();
- }
+ if (RegEnd == RISCV::X1)
+ return Error(MinusLoc, Twine("register '") + (UsesXRegs ? "x1" : "ra") +
+ "' cannot start a multiple register range");
- // parse extra part like ', x18[-x20]' for XRegList
- if (parseOptionalToken(AsmToken::Comma)) {
- if (RegEnd != RISCV::X9)
- return Error(
- getLoc(),
- "first contiguous registers pair of register list must be 'x8-x9'");
+ if (getTok().isNot(AsmToken::Identifier) ||
+ (RegEnd == RISCV::X18 && isRVE()))
----------------
lenary wrote:
The same applies here, and I do wonder if the `RegEnd` check could be sunk closer to e.g. new line 26289
https://github.com/llvm/llvm-project/pull/134938
More information about the llvm-commits
mailing list