@@ -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" );
0 commit comments