Skip to content

Commit 57527c5

Browse files
committed
[RISCV][MC] Support imm symbol in parseCSRSystemRegister
1 parent 33c14f1 commit 57527c5

File tree

3 files changed

+55
-48
lines changed

3 files changed

+55
-48
lines changed

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

Lines changed: 45 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1877,10 +1877,13 @@ ParseStatus RISCVAsmParser::parseInsnCDirectiveOpcode(OperandVector &Operands) {
18771877
ParseStatus RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {
18781878
SMLoc S = getLoc();
18791879
const MCExpr *Res;
1880+
auto Kind = getLexer().getKind();
18801881

1881-
switch (getLexer().getKind()) {
1882+
switch (Kind) {
18821883
default:
18831884
return ParseStatus::NoMatch;
1885+
1886+
case AsmToken::Identifier:
18841887
case AsmToken::LParen:
18851888
case AsmToken::Minus:
18861889
case AsmToken::Plus:
@@ -1891,6 +1894,47 @@ ParseStatus RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {
18911894
if (getParser().parseExpression(Res))
18921895
return ParseStatus::Failure;
18931896

1897+
if (Kind == AsmToken::Identifier) {
1898+
auto SRE = dyn_cast<MCSymbolRefExpr>(Res);
1899+
if (SRE) {
1900+
auto Identifier = SRE->getSymbol().getName();
1901+
const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
1902+
if (!SysReg)
1903+
SysReg = RISCVSysReg::lookupSysRegByAltName(Identifier);
1904+
if (!SysReg)
1905+
if ((SysReg = RISCVSysReg::lookupSysRegByDeprecatedName(Identifier)))
1906+
Warning(S, "'" + Identifier + "' is a deprecated alias for '" +
1907+
SysReg->Name + "'");
1908+
1909+
// Accept a named Sys Reg if the required features are present.
1910+
if (SysReg) {
1911+
const auto &FeatureBits = getSTI().getFeatureBits();
1912+
if (!SysReg->haveRequiredFeatures(FeatureBits)) {
1913+
const auto *Feature =
1914+
llvm::find_if(RISCVFeatureKV, [&](auto Feature) {
1915+
return SysReg->FeaturesRequired[Feature.Value];
1916+
});
1917+
auto ErrorMsg =
1918+
std::string("system register '") + SysReg->Name + "' ";
1919+
if (SysReg->isRV32Only && FeatureBits[RISCV::Feature64Bit]) {
1920+
ErrorMsg += "is RV32 only";
1921+
if (Feature != std::end(RISCVFeatureKV))
1922+
ErrorMsg += " and ";
1923+
}
1924+
if (Feature != std::end(RISCVFeatureKV)) {
1925+
ErrorMsg +=
1926+
"requires '" + std::string(Feature->Key) + "' to be enabled";
1927+
}
1928+
1929+
return Error(S, ErrorMsg);
1930+
}
1931+
Operands.push_back(
1932+
RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
1933+
return ParseStatus::Success;
1934+
}
1935+
}
1936+
}
1937+
18941938
auto *CE = dyn_cast<MCConstantExpr>(Res);
18951939
if (CE) {
18961940
int64_t Imm = CE->getValue();
@@ -1911,46 +1955,6 @@ ParseStatus RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {
19111955
}
19121956
}
19131957

1914-
return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
1915-
}
1916-
case AsmToken::Identifier: {
1917-
StringRef Identifier;
1918-
if (getParser().parseIdentifier(Identifier))
1919-
return ParseStatus::Failure;
1920-
1921-
const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
1922-
if (!SysReg)
1923-
SysReg = RISCVSysReg::lookupSysRegByAltName(Identifier);
1924-
if (!SysReg)
1925-
if ((SysReg = RISCVSysReg::lookupSysRegByDeprecatedName(Identifier)))
1926-
Warning(S, "'" + Identifier + "' is a deprecated alias for '" +
1927-
SysReg->Name + "'");
1928-
1929-
// Accept a named Sys Reg if the required features are present.
1930-
if (SysReg) {
1931-
const auto &FeatureBits = getSTI().getFeatureBits();
1932-
if (!SysReg->haveRequiredFeatures(FeatureBits)) {
1933-
const auto *Feature = llvm::find_if(RISCVFeatureKV, [&](auto Feature) {
1934-
return SysReg->FeaturesRequired[Feature.Value];
1935-
});
1936-
auto ErrorMsg = std::string("system register '") + SysReg->Name + "' ";
1937-
if (SysReg->isRV32Only && FeatureBits[RISCV::Feature64Bit]) {
1938-
ErrorMsg += "is RV32 only";
1939-
if (Feature != std::end(RISCVFeatureKV))
1940-
ErrorMsg += " and ";
1941-
}
1942-
if (Feature != std::end(RISCVFeatureKV)) {
1943-
ErrorMsg +=
1944-
"requires '" + std::string(Feature->Key) + "' to be enabled";
1945-
}
1946-
1947-
return Error(S, ErrorMsg);
1948-
}
1949-
Operands.push_back(
1950-
RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
1951-
return ParseStatus::Success;
1952-
}
1953-
19541958
return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
19551959
"operand must be a valid system register "
19561960
"name or an integer in the range");

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ ori a0, a1, -2049 # CHECK: :[[@LINE]]:13: error: operand must be a symbol with %
2121
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]
2222

2323
## uimm12
24-
csrrw a0, -1, a0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 4095]
25-
csrrs a0, 4096, a0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 4095]
26-
csrrs a0, -0xf, a0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 4095]
27-
csrrc a0, 0x1000, a0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 4095]
28-
csrrwi a0, -50, 0 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [0, 4095]
29-
csrrsi a0, 4097, a0 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [0, 4095]
30-
csrrci a0, 0xffff, a0 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [0, 4095]
24+
csrrw a0, -1, a0 # CHECK: :[[@LINE]]:11: error: operand must be a valid system register name or an integer in the range [0, 4095]
25+
csrrs a0, 4096, a0 # CHECK: :[[@LINE]]:11: error: operand must be a valid system register name or an integer in the range [0, 4095]
26+
csrrs a0, -0xf, a0 # CHECK: :[[@LINE]]:11: error: operand must be a valid system register name or an integer in the range [0, 4095]
27+
csrrc a0, 0x1000, a0 # CHECK: :[[@LINE]]:11: error: operand must be a valid system register name or an integer in the range [0, 4095]
28+
csrrwi a0, -50, 0 # CHECK: :[[@LINE]]:12: error: operand must be a valid system register name or an integer in the range [0, 4095]
29+
csrrsi a0, 4097, a0 # CHECK: :[[@LINE]]:12: error: operand must be a valid system register name or an integer in the range [0, 4095]
30+
csrrci a0, 0xffff, a0 # CHECK: :[[@LINE]]:12: error: operand must be a valid system register name or an integer in the range [0, 4095]
3131

3232
## simm13_lsb0
3333
beq t0, t1, -4098 # 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: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,3 +373,6 @@ 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+
# CHECK-ASM-AND-OBJ: csrrw t0, 16, t1
377+
# CHECK-ASM: encoding: [0xf3,0x12,0x03,0x01]
378+
csrrw t0, CONST, t1

0 commit comments

Comments
 (0)