[llvm] [RISCV][MC] Support imm symbol in parseCSRSystemRegister (PR #112007)
Mark Zhuang via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 11 08:04:40 PDT 2024
https://github.com/zqb-all created https://github.com/llvm/llvm-project/pull/112007
None
>From 51b0ce729e9c924ca925f2fe2ada36c78c803fea Mon Sep 17 00:00:00 2001
From: Mark Zhuang <mark.zhuang at spacemit.com>
Date: Thu, 10 Oct 2024 17:37:32 +0800
Subject: [PATCH] [RISCV][MC] Support imm symbol in parseCSRSystemRegister
---
.../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 84 ++++++++++---------
llvm/test/MC/RISCV/rv32i-invalid.s | 14 ++--
llvm/test/MC/RISCV/rv32i-valid.s | 3 +
3 files changed, 53 insertions(+), 48 deletions(-)
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index e68674e830436f..95f3fc0d473238 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -1877,10 +1877,13 @@ ParseStatus RISCVAsmParser::parseInsnCDirectiveOpcode(OperandVector &Operands) {
ParseStatus RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {
SMLoc S = getLoc();
const MCExpr *Res;
+ auto Kind = getLexer().getKind();
- switch (getLexer().getKind()) {
+ switch (Kind) {
default:
return ParseStatus::NoMatch;
+
+ case AsmToken::Identifier:
case AsmToken::LParen:
case AsmToken::Minus:
case AsmToken::Plus:
@@ -1891,6 +1894,45 @@ ParseStatus RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {
if (getParser().parseExpression(Res))
return ParseStatus::Failure;
+ if (Kind == AsmToken::Identifier) {
+ auto SRE = dyn_cast<MCSymbolRefExpr>(Res);
+ if (SRE) {
+ auto Identifier = SRE->getSymbol().getName();
+ const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
+ if (!SysReg)
+ SysReg = RISCVSysReg::lookupSysRegByAltName(Identifier);
+ if (!SysReg)
+ if ((SysReg = RISCVSysReg::lookupSysRegByDeprecatedName(Identifier)))
+ Warning(S, "'" + Identifier + "' is a deprecated alias for '" +
+ SysReg->Name + "'");
+
+ // Accept a named Sys Reg if the required features are present.
+ if (SysReg) {
+ const auto &FeatureBits = getSTI().getFeatureBits();
+ if (!SysReg->haveRequiredFeatures(FeatureBits)) {
+ const auto *Feature = llvm::find_if(RISCVFeatureKV, [&](auto Feature) {
+ return SysReg->FeaturesRequired[Feature.Value];
+ });
+ auto ErrorMsg = std::string("system register '") + SysReg->Name + "' ";
+ if (SysReg->isRV32Only && FeatureBits[RISCV::Feature64Bit]) {
+ ErrorMsg += "is RV32 only";
+ if (Feature != std::end(RISCVFeatureKV))
+ ErrorMsg += " and ";
+ }
+ if (Feature != std::end(RISCVFeatureKV)) {
+ ErrorMsg +=
+ "requires '" + std::string(Feature->Key) + "' to be enabled";
+ }
+
+ return Error(S, ErrorMsg);
+ }
+ Operands.push_back(
+ RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
+ return ParseStatus::Success;
+ }
+ }
+ }
+
auto *CE = dyn_cast<MCConstantExpr>(Res);
if (CE) {
int64_t Imm = CE->getValue();
@@ -1911,46 +1953,6 @@ ParseStatus RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {
}
}
- return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
- }
- case AsmToken::Identifier: {
- StringRef Identifier;
- if (getParser().parseIdentifier(Identifier))
- return ParseStatus::Failure;
-
- const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
- if (!SysReg)
- SysReg = RISCVSysReg::lookupSysRegByAltName(Identifier);
- if (!SysReg)
- if ((SysReg = RISCVSysReg::lookupSysRegByDeprecatedName(Identifier)))
- Warning(S, "'" + Identifier + "' is a deprecated alias for '" +
- SysReg->Name + "'");
-
- // Accept a named Sys Reg if the required features are present.
- if (SysReg) {
- const auto &FeatureBits = getSTI().getFeatureBits();
- if (!SysReg->haveRequiredFeatures(FeatureBits)) {
- const auto *Feature = llvm::find_if(RISCVFeatureKV, [&](auto Feature) {
- return SysReg->FeaturesRequired[Feature.Value];
- });
- auto ErrorMsg = std::string("system register '") + SysReg->Name + "' ";
- if (SysReg->isRV32Only && FeatureBits[RISCV::Feature64Bit]) {
- ErrorMsg += "is RV32 only";
- if (Feature != std::end(RISCVFeatureKV))
- ErrorMsg += " and ";
- }
- if (Feature != std::end(RISCVFeatureKV)) {
- ErrorMsg +=
- "requires '" + std::string(Feature->Key) + "' to be enabled";
- }
-
- return Error(S, ErrorMsg);
- }
- Operands.push_back(
- RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
- return ParseStatus::Success;
- }
-
return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
"operand must be a valid system register "
"name or an integer in the range");
diff --git a/llvm/test/MC/RISCV/rv32i-invalid.s b/llvm/test/MC/RISCV/rv32i-invalid.s
index 80a59df94e36a3..a33b53b8237e5f 100644
--- a/llvm/test/MC/RISCV/rv32i-invalid.s
+++ b/llvm/test/MC/RISCV/rv32i-invalid.s
@@ -21,13 +21,13 @@ ori a0, a1, -2049 # CHECK: :[[@LINE]]:13: error: operand must be a symbol with %
andi ra, sp, 2048 # CHECK: :[[@LINE]]:14: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047]
## uimm12
-csrrw a0, -1, a0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 4095]
-csrrs a0, 4096, a0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 4095]
-csrrs a0, -0xf, a0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 4095]
-csrrc a0, 0x1000, a0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 4095]
-csrrwi a0, -50, 0 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [0, 4095]
-csrrsi a0, 4097, a0 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [0, 4095]
-csrrci a0, 0xffff, a0 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [0, 4095]
+csrrw a0, -1, a0 # CHECK: :[[@LINE]]:11: error: operand must be a valid system register name or an integer in the range [0, 4095]
+csrrs a0, 4096, a0 # CHECK: :[[@LINE]]:11: error: operand must be a valid system register name or an integer in the range [0, 4095]
+csrrs a0, -0xf, a0 # CHECK: :[[@LINE]]:11: error: operand must be a valid system register name or an integer in the range [0, 4095]
+csrrc a0, 0x1000, a0 # CHECK: :[[@LINE]]:11: error: operand must be a valid system register name or an integer in the range [0, 4095]
+csrrwi a0, -50, 0 # CHECK: :[[@LINE]]:12: error: operand must be a valid system register name or an integer in the range [0, 4095]
+csrrsi a0, 4097, a0 # CHECK: :[[@LINE]]:12: error: operand must be a valid system register name or an integer in the range [0, 4095]
+csrrci a0, 0xffff, a0 # CHECK: :[[@LINE]]:12: error: operand must be a valid system register name or an integer in the range [0, 4095]
## simm13_lsb0
beq t0, t1, -4098 # CHECK: :[[@LINE]]:13: error: immediate must be a multiple of 2 bytes in the range [-4096, 4094]
diff --git a/llvm/test/MC/RISCV/rv32i-valid.s b/llvm/test/MC/RISCV/rv32i-valid.s
index f03c2e1c23cf3b..c5bad80e79de2d 100644
--- a/llvm/test/MC/RISCV/rv32i-valid.s
+++ b/llvm/test/MC/RISCV/rv32i-valid.s
@@ -373,3 +373,6 @@ csrrsi t2, 0xfff, 31
# CHECK-ASM-AND-OBJ: csrrci t1, sscratch, 5
# CHECK-ASM: encoding: [0x73,0xf3,0x02,0x14]
csrrci t1, 0x140, 5
+# CHECK-ASM-AND-OBJ: csrrw t0, 16, t1
+# CHECK-ASM: encoding: [0xf3,0x12,0x03,0x01]
+csrrw t0, CONST, t1
More information about the llvm-commits
mailing list