@@ -1878,6 +1878,26 @@ 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+ }
1893+ // Accept an immediate representing an un-named Sys Reg if the range is
1894+ // valid, regardless of the required features.
1895+ return RISCVOperand::createSysReg (" " , S, Imm);
1896+ }
1897+ }
1898+ return std::unique_ptr<RISCVOperand>();
1899+ };
1900+
18811901 switch (getLexer ().getKind ()) {
18821902 default :
18831903 return ParseStatus::NoMatch;
@@ -1891,24 +1911,9 @@ ParseStatus RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {
18911911 if (getParser ().parseExpression (Res))
18921912 return ParseStatus::Failure;
18931913
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- }
1914+ if (auto SysOpnd = SysRegFromConstantInt (Res, S)) {
1915+ Operands.push_back (std::move (SysOpnd));
1916+ return ParseStatus::Success;
19121917 }
19131918
19141919 return generateImmOutOfRangeError (S, 0 , (1 << 12 ) - 1 );
@@ -1951,6 +1956,18 @@ ParseStatus RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {
19511956 return ParseStatus::Success;
19521957 }
19531958
1959+ // Accept a symbol name that evaluates to an absolute value.
1960+ MCSymbol *Sym = getContext ().lookupSymbol (Identifier);
1961+ if (Sym && Sym->isVariable ()) {
1962+ // Pass false for SetUsed, since redefining the value later does not
1963+ // affect this instruction.
1964+ if (auto SysOpnd = SysRegFromConstantInt (
1965+ Sym->getVariableValue (/* SetUsed=*/ false ), S)) {
1966+ Operands.push_back (std::move (SysOpnd));
1967+ return ParseStatus::Success;
1968+ }
1969+ }
1970+
19541971 return generateImmOutOfRangeError (S, 0 , (1 << 12 ) - 1 ,
19551972 " operand must be a valid system register "
19561973 " name or an integer in the range" );
0 commit comments