[llvm] [RISC-V][MC] Accept an absolute variable value as a CSR number (PR #67377)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 25 14:59:22 PDT 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mc
<details>
<summary>Changes</summary>
This is used by https://github.com/riscv-non-isa/riscv-arch-test and is accepted by GCC so it seems like we should be doing the same here.
---
Full diff: https://github.com/llvm/llvm-project/pull/67377.diff
2 Files Affected:
- (modified) llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp (+28-11)
- (added) llvm/test/MC/RISCV/csr-abs-sym.s (+48)
``````````diff
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 7d8d82e381313bf..4b1a5745308dcc2 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -1762,6 +1762,19 @@ ParseStatus RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {
SMLoc S = getLoc();
const MCExpr *Res;
+ auto SysRegFromConstantInt = [](const MCExpr *E, SMLoc S) {
+ if (auto *CE = dyn_cast<MCConstantExpr>(E)) {
+ int64_t Imm = CE->getValue();
+ if (isUInt<12>(Imm)) {
+ auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm);
+ // Accept an immediate representing a named or un-named Sys Reg
+ // if the range is valid, regardless of the required features.
+ return RISCVOperand::createSysReg(SysReg ? SysReg->Name : "", S, Imm);
+ }
+ }
+ return std::unique_ptr<RISCVOperand>();
+ };
+
switch (getLexer().getKind()) {
default:
return ParseStatus::NoMatch;
@@ -1775,17 +1788,9 @@ ParseStatus RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {
if (getParser().parseExpression(Res))
return ParseStatus::Failure;
- auto *CE = dyn_cast<MCConstantExpr>(Res);
- if (CE) {
- int64_t Imm = CE->getValue();
- if (isUInt<12>(Imm)) {
- auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm);
- // Accept an immediate representing a named or un-named Sys Reg
- // if the range is valid, regardless of the required features.
- Operands.push_back(
- RISCVOperand::createSysReg(SysReg ? SysReg->Name : "", S, Imm));
- return ParseStatus::Success;
- }
+ if (auto SysOpnd = SysRegFromConstantInt(Res, S)) {
+ Operands.push_back(std::move(SysOpnd));
+ return ParseStatus::Success;
}
return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
@@ -1851,6 +1856,18 @@ ParseStatus RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {
return ParseStatus::Success;
}
+ // Accept a symbol name that evaluates to an absolute value.
+ MCSymbol *Sym = getContext().lookupSymbol(Identifier);
+ if (Sym && Sym->isVariable()) {
+ // Pass false for SetUsed, since redefining the value later does not
+ // affect this instruction.
+ if (auto SysOpnd = SysRegFromConstantInt(
+ Sym->getVariableValue(/*SetUsed=*/false), S)) {
+ Operands.push_back(std::move(SysOpnd));
+ 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/csr-abs-sym.s b/llvm/test/MC/RISCV/csr-abs-sym.s
new file mode 100644
index 000000000000000..93ecab0db106ba9
--- /dev/null
+++ b/llvm/test/MC/RISCV/csr-abs-sym.s
@@ -0,0 +1,48 @@
+## Check that we can use an absolute symbol value as a CSR number
+# RUN: llvm-mc -triple riscv32 %s | FileCheck %s
+# RUN: not llvm-mc -triple riscv32 %s --defsym=CHECK_BAD=1 2>&1 | FileCheck %s --check-prefix=ERROR
+
+.set fflags_abs_sym, 1
+csrr a0, fflags_abs_sym
+# CHECK: csrr a0, fflags
+
+csrr a0, (fflags_abs_sym+1)
+# CHECK: csrr a0, frm
+
+.equ fplus_one_abs_sym, fflags_abs_sym + 1
+csrr a0, fplus_one_abs_sym
+# CHECK: csrr a0, frm
+
+## Check that redefining the value is allowed
+## If we were to use Sym->getVariableValue(true) this code would assert with
+## Assertion `!IsUsed && "Cannot set a variable that has already been used."' failed.
+.set csr_index, 1
+# CHECK: csrr a0, fflags
+csrr a0, csr_index
+.set csr_index, 2
+# CHECK: csrr a0, frm
+csrr a0, csr_index
+
+.ifdef CHECK_BAD
+.set out_of_range, 4097
+csrr a0, out_of_range
+# ERROR: [[#@LINE-1]]:10: error: operand must be a valid system register name or an integer in the range [0, 4095]
+
+csrr a0, undef_symbol
+# ERROR: [[#@LINE-1]]:10: error: operand must be a valid system register name or an integer in the range [0, 4095]
+
+local_label:
+csrr a0, local_label
+# ERROR: [[#@LINE-1]]:10: error: operand must be a valid system register name or an integer in the range [0, 4095]
+
+.Lstart:
+.space 10
+.Lend:
+csrr a0, .Lstart-.Lend
+# ERROR: [[#@LINE-1]]:10: error: operand must be a valid system register name or an integer in the range [0, 4095]
+
+.set dot_set_sym_diff, .Lstart-.Lend
+csrr a0, dot_set_sym_diff
+# ERROR: [[#@LINE-1]]:10: error: operand must be a valid system register name or an integer in the range [0, 4095]
+
+.endif
``````````
</details>
https://github.com/llvm/llvm-project/pull/67377
More information about the llvm-commits
mailing list