Skip to content

Commit

Permalink
dialects: (x86) PR10 - RRI Operations (#2524)
Browse files Browse the repository at this point in the history
Added support for instructions with 1 destination register, one source
register and one immediate.

---------

Co-authored-by: Sasha Lopoukhine <superlopuh@gmail.com>
  • Loading branch information
KGrykiel and superlopuh authored May 2, 2024
1 parent 044ebe9 commit 167d54c
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 0 deletions.
3 changes: 3 additions & 0 deletions tests/filecheck/dialects/x86/x86_assembly_emission.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,6 @@ x86.mi.xor %0, 2, 8 : (!x86.reg<rax>) -> ()
// CHECK: xor [rax+8], 2
x86.mi.mov %0, 2, 8 : (!x86.reg<rax>) -> ()
// CHECK: mov [rax+8], 2

%rri_imul = x86.rri.imul %1, 2 : (!x86.reg<rdx>) -> !x86.reg<rax>
// CHECK: imul rax, rdx, 2
3 changes: 3 additions & 0 deletions tests/filecheck/dialects/x86/x86_ops.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,6 @@ x86.mi.xor %0, 2, 8 : (!x86.reg<>) -> ()
// CHECK-NEXT: x86.mi.xor %{{.*}}, 2, 8 : (!x86.reg<>) -> ()
x86.mi.mov %0, 2, 8 : (!x86.reg<>) -> ()
// CHECK-NEXT: x86.mi.mov %{{.*}}, 2, 8 : (!x86.reg<>) -> ()

%rri_imul = x86.rri.imul %1, 2 : (!x86.reg<>) -> !x86.reg<>
// CHECK-NEXT: %{{.*}} = x86.rri.imul %{{.*}}, 2 : (!x86.reg<>) -> !x86.reg<>
2 changes: 2 additions & 0 deletions xdsl/dialects/x86/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
RR_OrOp,
RR_SubOp,
RR_XorOp,
RRI_ImulOP,
)
from .register import GeneralRegisterType

Expand Down Expand Up @@ -78,6 +79,7 @@
MI_OrOp,
MI_XorOp,
MI_MovOp,
RRI_ImulOP,
GetRegisterOp,
],
[
Expand Down
61 changes: 61 additions & 0 deletions xdsl/dialects/x86/ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -948,6 +948,67 @@ class MI_MovOp(M_MI_Operation[GeneralRegisterType]):
name = "x86.mi.mov"


class R_RRI_Operation(Generic[R1InvT, R2InvT], IRDLOperation, X86Instruction, ABC):
"""
A base class for x86 operations that have one destination register, one source register and an immediate value.
"""

r2 = operand_def(R2InvT)
immediate: AnyIntegerAttr = attr_def(AnyIntegerAttr)

r1 = result_def(R1InvT)

def __init__(
self,
r2: Operation | SSAValue,
immediate: int | AnyIntegerAttr,
*,
comment: str | StringAttr | None = None,
r1: R1InvT,
):
if isinstance(immediate, int):
immediate = IntegerAttr(
immediate, 32
) # the default immediate size is 32 bits
if isinstance(comment, str):
comment = StringAttr(comment)

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

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

@classmethod
def custom_parse_attributes(cls, parser: Parser) -> dict[str, Attribute]:
attributes = dict[str, Attribute]()
temp = _parse_immediate_value(parser, IntegerType(32, Signedness.SIGNED))
attributes["immediate"] = temp
return attributes

def custom_print_attributes(self, printer: Printer) -> Set[str]:
printer.print(", ")
_print_immediate_value(printer, self.immediate)
return {"immediate"}


@irdl_op_definition
class RRI_ImulOP(R_RRI_Operation[GeneralRegisterType, GeneralRegisterType]):
"""
Multiplies the immediate value with the source register and stores the result in the destination register.
x[r1] = x[r2] * immediate
https://www.felixcloutier.com/x86/imul
"""

name = "x86.rri.imul"


# region Assembly printing
def _append_comment(line: str, comment: StringAttr | None) -> str:
if comment is None:
Expand Down

0 comments on commit 167d54c

Please sign in to comment.