Skip to content

Abstract ops

abstract_ops

AssemblyInstructionArg: TypeAlias = IntegerAttr | LabelAttr | SSAValue | RegisterType | str module-attribute

IWidth = TypeVar('IWidth', bound=I32 | I64) module-attribute

ShiftImmT = TypeVar('ShiftImmT', bound=UI5 | UI6) module-attribute

ShiftImmAttrT = TypeVar('ShiftImmAttrT', bound=I32 | I64) module-attribute

IOffset = TypeVar('IOffset', bound=I12 | SI12) module-attribute

RISCVAsmOperation dataclass

Bases: IRDLOperation, OneLineAssemblyPrintable, ABC

Base class for operations that can be a part of RISC-V assembly printing.

Source code in xdsl/dialects/riscv/abstract_ops.py
class RISCVAsmOperation(IRDLOperation, OneLineAssemblyPrintable, ABC):
    """
    Base class for operations that can be a part of RISC-V assembly printing.
    """

RISCVRegallocOperation dataclass

Bases: HasRegisterConstraints, IRDLOperation, ABC

Base class for operations that can take part in register allocation.

Source code in xdsl/dialects/riscv/abstract_ops.py
class RISCVRegallocOperation(HasRegisterConstraints, IRDLOperation, ABC):
    """
    Base class for operations that can take part in register allocation.
    """

    def get_register_constraints(self) -> RegisterConstraints:
        # The default register constraints are that all operands are "in", and all
        # results are "out" registers.
        # If some registers are "inout" then this function must be overridden.
        return RegisterConstraints(self.operands, self.results, ())

get_register_constraints() -> RegisterConstraints

Source code in xdsl/dialects/riscv/abstract_ops.py
def get_register_constraints(self) -> RegisterConstraints:
    # The default register constraints are that all operands are "in", and all
    # results are "out" registers.
    # If some registers are "inout" then this function must be overridden.
    return RegisterConstraints(self.operands, self.results, ())

RISCVCustomFormatOperation dataclass

Bases: IRDLOperation, ABC

Base class for RISC-V operations that specialize their custom format.

Source code in xdsl/dialects/riscv/abstract_ops.py
class RISCVCustomFormatOperation(IRDLOperation, ABC):
    """
    Base class for RISC-V operations that specialize their custom format.
    """

    @classmethod
    def parse(cls, parser: Parser) -> Self:
        args = cls.parse_unresolved_operands(parser)
        custom_attributes = cls.custom_parse_attributes(parser)
        remaining_attributes = parser.parse_optional_attr_dict()
        # TODO ensure distinct keys for attributes
        attributes = custom_attributes | remaining_attributes
        regions = parser.parse_region_list()
        pos = parser.pos
        operand_types, result_types = cls.parse_op_type(parser)
        operands = parser.resolve_operands(args, operand_types, pos)
        return cls.create(
            operands=operands,
            result_types=result_types,
            attributes=attributes,
            regions=regions,
        )

    @classmethod
    def parse_unresolved_operands(cls, parser: Parser) -> list[UnresolvedOperand]:
        """
        Parse a list of comma separated unresolved operands.

        Notice that this method will consume trailing comma.
        """
        if operand := parser.parse_optional_unresolved_operand():
            operands = [operand]
            while parser.parse_optional_punctuation(",") and (
                operand := parser.parse_optional_unresolved_operand()
            ):
                operands.append(operand)
            return operands
        return []

    @classmethod
    def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
        """
        Parse attributes with custom syntax. Subclasses may override this method.
        """
        return parser.parse_optional_attr_dict()

    @classmethod
    def parse_op_type(
        cls, parser: Parser
    ) -> tuple[Sequence[Attribute], Sequence[Attribute]]:
        parser.parse_punctuation(":")
        func_type = parser.parse_function_type()
        return func_type.inputs.data, func_type.outputs.data

    def print(self, printer: Printer) -> None:
        if self.operands:
            printer.print_string(" ")
            printer.print_list(self.operands, printer.print_operand)
        printed_attributes = self.custom_print_attributes(printer)
        unprinted_attributes = {
            name: attr
            for name, attr in self.attributes.items()
            if name not in printed_attributes
        }
        printer.print_op_attributes(unprinted_attributes)
        printer.print_regions(self.regions)
        self.print_op_type(printer)

    def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
        """
        Print attributes with custom syntax. Return the names of the attributes printed. Subclasses may override this method.
        """
        printer.print_op_attributes(self.attributes)
        return self.attributes.keys()

    def print_op_type(self, printer: Printer) -> None:
        printer.print_string(" : ")
        printer.print_operation_type(self)

parse(parser: Parser) -> Self classmethod

Source code in xdsl/dialects/riscv/abstract_ops.py
@classmethod
def parse(cls, parser: Parser) -> Self:
    args = cls.parse_unresolved_operands(parser)
    custom_attributes = cls.custom_parse_attributes(parser)
    remaining_attributes = parser.parse_optional_attr_dict()
    # TODO ensure distinct keys for attributes
    attributes = custom_attributes | remaining_attributes
    regions = parser.parse_region_list()
    pos = parser.pos
    operand_types, result_types = cls.parse_op_type(parser)
    operands = parser.resolve_operands(args, operand_types, pos)
    return cls.create(
        operands=operands,
        result_types=result_types,
        attributes=attributes,
        regions=regions,
    )

parse_unresolved_operands(parser: Parser) -> list[UnresolvedOperand] classmethod

Parse a list of comma separated unresolved operands.

Notice that this method will consume trailing comma.

Source code in xdsl/dialects/riscv/abstract_ops.py
@classmethod
def parse_unresolved_operands(cls, parser: Parser) -> list[UnresolvedOperand]:
    """
    Parse a list of comma separated unresolved operands.

    Notice that this method will consume trailing comma.
    """
    if operand := parser.parse_optional_unresolved_operand():
        operands = [operand]
        while parser.parse_optional_punctuation(",") and (
            operand := parser.parse_optional_unresolved_operand()
        ):
            operands.append(operand)
        return operands
    return []

custom_parse_attributes(parser: Parser) -> dict[str, Attribute] classmethod

Parse attributes with custom syntax. Subclasses may override this method.

Source code in xdsl/dialects/riscv/abstract_ops.py
@classmethod
def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
    """
    Parse attributes with custom syntax. Subclasses may override this method.
    """
    return parser.parse_optional_attr_dict()

parse_op_type(parser: Parser) -> tuple[Sequence[Attribute], Sequence[Attribute]] classmethod

Source code in xdsl/dialects/riscv/abstract_ops.py
@classmethod
def parse_op_type(
    cls, parser: Parser
) -> tuple[Sequence[Attribute], Sequence[Attribute]]:
    parser.parse_punctuation(":")
    func_type = parser.parse_function_type()
    return func_type.inputs.data, func_type.outputs.data

print(printer: Printer) -> None

Source code in xdsl/dialects/riscv/abstract_ops.py
def print(self, printer: Printer) -> None:
    if self.operands:
        printer.print_string(" ")
        printer.print_list(self.operands, printer.print_operand)
    printed_attributes = self.custom_print_attributes(printer)
    unprinted_attributes = {
        name: attr
        for name, attr in self.attributes.items()
        if name not in printed_attributes
    }
    printer.print_op_attributes(unprinted_attributes)
    printer.print_regions(self.regions)
    self.print_op_type(printer)

custom_print_attributes(printer: Printer) -> AbstractSet[str]

Print attributes with custom syntax. Return the names of the attributes printed. Subclasses may override this method.

Source code in xdsl/dialects/riscv/abstract_ops.py
def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
    """
    Print attributes with custom syntax. Return the names of the attributes printed. Subclasses may override this method.
    """
    printer.print_op_attributes(self.attributes)
    return self.attributes.keys()

print_op_type(printer: Printer) -> None

Source code in xdsl/dialects/riscv/abstract_ops.py
def print_op_type(self, printer: Printer) -> None:
    printer.print_string(" : ")
    printer.print_operation_type(self)

RISCVInstruction dataclass

Bases: RISCVAsmOperation, RISCVRegallocOperation, ABC

Base class for operations that can be a part of RISC-V assembly printing. Must represent an instruction in the RISC-V instruction set, and have the following format:

name arg0, arg1, arg2 # comment

The name of the operation will be used as the RISC-V assembly instruction name.

Source code in xdsl/dialects/riscv/abstract_ops.py
class RISCVInstruction(RISCVAsmOperation, RISCVRegallocOperation, ABC):
    """
    Base class for operations that can be a part of RISC-V assembly printing. Must
    represent an instruction in the RISC-V instruction set, and have the following format:

    name arg0, arg1, arg2           # comment

    The name of the operation will be used as the RISC-V assembly instruction name.
    """

    comment = opt_attr_def(StringAttr)
    """
    An optional comment that will be printed along with the instruction.
    """

    traits = traits_def(RegisterAllocatedMemoryEffect())

    @abstractmethod
    def assembly_line_args(self) -> tuple[AssemblyInstructionArg | None, ...]:
        """
        The arguments to the instruction, in the order they should be printed in the
        assembly.
        """
        raise NotImplementedError()

    def assembly_instruction_name(self) -> str:
        """
        By default, the name of the instruction is the same as the name of the operation.
        """

        return Dialect.split_name(self.name)[1]

    def assembly_line(self) -> str | None:
        # default assembly code generator
        instruction_name = self.assembly_instruction_name()
        arg_str = ", ".join(
            assembly_arg_str(arg)
            for arg in self.assembly_line_args()
            if arg is not None
        )
        return AssemblyPrinter.assembly_line(instruction_name, arg_str, self.comment)

comment = opt_attr_def(StringAttr) class-attribute instance-attribute

An optional comment that will be printed along with the instruction.

traits = traits_def(RegisterAllocatedMemoryEffect()) class-attribute instance-attribute

assembly_line_args() -> tuple[AssemblyInstructionArg | None, ...] abstractmethod

The arguments to the instruction, in the order they should be printed in the assembly.

Source code in xdsl/dialects/riscv/abstract_ops.py
@abstractmethod
def assembly_line_args(self) -> tuple[AssemblyInstructionArg | None, ...]:
    """
    The arguments to the instruction, in the order they should be printed in the
    assembly.
    """
    raise NotImplementedError()

assembly_instruction_name() -> str

By default, the name of the instruction is the same as the name of the operation.

Source code in xdsl/dialects/riscv/abstract_ops.py
def assembly_instruction_name(self) -> str:
    """
    By default, the name of the instruction is the same as the name of the operation.
    """

    return Dialect.split_name(self.name)[1]

assembly_line() -> str | None

Source code in xdsl/dialects/riscv/abstract_ops.py
def assembly_line(self) -> str | None:
    # default assembly code generator
    instruction_name = self.assembly_instruction_name()
    arg_str = ", ".join(
        assembly_arg_str(arg)
        for arg in self.assembly_line_args()
        if arg is not None
    )
    return AssemblyPrinter.assembly_line(instruction_name, arg_str, self.comment)

RISCVAsmTarget dataclass

Bases: Target

Source code in xdsl/dialects/riscv/abstract_ops.py
@dataclass(frozen=True)
class RISCVAsmTarget(Target):
    name = "riscv-asm"

    def emit(self, ctx: Context, module: ModuleOp, output: IO[str]) -> None:
        print_assembly(module, output)

name = 'riscv-asm' class-attribute instance-attribute

__init__() -> None

emit(ctx: Context, module: ModuleOp, output: IO[str]) -> None

Source code in xdsl/dialects/riscv/abstract_ops.py
def emit(self, ctx: Context, module: ModuleOp, output: IO[str]) -> None:
    print_assembly(module, output)

RdRsRsOperation

Bases: RISCVCustomFormatOperation, RISCVInstruction, ABC, Generic[RDInvT, RS1InvT, RS2InvT]

A base class for RISC-V operations that have one destination register, and two source registers.

This is called R-Type in the RISC-V specification.

Source code in xdsl/dialects/riscv/abstract_ops.py
class RdRsRsOperation(
    RISCVCustomFormatOperation, RISCVInstruction, ABC, Generic[RDInvT, RS1InvT, RS2InvT]
):
    """
    A base class for RISC-V operations that have one destination register, and two source
    registers.

    This is called R-Type in the RISC-V specification.
    """

    rd: OpResult[RDInvT] = result_def(RDInvT)
    rs1 = operand_def(RS1InvT)
    rs2 = operand_def(RS2InvT)

    def __init__(
        self,
        rs1: Operation | SSAValue,
        rs2: Operation | SSAValue,
        *,
        rd: RDInvT = Registers.UNALLOCATED_INT,
        comment: str | StringAttr | None = None,
    ):
        if isinstance(comment, str):
            comment = StringAttr(comment)

        super().__init__(
            operands=[rs1, rs2],
            attributes={
                "comment": comment,
            },
            result_types=[rd],
        )

    def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
        return self.rd, self.rs1, self.rs2

rd: OpResult[RDInvT] = result_def(RDInvT) class-attribute instance-attribute

rs1 = operand_def(RS1InvT) class-attribute instance-attribute

rs2 = operand_def(RS2InvT) class-attribute instance-attribute

__init__(rs1: Operation | SSAValue, rs2: Operation | SSAValue, *, rd: RDInvT = Registers.UNALLOCATED_INT, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/riscv/abstract_ops.py
def __init__(
    self,
    rs1: Operation | SSAValue,
    rs2: Operation | SSAValue,
    *,
    rd: RDInvT = Registers.UNALLOCATED_INT,
    comment: str | StringAttr | None = None,
):
    if isinstance(comment, str):
        comment = StringAttr(comment)

    super().__init__(
        operands=[rs1, rs2],
        attributes={
            "comment": comment,
        },
        result_types=[rd],
    )

assembly_line_args() -> tuple[AssemblyInstructionArg, ...]

Source code in xdsl/dialects/riscv/abstract_ops.py
def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
    return self.rd, self.rs1, self.rs2

RdRsRsIntegerOperation

Bases: RdRsRsOperation[IntRegisterType, RS1InvT, RS2InvT], ABC, Generic[RS1InvT, RS2InvT]

Source code in xdsl/dialects/riscv/abstract_ops.py
class RdRsRsIntegerOperation(
    RdRsRsOperation[IntRegisterType, RS1InvT, RS2InvT], ABC, Generic[RS1InvT, RS2InvT]
):
    def __init__(
        self,
        rs1: Operation | SSAValue,
        rs2: Operation | SSAValue,
        *,
        rd: IntRegisterType = Registers.UNALLOCATED_INT,
        comment: str | StringAttr | None = None,
    ):
        super().__init__(rs1, rs2, rd=rd, comment=comment)

__init__(rs1: Operation | SSAValue, rs2: Operation | SSAValue, *, rd: IntRegisterType = Registers.UNALLOCATED_INT, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/riscv/abstract_ops.py
def __init__(
    self,
    rs1: Operation | SSAValue,
    rs2: Operation | SSAValue,
    *,
    rd: IntRegisterType = Registers.UNALLOCATED_INT,
    comment: str | StringAttr | None = None,
):
    super().__init__(rs1, rs2, rd=rd, comment=comment)

RdRsRsFloatOperation

Bases: RdRsRsOperation[FloatRegisterType, RS1InvT, RS2InvT], ABC, Generic[RS1InvT, RS2InvT]

Source code in xdsl/dialects/riscv/abstract_ops.py
class RdRsRsFloatOperation(
    RdRsRsOperation[FloatRegisterType, RS1InvT, RS2InvT], ABC, Generic[RS1InvT, RS2InvT]
):
    def __init__(
        self,
        rs1: Operation | SSAValue,
        rs2: Operation | SSAValue,
        *,
        rd: FloatRegisterType = Registers.UNALLOCATED_FLOAT,
        comment: str | StringAttr | None = None,
    ):
        super().__init__(rs1, rs2, rd=rd, comment=comment)

__init__(rs1: Operation | SSAValue, rs2: Operation | SSAValue, *, rd: FloatRegisterType = Registers.UNALLOCATED_FLOAT, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/riscv/abstract_ops.py
def __init__(
    self,
    rs1: Operation | SSAValue,
    rs2: Operation | SSAValue,
    *,
    rd: FloatRegisterType = Registers.UNALLOCATED_FLOAT,
    comment: str | StringAttr | None = None,
):
    super().__init__(rs1, rs2, rd=rd, comment=comment)

RsRsImmFloatOperation

Bases: RISCVCustomFormatOperation, RISCVInstruction, ABC

A base class for RV32F operations that have two source registers (one integer and one floating-point) and an immediate.

Source code in xdsl/dialects/riscv/abstract_ops.py
class RsRsImmFloatOperation(RISCVCustomFormatOperation, RISCVInstruction, ABC):
    """
    A base class for RV32F operations that have two source registers
    (one integer and one floating-point) and an immediate.
    """

    rs1 = operand_def(IntRegisterType)
    rs2 = operand_def(FloatRegisterType)
    immediate = attr_def(IntegerAttr[I12])

    def __init__(
        self,
        rs1: Operation | SSAValue,
        rs2: Operation | SSAValue,
        immediate: int | IntegerAttr[I12] | str | LabelAttr,
        *,
        comment: str | StringAttr | None = None,
    ):
        if isinstance(immediate, int):
            immediate = IntegerAttr(immediate, i12)
        elif isinstance(immediate, str):
            immediate = LabelAttr(immediate)
        if isinstance(comment, str):
            comment = StringAttr(comment)

        super().__init__(
            operands=[rs1, rs2],
            attributes={
                "immediate": immediate,
                "comment": comment,
            },
        )

    def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
        return self.rs1, self.rs2, self.immediate

    @classmethod
    def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
        attributes = dict[str, Attribute]()
        attributes["immediate"] = parse_immediate_value(parser, i12)
        return attributes

    def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
        printer.print_string(", ")
        print_immediate_value(printer, self.immediate)
        return {"immediate"}

rs1 = operand_def(IntRegisterType) class-attribute instance-attribute

rs2 = operand_def(FloatRegisterType) class-attribute instance-attribute

immediate = attr_def(IntegerAttr[I12]) class-attribute instance-attribute

__init__(rs1: Operation | SSAValue, rs2: Operation | SSAValue, immediate: int | IntegerAttr[I12] | str | LabelAttr, *, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/riscv/abstract_ops.py
def __init__(
    self,
    rs1: Operation | SSAValue,
    rs2: Operation | SSAValue,
    immediate: int | IntegerAttr[I12] | str | LabelAttr,
    *,
    comment: str | StringAttr | None = None,
):
    if isinstance(immediate, int):
        immediate = IntegerAttr(immediate, i12)
    elif isinstance(immediate, str):
        immediate = LabelAttr(immediate)
    if isinstance(comment, str):
        comment = StringAttr(comment)

    super().__init__(
        operands=[rs1, rs2],
        attributes={
            "immediate": immediate,
            "comment": comment,
        },
    )

assembly_line_args() -> tuple[AssemblyInstructionArg, ...]

Source code in xdsl/dialects/riscv/abstract_ops.py
def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
    return self.rs1, self.rs2, self.immediate

custom_parse_attributes(parser: Parser) -> dict[str, Attribute] classmethod

Source code in xdsl/dialects/riscv/abstract_ops.py
@classmethod
def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
    attributes = dict[str, Attribute]()
    attributes["immediate"] = parse_immediate_value(parser, i12)
    return attributes

custom_print_attributes(printer: Printer) -> AbstractSet[str]

Source code in xdsl/dialects/riscv/abstract_ops.py
def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
    printer.print_string(", ")
    print_immediate_value(printer, self.immediate)
    return {"immediate"}

RdRsImmFloatOperation

Bases: RISCVCustomFormatOperation, RISCVInstruction, ABC

A base class for RV32Foperations that have one floating-point destination register, one source register and one immediate operand.

Source code in xdsl/dialects/riscv/abstract_ops.py
class RdRsImmFloatOperation(RISCVCustomFormatOperation, RISCVInstruction, ABC):
    """
    A base class for RV32Foperations that have one floating-point
    destination register, one source register and
    one immediate operand.
    """

    rd = result_def(FloatRegisterType)
    rs1 = operand_def(IntRegisterType)
    immediate = attr_def(IntegerAttr[I12] | LabelAttr)

    def __init__(
        self,
        rs1: Operation | SSAValue,
        immediate: int | IntegerAttr[I12] | str | LabelAttr,
        *,
        rd: FloatRegisterType = Registers.UNALLOCATED_FLOAT,
        comment: str | StringAttr | None = None,
    ):
        if isinstance(immediate, int):
            immediate = IntegerAttr(immediate, i12)
        elif isinstance(immediate, str):
            immediate = LabelAttr(immediate)

        if isinstance(comment, str):
            comment = StringAttr(comment)
        super().__init__(
            operands=[rs1],
            result_types=[rd],
            attributes={
                "immediate": immediate,
                "comment": comment,
            },
        )

    def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
        return self.rd, self.rs1, self.immediate

    @classmethod
    def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
        attributes = dict[str, Attribute]()
        attributes["immediate"] = parse_immediate_value(parser, i12)
        return attributes

    def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
        printer.print_string(", ")
        print_immediate_value(printer, self.immediate)
        return {"immediate"}

rd = result_def(FloatRegisterType) class-attribute instance-attribute

rs1 = operand_def(IntRegisterType) class-attribute instance-attribute

immediate = attr_def(IntegerAttr[I12] | LabelAttr) class-attribute instance-attribute

__init__(rs1: Operation | SSAValue, immediate: int | IntegerAttr[I12] | str | LabelAttr, *, rd: FloatRegisterType = Registers.UNALLOCATED_FLOAT, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/riscv/abstract_ops.py
def __init__(
    self,
    rs1: Operation | SSAValue,
    immediate: int | IntegerAttr[I12] | str | LabelAttr,
    *,
    rd: FloatRegisterType = Registers.UNALLOCATED_FLOAT,
    comment: str | StringAttr | None = None,
):
    if isinstance(immediate, int):
        immediate = IntegerAttr(immediate, i12)
    elif isinstance(immediate, str):
        immediate = LabelAttr(immediate)

    if isinstance(comment, str):
        comment = StringAttr(comment)
    super().__init__(
        operands=[rs1],
        result_types=[rd],
        attributes={
            "immediate": immediate,
            "comment": comment,
        },
    )

assembly_line_args() -> tuple[AssemblyInstructionArg, ...]

Source code in xdsl/dialects/riscv/abstract_ops.py
def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
    return self.rd, self.rs1, self.immediate

custom_parse_attributes(parser: Parser) -> dict[str, Attribute] classmethod

Source code in xdsl/dialects/riscv/abstract_ops.py
@classmethod
def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
    attributes = dict[str, Attribute]()
    attributes["immediate"] = parse_immediate_value(parser, i12)
    return attributes

custom_print_attributes(printer: Printer) -> AbstractSet[str]

Source code in xdsl/dialects/riscv/abstract_ops.py
def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
    printer.print_string(", ")
    print_immediate_value(printer, self.immediate)
    return {"immediate"}

RdRsRsRsFloatOperation

Bases: RISCVCustomFormatOperation, RISCVInstruction, ABC

A base class for RV32F operations that take three floating-point input registers and a destination register, e.g: fused-multiply-add (FMA) instructions.

Source code in xdsl/dialects/riscv/abstract_ops.py
class RdRsRsRsFloatOperation(RISCVCustomFormatOperation, RISCVInstruction, ABC):
    """
    A base class for RV32F operations that take three
    floating-point input registers and a destination register,
    e.g: fused-multiply-add (FMA) instructions.
    """

    rd = result_def(FloatRegisterType)
    rs1 = operand_def(FloatRegisterType)
    rs2 = operand_def(FloatRegisterType)
    rs3 = operand_def(FloatRegisterType)

    def __init__(
        self,
        rs1: Operation | SSAValue,
        rs2: Operation | SSAValue,
        rs3: Operation | SSAValue,
        *,
        rd: FloatRegisterType = Registers.UNALLOCATED_FLOAT,
        comment: str | StringAttr | None = None,
    ):
        if isinstance(comment, str):
            comment = StringAttr(comment)

        super().__init__(
            operands=[rs1, rs2, rs3],
            attributes={
                "comment": comment,
            },
            result_types=[rd],
        )

    def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
        return self.rd, self.rs1, self.rs2, self.rs3

rd = result_def(FloatRegisterType) class-attribute instance-attribute

rs1 = operand_def(FloatRegisterType) class-attribute instance-attribute

rs2 = operand_def(FloatRegisterType) class-attribute instance-attribute

rs3 = operand_def(FloatRegisterType) class-attribute instance-attribute

__init__(rs1: Operation | SSAValue, rs2: Operation | SSAValue, rs3: Operation | SSAValue, *, rd: FloatRegisterType = Registers.UNALLOCATED_FLOAT, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/riscv/abstract_ops.py
def __init__(
    self,
    rs1: Operation | SSAValue,
    rs2: Operation | SSAValue,
    rs3: Operation | SSAValue,
    *,
    rd: FloatRegisterType = Registers.UNALLOCATED_FLOAT,
    comment: str | StringAttr | None = None,
):
    if isinstance(comment, str):
        comment = StringAttr(comment)

    super().__init__(
        operands=[rs1, rs2, rs3],
        attributes={
            "comment": comment,
        },
        result_types=[rd],
    )

assembly_line_args() -> tuple[AssemblyInstructionArg, ...]

Source code in xdsl/dialects/riscv/abstract_ops.py
def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
    return self.rd, self.rs1, self.rs2, self.rs3

RdRsRsFloatFloatIntegerOperationWithFastMath

Bases: RISCVCustomFormatOperation, RISCVInstruction, ABC

A base class for RISC-V operations that have two source floating-point registers with an integer destination register, and can be annotated with fastmath flags.

This is called R-Type in the RISC-V specification.

Source code in xdsl/dialects/riscv/abstract_ops.py
class RdRsRsFloatFloatIntegerOperationWithFastMath(
    RISCVCustomFormatOperation, RISCVInstruction, ABC
):
    """
    A base class for RISC-V operations that have two source floating-point
    registers with an integer destination register, and can be annotated with fastmath flags.

    This is called R-Type in the RISC-V specification.
    """

    rd = result_def(IntRegisterType)
    rs1 = operand_def(FloatRegisterType)
    rs2 = operand_def(FloatRegisterType)
    fastmath = attr_def(FastMathFlagsAttr)

    def __init__(
        self,
        rs1: Operation | SSAValue,
        rs2: Operation | SSAValue,
        *,
        rd: IntRegisterType = Registers.UNALLOCATED_INT,
        fastmath: FastMathFlagsAttr = FastMathFlagsAttr("none"),
        comment: str | StringAttr | None = None,
    ):
        if isinstance(comment, str):
            comment = StringAttr(comment)

        super().__init__(
            operands=[rs1, rs2],
            attributes={
                "comment": comment,
                "fastmath": fastmath,
            },
            result_types=[rd],
        )

    def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
        return self.rd, self.rs1, self.rs2

    @classmethod
    def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
        attributes = dict[str, Attribute]()
        fast = FastMathFlagsAttr("none")
        if parser.parse_optional_keyword("fastmath") is not None:
            fast = FastMathFlagsAttr(FastMathFlagsAttr.parse_parameter(parser))
        attributes["fastmath"] = fast
        return attributes

    def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
        if self.fastmath != FastMathFlagsAttr("none"):
            printer.print_string(" fastmath")
            self.fastmath.print_parameter(printer)
        return {"fastmath"}

rd = result_def(IntRegisterType) class-attribute instance-attribute

rs1 = operand_def(FloatRegisterType) class-attribute instance-attribute

rs2 = operand_def(FloatRegisterType) class-attribute instance-attribute

fastmath = attr_def(FastMathFlagsAttr) class-attribute instance-attribute

__init__(rs1: Operation | SSAValue, rs2: Operation | SSAValue, *, rd: IntRegisterType = Registers.UNALLOCATED_INT, fastmath: FastMathFlagsAttr = FastMathFlagsAttr('none'), comment: str | StringAttr | None = None)

Source code in xdsl/dialects/riscv/abstract_ops.py
def __init__(
    self,
    rs1: Operation | SSAValue,
    rs2: Operation | SSAValue,
    *,
    rd: IntRegisterType = Registers.UNALLOCATED_INT,
    fastmath: FastMathFlagsAttr = FastMathFlagsAttr("none"),
    comment: str | StringAttr | None = None,
):
    if isinstance(comment, str):
        comment = StringAttr(comment)

    super().__init__(
        operands=[rs1, rs2],
        attributes={
            "comment": comment,
            "fastmath": fastmath,
        },
        result_types=[rd],
    )

assembly_line_args() -> tuple[AssemblyInstructionArg, ...]

Source code in xdsl/dialects/riscv/abstract_ops.py
def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
    return self.rd, self.rs1, self.rs2

custom_parse_attributes(parser: Parser) -> dict[str, Attribute] classmethod

Source code in xdsl/dialects/riscv/abstract_ops.py
@classmethod
def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
    attributes = dict[str, Attribute]()
    fast = FastMathFlagsAttr("none")
    if parser.parse_optional_keyword("fastmath") is not None:
        fast = FastMathFlagsAttr(FastMathFlagsAttr.parse_parameter(parser))
    attributes["fastmath"] = fast
    return attributes

custom_print_attributes(printer: Printer) -> AbstractSet[str]

Source code in xdsl/dialects/riscv/abstract_ops.py
def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
    if self.fastmath != FastMathFlagsAttr("none"):
        printer.print_string(" fastmath")
        self.fastmath.print_parameter(printer)
    return {"fastmath"}

RdRsRsFloatOperationWithFastMath

Bases: RISCVCustomFormatOperation, RISCVInstruction, ABC

A base class for RISC-V operations that have one destination floating-point register, and two source floating-point registers and can be annotated with fastmath flags.

This is called R-Type in the RISC-V specification.

Source code in xdsl/dialects/riscv/abstract_ops.py
class RdRsRsFloatOperationWithFastMath(
    RISCVCustomFormatOperation, RISCVInstruction, ABC
):
    """
    A base class for RISC-V operations that have one destination floating-point register,
    and two source floating-point registers and can be annotated with fastmath flags.

    This is called R-Type in the RISC-V specification.
    """

    rd = result_def(FloatRegisterType)
    rs1 = operand_def(FloatRegisterType)
    rs2 = operand_def(FloatRegisterType)
    fastmath = opt_attr_def(FastMathFlagsAttr)

    def __init__(
        self,
        rs1: Operation | SSAValue,
        rs2: Operation | SSAValue,
        *,
        rd: FloatRegisterType = Registers.UNALLOCATED_FLOAT,
        fastmath: FastMathFlagsAttr | None = None,
        comment: str | StringAttr | None = None,
    ):
        if isinstance(comment, str):
            comment = StringAttr(comment)

        super().__init__(
            operands=[rs1, rs2],
            attributes={
                "fastmath": fastmath,
                "comment": comment,
            },
            result_types=[rd],
        )

    def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
        return self.rd, self.rs1, self.rs2

    @classmethod
    def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
        attributes = dict[str, Attribute]()
        flags = FastMathFlagsAttr("none")
        if parser.parse_optional_keyword("fastmath") is not None:
            flags = FastMathFlagsAttr(FastMathFlagsAttr.parse_parameter(parser))
        attributes["fastmath"] = flags
        return attributes

    def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
        if self.fastmath is not None and self.fastmath != FastMathFlagsAttr("none"):
            printer.print_string(" fastmath")
            self.fastmath.print_parameter(printer)
        return {"fastmath"}

rd = result_def(FloatRegisterType) class-attribute instance-attribute

rs1 = operand_def(FloatRegisterType) class-attribute instance-attribute

rs2 = operand_def(FloatRegisterType) class-attribute instance-attribute

fastmath = opt_attr_def(FastMathFlagsAttr) class-attribute instance-attribute

__init__(rs1: Operation | SSAValue, rs2: Operation | SSAValue, *, rd: FloatRegisterType = Registers.UNALLOCATED_FLOAT, fastmath: FastMathFlagsAttr | None = None, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/riscv/abstract_ops.py
def __init__(
    self,
    rs1: Operation | SSAValue,
    rs2: Operation | SSAValue,
    *,
    rd: FloatRegisterType = Registers.UNALLOCATED_FLOAT,
    fastmath: FastMathFlagsAttr | None = None,
    comment: str | StringAttr | None = None,
):
    if isinstance(comment, str):
        comment = StringAttr(comment)

    super().__init__(
        operands=[rs1, rs2],
        attributes={
            "fastmath": fastmath,
            "comment": comment,
        },
        result_types=[rd],
    )

assembly_line_args() -> tuple[AssemblyInstructionArg, ...]

Source code in xdsl/dialects/riscv/abstract_ops.py
def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
    return self.rd, self.rs1, self.rs2

custom_parse_attributes(parser: Parser) -> dict[str, Attribute] classmethod

Source code in xdsl/dialects/riscv/abstract_ops.py
@classmethod
def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
    attributes = dict[str, Attribute]()
    flags = FastMathFlagsAttr("none")
    if parser.parse_optional_keyword("fastmath") is not None:
        flags = FastMathFlagsAttr(FastMathFlagsAttr.parse_parameter(parser))
    attributes["fastmath"] = flags
    return attributes

custom_print_attributes(printer: Printer) -> AbstractSet[str]

Source code in xdsl/dialects/riscv/abstract_ops.py
def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
    if self.fastmath is not None and self.fastmath != FastMathFlagsAttr("none"):
        printer.print_string(" fastmath")
        self.fastmath.print_parameter(printer)
    return {"fastmath"}

RdImmIntegerOperation

Bases: RISCVCustomFormatOperation, RISCVInstruction, ABC

A base class for RISC-V operations that have one destination register, and one immediate operand (e.g. U-Type and J-Type instructions in the RISC-V spec).

Source code in xdsl/dialects/riscv/abstract_ops.py
class RdImmIntegerOperation(RISCVCustomFormatOperation, RISCVInstruction, ABC):
    """
    A base class for RISC-V operations that have one destination register, and one
    immediate operand (e.g. U-Type and J-Type instructions in the RISC-V spec).
    """

    rd = result_def(IntRegisterType)
    immediate = attr_def(IntegerAttr[I20] | LabelAttr)

    def __init__(
        self,
        immediate: int | IntegerAttr | str | LabelAttr,
        *,
        rd: IntRegisterType = Registers.UNALLOCATED_INT,
        comment: str | StringAttr | None = None,
    ):
        if isinstance(immediate, int):
            immediate = IntegerAttr(immediate, i20)
        elif isinstance(immediate, str):
            immediate = LabelAttr(immediate)
        if isinstance(comment, str):
            comment = StringAttr(comment)

        super().__init__(
            result_types=[rd],
            attributes={
                "immediate": immediate,
                "comment": comment,
            },
        )

    def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
        return self.rd, self.immediate

    @classmethod
    def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
        attributes = dict[str, Attribute]()
        attributes["immediate"] = parse_immediate_value(parser, i20)
        return attributes

    def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
        printer.print_string(" ")
        print_immediate_value(printer, self.immediate)
        return {"immediate"}

rd = result_def(IntRegisterType) class-attribute instance-attribute

immediate = attr_def(IntegerAttr[I20] | LabelAttr) class-attribute instance-attribute

__init__(immediate: int | IntegerAttr | str | LabelAttr, *, rd: IntRegisterType = Registers.UNALLOCATED_INT, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/riscv/abstract_ops.py
def __init__(
    self,
    immediate: int | IntegerAttr | str | LabelAttr,
    *,
    rd: IntRegisterType = Registers.UNALLOCATED_INT,
    comment: str | StringAttr | None = None,
):
    if isinstance(immediate, int):
        immediate = IntegerAttr(immediate, i20)
    elif isinstance(immediate, str):
        immediate = LabelAttr(immediate)
    if isinstance(comment, str):
        comment = StringAttr(comment)

    super().__init__(
        result_types=[rd],
        attributes={
            "immediate": immediate,
            "comment": comment,
        },
    )

assembly_line_args() -> tuple[AssemblyInstructionArg, ...]

Source code in xdsl/dialects/riscv/abstract_ops.py
def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
    return self.rd, self.immediate

custom_parse_attributes(parser: Parser) -> dict[str, Attribute] classmethod

Source code in xdsl/dialects/riscv/abstract_ops.py
@classmethod
def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
    attributes = dict[str, Attribute]()
    attributes["immediate"] = parse_immediate_value(parser, i20)
    return attributes

custom_print_attributes(printer: Printer) -> AbstractSet[str]

Source code in xdsl/dialects/riscv/abstract_ops.py
def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
    printer.print_string(" ")
    print_immediate_value(printer, self.immediate)
    return {"immediate"}

RdImmJumpOperation

Bases: RISCVCustomFormatOperation, RISCVInstruction, ABC

In the RISC-V spec, this is the same as RdImmOperation. For jumps, the rd register is neither an operand, because the stored value is overwritten, nor a result value, because the value in rd is not defined after the jump back. So the rd makes the most sense as an attribute.

Source code in xdsl/dialects/riscv/abstract_ops.py
class RdImmJumpOperation(RISCVCustomFormatOperation, RISCVInstruction, ABC):
    """
    In the RISC-V spec, this is the same as `RdImmOperation`. For jumps, the `rd` register
    is neither an operand, because the stored value is overwritten, nor a result value,
    because the value in `rd` is not defined after the jump back. So the `rd` makes the
    most sense as an attribute.
    """

    rd = opt_attr_def(IntRegisterType)
    """
    The rd register here is not a register storing the result, rather the register where
    the program counter is stored before jumping.
    """
    immediate = attr_def(IntegerAttr[SI20] | LabelAttr)

    def __init__(
        self,
        immediate: int | IntegerAttr[SI20] | str | LabelAttr,
        *,
        rd: IntRegisterType | None = None,
        comment: str | StringAttr | None = None,
    ):
        if isinstance(immediate, int):
            immediate = IntegerAttr(immediate, si20)
        elif isinstance(immediate, str):
            immediate = LabelAttr(immediate)
        if isinstance(comment, str):
            comment = StringAttr(comment)
        super().__init__(
            attributes={
                "immediate": immediate,
                "rd": rd,
                "comment": comment,
            }
        )

    def assembly_line_args(self) -> tuple[AssemblyInstructionArg | None, ...]:
        return self.rd, self.immediate

    @classmethod
    def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
        attributes = dict[str, Attribute]()
        attributes["immediate"] = parse_immediate_value(parser, si20)
        if parser.parse_optional_punctuation(","):
            attributes["rd"] = parser.parse_attribute()
        return attributes

    def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
        printer.print_string(" ")
        print_immediate_value(printer, self.immediate)
        if self.rd is not None:
            printer.print_string(", ")
            printer.print_attribute(self.rd)
        return {"immediate", "rd"}

    def print_op_type(self, printer: Printer) -> None:
        return

    @classmethod
    def parse_op_type(
        cls, parser: Parser
    ) -> tuple[Sequence[Attribute], Sequence[Attribute]]:
        return (), ()

rd = opt_attr_def(IntRegisterType) class-attribute instance-attribute

The rd register here is not a register storing the result, rather the register where the program counter is stored before jumping.

immediate = attr_def(IntegerAttr[SI20] | LabelAttr) class-attribute instance-attribute

__init__(immediate: int | IntegerAttr[SI20] | str | LabelAttr, *, rd: IntRegisterType | None = None, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/riscv/abstract_ops.py
def __init__(
    self,
    immediate: int | IntegerAttr[SI20] | str | LabelAttr,
    *,
    rd: IntRegisterType | None = None,
    comment: str | StringAttr | None = None,
):
    if isinstance(immediate, int):
        immediate = IntegerAttr(immediate, si20)
    elif isinstance(immediate, str):
        immediate = LabelAttr(immediate)
    if isinstance(comment, str):
        comment = StringAttr(comment)
    super().__init__(
        attributes={
            "immediate": immediate,
            "rd": rd,
            "comment": comment,
        }
    )

assembly_line_args() -> tuple[AssemblyInstructionArg | None, ...]

Source code in xdsl/dialects/riscv/abstract_ops.py
def assembly_line_args(self) -> tuple[AssemblyInstructionArg | None, ...]:
    return self.rd, self.immediate

custom_parse_attributes(parser: Parser) -> dict[str, Attribute] classmethod

Source code in xdsl/dialects/riscv/abstract_ops.py
@classmethod
def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
    attributes = dict[str, Attribute]()
    attributes["immediate"] = parse_immediate_value(parser, si20)
    if parser.parse_optional_punctuation(","):
        attributes["rd"] = parser.parse_attribute()
    return attributes

custom_print_attributes(printer: Printer) -> AbstractSet[str]

Source code in xdsl/dialects/riscv/abstract_ops.py
def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
    printer.print_string(" ")
    print_immediate_value(printer, self.immediate)
    if self.rd is not None:
        printer.print_string(", ")
        printer.print_attribute(self.rd)
    return {"immediate", "rd"}

print_op_type(printer: Printer) -> None

Source code in xdsl/dialects/riscv/abstract_ops.py
def print_op_type(self, printer: Printer) -> None:
    return

parse_op_type(parser: Parser) -> tuple[Sequence[Attribute], Sequence[Attribute]] classmethod

Source code in xdsl/dialects/riscv/abstract_ops.py
@classmethod
def parse_op_type(
    cls, parser: Parser
) -> tuple[Sequence[Attribute], Sequence[Attribute]]:
    return (), ()

RdRsImmIntegerOperation

Bases: RISCVCustomFormatOperation, RISCVInstruction, ABC

A base class for RISC-V operations that have one destination register, one source register and one immediate operand.

This is called I-Type in the RISC-V specification.

Source code in xdsl/dialects/riscv/abstract_ops.py
class RdRsImmIntegerOperation(RISCVCustomFormatOperation, RISCVInstruction, ABC):
    """
    A base class for RISC-V operations that have one destination register, one source
    register and one immediate operand.

    This is called I-Type in the RISC-V specification.
    """

    rd = result_def(IntRegisterType)
    rs1 = operand_def(IntRegisterType)
    immediate = attr_def(IntegerAttr[SI12] | LabelAttr)

    def __init__(
        self,
        rs1: Operation | SSAValue,
        immediate: int | IntegerAttr[SI12] | str | LabelAttr,
        *,
        rd: IntRegisterType = Registers.UNALLOCATED_INT,
        comment: str | StringAttr | None = None,
    ):
        if isinstance(immediate, int):
            immediate = IntegerAttr(immediate, si12)
        elif isinstance(immediate, str):
            immediate = LabelAttr(immediate)

        if isinstance(comment, str):
            comment = StringAttr(comment)
        super().__init__(
            operands=[rs1],
            result_types=[rd],
            attributes={
                "immediate": immediate,
                "comment": comment,
            },
        )

    def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
        return self.rd, self.rs1, self.immediate

    @classmethod
    def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
        attributes = dict[str, Attribute]()
        attributes["immediate"] = parse_immediate_value(parser, si12)
        return attributes

    def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
        printer.print_string(", ")
        print_immediate_value(printer, self.immediate)
        return {"immediate"}

rd = result_def(IntRegisterType) class-attribute instance-attribute

rs1 = operand_def(IntRegisterType) class-attribute instance-attribute

immediate = attr_def(IntegerAttr[SI12] | LabelAttr) class-attribute instance-attribute

__init__(rs1: Operation | SSAValue, immediate: int | IntegerAttr[SI12] | str | LabelAttr, *, rd: IntRegisterType = Registers.UNALLOCATED_INT, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/riscv/abstract_ops.py
def __init__(
    self,
    rs1: Operation | SSAValue,
    immediate: int | IntegerAttr[SI12] | str | LabelAttr,
    *,
    rd: IntRegisterType = Registers.UNALLOCATED_INT,
    comment: str | StringAttr | None = None,
):
    if isinstance(immediate, int):
        immediate = IntegerAttr(immediate, si12)
    elif isinstance(immediate, str):
        immediate = LabelAttr(immediate)

    if isinstance(comment, str):
        comment = StringAttr(comment)
    super().__init__(
        operands=[rs1],
        result_types=[rd],
        attributes={
            "immediate": immediate,
            "comment": comment,
        },
    )

assembly_line_args() -> tuple[AssemblyInstructionArg, ...]

Source code in xdsl/dialects/riscv/abstract_ops.py
def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
    return self.rd, self.rs1, self.immediate

custom_parse_attributes(parser: Parser) -> dict[str, Attribute] classmethod

Source code in xdsl/dialects/riscv/abstract_ops.py
@classmethod
def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
    attributes = dict[str, Attribute]()
    attributes["immediate"] = parse_immediate_value(parser, si12)
    return attributes

custom_print_attributes(printer: Printer) -> AbstractSet[str]

Source code in xdsl/dialects/riscv/abstract_ops.py
def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
    printer.print_string(", ")
    print_immediate_value(printer, self.immediate)
    return {"immediate"}

RdRsImmShiftOperation

Bases: RISCVInstruction, ABC, Generic[ShiftImmT, ShiftImmAttrT]

A base class for RISC-V operations that have one destination register, one source register and one immediate operand.

This is called I-Type in the RISC-V specification.

Shifts by a constant are encoded as a specialization of the I-type format. The shift amount is encoded in the lower 5 bits of the I-immediate field for RV32

For RV32I, SLLI, SRLI, and SRAI generate an illegal instruction exception if imm[5] 6 != 0 but the shift amount is encoded in the lower 6 bits of the I-immediate field for RV64I.

Source code in xdsl/dialects/riscv/abstract_ops.py
class RdRsImmShiftOperation(RISCVInstruction, ABC, Generic[ShiftImmT, ShiftImmAttrT]):
    """
    A base class for RISC-V operations that have one destination register, one source
    register and one immediate operand.

    This is called I-Type in the RISC-V specification.

    Shifts by a constant are encoded as a specialization of the I-type format.
    The shift amount is encoded in the lower 5 bits of the I-immediate field for RV32

    For RV32I, SLLI, SRLI, and SRAI generate an illegal instruction exception if
    imm[5] 6 != 0 but the shift amount is encoded in the lower 6 bits of the I-immediate field for RV64I.
    """

    rd = result_def(IntRegisterType)
    rs1 = operand_def(IntRegisterType)
    immediate = attr_def(IntegerAttr[ShiftImmT])

    assembly_format = (
        "$rs1 `,` $immediate attr-dict `:` `(` type($rs1) `)` `->` type($rd)"
    )

    def __init__(
        self,
        rs1: Operation | SSAValue,
        immediate: IntegerAttr[ShiftImmT],
        *,
        rd: IntRegisterType = Registers.UNALLOCATED_INT,
        comment: str | StringAttr | None = None,
    ):
        if isinstance(comment, str):
            comment = StringAttr(comment)
        super().__init__(
            operands=[rs1],
            result_types=[rd],
            attributes={
                "immediate": immediate,
                "comment": comment,
            },
        )

    def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
        return self.rd, self.rs1, self.immediate

    @abstractmethod
    def py_operation(
        self, rs1: IntegerAttr[ShiftImmAttrT]
    ) -> IntegerAttr[ShiftImmAttrT]:
        """
        Performs a python function corresponding to this operation.

        If `i := py_operation(rs1)` is an IntegerAttr[ShiftImmAttrT], then this operation can be
        canonicalized to a constant with value `i` when the inputs are constants
        with values `rs1`. The immediate value is retrieved from the `immediate` attribute of the operation.
        """

        raise NotImplementedError(
            "RdRsImmShiftOperation py_operation is not yet implemented"
        )

rd = result_def(IntRegisterType) class-attribute instance-attribute

rs1 = operand_def(IntRegisterType) class-attribute instance-attribute

immediate = attr_def(IntegerAttr[ShiftImmT]) class-attribute instance-attribute

assembly_format = '$rs1 `,` $immediate attr-dict `:` `(` type($rs1) `)` `->` type($rd)' class-attribute instance-attribute

__init__(rs1: Operation | SSAValue, immediate: IntegerAttr[ShiftImmT], *, rd: IntRegisterType = Registers.UNALLOCATED_INT, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/riscv/abstract_ops.py
def __init__(
    self,
    rs1: Operation | SSAValue,
    immediate: IntegerAttr[ShiftImmT],
    *,
    rd: IntRegisterType = Registers.UNALLOCATED_INT,
    comment: str | StringAttr | None = None,
):
    if isinstance(comment, str):
        comment = StringAttr(comment)
    super().__init__(
        operands=[rs1],
        result_types=[rd],
        attributes={
            "immediate": immediate,
            "comment": comment,
        },
    )

assembly_line_args() -> tuple[AssemblyInstructionArg, ...]

Source code in xdsl/dialects/riscv/abstract_ops.py
def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
    return self.rd, self.rs1, self.immediate

py_operation(rs1: IntegerAttr[ShiftImmAttrT]) -> IntegerAttr[ShiftImmAttrT] abstractmethod

Performs a python function corresponding to this operation.

If i := py_operation(rs1) is an IntegerAttr[ShiftImmAttrT], then this operation can be canonicalized to a constant with value i when the inputs are constants with values rs1. The immediate value is retrieved from the immediate attribute of the operation.

Source code in xdsl/dialects/riscv/abstract_ops.py
@abstractmethod
def py_operation(
    self, rs1: IntegerAttr[ShiftImmAttrT]
) -> IntegerAttr[ShiftImmAttrT]:
    """
    Performs a python function corresponding to this operation.

    If `i := py_operation(rs1)` is an IntegerAttr[ShiftImmAttrT], then this operation can be
    canonicalized to a constant with value `i` when the inputs are constants
    with values `rs1`. The immediate value is retrieved from the `immediate` attribute of the operation.
    """

    raise NotImplementedError(
        "RdRsImmShiftOperation py_operation is not yet implemented"
    )

ImmShiftOpHasCanonicalizationPatternsTrait dataclass

Bases: HasCanonicalizationPatternsTrait, Generic[IWidth]

Source code in xdsl/dialects/riscv/abstract_ops.py
class ImmShiftOpHasCanonicalizationPatternsTrait(
    HasCanonicalizationPatternsTrait, Generic[IWidth]
):
    li_op_type: type[LiOperation[IWidth]]
    shift_op_type: type[RdRsImmShiftOperation[Any, IWidth]]

    def __init_subclass__(
        cls,
        li_op_type: type[LiOperation[IWidth]],
        shift_op_type: type[RdRsImmShiftOperation[Any, IWidth]],
        **kwargs: Any,
    ) -> None:
        super().__init_subclass__(**kwargs)
        cls.li_op_type = li_op_type
        cls.shift_op_type = shift_op_type

    @classmethod
    def get_canonicalization_patterns(cls) -> tuple[RewritePattern, ...]:
        from xdsl.transforms.canonicalization_patterns.riscv import (
            ShiftbyZero,
            ShiftConstantFolding,
        )

        return (
            ShiftbyZero(cls.shift_op_type),
            ShiftConstantFolding(cls.li_op_type, cls.shift_op_type),
        )

li_op_type: type[LiOperation[IWidth]] instance-attribute

shift_op_type: type[RdRsImmShiftOperation[Any, IWidth]] instance-attribute

__init_subclass__(li_op_type: type[LiOperation[IWidth]], shift_op_type: type[RdRsImmShiftOperation[Any, IWidth]], **kwargs: Any) -> None

Source code in xdsl/dialects/riscv/abstract_ops.py
def __init_subclass__(
    cls,
    li_op_type: type[LiOperation[IWidth]],
    shift_op_type: type[RdRsImmShiftOperation[Any, IWidth]],
    **kwargs: Any,
) -> None:
    super().__init_subclass__(**kwargs)
    cls.li_op_type = li_op_type
    cls.shift_op_type = shift_op_type

get_canonicalization_patterns() -> tuple[RewritePattern, ...] classmethod

Source code in xdsl/dialects/riscv/abstract_ops.py
@classmethod
def get_canonicalization_patterns(cls) -> tuple[RewritePattern, ...]:
    from xdsl.transforms.canonicalization_patterns.riscv import (
        ShiftbyZero,
        ShiftConstantFolding,
    )

    return (
        ShiftbyZero(cls.shift_op_type),
        ShiftConstantFolding(cls.li_op_type, cls.shift_op_type),
    )

RdRsImmBitManipOperation

Bases: RISCVCustomFormatOperation, RISCVInstruction, ABC

A base class for RISC-V operations that have one destination register, one source register and one immediate operand.

These operations are from the Zba, Zbb, and Zbs extensions.

The immediate value is encoded in the lower 5 bits of the immediate field for RV32 and the lower 6 bits for RV64.

See external documentation.

Source code in xdsl/dialects/riscv/abstract_ops.py
class RdRsImmBitManipOperation(RISCVCustomFormatOperation, RISCVInstruction, ABC):
    """
    A base class for RISC-V operations that have one destination register, one source
    register and one immediate operand.

    These operations are from the Zba, Zbb, and Zbs extensions.

    The immediate value is encoded in the lower 5 bits of the immediate field for RV32
    and the lower 6 bits for RV64.

    See external [documentation](https://five-embeddev.com/riscv-bitmanip/1.0.0/bitmanip.html#).
    """

    rd = result_def(IntRegisterType)
    rs1 = operand_def(IntRegisterType)
    immediate = attr_def(IntegerAttr[UI5] | LabelAttr)

    def __init__(
        self,
        rs1: Operation | SSAValue,
        immediate: int | IntegerAttr[UI5] | str | LabelAttr,
        *,
        rd: IntRegisterType = Registers.UNALLOCATED_INT,
        comment: str | StringAttr | None = None,
    ):
        if isinstance(immediate, int):
            immediate = IntegerAttr(immediate, ui5)
        elif isinstance(immediate, str):
            immediate = LabelAttr(immediate)

        if isinstance(comment, str):
            comment = StringAttr(comment)
        super().__init__(
            operands=[rs1],
            result_types=[rd],
            attributes={
                "immediate": immediate,
                "comment": comment,
            },
        )

    def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
        return self.rd, self.rs1, self.immediate

    @classmethod
    def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
        attributes = dict[str, Attribute]()
        attributes["immediate"] = parse_immediate_value(parser, ui5)
        return attributes

    def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
        printer.print_string(", ")
        print_immediate_value(printer, self.immediate)
        return {"immediate"}

rd = result_def(IntRegisterType) class-attribute instance-attribute

rs1 = operand_def(IntRegisterType) class-attribute instance-attribute

immediate = attr_def(IntegerAttr[UI5] | LabelAttr) class-attribute instance-attribute

__init__(rs1: Operation | SSAValue, immediate: int | IntegerAttr[UI5] | str | LabelAttr, *, rd: IntRegisterType = Registers.UNALLOCATED_INT, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/riscv/abstract_ops.py
def __init__(
    self,
    rs1: Operation | SSAValue,
    immediate: int | IntegerAttr[UI5] | str | LabelAttr,
    *,
    rd: IntRegisterType = Registers.UNALLOCATED_INT,
    comment: str | StringAttr | None = None,
):
    if isinstance(immediate, int):
        immediate = IntegerAttr(immediate, ui5)
    elif isinstance(immediate, str):
        immediate = LabelAttr(immediate)

    if isinstance(comment, str):
        comment = StringAttr(comment)
    super().__init__(
        operands=[rs1],
        result_types=[rd],
        attributes={
            "immediate": immediate,
            "comment": comment,
        },
    )

assembly_line_args() -> tuple[AssemblyInstructionArg, ...]

Source code in xdsl/dialects/riscv/abstract_ops.py
def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
    return self.rd, self.rs1, self.immediate

custom_parse_attributes(parser: Parser) -> dict[str, Attribute] classmethod

Source code in xdsl/dialects/riscv/abstract_ops.py
@classmethod
def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
    attributes = dict[str, Attribute]()
    attributes["immediate"] = parse_immediate_value(parser, ui5)
    return attributes

custom_print_attributes(printer: Printer) -> AbstractSet[str]

Source code in xdsl/dialects/riscv/abstract_ops.py
def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
    printer.print_string(", ")
    print_immediate_value(printer, self.immediate)
    return {"immediate"}

RdRsImmJumpOperation

Bases: RISCVCustomFormatOperation, RISCVInstruction, ABC

A base class for RISC-V operations that have one destination register, one source register and one immediate operand.

This is called I-Type in the RISC-V specification.

In the RISC-V spec, this is the same as RdRsImmOperation. For jumps, the rd register is neither an operand, because the stored value is overwritten, nor a result value, because the value in rd is not defined after the jump back. So the rd makes the most sense as an attribute.

Source code in xdsl/dialects/riscv/abstract_ops.py
class RdRsImmJumpOperation(RISCVCustomFormatOperation, RISCVInstruction, ABC):
    """
    A base class for RISC-V operations that have one destination register, one source
    register and one immediate operand.

    This is called I-Type in the RISC-V specification.

    In the RISC-V spec, this is the same as `RdRsImmOperation`. For jumps, the `rd` register
    is neither an operand, because the stored value is overwritten, nor a result value,
    because the value in `rd` is not defined after the jump back. So the `rd` makes the
    most sense as an attribute.
    """

    rs1 = operand_def(IntRegisterType)
    rd = opt_attr_def(IntRegisterType)
    """
    The rd register here is not a register storing the result, rather the register where
    the program counter is stored before jumping.
    """
    immediate = attr_def(IntegerAttr[SI12] | LabelAttr)

    def __init__(
        self,
        rs1: Operation | SSAValue,
        immediate: int | IntegerAttr[SI12] | str | LabelAttr,
        *,
        rd: IntRegisterType | None = None,
        comment: str | StringAttr | None = None,
    ):
        if isinstance(immediate, int):
            immediate = IntegerAttr(immediate, si12)
        elif isinstance(immediate, str):
            immediate = LabelAttr(immediate)

        if isinstance(comment, str):
            comment = StringAttr(comment)

        super().__init__(
            operands=[rs1],
            attributes={
                "immediate": immediate,
                "rd": rd,
                "comment": comment,
            },
        )

    def assembly_line_args(self) -> tuple[AssemblyInstructionArg | None, ...]:
        return self.rd, self.rs1, self.immediate

    @classmethod
    def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
        attributes = dict[str, Attribute]()
        attributes["immediate"] = parse_immediate_value(parser, si12)
        if parser.parse_optional_punctuation(","):
            attributes["rd"] = parser.parse_attribute()
        return attributes

    def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
        printer.print_string(", ")
        print_immediate_value(printer, self.immediate)
        if self.rd is not None:
            printer.print_string(", ")
            printer.print_attribute(self.rd)
        return {"immediate", "rd"}

rs1 = operand_def(IntRegisterType) class-attribute instance-attribute

rd = opt_attr_def(IntRegisterType) class-attribute instance-attribute

The rd register here is not a register storing the result, rather the register where the program counter is stored before jumping.

immediate = attr_def(IntegerAttr[SI12] | LabelAttr) class-attribute instance-attribute

__init__(rs1: Operation | SSAValue, immediate: int | IntegerAttr[SI12] | str | LabelAttr, *, rd: IntRegisterType | None = None, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/riscv/abstract_ops.py
def __init__(
    self,
    rs1: Operation | SSAValue,
    immediate: int | IntegerAttr[SI12] | str | LabelAttr,
    *,
    rd: IntRegisterType | None = None,
    comment: str | StringAttr | None = None,
):
    if isinstance(immediate, int):
        immediate = IntegerAttr(immediate, si12)
    elif isinstance(immediate, str):
        immediate = LabelAttr(immediate)

    if isinstance(comment, str):
        comment = StringAttr(comment)

    super().__init__(
        operands=[rs1],
        attributes={
            "immediate": immediate,
            "rd": rd,
            "comment": comment,
        },
    )

assembly_line_args() -> tuple[AssemblyInstructionArg | None, ...]

Source code in xdsl/dialects/riscv/abstract_ops.py
def assembly_line_args(self) -> tuple[AssemblyInstructionArg | None, ...]:
    return self.rd, self.rs1, self.immediate

custom_parse_attributes(parser: Parser) -> dict[str, Attribute] classmethod

Source code in xdsl/dialects/riscv/abstract_ops.py
@classmethod
def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
    attributes = dict[str, Attribute]()
    attributes["immediate"] = parse_immediate_value(parser, si12)
    if parser.parse_optional_punctuation(","):
        attributes["rd"] = parser.parse_attribute()
    return attributes

custom_print_attributes(printer: Printer) -> AbstractSet[str]

Source code in xdsl/dialects/riscv/abstract_ops.py
def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
    printer.print_string(", ")
    print_immediate_value(printer, self.immediate)
    if self.rd is not None:
        printer.print_string(", ")
        printer.print_attribute(self.rd)
    return {"immediate", "rd"}

RdRsOperation

Bases: RISCVCustomFormatOperation, RISCVInstruction, ABC, Generic[RDInvT, RSInvT]

A base class for RISC-V pseudo-instructions that have one destination register and one source register.

Source code in xdsl/dialects/riscv/abstract_ops.py
class RdRsOperation(
    RISCVCustomFormatOperation, RISCVInstruction, ABC, Generic[RDInvT, RSInvT]
):
    """
    A base class for RISC-V pseudo-instructions that have one destination register and one
    source register.
    """

    rd = result_def(RDInvT)
    rs = operand_def(RSInvT)

    def __init__(
        self,
        rs: Operation | SSAValue,
        *,
        rd: RDInvT,
        comment: str | StringAttr | None = None,
    ):
        if isinstance(comment, str):
            comment = StringAttr(comment)
        super().__init__(
            operands=[rs],
            result_types=[rd],
            attributes={"comment": comment},
        )

    def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
        return self.rd, self.rs

rd = result_def(RDInvT) class-attribute instance-attribute

rs = operand_def(RSInvT) class-attribute instance-attribute

__init__(rs: Operation | SSAValue, *, rd: RDInvT, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/riscv/abstract_ops.py
def __init__(
    self,
    rs: Operation | SSAValue,
    *,
    rd: RDInvT,
    comment: str | StringAttr | None = None,
):
    if isinstance(comment, str):
        comment = StringAttr(comment)
    super().__init__(
        operands=[rs],
        result_types=[rd],
        attributes={"comment": comment},
    )

assembly_line_args() -> tuple[AssemblyInstructionArg, ...]

Source code in xdsl/dialects/riscv/abstract_ops.py
def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
    return self.rd, self.rs

RdRsIntegerOperation

Bases: RdRsOperation[IntRegisterType, RSInvT], ABC, Generic[RSInvT]

Source code in xdsl/dialects/riscv/abstract_ops.py
class RdRsIntegerOperation(
    RdRsOperation[IntRegisterType, RSInvT], ABC, Generic[RSInvT]
):
    def __init__(
        self,
        rs: Operation | SSAValue,
        *,
        rd: IntRegisterType = Registers.UNALLOCATED_INT,
        comment: str | StringAttr | None = None,
    ):
        super().__init__(rs, rd=rd, comment=comment)

__init__(rs: Operation | SSAValue, *, rd: IntRegisterType = Registers.UNALLOCATED_INT, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/riscv/abstract_ops.py
def __init__(
    self,
    rs: Operation | SSAValue,
    *,
    rd: IntRegisterType = Registers.UNALLOCATED_INT,
    comment: str | StringAttr | None = None,
):
    super().__init__(rs, rd=rd, comment=comment)

RdRsFloatOperation

Bases: RdRsOperation[FloatRegisterType, RSInvT], ABC, Generic[RSInvT]

Source code in xdsl/dialects/riscv/abstract_ops.py
class RdRsFloatOperation(
    RdRsOperation[FloatRegisterType, RSInvT], ABC, Generic[RSInvT]
):
    def __init__(
        self,
        rs: Operation | SSAValue,
        *,
        rd: FloatRegisterType = Registers.UNALLOCATED_FLOAT,
        comment: str | StringAttr | None = None,
    ):
        super().__init__(rs, rd=rd, comment=comment)

__init__(rs: Operation | SSAValue, *, rd: FloatRegisterType = Registers.UNALLOCATED_FLOAT, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/riscv/abstract_ops.py
def __init__(
    self,
    rs: Operation | SSAValue,
    *,
    rd: FloatRegisterType = Registers.UNALLOCATED_FLOAT,
    comment: str | StringAttr | None = None,
):
    super().__init__(rs, rd=rd, comment=comment)

RsRsOffIntegerOperation

Bases: RISCVCustomFormatOperation, RISCVInstruction, ABC

A base class for RISC-V operations that have one source register and a destination register, and an offset.

This is called B-Type in the RISC-V specification.

Source code in xdsl/dialects/riscv/abstract_ops.py
class RsRsOffIntegerOperation(RISCVCustomFormatOperation, RISCVInstruction, ABC):
    """
    A base class for RISC-V operations that have one source register and a destination
    register, and an offset.

    This is called B-Type in the RISC-V specification.
    """

    rs1 = operand_def(IntRegisterType)
    rs2 = operand_def(IntRegisterType)
    offset = attr_def(IntegerAttr[SI12] | LabelAttr)

    def __init__(
        self,
        rs1: Operation | SSAValue,
        rs2: Operation | SSAValue,
        offset: int | IntegerAttr[SI12] | LabelAttr,
        *,
        comment: str | StringAttr | None = None,
    ):
        if isinstance(offset, int):
            offset = IntegerAttr(offset, si12)
        if isinstance(offset, str):
            offset = LabelAttr(offset)
        if isinstance(comment, str):
            comment = StringAttr(comment)

        super().__init__(
            operands=[rs1, rs2],
            attributes={
                "offset": offset,
                "comment": comment,
            },
        )

    def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
        return self.rs1, self.rs2, self.offset

    @classmethod
    def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
        attributes = dict[str, Attribute]()
        attributes["offset"] = parse_immediate_value(parser, si12)
        return attributes

    def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
        printer.print_string(", ")
        print_immediate_value(printer, self.offset)
        return {"offset"}

rs1 = operand_def(IntRegisterType) class-attribute instance-attribute

rs2 = operand_def(IntRegisterType) class-attribute instance-attribute

offset = attr_def(IntegerAttr[SI12] | LabelAttr) class-attribute instance-attribute

__init__(rs1: Operation | SSAValue, rs2: Operation | SSAValue, offset: int | IntegerAttr[SI12] | LabelAttr, *, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/riscv/abstract_ops.py
def __init__(
    self,
    rs1: Operation | SSAValue,
    rs2: Operation | SSAValue,
    offset: int | IntegerAttr[SI12] | LabelAttr,
    *,
    comment: str | StringAttr | None = None,
):
    if isinstance(offset, int):
        offset = IntegerAttr(offset, si12)
    if isinstance(offset, str):
        offset = LabelAttr(offset)
    if isinstance(comment, str):
        comment = StringAttr(comment)

    super().__init__(
        operands=[rs1, rs2],
        attributes={
            "offset": offset,
            "comment": comment,
        },
    )

assembly_line_args() -> tuple[AssemblyInstructionArg, ...]

Source code in xdsl/dialects/riscv/abstract_ops.py
def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
    return self.rs1, self.rs2, self.offset

custom_parse_attributes(parser: Parser) -> dict[str, Attribute] classmethod

Source code in xdsl/dialects/riscv/abstract_ops.py
@classmethod
def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
    attributes = dict[str, Attribute]()
    attributes["offset"] = parse_immediate_value(parser, si12)
    return attributes

custom_print_attributes(printer: Printer) -> AbstractSet[str]

Source code in xdsl/dialects/riscv/abstract_ops.py
def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
    printer.print_string(", ")
    print_immediate_value(printer, self.offset)
    return {"offset"}

RsRsImmIntegerOperation

Bases: RISCVCustomFormatOperation, RISCVInstruction, ABC

A base class for RISC-V operations that have two source registers and an immediate.

This is called S-Type in the RISC-V specification.

Source code in xdsl/dialects/riscv/abstract_ops.py
class RsRsImmIntegerOperation(RISCVCustomFormatOperation, RISCVInstruction, ABC):
    """
    A base class for RISC-V operations that have two source registers and an
    immediate.

    This is called S-Type in the RISC-V specification.
    """

    rs1 = operand_def(IntRegisterType)
    rs2 = operand_def(IntRegisterType)
    immediate = attr_def(IntegerAttr[SI12])

    # All S-Type operations write to memory
    traits = traits_def(MemoryWriteEffect())

    def __init__(
        self,
        rs1: Operation | SSAValue,
        rs2: Operation | SSAValue,
        immediate: int | IntegerAttr[SI12] | str | LabelAttr,
        *,
        comment: str | StringAttr | None = None,
    ):
        if isinstance(immediate, int):
            immediate = IntegerAttr(immediate, si12)
        elif isinstance(immediate, str):
            immediate = LabelAttr(immediate)
        if isinstance(comment, str):
            comment = StringAttr(comment)

        super().__init__(
            operands=[rs1, rs2],
            attributes={
                "immediate": immediate,
                "comment": comment,
            },
        )

    def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
        return self.rs1, self.rs2, self.immediate

    @classmethod
    def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
        attributes = dict[str, Attribute]()
        attributes["immediate"] = parse_immediate_value(parser, si12)
        return attributes

    def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
        printer.print_string(", ")
        print_immediate_value(printer, self.immediate)
        return {"immediate"}

rs1 = operand_def(IntRegisterType) class-attribute instance-attribute

rs2 = operand_def(IntRegisterType) class-attribute instance-attribute

immediate = attr_def(IntegerAttr[SI12]) class-attribute instance-attribute

traits = traits_def(MemoryWriteEffect()) class-attribute instance-attribute

__init__(rs1: Operation | SSAValue, rs2: Operation | SSAValue, immediate: int | IntegerAttr[SI12] | str | LabelAttr, *, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/riscv/abstract_ops.py
def __init__(
    self,
    rs1: Operation | SSAValue,
    rs2: Operation | SSAValue,
    immediate: int | IntegerAttr[SI12] | str | LabelAttr,
    *,
    comment: str | StringAttr | None = None,
):
    if isinstance(immediate, int):
        immediate = IntegerAttr(immediate, si12)
    elif isinstance(immediate, str):
        immediate = LabelAttr(immediate)
    if isinstance(comment, str):
        comment = StringAttr(comment)

    super().__init__(
        operands=[rs1, rs2],
        attributes={
            "immediate": immediate,
            "comment": comment,
        },
    )

assembly_line_args() -> tuple[AssemblyInstructionArg, ...]

Source code in xdsl/dialects/riscv/abstract_ops.py
def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
    return self.rs1, self.rs2, self.immediate

custom_parse_attributes(parser: Parser) -> dict[str, Attribute] classmethod

Source code in xdsl/dialects/riscv/abstract_ops.py
@classmethod
def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
    attributes = dict[str, Attribute]()
    attributes["immediate"] = parse_immediate_value(parser, si12)
    return attributes

custom_print_attributes(printer: Printer) -> AbstractSet[str]

Source code in xdsl/dialects/riscv/abstract_ops.py
def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
    printer.print_string(", ")
    print_immediate_value(printer, self.immediate)
    return {"immediate"}

RsRsIntegerOperation

Bases: RISCVCustomFormatOperation, RISCVInstruction, ABC

A base class for RISC-V operations that have two source registers.

Source code in xdsl/dialects/riscv/abstract_ops.py
class RsRsIntegerOperation(RISCVCustomFormatOperation, RISCVInstruction, ABC):
    """
    A base class for RISC-V operations that have two source
    registers.
    """

    rs1 = operand_def(IntRegisterType)
    rs2 = operand_def(IntRegisterType)

    def __init__(
        self,
        rs1: Operation | SSAValue,
        rs2: Operation | SSAValue,
        comment: str | StringAttr | None = None,
    ):
        if isinstance(comment, str):
            comment = StringAttr(comment)
        super().__init__(
            operands=[rs1, rs2],
            attributes={
                "comment": comment,
            },
        )

    def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
        return self.rs1, self.rs2

rs1 = operand_def(IntRegisterType) class-attribute instance-attribute

rs2 = operand_def(IntRegisterType) class-attribute instance-attribute

__init__(rs1: Operation | SSAValue, rs2: Operation | SSAValue, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/riscv/abstract_ops.py
def __init__(
    self,
    rs1: Operation | SSAValue,
    rs2: Operation | SSAValue,
    comment: str | StringAttr | None = None,
):
    if isinstance(comment, str):
        comment = StringAttr(comment)
    super().__init__(
        operands=[rs1, rs2],
        attributes={
            "comment": comment,
        },
    )

assembly_line_args() -> tuple[AssemblyInstructionArg, ...]

Source code in xdsl/dialects/riscv/abstract_ops.py
def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
    return self.rs1, self.rs2

NullaryOperation

Bases: RISCVCustomFormatOperation, RISCVInstruction, ABC

A base class for RISC-V operations that have neither sources nor destinations.

Source code in xdsl/dialects/riscv/abstract_ops.py
class NullaryOperation(RISCVCustomFormatOperation, RISCVInstruction, ABC):
    """
    A base class for RISC-V operations that have neither sources nor destinations.
    """

    def __init__(
        self,
        *,
        comment: str | StringAttr | None = None,
    ):
        if isinstance(comment, str):
            comment = StringAttr(comment)

        super().__init__(
            attributes={
                "comment": comment,
            },
        )

    def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
        return ()

    @classmethod
    def parse_unresolved_operands(cls, parser: Parser) -> list[UnresolvedOperand]:
        return []

    def print_op_type(self, printer: Printer) -> None:
        return

    @classmethod
    def parse_op_type(
        cls, parser: Parser
    ) -> tuple[Sequence[Attribute], Sequence[Attribute]]:
        return (), ()

__init__(*, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/riscv/abstract_ops.py
def __init__(
    self,
    *,
    comment: str | StringAttr | None = None,
):
    if isinstance(comment, str):
        comment = StringAttr(comment)

    super().__init__(
        attributes={
            "comment": comment,
        },
    )

assembly_line_args() -> tuple[AssemblyInstructionArg, ...]

Source code in xdsl/dialects/riscv/abstract_ops.py
def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
    return ()

parse_unresolved_operands(parser: Parser) -> list[UnresolvedOperand] classmethod

Source code in xdsl/dialects/riscv/abstract_ops.py
@classmethod
def parse_unresolved_operands(cls, parser: Parser) -> list[UnresolvedOperand]:
    return []

print_op_type(printer: Printer) -> None

Source code in xdsl/dialects/riscv/abstract_ops.py
def print_op_type(self, printer: Printer) -> None:
    return

parse_op_type(parser: Parser) -> tuple[Sequence[Attribute], Sequence[Attribute]] classmethod

Source code in xdsl/dialects/riscv/abstract_ops.py
@classmethod
def parse_op_type(
    cls, parser: Parser
) -> tuple[Sequence[Attribute], Sequence[Attribute]]:
    return (), ()

CsrReadWriteOperation

Bases: RISCVCustomFormatOperation, RISCVInstruction, ABC

A base class for RISC-V operations performing a swap to/from a CSR.

The 'writeonly' attribute controls the actual behaviour of the operation: * when True, the operation writes the rs value to the CSR but never reads it and in this case rd must be allocated to x0 * when False, a proper atomic swap is performed and the previous CSR value is returned in rd

Source code in xdsl/dialects/riscv/abstract_ops.py
class CsrReadWriteOperation(RISCVCustomFormatOperation, RISCVInstruction, ABC):
    """
    A base class for RISC-V operations performing a swap to/from a CSR.

    The 'writeonly' attribute controls the actual behaviour of the operation:
    * when True, the operation writes the rs value to the CSR but never reads it and
      in this case rd *must* be allocated to x0
    * when False, a proper atomic swap is performed and the previous CSR value is
      returned in rd
    """

    rd = result_def(IntRegisterType)
    rs1 = operand_def(IntRegisterType)
    csr = attr_def(IntegerAttr)
    writeonly = opt_attr_def(UnitAttr)

    traits = traits_def(MemoryReadEffect(), MemoryWriteEffect())

    def __init__(
        self,
        rs1: Operation | SSAValue,
        csr: IntegerAttr,
        *,
        writeonly: bool = False,
        rd: IntRegisterType = Registers.UNALLOCATED_INT,
        comment: str | StringAttr | None = None,
    ):
        if isinstance(comment, str):
            comment = StringAttr(comment)
        super().__init__(
            operands=[rs1],
            attributes={
                "csr": csr,
                "writeonly": UnitAttr() if writeonly else None,
                "comment": comment,
            },
            result_types=[rd],
        )

    def verify_(self) -> None:
        if not self.writeonly:
            return
        if is_non_zero(self.rd.type):
            raise VerifyException(
                "When in 'writeonly' mode, destination must be register x0 (a.k.a. 'zero'), "
                f"not '{self.rd.type.register_name.data}'"
            )

    def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
        return self.rd, self.csr, self.rs1

    @classmethod
    def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
        attributes = dict[str, Attribute]()
        attributes["csr"] = IntegerAttr(
            parser.parse_integer(allow_boolean=False, context_msg="Expected csr"),
            IntegerType(32),
        )
        if parser.parse_optional_punctuation(",") is not None:
            if (flag := parser.parse_str_literal("Expected 'w' flag")) != "w":
                parser.raise_error(f"Expected 'w' flag, got '{flag}'")
            attributes["writeonly"] = UnitAttr()
        return attributes

    def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
        printer.print_string(", ")
        self.csr.print_without_type(printer)
        if self.writeonly is not None:
            printer.print_string(', "w"')
        return {"csr", "writeonly"}

rd = result_def(IntRegisterType) class-attribute instance-attribute

rs1 = operand_def(IntRegisterType) class-attribute instance-attribute

csr = attr_def(IntegerAttr) class-attribute instance-attribute

writeonly = opt_attr_def(UnitAttr) class-attribute instance-attribute

traits = traits_def(MemoryReadEffect(), MemoryWriteEffect()) class-attribute instance-attribute

__init__(rs1: Operation | SSAValue, csr: IntegerAttr, *, writeonly: bool = False, rd: IntRegisterType = Registers.UNALLOCATED_INT, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/riscv/abstract_ops.py
def __init__(
    self,
    rs1: Operation | SSAValue,
    csr: IntegerAttr,
    *,
    writeonly: bool = False,
    rd: IntRegisterType = Registers.UNALLOCATED_INT,
    comment: str | StringAttr | None = None,
):
    if isinstance(comment, str):
        comment = StringAttr(comment)
    super().__init__(
        operands=[rs1],
        attributes={
            "csr": csr,
            "writeonly": UnitAttr() if writeonly else None,
            "comment": comment,
        },
        result_types=[rd],
    )

verify_() -> None

Source code in xdsl/dialects/riscv/abstract_ops.py
def verify_(self) -> None:
    if not self.writeonly:
        return
    if is_non_zero(self.rd.type):
        raise VerifyException(
            "When in 'writeonly' mode, destination must be register x0 (a.k.a. 'zero'), "
            f"not '{self.rd.type.register_name.data}'"
        )

assembly_line_args() -> tuple[AssemblyInstructionArg, ...]

Source code in xdsl/dialects/riscv/abstract_ops.py
def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
    return self.rd, self.csr, self.rs1

custom_parse_attributes(parser: Parser) -> dict[str, Attribute] classmethod

Source code in xdsl/dialects/riscv/abstract_ops.py
@classmethod
def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
    attributes = dict[str, Attribute]()
    attributes["csr"] = IntegerAttr(
        parser.parse_integer(allow_boolean=False, context_msg="Expected csr"),
        IntegerType(32),
    )
    if parser.parse_optional_punctuation(",") is not None:
        if (flag := parser.parse_str_literal("Expected 'w' flag")) != "w":
            parser.raise_error(f"Expected 'w' flag, got '{flag}'")
        attributes["writeonly"] = UnitAttr()
    return attributes

custom_print_attributes(printer: Printer) -> AbstractSet[str]

Source code in xdsl/dialects/riscv/abstract_ops.py
def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
    printer.print_string(", ")
    self.csr.print_without_type(printer)
    if self.writeonly is not None:
        printer.print_string(', "w"')
    return {"csr", "writeonly"}

CsrBitwiseOperation

Bases: RISCVCustomFormatOperation, RISCVInstruction, ABC

A base class for RISC-V operations performing a masked bitwise operation on the CSR while returning the original value.

The 'readonly' attribute controls the actual behaviour of the operation: * when True, the operation is guaranteed to have no side effects that can be potentially related to writing to a CSR; in this case rs must be allocated to x0 * when False, the bitwise operations is performed and any side effect related to writing to a CSR takes place even if the mask in rs has no actual bits set.

Source code in xdsl/dialects/riscv/abstract_ops.py
class CsrBitwiseOperation(RISCVCustomFormatOperation, RISCVInstruction, ABC):
    """
    A base class for RISC-V operations performing a masked bitwise operation on the
    CSR while returning the original value.

    The 'readonly' attribute controls the actual behaviour of the operation:
    * when True, the operation is guaranteed to have no side effects that can
      be potentially related to writing to a CSR; in this case rs *must be
      allocated to x0*
    * when False, the bitwise operations is performed and any side effect related
      to writing to a CSR takes place even if the mask in rs has no actual bits set.
    """

    rd = result_def(IntRegisterType)
    rs1 = operand_def(IntRegisterType)
    csr = attr_def(IntegerAttr)
    readonly = opt_attr_def(UnitAttr)

    # Conservatively set the write effect, in the future we should be conditional on
    # the `readonly` flag.
    traits = traits_def(MemoryReadEffect(), MemoryWriteEffect())

    def __init__(
        self,
        rs1: Operation | SSAValue,
        csr: IntegerAttr,
        *,
        readonly: bool = False,
        rd: IntRegisterType = Registers.UNALLOCATED_INT,
        comment: str | StringAttr | None = None,
    ):
        if isinstance(comment, str):
            comment = StringAttr(comment)
        super().__init__(
            operands=[rs1],
            attributes={
                "csr": csr,
                "readonly": UnitAttr() if readonly else None,
                "comment": comment,
            },
            result_types=[rd],
        )

    def verify_(self) -> None:
        if not self.readonly:
            return
        assert isinstance(self.rs1.type, IntRegisterType)
        if is_non_zero(self.rs1.type):
            raise VerifyException(
                "When in 'readonly' mode, source must be register x0 (a.k.a. 'zero'), "
                f"not '{self.rs1.type.register_name.data}'"
            )

    def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
        return self.rd, self.csr, self.rs1

    @classmethod
    def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
        attributes = dict[str, Attribute]()
        attributes["csr"] = IntegerAttr(
            parser.parse_integer(allow_boolean=False, context_msg="Expected csr"),
            IntegerType(32),
        )
        if parser.parse_optional_punctuation(",") is not None:
            if (flag := parser.parse_str_literal("Expected 'r' flag")) != "r":
                parser.raise_error(f"Expected 'r' flag, got '{flag}'")
            attributes["readonly"] = UnitAttr()
        return attributes

    def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
        printer.print_string(", ")
        self.csr.print_without_type(printer)
        if self.readonly is not None:
            printer.print_string(', "r"')
        return {"csr", "readonly"}

rd = result_def(IntRegisterType) class-attribute instance-attribute

rs1 = operand_def(IntRegisterType) class-attribute instance-attribute

csr = attr_def(IntegerAttr) class-attribute instance-attribute

readonly = opt_attr_def(UnitAttr) class-attribute instance-attribute

traits = traits_def(MemoryReadEffect(), MemoryWriteEffect()) class-attribute instance-attribute

__init__(rs1: Operation | SSAValue, csr: IntegerAttr, *, readonly: bool = False, rd: IntRegisterType = Registers.UNALLOCATED_INT, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/riscv/abstract_ops.py
def __init__(
    self,
    rs1: Operation | SSAValue,
    csr: IntegerAttr,
    *,
    readonly: bool = False,
    rd: IntRegisterType = Registers.UNALLOCATED_INT,
    comment: str | StringAttr | None = None,
):
    if isinstance(comment, str):
        comment = StringAttr(comment)
    super().__init__(
        operands=[rs1],
        attributes={
            "csr": csr,
            "readonly": UnitAttr() if readonly else None,
            "comment": comment,
        },
        result_types=[rd],
    )

verify_() -> None

Source code in xdsl/dialects/riscv/abstract_ops.py
def verify_(self) -> None:
    if not self.readonly:
        return
    assert isinstance(self.rs1.type, IntRegisterType)
    if is_non_zero(self.rs1.type):
        raise VerifyException(
            "When in 'readonly' mode, source must be register x0 (a.k.a. 'zero'), "
            f"not '{self.rs1.type.register_name.data}'"
        )

assembly_line_args() -> tuple[AssemblyInstructionArg, ...]

Source code in xdsl/dialects/riscv/abstract_ops.py
def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
    return self.rd, self.csr, self.rs1

custom_parse_attributes(parser: Parser) -> dict[str, Attribute] classmethod

Source code in xdsl/dialects/riscv/abstract_ops.py
@classmethod
def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
    attributes = dict[str, Attribute]()
    attributes["csr"] = IntegerAttr(
        parser.parse_integer(allow_boolean=False, context_msg="Expected csr"),
        IntegerType(32),
    )
    if parser.parse_optional_punctuation(",") is not None:
        if (flag := parser.parse_str_literal("Expected 'r' flag")) != "r":
            parser.raise_error(f"Expected 'r' flag, got '{flag}'")
        attributes["readonly"] = UnitAttr()
    return attributes

custom_print_attributes(printer: Printer) -> AbstractSet[str]

Source code in xdsl/dialects/riscv/abstract_ops.py
def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
    printer.print_string(", ")
    self.csr.print_without_type(printer)
    if self.readonly is not None:
        printer.print_string(', "r"')
    return {"csr", "readonly"}

CsrReadWriteImmOperation

Bases: RISCVCustomFormatOperation, RISCVInstruction, ABC

A base class for RISC-V operations performing a write immediate to/read from a CSR.

The 'writeonly' attribute controls the actual behaviour of the operation: * when True, the operation writes the rs value to the CSR but never reads it and in this case rd must be allocated to x0 * when False, a proper atomic swap is performed and the previous CSR value is returned in rd

Source code in xdsl/dialects/riscv/abstract_ops.py
class CsrReadWriteImmOperation(RISCVCustomFormatOperation, RISCVInstruction, ABC):
    """
    A base class for RISC-V operations performing a write immediate to/read from a CSR.

    The 'writeonly' attribute controls the actual behaviour of the operation:
    * when True, the operation writes the rs value to the CSR but never reads it and
      in this case rd *must* be allocated to x0
    * when False, a proper atomic swap is performed and the previous CSR value is
      returned in rd
    """

    rd = result_def(IntRegisterType)
    csr = attr_def(IntegerAttr)
    immediate = attr_def(IntegerAttr)
    writeonly = opt_attr_def(UnitAttr)

    traits = traits_def(MemoryReadEffect(), MemoryWriteEffect())

    def __init__(
        self,
        csr: IntegerAttr,
        immediate: IntegerAttr,
        *,
        writeonly: bool = False,
        rd: IntRegisterType = Registers.UNALLOCATED_INT,
        comment: str | StringAttr | None = None,
    ):
        if isinstance(comment, str):
            comment = StringAttr(comment)
        super().__init__(
            attributes={
                "csr": csr,
                "immediate": immediate,
                "writeonly": UnitAttr() if writeonly else None,
                "comment": comment,
            },
            result_types=[rd],
        )

    def verify_(self) -> None:
        if self.writeonly is None:
            return
        if is_non_zero(self.rd.type):
            raise VerifyException(
                "When in 'writeonly' mode, destination must be register x0 (a.k.a. 'zero'), "
                f"not '{self.rd.type.register_name.data}'"
            )

    def assembly_line_args(self) -> tuple[AssemblyInstructionArg | None, ...]:
        return self.rd, self.csr, self.immediate

    @classmethod
    def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
        attributes = dict[str, Attribute]()
        attributes["csr"] = IntegerAttr(
            parser.parse_integer(allow_boolean=False, context_msg="Expected csr"),
            IntegerType(32),
        )
        parser.parse_punctuation(",")
        attributes["immediate"] = parse_immediate_value(parser, IntegerType(32))
        if parser.parse_optional_punctuation(",") is not None:
            if (flag := parser.parse_str_literal("Expected 'w' flag")) != "w":
                parser.raise_error(f"Expected 'w' flag, got '{flag}'")
            attributes["writeonly"] = UnitAttr()
        return attributes

    def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
        printer.print_string(" ")
        self.csr.print_without_type(printer)
        printer.print_string(", ")
        print_immediate_value(printer, self.immediate)
        if self.writeonly is not None:
            printer.print_string(', "w"')
        return {"csr", "immediate", "writeonly"}

rd = result_def(IntRegisterType) class-attribute instance-attribute

csr = attr_def(IntegerAttr) class-attribute instance-attribute

immediate = attr_def(IntegerAttr) class-attribute instance-attribute

writeonly = opt_attr_def(UnitAttr) class-attribute instance-attribute

traits = traits_def(MemoryReadEffect(), MemoryWriteEffect()) class-attribute instance-attribute

__init__(csr: IntegerAttr, immediate: IntegerAttr, *, writeonly: bool = False, rd: IntRegisterType = Registers.UNALLOCATED_INT, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/riscv/abstract_ops.py
def __init__(
    self,
    csr: IntegerAttr,
    immediate: IntegerAttr,
    *,
    writeonly: bool = False,
    rd: IntRegisterType = Registers.UNALLOCATED_INT,
    comment: str | StringAttr | None = None,
):
    if isinstance(comment, str):
        comment = StringAttr(comment)
    super().__init__(
        attributes={
            "csr": csr,
            "immediate": immediate,
            "writeonly": UnitAttr() if writeonly else None,
            "comment": comment,
        },
        result_types=[rd],
    )

verify_() -> None

Source code in xdsl/dialects/riscv/abstract_ops.py
def verify_(self) -> None:
    if self.writeonly is None:
        return
    if is_non_zero(self.rd.type):
        raise VerifyException(
            "When in 'writeonly' mode, destination must be register x0 (a.k.a. 'zero'), "
            f"not '{self.rd.type.register_name.data}'"
        )

assembly_line_args() -> tuple[AssemblyInstructionArg | None, ...]

Source code in xdsl/dialects/riscv/abstract_ops.py
def assembly_line_args(self) -> tuple[AssemblyInstructionArg | None, ...]:
    return self.rd, self.csr, self.immediate

custom_parse_attributes(parser: Parser) -> dict[str, Attribute] classmethod

Source code in xdsl/dialects/riscv/abstract_ops.py
@classmethod
def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
    attributes = dict[str, Attribute]()
    attributes["csr"] = IntegerAttr(
        parser.parse_integer(allow_boolean=False, context_msg="Expected csr"),
        IntegerType(32),
    )
    parser.parse_punctuation(",")
    attributes["immediate"] = parse_immediate_value(parser, IntegerType(32))
    if parser.parse_optional_punctuation(",") is not None:
        if (flag := parser.parse_str_literal("Expected 'w' flag")) != "w":
            parser.raise_error(f"Expected 'w' flag, got '{flag}'")
        attributes["writeonly"] = UnitAttr()
    return attributes

custom_print_attributes(printer: Printer) -> AbstractSet[str]

Source code in xdsl/dialects/riscv/abstract_ops.py
def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
    printer.print_string(" ")
    self.csr.print_without_type(printer)
    printer.print_string(", ")
    print_immediate_value(printer, self.immediate)
    if self.writeonly is not None:
        printer.print_string(', "w"')
    return {"csr", "immediate", "writeonly"}

CsrBitwiseImmOperation

Bases: RISCVCustomFormatOperation, RISCVInstruction, ABC

A base class for RISC-V operations performing a masked bitwise operation on the CSR while returning the original value. The bitmask is specified in the 'immediate' attribute.

The 'immediate' attribute controls the actual behaviour of the operation: * when equals to zero, the operation is guaranteed to have no side effects that can be potentially related to writing to a CSR; * when not equal to zero, any side effect related to writing to a CSR takes place.

Source code in xdsl/dialects/riscv/abstract_ops.py
class CsrBitwiseImmOperation(RISCVCustomFormatOperation, RISCVInstruction, ABC):
    """
    A base class for RISC-V operations performing a masked bitwise operation on the
    CSR while returning the original value. The bitmask is specified in the 'immediate'
    attribute.

    The 'immediate' attribute controls the actual behaviour of the operation:
    * when equals to zero, the operation is guaranteed to have no side effects
      that can be potentially related to writing to a CSR;
    * when not equal to zero, any side effect related to writing to a CSR takes
      place.
    """

    rd = result_def(IntRegisterType)
    csr = attr_def(IntegerAttr)
    immediate = attr_def(IntegerAttr)

    traits = traits_def(MemoryReadEffect(), MemoryWriteEffect())

    def __init__(
        self,
        csr: IntegerAttr,
        immediate: IntegerAttr,
        *,
        rd: IntRegisterType = Registers.UNALLOCATED_INT,
        comment: str | StringAttr | None = None,
    ):
        if isinstance(comment, str):
            comment = StringAttr(comment)
        super().__init__(
            attributes={
                "csr": csr,
                "immediate": immediate,
                "comment": comment,
            },
            result_types=[rd],
        )

    def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
        return self.rd, self.csr, self.immediate

    @classmethod
    def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
        attributes = dict[str, Attribute]()
        attributes["csr"] = IntegerAttr(
            parser.parse_integer(allow_boolean=False, context_msg="Expected csr"),
            IntegerType(32),
        )
        parser.parse_punctuation(",")
        attributes["immediate"] = parse_immediate_value(parser, IntegerType(32))
        return attributes

    def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
        printer.print_string(" ")
        self.csr.print_without_type(printer)
        printer.print_string(", ")
        print_immediate_value(printer, self.immediate)
        return {"csr", "immediate"}

rd = result_def(IntRegisterType) class-attribute instance-attribute

csr = attr_def(IntegerAttr) class-attribute instance-attribute

immediate = attr_def(IntegerAttr) class-attribute instance-attribute

traits = traits_def(MemoryReadEffect(), MemoryWriteEffect()) class-attribute instance-attribute

__init__(csr: IntegerAttr, immediate: IntegerAttr, *, rd: IntRegisterType = Registers.UNALLOCATED_INT, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/riscv/abstract_ops.py
def __init__(
    self,
    csr: IntegerAttr,
    immediate: IntegerAttr,
    *,
    rd: IntRegisterType = Registers.UNALLOCATED_INT,
    comment: str | StringAttr | None = None,
):
    if isinstance(comment, str):
        comment = StringAttr(comment)
    super().__init__(
        attributes={
            "csr": csr,
            "immediate": immediate,
            "comment": comment,
        },
        result_types=[rd],
    )

assembly_line_args() -> tuple[AssemblyInstructionArg, ...]

Source code in xdsl/dialects/riscv/abstract_ops.py
def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
    return self.rd, self.csr, self.immediate

custom_parse_attributes(parser: Parser) -> dict[str, Attribute] classmethod

Source code in xdsl/dialects/riscv/abstract_ops.py
@classmethod
def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
    attributes = dict[str, Attribute]()
    attributes["csr"] = IntegerAttr(
        parser.parse_integer(allow_boolean=False, context_msg="Expected csr"),
        IntegerType(32),
    )
    parser.parse_punctuation(",")
    attributes["immediate"] = parse_immediate_value(parser, IntegerType(32))
    return attributes

custom_print_attributes(printer: Printer) -> AbstractSet[str]

Source code in xdsl/dialects/riscv/abstract_ops.py
def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
    printer.print_string(" ")
    self.csr.print_without_type(printer)
    printer.print_string(", ")
    print_immediate_value(printer, self.immediate)
    return {"csr", "immediate"}

LiOpHasCanonicalizationPatternTrait dataclass

Bases: HasCanonicalizationPatternsTrait

Source code in xdsl/dialects/riscv/abstract_ops.py
class LiOpHasCanonicalizationPatternTrait(HasCanonicalizationPatternsTrait):
    @classmethod
    def get_canonicalization_patterns(cls) -> tuple[RewritePattern, ...]:
        from xdsl.transforms.canonicalization_patterns.riscv import (
            LoadImmediate0,
        )

        return (LoadImmediate0(),)

get_canonicalization_patterns() -> tuple[RewritePattern, ...] classmethod

Source code in xdsl/dialects/riscv/abstract_ops.py
@classmethod
def get_canonicalization_patterns(cls) -> tuple[RewritePattern, ...]:
    from xdsl.transforms.canonicalization_patterns.riscv import (
        LoadImmediate0,
    )

    return (LoadImmediate0(),)

LiOperation

Bases: RISCVCustomFormatOperation, RISCVInstruction, HasFolderInterface, ABC, Generic[IWidth]

Base class for RISC-V operations that load an immediate into rd.

See external documentation.

Source code in xdsl/dialects/riscv/abstract_ops.py
class LiOperation(
    RISCVCustomFormatOperation,
    RISCVInstruction,
    HasFolderInterface,
    ABC,
    Generic[IWidth],
):
    """
    Base class for RISC-V operations that load an immediate into rd.

    See external [documentation](https://github.com/riscv-non-isa/riscv-asm-manual/blob/main/src/asm-manual.adoc).
    """

    rd = result_def(IntRegisterType)
    immediate = attr_def(IntegerAttr[IWidth] | LabelAttr)

    traits = traits_def(
        AlwaysSpeculatable(), ConstantLike(), LiOpHasCanonicalizationPatternTrait()
    )

    def __init__(
        self,
        immediate: IntegerAttr[IWidth] | str | LabelAttr,
        *,
        rd: IntRegisterType = Registers.UNALLOCATED_INT,
        comment: str | StringAttr | None = None,
    ):
        if isinstance(immediate, str):
            immediate = LabelAttr(immediate)
        if isinstance(comment, str):
            comment = StringAttr(comment)

        super().__init__(
            result_types=[rd],
            attributes={
                "immediate": immediate,
                "comment": comment,
            },
        )

    def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
        return self.rd, self.immediate

    def fold(self) -> tuple[IntegerAttr[IWidth] | LabelAttr]:
        return (self.immediate,)

    def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
        printer.print_string(" ")
        print_immediate_value(printer, self.immediate)
        return {"immediate", "fastmath"}

    @classmethod
    def parse_op_type(
        cls, parser: Parser
    ) -> tuple[Sequence[Attribute], Sequence[Attribute]]:
        parser.parse_punctuation(":")
        res_type = parser.parse_attribute()
        return (), (res_type,)

    def print_op_type(self, printer: Printer) -> None:
        printer.print_string(" : ")
        printer.print_attribute(self.rd.type)

rd = result_def(IntRegisterType) class-attribute instance-attribute

immediate = attr_def(IntegerAttr[IWidth] | LabelAttr) class-attribute instance-attribute

traits = traits_def(AlwaysSpeculatable(), ConstantLike(), LiOpHasCanonicalizationPatternTrait()) class-attribute instance-attribute

__init__(immediate: IntegerAttr[IWidth] | str | LabelAttr, *, rd: IntRegisterType = Registers.UNALLOCATED_INT, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/riscv/abstract_ops.py
def __init__(
    self,
    immediate: IntegerAttr[IWidth] | str | LabelAttr,
    *,
    rd: IntRegisterType = Registers.UNALLOCATED_INT,
    comment: str | StringAttr | None = None,
):
    if isinstance(immediate, str):
        immediate = LabelAttr(immediate)
    if isinstance(comment, str):
        comment = StringAttr(comment)

    super().__init__(
        result_types=[rd],
        attributes={
            "immediate": immediate,
            "comment": comment,
        },
    )

assembly_line_args() -> tuple[AssemblyInstructionArg, ...]

Source code in xdsl/dialects/riscv/abstract_ops.py
def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
    return self.rd, self.immediate

fold() -> tuple[IntegerAttr[IWidth] | LabelAttr]

Source code in xdsl/dialects/riscv/abstract_ops.py
def fold(self) -> tuple[IntegerAttr[IWidth] | LabelAttr]:
    return (self.immediate,)

custom_print_attributes(printer: Printer) -> AbstractSet[str]

Source code in xdsl/dialects/riscv/abstract_ops.py
def custom_print_attributes(self, printer: Printer) -> AbstractSet[str]:
    printer.print_string(" ")
    print_immediate_value(printer, self.immediate)
    return {"immediate", "fastmath"}

parse_op_type(parser: Parser) -> tuple[Sequence[Attribute], Sequence[Attribute]] classmethod

Source code in xdsl/dialects/riscv/abstract_ops.py
@classmethod
def parse_op_type(
    cls, parser: Parser
) -> tuple[Sequence[Attribute], Sequence[Attribute]]:
    parser.parse_punctuation(":")
    res_type = parser.parse_attribute()
    return (), (res_type,)

print_op_type(printer: Printer) -> None

Source code in xdsl/dialects/riscv/abstract_ops.py
def print_op_type(self, printer: Printer) -> None:
    printer.print_string(" : ")
    printer.print_attribute(self.rd.type)

GetAnyRegisterOperation

Bases: RISCVCustomFormatOperation, RISCVAsmOperation, RISCVRegallocOperation, ABC, Generic[RDInvT]

This instruction allows us to create an SSAValue with for a given register name. This is useful for bridging the RISC-V convention that stores the result of function calls in a0 and a1 into SSA form.

For example, to generate this assembly:

jal my_func
add a0 s0 a0

One needs to do the following:

rhs = rv32.GetRegisterOp(Registers.s0).res
riscv.JalOp("my_func")
lhs = rv32.GetRegisterOp(Registers.A0).res
sum = riscv.AddOp(lhs, rhs, Registers.A0).rd
Source code in xdsl/dialects/riscv/abstract_ops.py
class GetAnyRegisterOperation(
    RISCVCustomFormatOperation,
    RISCVAsmOperation,
    RISCVRegallocOperation,
    ABC,
    Generic[RDInvT],
):
    """
    This instruction allows us to create an SSAValue with for a given register name. This
    is useful for bridging the RISC-V convention that stores the result of function calls
    in `a0` and `a1` into SSA form.

    For example, to generate this assembly:
    ```
    jal my_func
    add a0 s0 a0
    ```

    One needs to do the following:

    ``` python
    rhs = rv32.GetRegisterOp(Registers.s0).res
    riscv.JalOp("my_func")
    lhs = rv32.GetRegisterOp(Registers.A0).res
    sum = riscv.AddOp(lhs, rhs, Registers.A0).rd
    ```
    """

    res = result_def(RDInvT)

    traits = traits_def(Pure())

    def __init__(
        self,
        register_type: RDInvT,
    ):
        super().__init__(result_types=[register_type])

    def assembly_line(self) -> str | None:
        # Don't print assembly for creating a SSA value representing register
        return None

    @classmethod
    def parse_op_type(
        cls, parser: Parser
    ) -> tuple[Sequence[Attribute], Sequence[Attribute]]:
        parser.parse_punctuation(":")
        res_type = parser.parse_attribute()
        return (), (res_type,)

    def print_op_type(self, printer: Printer) -> None:
        printer.print_string(" : ")
        printer.print_attribute(self.res.type)

res = result_def(RDInvT) class-attribute instance-attribute

traits = traits_def(Pure()) class-attribute instance-attribute

__init__(register_type: RDInvT)

Source code in xdsl/dialects/riscv/abstract_ops.py
def __init__(
    self,
    register_type: RDInvT,
):
    super().__init__(result_types=[register_type])

assembly_line() -> str | None

Source code in xdsl/dialects/riscv/abstract_ops.py
def assembly_line(self) -> str | None:
    # Don't print assembly for creating a SSA value representing register
    return None

parse_op_type(parser: Parser) -> tuple[Sequence[Attribute], Sequence[Attribute]] classmethod

Source code in xdsl/dialects/riscv/abstract_ops.py
@classmethod
def parse_op_type(
    cls, parser: Parser
) -> tuple[Sequence[Attribute], Sequence[Attribute]]:
    parser.parse_punctuation(":")
    res_type = parser.parse_attribute()
    return (), (res_type,)

print_op_type(printer: Printer) -> None

Source code in xdsl/dialects/riscv/abstract_ops.py
def print_op_type(self, printer: Printer) -> None:
    printer.print_string(" : ")
    printer.print_attribute(self.res.type)

assembly_arg_str(arg: AssemblyInstructionArg) -> str

Source code in xdsl/dialects/riscv/abstract_ops.py
def assembly_arg_str(arg: AssemblyInstructionArg) -> str:
    if isinstance(arg, SSAValue):
        if not isinstance(t := arg.type, RegisterType):
            raise ValueError(f"Unexpected register type {t}")
        return t.register_name.data
    elif isinstance(arg, IntegerAttr):
        return f"{arg.value.data}"
    elif isinstance(arg, LabelAttr):
        return arg.data
    elif isinstance(arg, RegisterType):
        return arg.register_name.data

    return arg

print_assembly(module: ModuleOp, output: IO[str]) -> None

Source code in xdsl/dialects/riscv/abstract_ops.py
def print_assembly(module: ModuleOp, output: IO[str]) -> None:
    printer = AssemblyPrinter(stream=output)
    printer.print_module(module)

riscv_code(module: ModuleOp) -> str

Source code in xdsl/dialects/riscv/abstract_ops.py
def riscv_code(module: ModuleOp) -> str:
    stream = StringIO()
    print_assembly(module, stream)
    return stream.getvalue()