Skip to content

Riscv cf

riscv_cf

RISCV_Cf = Dialect('riscv_cf', [JOp, BranchOp, BeqOp, BneOp, BltOp, BgeOp, BltuOp, BgeuOp]) module-attribute

ConditionalBranchOperation

Bases: RISCVInstruction, HasCanonicalizationPatternsInterface, ABC

A base class for RISC-V branch operations. Lowers to RsRsOffOperation.

Source code in xdsl/dialects/riscv_cf.py
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
class ConditionalBranchOperation(
    RISCVInstruction, HasCanonicalizationPatternsInterface, ABC
):
    """
    A base class for RISC-V branch operations. Lowers to RsRsOffOperation.
    """

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

    then_arguments = var_operand_def(RISCVRegisterType)
    else_arguments = var_operand_def(RISCVRegisterType)

    irdl_options = (AttrSizedOperandSegments(),)

    then_block = successor_def()
    else_block = successor_def()

    traits = traits_def(IsTerminator())

    def __init__(
        self,
        rs1: Operation | SSAValue,
        rs2: Operation | SSAValue,
        then_arguments: Sequence[SSAValue],
        else_arguments: Sequence[SSAValue],
        then_block: Successor,
        else_block: Successor,
        *,
        comment: str | StringAttr | None = None,
    ):
        if isinstance(comment, str):
            comment = StringAttr(comment)

        super().__init__(
            operands=[rs1, rs2, then_arguments, else_arguments],
            attributes={
                "comment": comment,
            },
            successors=(then_block, else_block),
        )

    def verify_(self) -> None:
        # The then block must start with a label op

        then_block_first_op = self.then_block.first_op

        if not isinstance(then_block_first_op, riscv.LabelOp):
            raise VerifyException(
                "riscv_cf branch op then block first op must be a label"
            )

        # Types of arguments must match arg types of blocks

        for op_arg, block_arg in zip(self.then_arguments, self.then_block.args):
            if op_arg.type != block_arg.type:
                raise VerifyException(
                    f"Block arg types must match {op_arg.type} {block_arg.type}"
                )

        for op_arg, block_arg in zip(self.else_arguments, self.else_block.args):
            if op_arg.type != block_arg.type:
                raise VerifyException(
                    f"Block arg types must match {op_arg.type} {block_arg.type}"
                )

        # The else block must be the one immediately following this one

        parent_block = self.parent
        if parent_block is None:
            return

        parent_region = parent_block.parent
        if parent_region is None:
            return

        if parent_block.next_block is not self.else_block:
            raise VerifyException(
                "riscv_cf branch op else block must be immediately after op"
            )

    def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
        then_label = self.then_block.first_op
        assert isinstance(then_label, riscv.LabelOp)
        return self.rs1, self.rs2, then_label.label

    def print(self, printer: Printer) -> None:
        printer.print_string(" ")
        _print_type_pair(printer, self.rs1)
        printer.print_string(", ")
        _print_type_pair(printer, self.rs2)
        printer.print_string(", ")
        printer.print_block_name(self.then_block)
        printer.print_string("(")
        printer.print_list(
            self.then_arguments, lambda val: _print_type_pair(printer, val)
        )
        printer.print_string("), ")
        printer.print_block_name(self.else_block)
        printer.print_string("(")
        printer.print_list(
            self.else_arguments, lambda val: _print_type_pair(printer, val)
        )
        printer.print_string(")")
        if self.attributes:
            printer.print_op_attributes(
                self.attributes,
                reserved_attr_names="operandSegmentSizes",
                print_keyword=True,
            )

    @classmethod
    def parse(cls, parser: Parser) -> Self:
        rs1 = _parse_type_pair(parser)
        parser.parse_punctuation(",")
        rs2 = _parse_type_pair(parser)
        parser.parse_punctuation(",")
        then_block = parser.parse_successor()
        then_args = parser.parse_comma_separated_list(
            parser.Delimiter.PAREN, lambda: _parse_type_pair(parser)
        )
        parser.parse_punctuation(",")
        else_block = parser.parse_successor()
        else_args = parser.parse_comma_separated_list(
            parser.Delimiter.PAREN, lambda: _parse_type_pair(parser)
        )
        attrs = parser.parse_optional_attr_dict_with_keyword()
        op = cls(rs1, rs2, then_args, else_args, then_block, else_block)
        if attrs is not None:
            op.attributes |= attrs.data
        return op

    @abstractmethod
    def const_evaluate(self, rs1: int, rs2: int, bitwidth: int) -> bool:
        pass

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

        return (ElideConstantBranches(),)

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

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

then_arguments = var_operand_def(RISCVRegisterType) class-attribute instance-attribute

else_arguments = var_operand_def(RISCVRegisterType) class-attribute instance-attribute

irdl_options = (AttrSizedOperandSegments(),) class-attribute instance-attribute

then_block = successor_def() class-attribute instance-attribute

else_block = successor_def() class-attribute instance-attribute

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

__init__(rs1: Operation | SSAValue, rs2: Operation | SSAValue, then_arguments: Sequence[SSAValue], else_arguments: Sequence[SSAValue], then_block: Successor, else_block: Successor, *, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/riscv_cf.py
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
def __init__(
    self,
    rs1: Operation | SSAValue,
    rs2: Operation | SSAValue,
    then_arguments: Sequence[SSAValue],
    else_arguments: Sequence[SSAValue],
    then_block: Successor,
    else_block: Successor,
    *,
    comment: str | StringAttr | None = None,
):
    if isinstance(comment, str):
        comment = StringAttr(comment)

    super().__init__(
        operands=[rs1, rs2, then_arguments, else_arguments],
        attributes={
            "comment": comment,
        },
        successors=(then_block, else_block),
    )

verify_() -> None

Source code in xdsl/dialects/riscv_cf.py
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
def verify_(self) -> None:
    # The then block must start with a label op

    then_block_first_op = self.then_block.first_op

    if not isinstance(then_block_first_op, riscv.LabelOp):
        raise VerifyException(
            "riscv_cf branch op then block first op must be a label"
        )

    # Types of arguments must match arg types of blocks

    for op_arg, block_arg in zip(self.then_arguments, self.then_block.args):
        if op_arg.type != block_arg.type:
            raise VerifyException(
                f"Block arg types must match {op_arg.type} {block_arg.type}"
            )

    for op_arg, block_arg in zip(self.else_arguments, self.else_block.args):
        if op_arg.type != block_arg.type:
            raise VerifyException(
                f"Block arg types must match {op_arg.type} {block_arg.type}"
            )

    # The else block must be the one immediately following this one

    parent_block = self.parent
    if parent_block is None:
        return

    parent_region = parent_block.parent
    if parent_region is None:
        return

    if parent_block.next_block is not self.else_block:
        raise VerifyException(
            "riscv_cf branch op else block must be immediately after op"
        )

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

Source code in xdsl/dialects/riscv_cf.py
128
129
130
131
def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
    then_label = self.then_block.first_op
    assert isinstance(then_label, riscv.LabelOp)
    return self.rs1, self.rs2, then_label.label

print(printer: Printer) -> None

Source code in xdsl/dialects/riscv_cf.py
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
def print(self, printer: Printer) -> None:
    printer.print_string(" ")
    _print_type_pair(printer, self.rs1)
    printer.print_string(", ")
    _print_type_pair(printer, self.rs2)
    printer.print_string(", ")
    printer.print_block_name(self.then_block)
    printer.print_string("(")
    printer.print_list(
        self.then_arguments, lambda val: _print_type_pair(printer, val)
    )
    printer.print_string("), ")
    printer.print_block_name(self.else_block)
    printer.print_string("(")
    printer.print_list(
        self.else_arguments, lambda val: _print_type_pair(printer, val)
    )
    printer.print_string(")")
    if self.attributes:
        printer.print_op_attributes(
            self.attributes,
            reserved_attr_names="operandSegmentSizes",
            print_keyword=True,
        )

parse(parser: Parser) -> Self classmethod

Source code in xdsl/dialects/riscv_cf.py
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
@classmethod
def parse(cls, parser: Parser) -> Self:
    rs1 = _parse_type_pair(parser)
    parser.parse_punctuation(",")
    rs2 = _parse_type_pair(parser)
    parser.parse_punctuation(",")
    then_block = parser.parse_successor()
    then_args = parser.parse_comma_separated_list(
        parser.Delimiter.PAREN, lambda: _parse_type_pair(parser)
    )
    parser.parse_punctuation(",")
    else_block = parser.parse_successor()
    else_args = parser.parse_comma_separated_list(
        parser.Delimiter.PAREN, lambda: _parse_type_pair(parser)
    )
    attrs = parser.parse_optional_attr_dict_with_keyword()
    op = cls(rs1, rs2, then_args, else_args, then_block, else_block)
    if attrs is not None:
        op.attributes |= attrs.data
    return op

const_evaluate(rs1: int, rs2: int, bitwidth: int) -> bool abstractmethod

Source code in xdsl/dialects/riscv_cf.py
179
180
181
@abstractmethod
def const_evaluate(self, rs1: int, rs2: int, bitwidth: int) -> bool:
    pass

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

Source code in xdsl/dialects/riscv_cf.py
183
184
185
186
187
188
189
@classmethod
def get_canonicalization_patterns(cls) -> tuple[RewritePattern, ...]:
    from xdsl.transforms.canonicalization_patterns.riscv_cf import (
        ElideConstantBranches,
    )

    return (ElideConstantBranches(),)

BeqOp dataclass

Bases: ConditionalBranchOperation

Take the branch if registers rs1 and rs2 are equal.

if (x[rs1] == x[rs2]) pc += sext(offset)

See external documentation.

Source code in xdsl/dialects/riscv_cf.py
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
@irdl_op_definition
class BeqOp(ConditionalBranchOperation):
    """
    Take the branch if registers rs1 and rs2 are equal.

    if (x[rs1] == x[rs2]) pc += sext(offset)

    See external [documentation](https://msyksphinz-self.github.io/riscv-isadoc/html/rvi.html#beq).
    """

    name = "riscv_cf.beq"

    def const_evaluate(self, rs1: int, rs2: int, bitwidth: int) -> bool:
        lhs = to_unsigned(rs1, bitwidth)
        rhs = to_unsigned(rs2, bitwidth)
        return lhs == rhs

name = 'riscv_cf.beq' class-attribute instance-attribute

const_evaluate(rs1: int, rs2: int, bitwidth: int) -> bool

Source code in xdsl/dialects/riscv_cf.py
204
205
206
207
def const_evaluate(self, rs1: int, rs2: int, bitwidth: int) -> bool:
    lhs = to_unsigned(rs1, bitwidth)
    rhs = to_unsigned(rs2, bitwidth)
    return lhs == rhs

BneOp dataclass

Bases: ConditionalBranchOperation

Take the branch if registers rs1 and rs2 are not equal.

if (x[rs1] != x[rs2]) pc += sext(offset)

See external documentation.

Source code in xdsl/dialects/riscv_cf.py
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
@irdl_op_definition
class BneOp(ConditionalBranchOperation):
    """
    Take the branch if registers rs1 and rs2 are not equal.

    if (x[rs1] != x[rs2]) pc += sext(offset)

    See external [documentation](https://msyksphinz-self.github.io/riscv-isadoc/html/rvi.html#bne).
    """

    name = "riscv_cf.bne"

    def const_evaluate(self, rs1: int, rs2: int, bitwidth: int) -> bool:
        lhs = to_unsigned(rs1, bitwidth)
        rhs = to_unsigned(rs2, bitwidth)
        return lhs != rhs

name = 'riscv_cf.bne' class-attribute instance-attribute

const_evaluate(rs1: int, rs2: int, bitwidth: int) -> bool

Source code in xdsl/dialects/riscv_cf.py
222
223
224
225
def const_evaluate(self, rs1: int, rs2: int, bitwidth: int) -> bool:
    lhs = to_unsigned(rs1, bitwidth)
    rhs = to_unsigned(rs2, bitwidth)
    return lhs != rhs

BltOp dataclass

Bases: ConditionalBranchOperation

Take the branch if registers rs1 is less than rs2, using signed comparison.

if (x[rs1] <s x[rs2]) pc += sext(offset)

See external documentation.

Source code in xdsl/dialects/riscv_cf.py
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
@irdl_op_definition
class BltOp(ConditionalBranchOperation):
    """
    Take the branch if registers rs1 is less than rs2, using signed comparison.

    if (x[rs1] <s x[rs2]) pc += sext(offset)

    See external [documentation](https://msyksphinz-self.github.io/riscv-isadoc/html/rvi.html#blt).
    """

    name = "riscv_cf.blt"

    def const_evaluate(self, rs1: int, rs2: int, bitwidth: int) -> bool:
        lhs = to_signed(rs1, bitwidth)
        rhs = to_signed(rs2, bitwidth)
        return lhs < rhs

name = 'riscv_cf.blt' class-attribute instance-attribute

const_evaluate(rs1: int, rs2: int, bitwidth: int) -> bool

Source code in xdsl/dialects/riscv_cf.py
240
241
242
243
def const_evaluate(self, rs1: int, rs2: int, bitwidth: int) -> bool:
    lhs = to_signed(rs1, bitwidth)
    rhs = to_signed(rs2, bitwidth)
    return lhs < rhs

BgeOp dataclass

Bases: ConditionalBranchOperation

Take the branch if registers rs1 is greater than or equal to rs2, using signed comparison.

if (x[rs1] >=s x[rs2]) pc += sext(offset)

See external documentation.

Source code in xdsl/dialects/riscv_cf.py
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
@irdl_op_definition
class BgeOp(ConditionalBranchOperation):
    """
    Take the branch if registers rs1 is greater than or equal to rs2, using signed comparison.

    if (x[rs1] >=s x[rs2]) pc += sext(offset)

    See external [documentation](https://msyksphinz-self.github.io/riscv-isadoc/html/rvi.html#bge).
    """

    name = "riscv_cf.bge"

    def const_evaluate(self, rs1: int, rs2: int, bitwidth: int) -> bool:
        lhs = to_signed(rs1, bitwidth)
        rhs = to_signed(rs2, bitwidth)
        return lhs >= rhs

name = 'riscv_cf.bge' class-attribute instance-attribute

const_evaluate(rs1: int, rs2: int, bitwidth: int) -> bool

Source code in xdsl/dialects/riscv_cf.py
258
259
260
261
def const_evaluate(self, rs1: int, rs2: int, bitwidth: int) -> bool:
    lhs = to_signed(rs1, bitwidth)
    rhs = to_signed(rs2, bitwidth)
    return lhs >= rhs

BltuOp dataclass

Bases: ConditionalBranchOperation

Take the branch if registers rs1 is less than rs2, using unsigned comparison.

if (x[rs1] <u x[rs2]) pc += sext(offset)

See external documentation.

Source code in xdsl/dialects/riscv_cf.py
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
@irdl_op_definition
class BltuOp(ConditionalBranchOperation):
    """
    Take the branch if registers rs1 is less than rs2, using unsigned comparison.

    if (x[rs1] <u x[rs2]) pc += sext(offset)

    See external [documentation](https://msyksphinz-self.github.io/riscv-isadoc/html/rvi.html#bltu).
    """

    name = "riscv_cf.bltu"

    def const_evaluate(self, rs1: int, rs2: int, bitwidth: int) -> bool:
        lhs = to_unsigned(rs1, bitwidth)
        rhs = to_unsigned(rs2, bitwidth)
        return lhs < rhs

name = 'riscv_cf.bltu' class-attribute instance-attribute

const_evaluate(rs1: int, rs2: int, bitwidth: int) -> bool

Source code in xdsl/dialects/riscv_cf.py
276
277
278
279
def const_evaluate(self, rs1: int, rs2: int, bitwidth: int) -> bool:
    lhs = to_unsigned(rs1, bitwidth)
    rhs = to_unsigned(rs2, bitwidth)
    return lhs < rhs

BgeuOp dataclass

Bases: ConditionalBranchOperation

Take the branch if registers rs1 is greater than or equal to rs2, using unsigned comparison.

if (x[rs1] >=u x[rs2]) pc += sext(offset)

See external documentation.

Source code in xdsl/dialects/riscv_cf.py
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
@irdl_op_definition
class BgeuOp(ConditionalBranchOperation):
    """
    Take the branch if registers rs1 is greater than or equal to rs2, using unsigned comparison.

    if (x[rs1] >=u x[rs2]) pc += sext(offset)

    See external [documentation](https://msyksphinz-self.github.io/riscv-isadoc/html/rvi.html#bgeu).
    """

    name = "riscv_cf.bgeu"

    def const_evaluate(self, rs1: int, rs2: int, bitwidth: int) -> bool:
        lhs = to_unsigned(rs1, bitwidth)
        rhs = to_unsigned(rs2, bitwidth)
        return lhs >= rhs

name = 'riscv_cf.bgeu' class-attribute instance-attribute

const_evaluate(rs1: int, rs2: int, bitwidth: int) -> bool

Source code in xdsl/dialects/riscv_cf.py
294
295
296
297
def const_evaluate(self, rs1: int, rs2: int, bitwidth: int) -> bool:
    lhs = to_unsigned(rs1, bitwidth)
    rhs = to_unsigned(rs2, bitwidth)
    return lhs >= rhs

BranchOp

Bases: RISCVAsmOperation

Branches to a different block, which must follow this operation's block in the parent region. Is not printed in assembly.

Source code in xdsl/dialects/riscv_cf.py
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
@irdl_op_definition
class BranchOp(riscv.RISCVAsmOperation):
    """
    Branches to a different block, which must follow this operation's block in the parent
    region. Is not printed in assembly.
    """

    name = "riscv_cf.branch"

    block_arguments = var_operand_def(RISCVRegisterType)
    successor = successor_def()
    comment = opt_attr_def(StringAttr)
    """
    An optional comment that will be printed along with the instruction.
    """

    traits = traits_def(IsTerminator())

    def __init__(
        self,
        block_arguments: Sequence[SSAValue],
        successor: Successor,
        *,
        comment: str | StringAttr | None = None,
    ):
        if isinstance(comment, str):
            comment = StringAttr(comment)

        super().__init__(
            operands=[block_arguments],
            attributes={
                "comment": comment,
            },
            successors=(successor,),
        )

    def verify_(self) -> None:
        # Types of arguments must match arg types of blocks
        for op_arg, block_arg in zip(self.block_arguments, self.successor.args):
            if op_arg.type != block_arg.type:
                raise VerifyException(
                    f"Block arg types must match {op_arg.type} {block_arg.type}"
                )

        # The successor must immediately follow the parent block.
        if (parent_block := self.parent) is None or (
            parent_region := parent_block.parent
        ) is None:
            return

        parent_index = parent_region.get_block_index(parent_block)
        successor_index = parent_region.get_block_index(self.successor)

        if parent_index + 1 != successor_index:
            raise VerifyException(
                "Successor block must be immediately after parent block in the parent "
                "region."
            )

    def print(self, printer: Printer) -> None:
        printer.print_string(" ")
        printer.print_block_name(self.successor)
        printer.print_string("(")
        printer.print_list(
            self.block_arguments, lambda val: _print_type_pair(printer, val)
        )
        printer.print_string(")")
        if self.attributes:
            printer.print_op_attributes(self.attributes, print_keyword=True)

    @classmethod
    def parse(cls, parser: Parser) -> Self:
        successor = parser.parse_successor()
        block_arguments = parser.parse_comma_separated_list(
            parser.Delimiter.PAREN, lambda: _parse_type_pair(parser)
        )
        attrs = parser.parse_optional_attr_dict_with_keyword()
        op = cls(block_arguments, successor)
        if attrs is not None:
            op.attributes |= attrs.data
        return op

    def assembly_line(self) -> str | None:
        if self.comment is None:
            return None

        return f"    # {self.comment.data}"

name = 'riscv_cf.branch' class-attribute instance-attribute

block_arguments = var_operand_def(RISCVRegisterType) class-attribute instance-attribute

successor = successor_def() class-attribute instance-attribute

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

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

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

__init__(block_arguments: Sequence[SSAValue], successor: Successor, *, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/riscv_cf.py
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
def __init__(
    self,
    block_arguments: Sequence[SSAValue],
    successor: Successor,
    *,
    comment: str | StringAttr | None = None,
):
    if isinstance(comment, str):
        comment = StringAttr(comment)

    super().__init__(
        operands=[block_arguments],
        attributes={
            "comment": comment,
        },
        successors=(successor,),
    )

verify_() -> None

Source code in xdsl/dialects/riscv_cf.py
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
def verify_(self) -> None:
    # Types of arguments must match arg types of blocks
    for op_arg, block_arg in zip(self.block_arguments, self.successor.args):
        if op_arg.type != block_arg.type:
            raise VerifyException(
                f"Block arg types must match {op_arg.type} {block_arg.type}"
            )

    # The successor must immediately follow the parent block.
    if (parent_block := self.parent) is None or (
        parent_region := parent_block.parent
    ) is None:
        return

    parent_index = parent_region.get_block_index(parent_block)
    successor_index = parent_region.get_block_index(self.successor)

    if parent_index + 1 != successor_index:
        raise VerifyException(
            "Successor block must be immediately after parent block in the parent "
            "region."
        )

print(printer: Printer) -> None

Source code in xdsl/dialects/riscv_cf.py
359
360
361
362
363
364
365
366
367
368
def print(self, printer: Printer) -> None:
    printer.print_string(" ")
    printer.print_block_name(self.successor)
    printer.print_string("(")
    printer.print_list(
        self.block_arguments, lambda val: _print_type_pair(printer, val)
    )
    printer.print_string(")")
    if self.attributes:
        printer.print_op_attributes(self.attributes, print_keyword=True)

parse(parser: Parser) -> Self classmethod

Source code in xdsl/dialects/riscv_cf.py
370
371
372
373
374
375
376
377
378
379
380
@classmethod
def parse(cls, parser: Parser) -> Self:
    successor = parser.parse_successor()
    block_arguments = parser.parse_comma_separated_list(
        parser.Delimiter.PAREN, lambda: _parse_type_pair(parser)
    )
    attrs = parser.parse_optional_attr_dict_with_keyword()
    op = cls(block_arguments, successor)
    if attrs is not None:
        op.attributes |= attrs.data
    return op

assembly_line() -> str | None

Source code in xdsl/dialects/riscv_cf.py
382
383
384
385
386
def assembly_line(self) -> str | None:
    if self.comment is None:
        return None

    return f"    # {self.comment.data}"

JOp

Bases: RISCVInstruction

A pseudo-instruction, for unconditional jumps you don't expect to return from. Is equivalent to JalOp with rd = x0. Used to be a part of the spec, removed in 2.0.

Source code in xdsl/dialects/riscv_cf.py
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
@irdl_op_definition
class JOp(RISCVInstruction):
    """
    A pseudo-instruction, for unconditional jumps you don't expect to return from.
    Is equivalent to JalOp with `rd` = `x0`.
    Used to be a part of the spec, removed in 2.0.
    """

    name = "riscv_cf.j"

    block_arguments = var_operand_def(RISCVRegisterType)

    successor = successor_def()

    traits = traits_def(IsTerminator())

    def __init__(
        self,
        block_arguments: Sequence[SSAValue],
        successor: Successor,
        *,
        comment: str | StringAttr | None = None,
    ):
        if isinstance(comment, str):
            comment = StringAttr(comment)

        super().__init__(
            operands=[block_arguments],
            attributes={
                "comment": comment,
            },
            successors=(successor,),
        )

    def verify_(self) -> None:
        # Types of arguments must match arg types of blocks

        for op_arg, block_arg in zip(self.block_arguments, self.successor.args):
            if op_arg.type != block_arg.type:
                raise VerifyException(
                    f"Block arg types must match {op_arg.type} {block_arg.type}"
                )

        if not isinstance(self.successor.first_op, riscv.LabelOp):
            raise VerifyException(
                "riscv_cf.j operation successor must have a riscv.label operation as a "
                f"first argument, found {self.successor.first_op}"
            )

    def print(self, printer: Printer) -> None:
        printer.print_string(" ")
        printer.print_block_name(self.successor)
        printer.print_string("(")
        printer.print_list(
            self.block_arguments, lambda val: _print_type_pair(printer, val)
        )
        printer.print_string(")")
        if self.attributes:
            printer.print_op_attributes(self.attributes, print_keyword=True)

    @classmethod
    def parse(cls, parser: Parser) -> Self:
        successor = parser.parse_successor()
        block_arguments = parser.parse_comma_separated_list(
            parser.Delimiter.PAREN, lambda: _parse_type_pair(parser)
        )
        attrs = parser.parse_optional_attr_dict_with_keyword()
        op = cls(block_arguments, successor)
        if attrs is not None:
            op.attributes |= attrs.data
        return op

    def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
        dest_label = self.successor.first_op
        assert isinstance(dest_label, riscv.LabelOp)
        return (dest_label.label,)

name = 'riscv_cf.j' class-attribute instance-attribute

block_arguments = var_operand_def(RISCVRegisterType) class-attribute instance-attribute

successor = successor_def() class-attribute instance-attribute

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

__init__(block_arguments: Sequence[SSAValue], successor: Successor, *, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/riscv_cf.py
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
def __init__(
    self,
    block_arguments: Sequence[SSAValue],
    successor: Successor,
    *,
    comment: str | StringAttr | None = None,
):
    if isinstance(comment, str):
        comment = StringAttr(comment)

    super().__init__(
        operands=[block_arguments],
        attributes={
            "comment": comment,
        },
        successors=(successor,),
    )

verify_() -> None

Source code in xdsl/dialects/riscv_cf.py
423
424
425
426
427
428
429
430
431
432
433
434
435
436
def verify_(self) -> None:
    # Types of arguments must match arg types of blocks

    for op_arg, block_arg in zip(self.block_arguments, self.successor.args):
        if op_arg.type != block_arg.type:
            raise VerifyException(
                f"Block arg types must match {op_arg.type} {block_arg.type}"
            )

    if not isinstance(self.successor.first_op, riscv.LabelOp):
        raise VerifyException(
            "riscv_cf.j operation successor must have a riscv.label operation as a "
            f"first argument, found {self.successor.first_op}"
        )

print(printer: Printer) -> None

Source code in xdsl/dialects/riscv_cf.py
438
439
440
441
442
443
444
445
446
447
def print(self, printer: Printer) -> None:
    printer.print_string(" ")
    printer.print_block_name(self.successor)
    printer.print_string("(")
    printer.print_list(
        self.block_arguments, lambda val: _print_type_pair(printer, val)
    )
    printer.print_string(")")
    if self.attributes:
        printer.print_op_attributes(self.attributes, print_keyword=True)

parse(parser: Parser) -> Self classmethod

Source code in xdsl/dialects/riscv_cf.py
449
450
451
452
453
454
455
456
457
458
459
@classmethod
def parse(cls, parser: Parser) -> Self:
    successor = parser.parse_successor()
    block_arguments = parser.parse_comma_separated_list(
        parser.Delimiter.PAREN, lambda: _parse_type_pair(parser)
    )
    attrs = parser.parse_optional_attr_dict_with_keyword()
    op = cls(block_arguments, successor)
    if attrs is not None:
        op.attributes |= attrs.data
    return op

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

Source code in xdsl/dialects/riscv_cf.py
461
462
463
464
def assembly_line_args(self) -> tuple[AssemblyInstructionArg, ...]:
    dest_label = self.successor.first_op
    assert isinstance(dest_label, riscv.LabelOp)
    return (dest_label.label,)