[RISCV] Improve error for using x18-x27 in a register list with RVE. (#133936)
matchRegisterNameHelper returns MCRegister() for RVE so the first RVE
check was dead.
For the second check, I've moved the RVE check from the comma parsing to
the identifier parsing so the diagnostic points at the register. Note
we're using matchRegisterName instead of matchRegisterNameHelper to
avoid allowing ABI names so we don't get the RVE check that lives inside
matchRegisterNameHelper.
The errors for RVE in general should probably say something other than
"invalid register", but that's a problem throughout the assembler.
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index f1ccf0c..1e07ada 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -2577,7 +2577,7 @@
if (parseToken(AsmToken::LCurly, "register list must start with '{'"))
return ParseStatus::Failure;
- bool IsEABI = isRVE();
+ bool IsRVE = isRVE();
if (getLexer().isNot(AsmToken::Identifier))
return Error(getLoc(), "register list must start from 'ra' or 'x1'");
@@ -2617,46 +2617,41 @@
// parse case like -s1
if (parseOptionalToken(AsmToken::Minus)) {
StringRef EndName = getLexer().getTok().getIdentifier();
- // FIXME: the register mapping and checks of EABI is wrong
+ // 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");
- if (IsEABI && RegEnd != RISCV::X9)
- return Error(getLoc(), "contiguous register list of EABI can only be "
- "'s0-s1' or 'x8-x9' pair");
getLexer().Lex();
}
- if (!IsEABI) {
- // 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'");
+ // 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'");
- // parse ', x18' for extra part
- if (getLexer().isNot(AsmToken::Identifier))
+ // parse ', x18' for extra part
+ if (getLexer().isNot(AsmToken::Identifier) || IsRVE)
+ return Error(getLoc(), "invalid register");
+ StringRef EndName = getLexer().getTok().getIdentifier();
+ RegEnd = MatchRegisterName(EndName);
+ if (RegEnd != RISCV::X18)
+ return Error(getLoc(),
+ "second contiguous registers pair of register list "
+ "must start from 'x18'");
+ getLexer().Lex();
+
+ // parse '-x20' for extra part
+ if (parseOptionalToken(AsmToken::Minus)) {
+ if (getLexer().isNot(AsmToken::Identifier) || IsRVE)
return Error(getLoc(), "invalid register");
- StringRef EndName = getLexer().getTok().getIdentifier();
+ EndName = getLexer().getTok().getIdentifier();
RegEnd = MatchRegisterName(EndName);
- if (RegEnd != RISCV::X18)
- return Error(getLoc(),
- "second contiguous registers pair of register list "
- "must start from 'x18'");
+ if (!(RegEnd >= RISCV::X19 && RegEnd <= RISCV::X27))
+ return Error(getLoc(), "invalid register");
getLexer().Lex();
-
- // parse '-x20' for extra part
- if (parseOptionalToken(AsmToken::Minus)) {
- if (getLexer().isNot(AsmToken::Identifier))
- return Error(getLoc(), "invalid register");
- EndName = getLexer().getTok().getIdentifier();
- RegEnd = MatchRegisterName(EndName);
- if (!(RegEnd >= RISCV::X19 && RegEnd <= RISCV::X27))
- return Error(getLoc(), "invalid register");
- getLexer().Lex();
- }
}
}
@@ -2667,7 +2662,7 @@
if (parseToken(AsmToken::RCurly, "register list must end with '}'"))
return ParseStatus::Failure;
- auto Encode = RISCVZC::encodeRlist(RegEnd, IsEABI);
+ auto Encode = RISCVZC::encodeRlist(RegEnd, IsRVE);
assert(Encode != RISCVZC::INVALID_RLIST);
if (MustIncludeS0)
assert(Encode != RISCVZC::RA);
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index 15c0753..d6672de 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -603,8 +603,8 @@
INVALID_RLIST,
};
-inline unsigned encodeRlist(MCRegister EndReg, bool IsRV32E = false) {
- assert((!IsRV32E || EndReg <= RISCV::X9) && "Invalid Rlist for RV32E");
+inline unsigned encodeRlist(MCRegister EndReg, bool IsRVE = false) {
+ assert((!IsRVE || EndReg <= RISCV::X9) && "Invalid Rlist for RV32E");
switch (EndReg) {
case RISCV::X1:
return RLISTENCODE::RA;
diff --git a/llvm/test/MC/RISCV/rv32e-xqccmp-invalid.s b/llvm/test/MC/RISCV/rv32e-xqccmp-invalid.s
index 6c3ef30..f24caa1 100644
--- a/llvm/test/MC/RISCV/rv32e-xqccmp-invalid.s
+++ b/llvm/test/MC/RISCV/rv32e-xqccmp-invalid.s
@@ -14,8 +14,11 @@
# CHECK: :[[@LINE+1]]:21: error: invalid register
qc.cm.popret {ra,s0-s2}, 16
# CHECK-DIS: ba72 <unknown>
-# CHECK: :[[@LINE+1]]:21: error: register list must end with '}'
+# CHECK: :[[@LINE+1]]:23: error: invalid register
qc.cm.pop {x1, x8-x9, x18}, 16
# CHECK-DIS: b972 <unknown>
-# CHECK: :[[@LINE+1]]:24: error: register list must end with '}'
+# CHECK: :[[@LINE+1]]:26: error: invalid register
qc.cm.pushfp {x1, x8-x9, x18}, -16
+# CHECK-DIS: b972 <unknown>
+# CHECK: :[[@LINE+1]]:22: error: invalid register
+qc.cm.pushfp {ra, s0-s2}, -16
diff --git a/llvm/test/MC/RISCV/rv32e-zcmp-invalid.s b/llvm/test/MC/RISCV/rv32e-zcmp-invalid.s
index eaf6b35..a2942a8 100644
--- a/llvm/test/MC/RISCV/rv32e-zcmp-invalid.s
+++ b/llvm/test/MC/RISCV/rv32e-zcmp-invalid.s
@@ -14,5 +14,8 @@
# CHECK: :[[@LINE+1]]:18: error: invalid register
cm.popret {ra,s0-s2}, 16
# CHECK-DIS: ba72 <unknown>
-# CHECK: :[[@LINE+1]]:18: error: register list must end with '}'
+# CHECK: :[[@LINE+1]]:20: error: invalid register
cm.pop {x1, x8-x9, x18}, 16
+# CHECK-DIS: ba72 <unknown>
+# CHECK: :[[@LINE+1]]:16: error: invalid register
+cm.pop {ra, s0-s2}, 16
diff --git a/llvm/test/MC/RISCV/rv64e-xqccmp-invalid.s b/llvm/test/MC/RISCV/rv64e-xqccmp-invalid.s
index f34ce83..39d9179 100644
--- a/llvm/test/MC/RISCV/rv64e-xqccmp-invalid.s
+++ b/llvm/test/MC/RISCV/rv64e-xqccmp-invalid.s
@@ -14,8 +14,11 @@
# CHECK: :[[@LINE+1]]:21: error: invalid register
qc.cm.popret {ra,s0-s2}, 32
# CHECK-DIS: ba72 <unknown>
-# CHECK: :[[@LINE+1]]:21: error: register list must end with '}'
+# CHECK: :[[@LINE+1]]:23: error: invalid register
qc.cm.pop {x1, x8-x9, x18}, 32
# CHECK-DIS: b972 <unknown>
-# CHECK: :[[@LINE+1]]:24: error: register list must end with '}'
+# CHECK: :[[@LINE+1]]:26: error: invalid register
qc.cm.pushfp {x1, x8-x9, x18}, -32
+# CHECK-DIS: b972 <unknown>
+# CHECK: :[[@LINE+1]]:22: error: invalid register
+qc.cm.pushfp {ra, s0-s2}, -32
diff --git a/llvm/test/MC/RISCV/rv64e-zcmp-invalid.s b/llvm/test/MC/RISCV/rv64e-zcmp-invalid.s
index e99721d..45081c6 100644
--- a/llvm/test/MC/RISCV/rv64e-zcmp-invalid.s
+++ b/llvm/test/MC/RISCV/rv64e-zcmp-invalid.s
@@ -14,5 +14,8 @@
# CHECK: :[[@LINE+1]]:18: error: invalid register
cm.popret {ra,s0-s2}, 32
# CHECK-DIS: ba72 <unknown>
-# CHECK: :[[@LINE+1]]:18: error: register list must end with '}'
+# CHECK: :[[@LINE+1]]:20: error: invalid register
cm.pop {x1, x8-x9, x18}, 32
+# CHECK-DIS: ba72 <unknown>
+# CHECK: :[[@LINE+1]]:16: error: invalid register
+cm.pop {ra, s0-s2}, 32