Skip to content

Commit 6eb93d0

Browse files
zqb-allarichardson
andauthored
[RISCV][MC] Support imm symbol in parseCSRSystemRegister (#112007)
Co-authored-by: Alex Richardson <[email protected]>
1 parent dd76d9b commit 6eb93d0

File tree

3 files changed

+76
-18
lines changed

3 files changed

+76
-18
lines changed

llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1878,6 +1878,25 @@ ParseStatus RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {
18781878
SMLoc S = getLoc();
18791879
const MCExpr *Res;
18801880

1881+
auto SysRegFromConstantInt = [this](const MCExpr *E, SMLoc S) {
1882+
if (auto *CE = dyn_cast<MCConstantExpr>(E)) {
1883+
int64_t Imm = CE->getValue();
1884+
if (isUInt<12>(Imm)) {
1885+
auto Range = RISCVSysReg::lookupSysRegByEncoding(Imm);
1886+
// Accept an immediate representing a named Sys Reg if it satisfies the
1887+
// the required features.
1888+
for (auto &Reg : Range) {
1889+
if (Reg.haveRequiredFeatures(STI->getFeatureBits()))
1890+
return RISCVOperand::createSysReg(Reg.Name, S, Imm);
1891+
}
1892+
// Accept an immediate representing an un-named Sys Reg if the range is
1893+
// valid, regardless of the required features.
1894+
return RISCVOperand::createSysReg("", S, Imm);
1895+
}
1896+
}
1897+
return std::unique_ptr<RISCVOperand>();
1898+
};
1899+
18811900
switch (getLexer().getKind()) {
18821901
default:
18831902
return ParseStatus::NoMatch;
@@ -1891,24 +1910,9 @@ ParseStatus RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {
18911910
if (getParser().parseExpression(Res))
18921911
return ParseStatus::Failure;
18931912

1894-
auto *CE = dyn_cast<MCConstantExpr>(Res);
1895-
if (CE) {
1896-
int64_t Imm = CE->getValue();
1897-
if (isUInt<12>(Imm)) {
1898-
auto Range = RISCVSysReg::lookupSysRegByEncoding(Imm);
1899-
// Accept an immediate representing a named Sys Reg if it satisfies the
1900-
// the required features.
1901-
for (auto &Reg : Range) {
1902-
if (Reg.haveRequiredFeatures(STI->getFeatureBits())) {
1903-
Operands.push_back(RISCVOperand::createSysReg(Reg.Name, S, Imm));
1904-
return ParseStatus::Success;
1905-
}
1906-
}
1907-
// Accept an immediate representing an un-named Sys Reg if the range is
1908-
// valid, regardless of the required features.
1909-
Operands.push_back(RISCVOperand::createSysReg("", S, Imm));
1910-
return ParseStatus::Success;
1911-
}
1913+
if (auto SysOpnd = SysRegFromConstantInt(Res, S)) {
1914+
Operands.push_back(std::move(SysOpnd));
1915+
return ParseStatus::Success;
19121916
}
19131917

19141918
return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
@@ -1951,6 +1955,18 @@ ParseStatus RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {
19511955
return ParseStatus::Success;
19521956
}
19531957

1958+
// Accept a symbol name that evaluates to an absolute value.
1959+
MCSymbol *Sym = getContext().lookupSymbol(Identifier);
1960+
if (Sym && Sym->isVariable()) {
1961+
// Pass false for SetUsed, since redefining the value later does not
1962+
// affect this instruction.
1963+
if (auto SysOpnd = SysRegFromConstantInt(
1964+
Sym->getVariableValue(/*SetUsed=*/false), S)) {
1965+
Operands.push_back(std::move(SysOpnd));
1966+
return ParseStatus::Success;
1967+
}
1968+
}
1969+
19541970
return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
19551971
"operand must be a valid system register "
19561972
"name or an integer in the range");

llvm/test/MC/RISCV/rv32i-invalid.s

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,19 @@ csrrsi a0, mhpm12counter, a0 # CHECK: :[[@LINE]]:12: error: operand must be a va
9393
csrrwi a0, mhpmcounter32, 0 # CHECK: :[[@LINE]]:12: error: operand must be a valid system register name or an integer in the range [0, 4095]
9494
csrrsi a0, A, a0 # CHECK: :[[@LINE]]:12: error: operand must be a valid system register name or an integer in the range [0, 4095]
9595

96+
## symbol in place of uimm12
97+
.set out_of_range, 4096
98+
csrr a0, out_of_range # CHECK: [[#@LINE]]:10: error: operand must be a valid system register name or an integer in the range [0, 4095]
99+
csrr a0, undef_symbol # CHECK: [[#@LINE]]:10: error: operand must be a valid system register name or an integer in the range [0, 4095]
100+
local_label:
101+
csrr a0, local_label # CHECK: [[#@LINE]]:10: error: operand must be a valid system register name or an integer in the range [0, 4095]
102+
.Lstart:
103+
.space 10
104+
.Lend:
105+
csrr a0, .Lstart-.Lend # CHECK: [[#@LINE]]:10: error: operand must be a valid system register name or an integer in the range [0, 4095]
106+
.set dot_set_sym_diff, .Lstart-.Lend
107+
csrr a0, dot_set_sym_diff # CHECK: [[#@LINE]]:10: error: operand must be a valid system register name or an integer in the range [0, 4095]
108+
96109
## simm13_lsb0
97110
beq t0, t1, %lo(1) # CHECK: :[[@LINE]]:13: error: immediate must be a multiple of 2 bytes in the range [-4096, 4094]
98111
bne t0, t1, %lo(a) # CHECK: :[[@LINE]]:13: error: immediate must be a multiple of 2 bytes in the range [-4096, 4094]

llvm/test/MC/RISCV/rv32i-valid.s

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,3 +373,32 @@ csrrsi t2, 0xfff, 31
373373
# CHECK-ASM-AND-OBJ: csrrci t1, sscratch, 5
374374
# CHECK-ASM: encoding: [0x73,0xf3,0x02,0x14]
375375
csrrci t1, 0x140, 5
376+
377+
## Check that we can use an absolute symbol value as a CSR number
378+
# CHECK-ASM-AND-OBJ: csrrs a0, fflags, zero
379+
# CHECK-ASM: encoding: [0x73,0x25,0x10,0x00]
380+
.set fflags_abs_sym, 1
381+
csrr a0, fflags_abs_sym
382+
# CHECK-ASM-AND-OBJ: csrrs a0, frm, zero
383+
# CHECK-ASM: encoding: [0x73,0x25,0x20,0x00]
384+
csrr a0, (fflags_abs_sym+1)
385+
# CHECK-ASM-AND-OBJ: csrrs a0, frm, zero
386+
# CHECK-ASM: encoding: [0x73,0x25,0x20,0x00]
387+
.equ fplus_one_abs_sym, fflags_abs_sym + 1
388+
csrr a0, fplus_one_abs_sym
389+
390+
## Check that redefining the value is allowed
391+
# CHECK-ASM-AND-OBJ: csrrs a0, fflags, zero
392+
# CHECK-ASM: encoding: [0x73,0x25,0x10,0x00]
393+
.set csr_index, 1
394+
csrr a0, csr_index
395+
# CHECK-ASM-AND-OBJ: csrrs a0, frm, zero
396+
# CHECK-ASM: encoding: [0x73,0x25,0x20,0x00]
397+
.set csr_index, 2
398+
csrr a0, csr_index
399+
400+
## Check that select the CSR first.
401+
.set frm, 1
402+
# CHECK-ASM-AND-OBJ: csrrs a0, frm, zero
403+
# CHECK-ASM: encoding: [0x73,0x25,0x20,0x00]
404+
csrr a0, frm

0 commit comments

Comments
 (0)