@@ -1878,6 +1878,25 @@ ParseStatus RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {
1878
1878
SMLoc S = getLoc ();
1879
1879
const MCExpr *Res;
1880
1880
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
+
1881
1900
switch (getLexer ().getKind ()) {
1882
1901
default :
1883
1902
return ParseStatus::NoMatch;
@@ -1891,24 +1910,9 @@ ParseStatus RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {
1891
1910
if (getParser ().parseExpression (Res))
1892
1911
return ParseStatus::Failure;
1893
1912
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;
1912
1916
}
1913
1917
1914
1918
return generateImmOutOfRangeError (S, 0 , (1 << 12 ) - 1 );
@@ -1951,6 +1955,18 @@ ParseStatus RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {
1951
1955
return ParseStatus::Success;
1952
1956
}
1953
1957
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
+
1954
1970
return generateImmOutOfRangeError (S, 0 , (1 << 12 ) - 1 ,
1955
1971
" operand must be a valid system register "
1956
1972
" name or an integer in the range" );
0 commit comments