diff --git a/tests/backend/riscv/test_regalloc.py b/tests/backend/riscv/test_regalloc.py index 9a00f4d184..f77092234a 100644 --- a/tests/backend/riscv/test_regalloc.py +++ b/tests/backend/riscv/test_regalloc.py @@ -66,7 +66,7 @@ def main_region() -> None: riscv.LabelOp("main", main_region) - riscv.AssemblySectionOp(".text", text_region) + riscv.DirectiveOp(".text", None, text_region) @ModuleOp @@ -109,7 +109,7 @@ def main_region() -> None: riscv.LabelOp("main", main_region) - riscv.AssemblySectionOp(".text", text_region) + riscv.DirectiveOp(".text", None, text_region) def test_allocate_simple_linear(): diff --git a/tests/filecheck/dialects/riscv/riscv_assembly_emission.mlir b/tests/filecheck/dialects/riscv/riscv_assembly_emission.mlir index 101cbb653b..df3b7d3a24 100644 --- a/tests/filecheck/dialects/riscv/riscv_assembly_emission.mlir +++ b/tests/filecheck/dialects/riscv/riscv_assembly_emission.mlir @@ -1,7 +1,7 @@ // RUN: xdsl-opt -t riscv-asm %s | filecheck %s "builtin.module"() ({ - riscv.label {"label" = #riscv.label<"main">} ({ + "riscv.label"() ({ %0 = "riscv.li"() {"immediate" = 6 : i32} : () -> !riscv.reg // CHECK: li zero, 6 %1 = "riscv.li"() {"immediate" = 5 : i32} : () -> !riscv.reg @@ -160,9 +160,9 @@ "riscv.directive"() {"directive" = ".align", "value" = "2"} : () -> () // CHECK-NEXT: .align 2 - riscv.assembly_section ".text" { + "riscv.directive"() ({ %nested_addi = "riscv.addi"(%1) {"immediate" = 1 : i32}: (!riscv.reg) -> !riscv.reg - } + }) {"directive" = ".text"} : () -> () // CHECK-NEXT: .text // CHECK-NEXT: addi j1, j1, 1 "riscv.label"() {"label" = #riscv.label<"label0">} : () -> () @@ -245,5 +245,5 @@ // Terminate block "riscv.ret"() : () -> () // CHECK-NEXT: ret - }) : () -> () + }) {"label" = #riscv.label<"main">}: () -> () }) : () -> () diff --git a/tests/filecheck/dialects/riscv/riscv_ops.mlir b/tests/filecheck/dialects/riscv/riscv_ops.mlir index ba0adcb9c4..dab0e526ce 100644 --- a/tests/filecheck/dialects/riscv/riscv_ops.mlir +++ b/tests/filecheck/dialects/riscv/riscv_ops.mlir @@ -180,19 +180,12 @@ // CHECK-NEXT: riscv.ebreak : () -> () riscv.directive {"directive" = ".align", "value" = "2"} : () -> () // CHECK-NEXT: riscv.directive {"directive" = ".align", "value" = "2"} : () -> () - riscv.assembly_section ".text" attributes {"foo" = i32} { + riscv.directive {"directive" = ".text"} ({ %nested_li = riscv.li {"immediate" = 1 : i32} : () -> !riscv.reg<> - } - // CHECK-NEXT: riscv.assembly_section ".text" attributes {"foo" = i32} { + }) : () -> () + // CHECK-NEXT: riscv.directive {"directive" = ".text"} ({ // CHECK-NEXT: %{{.*}} = riscv.li {"immediate" = 1 : i32} : () -> !riscv.reg<> - // CHECK-NEXT: } - - riscv.assembly_section ".text" { - %nested_li = riscv.li {"immediate" = 1 : i32} : () -> !riscv.reg<> - } - // CHECK-NEXT: riscv.assembly_section ".text" { - // CHECK-NEXT: %{{.*}} = riscv.li {"immediate" = 1 : i32} : () -> !riscv.reg<> - // CHECK-NEXT: } + // CHECK-NEXT: }) : () -> () // Custom instruction %custom0, %custom1 = riscv.custom_assembly_instruction %0, %1 {"instruction_name" = "hello"} : (!riscv.reg<>, !riscv.reg<>) -> (!riscv.reg<>, !riscv.reg<>) diff --git a/xdsl/dialects/riscv.py b/xdsl/dialects/riscv.py index b649161fa3..d508dbb315 100644 --- a/xdsl/dialects/riscv.py +++ b/xdsl/dialects/riscv.py @@ -18,7 +18,6 @@ ) from xdsl.ir import ( Attribute, - Block, Data, Dialect, Operation, @@ -30,6 +29,7 @@ from xdsl.irdl import ( IRDLOperation, Operand, + OptRegion, OptSingleBlockRegion, VarOperand, VarOpResult, @@ -38,11 +38,11 @@ irdl_op_definition, operand_def, opt_attr_def, + opt_region_def, result_def, var_operand_def, var_result_def, ) -from xdsl.irdl.irdl import OptRegion, opt_region_def, region_def from xdsl.parser import AttrParser, Parser, UnresolvedOperand from xdsl.printer import Printer from xdsl.traits import IsTerminator, NoTerminator @@ -2115,8 +2115,7 @@ def assembly_line(self) -> str | None: @irdl_op_definition class DirectiveOp(IRDLOperation, RISCVOp): """ - The directive operation is used to emit assembler directives (e.g. .word; .equ; etc.) - without any associated region of assembly code. + The directive operation is used to emit assembler directives (e.g. .word; .text; .data; etc.) A more complete list of directives can be found here: https://github.com/riscv-non-isa/riscv-asm-manual/blob/master/riscv-asm.md#pseudo-ops @@ -2125,22 +2124,29 @@ class DirectiveOp(IRDLOperation, RISCVOp): name = "riscv.directive" directive: StringAttr = attr_def(StringAttr) value: StringAttr | None = opt_attr_def(StringAttr) + data: OptRegion = opt_region_def("single_block") + + traits = frozenset([NoTerminator()]) def __init__( self, directive: str | StringAttr, value: str | StringAttr | None, + region: OptSingleBlockRegion = None, ): if isinstance(directive, str): directive = StringAttr(directive) if isinstance(value, str): value = StringAttr(value) + if region is None: + region = Region() super().__init__( attributes={ "directive": directive, "value": value, - } + }, + regions=[region], ) def assembly_line(self) -> str | None: @@ -2152,68 +2158,6 @@ def assembly_line(self) -> str | None: return _assembly_line(self.directive.data, arg_str, is_indented=False) -@irdl_op_definition -class AssemblySectionOp(IRDLOperation, RISCVOp): - """ - The directive operation is used to emit assembler directives (e.g. .text; .data; etc.) - with the scope of a section. - - A more complete list of directives can be found here: - - https://github.com/riscv-non-isa/riscv-asm-manual/blob/master/riscv-asm.md#pseudo-ops - - This operation can have nested operations, corresponding to a section of the assembly. - """ - - name = "riscv.assembly_section" - directive: StringAttr = attr_def(StringAttr) - data: Region = region_def("single_block") - - traits = frozenset([NoTerminator()]) - - def __init__( - self, - directive: str | StringAttr, - region: OptSingleBlockRegion = None, - ): - if isinstance(directive, str): - directive = StringAttr(directive) - if region is None: - region = Region() - - super().__init__( - regions=[region], - attributes={ - "directive": directive, - }, - ) - - @classmethod - def parse(cls, parser: Parser) -> AssemblySectionOp: - directive = parser.parse_str_literal() - attr_dict = parser.parse_optional_attr_dict_with_keyword(("directive")) - region = parser.parse_optional_region() - - if region is None: - region = Region(Block()) - section = AssemblySectionOp(directive, region) - if attr_dict is not None: - section.attributes |= attr_dict.data - - return section - - def print(self, printer: Printer) -> None: - printer.print_string(" ") - printer.print_string_literal(self.directive.data) - printer.print_op_attributes_with_keyword(self.attributes, ("directive")) - printer.print_string(" ") - if self.data.block.ops: - printer.print_region(self.data) - - def assembly_line(self) -> str | None: - return _assembly_line(self.directive.data, "", is_indented=False) - - @irdl_op_definition class CustomAssemblyInstructionOp(IRDLOperation, RISCVInstruction): """ @@ -3107,7 +3051,6 @@ class FSwOp(RsRsImmFloatOperation): EcallOp, LabelOp, DirectiveOp, - AssemblySectionOp, EbreakOp, WfiOp, CustomAssemblyInstructionOp,