diff --git a/tests/dialects/test_riscv.py b/tests/dialects/test_riscv.py index 614e246cfe..142b017f76 100644 --- a/tests/dialects/test_riscv.py +++ b/tests/dialects/test_riscv.py @@ -3,7 +3,9 @@ from xdsl.builder import Builder from xdsl.dialects import riscv from xdsl.dialects.builtin import IntegerAttr, ModuleOp, i32 -from xdsl.utils.exceptions import VerifyException +from xdsl.ir import MLContext +from xdsl.parser import Parser +from xdsl.utils.exceptions import ParseError, VerifyException from xdsl.utils.test_value import TestSSAValue @@ -246,3 +248,13 @@ def test_float_register(): f1 = TestSSAValue(riscv.Registers.FT0) f2 = TestSSAValue(riscv.Registers.FT1) riscv.FAddSOp(f1, f2).verify() + + +def test_riscv_parse_immediate_value(): + ctx = MLContext() + ctx.register_dialect(riscv.RISCV) + + prog = """riscv.jalr %0, 1.1, !riscv.reg<> : (!riscv.reg<>) -> ()""" + parser = Parser(ctx, prog) + with pytest.raises(ParseError, match="Expected immediate"): + parser.parse_operation() diff --git a/xdsl/dialects/riscv.py b/xdsl/dialects/riscv.py index b649161fa3..bfb936998d 100644 --- a/xdsl/dialects/riscv.py +++ b/xdsl/dialects/riscv.py @@ -9,6 +9,7 @@ from xdsl.dialects.builtin import ( AnyIntegerAttr, + IndexType, IntegerAttr, IntegerType, ModuleOp, @@ -759,12 +760,9 @@ def assembly_line_args(self) -> tuple[AssemblyInstructionArg | None, ...]: @classmethod def custom_parse_attributes(cls, parser: Parser) -> Mapping[str, Attribute]: attributes = dict[str, Attribute]() - if immediate := parser.parse_optional_integer(allow_boolean=False): - attributes["immediate"] = IntegerAttr( - immediate, IntegerType(12, Signedness.SIGNED) - ) - elif immediate := parser.parse_optional_str_literal(): - attributes["immediate"] = LabelAttr(immediate) + attributes["immediate"] = _parse_immediate_value( + parser, IntegerType(12, Signedness.SIGNED) + ) if parser.parse_optional_punctuation(","): attributes["rd"] = parser.parse_attribute() return attributes @@ -3046,6 +3044,28 @@ class FSwOp(RsRsImmFloatOperation): # endregion + +def _parse_optional_immediate_value( + parser: Parser, integer_type: IntegerType | IndexType +) -> IntegerAttr[IntegerType | IndexType] | LabelAttr | None: + """ + Parse an optional immediate value. If an integer is parsed, an integer attr with the specified type is created. + """ + if (immediate := parser.parse_optional_integer()) is not None: + return IntegerAttr(immediate, integer_type) + if (immediate := parser.parse_optional_str_literal()) is not None: + return LabelAttr(immediate) + + +def _parse_immediate_value( + parser: Parser, integer_type: IntegerType | IndexType +) -> IntegerAttr[IntegerType | IndexType] | LabelAttr: + return parser.expect( + lambda: _parse_optional_immediate_value(parser, integer_type), + "Expected immediate", + ) + + RISCV = Dialect( [ AddiOp,