Skip to content

Convert ptr to x86

convert_ptr_to_x86

PtrAddToX86 dataclass

Bases: RewritePattern

Source code in xdsl/backend/x86/lowering/convert_ptr_to_x86.py
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@dataclass
class PtrAddToX86(RewritePattern):
    arch: X86Arch

    @op_type_rewrite_pattern
    def match_and_rewrite(self, op: ptr.PtrAddOp, rewriter: PatternRewriter):
        # Pointer-sized GPR for address arithmetic (ptr + offset in the flat address space).
        reg = self.arch.register_type_for_type(ptr.PtrType()).unallocated()
        assert isinstance(reg, GeneralRegisterType)

        rewriter.replace_op(
            op,
            [
                ptr_cast_op := asm.ToRegOp.get(op.addr, reg),
                offset_cast_op := asm.ToRegOp.get(op.offset, reg),
                ptr_mv_op := x86.DS_MovOp(ptr_cast_op, destination=reg),
                add_op := x86.RS_AddOp(
                    ptr_mv_op.destination, offset_cast_op, register_out=reg
                ),
                asm.FromRegOp.get(add_op.register_out, ptr.PtrType()),
            ],
        )

arch: X86Arch instance-attribute

__init__(arch: X86Arch) -> None

match_and_rewrite(op: ptr.PtrAddOp, rewriter: PatternRewriter)

Source code in xdsl/backend/x86/lowering/convert_ptr_to_x86.py
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@op_type_rewrite_pattern
def match_and_rewrite(self, op: ptr.PtrAddOp, rewriter: PatternRewriter):
    # Pointer-sized GPR for address arithmetic (ptr + offset in the flat address space).
    reg = self.arch.register_type_for_type(ptr.PtrType()).unallocated()
    assert isinstance(reg, GeneralRegisterType)

    rewriter.replace_op(
        op,
        [
            ptr_cast_op := asm.ToRegOp.get(op.addr, reg),
            offset_cast_op := asm.ToRegOp.get(op.offset, reg),
            ptr_mv_op := x86.DS_MovOp(ptr_cast_op, destination=reg),
            add_op := x86.RS_AddOp(
                ptr_mv_op.destination, offset_cast_op, register_out=reg
            ),
            asm.FromRegOp.get(add_op.register_out, ptr.PtrType()),
        ],
    )

PtrStoreToX86 dataclass

Bases: RewritePattern

Source code in xdsl/backend/x86/lowering/convert_ptr_to_x86.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
@dataclass
class PtrStoreToX86(RewritePattern):
    arch: X86Arch

    @op_type_rewrite_pattern
    def match_and_rewrite(self, op: ptr.StoreOp, rewriter: PatternRewriter):
        value_type = op.value.type
        # Pointer casts
        addr_unalloc = self.arch.register_type_for_type(op.addr.type).unallocated()
        addr_cast_op = asm.ToRegOp.get(op.addr, addr_unalloc)
        x86_ptr = addr_cast_op.register
        if isa(value_type, VectorType[FixedBitwidthType]):
            x86_vect_type = self.arch.register_type_for_type(value_type)
            cast_op = asm.ToRegOp.get(op.value, x86_vect_type.unallocated())
            x86_data = cast_op.register
            # Choose the x86 vector instruction according to the
            # abstract vector element size
            match value_type.get_element_type().bitwidth:
                case 16:
                    raise DiagnosticException(
                        "Half-precision floating point vector load is not implemented yet."
                    )
                case 32:
                    mov = x86.ops.MS_VmovupsOp
                case 64:
                    mov = x86.ops.MS_VmovapdOp
                case _:
                    raise DiagnosticException(
                        "Float precision must be half, single or double."
                    )
            mov_op = mov(x86_ptr, x86_data, memory_offset=0)
        else:
            value_unalloc = self.arch.register_type_for_type(value_type).unallocated()
            cast_op = asm.ToRegOp.get(op.value, value_unalloc)
            x86_data = cast_op.register
            mov_op = x86.MS_MovOp(x86_ptr, x86_data, memory_offset=0)

        rewriter.replace_op(op, [addr_cast_op, cast_op, mov_op])

arch: X86Arch instance-attribute

__init__(arch: X86Arch) -> None

match_and_rewrite(op: ptr.StoreOp, rewriter: PatternRewriter)

Source code in xdsl/backend/x86/lowering/convert_ptr_to_x86.py
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
@op_type_rewrite_pattern
def match_and_rewrite(self, op: ptr.StoreOp, rewriter: PatternRewriter):
    value_type = op.value.type
    # Pointer casts
    addr_unalloc = self.arch.register_type_for_type(op.addr.type).unallocated()
    addr_cast_op = asm.ToRegOp.get(op.addr, addr_unalloc)
    x86_ptr = addr_cast_op.register
    if isa(value_type, VectorType[FixedBitwidthType]):
        x86_vect_type = self.arch.register_type_for_type(value_type)
        cast_op = asm.ToRegOp.get(op.value, x86_vect_type.unallocated())
        x86_data = cast_op.register
        # Choose the x86 vector instruction according to the
        # abstract vector element size
        match value_type.get_element_type().bitwidth:
            case 16:
                raise DiagnosticException(
                    "Half-precision floating point vector load is not implemented yet."
                )
            case 32:
                mov = x86.ops.MS_VmovupsOp
            case 64:
                mov = x86.ops.MS_VmovapdOp
            case _:
                raise DiagnosticException(
                    "Float precision must be half, single or double."
                )
        mov_op = mov(x86_ptr, x86_data, memory_offset=0)
    else:
        value_unalloc = self.arch.register_type_for_type(value_type).unallocated()
        cast_op = asm.ToRegOp.get(op.value, value_unalloc)
        x86_data = cast_op.register
        mov_op = x86.MS_MovOp(x86_ptr, x86_data, memory_offset=0)

    rewriter.replace_op(op, [addr_cast_op, cast_op, mov_op])

PtrLoadToX86 dataclass

Bases: RewritePattern

Source code in xdsl/backend/x86/lowering/convert_ptr_to_x86.py
 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
@dataclass
class PtrLoadToX86(RewritePattern):
    arch: X86Arch

    @op_type_rewrite_pattern
    def match_and_rewrite(self, op: ptr.LoadOp, rewriter: PatternRewriter):
        # Pointer cast
        x86_reg_type = self.arch.register_type_for_type(op.addr.type).unallocated()
        assert isinstance(x86_reg_type, GeneralRegisterType)
        cast_op = asm.ToRegOp.get(op.addr, x86_reg_type)
        addr_x86 = cast_op.register
        value_type = op.res.type
        if isa(value_type, VectorType[FixedBitwidthType]):
            # Choose the x86 vector instruction according to the
            # abstract vector element size
            match value_type.get_element_type().bitwidth:
                case 16:
                    raise DiagnosticException(
                        "Half-precision floating point vector load is not implemented yet."
                    )
                case 32:
                    mov = x86.ops.DM_VmovupsOp
                case 64:
                    mov = x86.ops.DM_VmovupdOp
                case _:
                    raise DiagnosticException(
                        "Float precision must be half, single or double."
                    )
            mov_op = mov(
                addr_x86,
                memory_offset=0,
                destination=self.arch.register_type_for_type(value_type).unallocated(),
            )
        else:
            mov_op = x86.DM_MovOp(addr_x86, memory_offset=0, destination=x86_reg_type)

        res_cast_op = asm.FromRegOp.get(mov_op.results[0], value_type)
        rewriter.replace_op(op, [cast_op, mov_op, res_cast_op])

arch: X86Arch instance-attribute

__init__(arch: X86Arch) -> None

match_and_rewrite(op: ptr.LoadOp, rewriter: PatternRewriter)

Source code in xdsl/backend/x86/lowering/convert_ptr_to_x86.py
 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
@op_type_rewrite_pattern
def match_and_rewrite(self, op: ptr.LoadOp, rewriter: PatternRewriter):
    # Pointer cast
    x86_reg_type = self.arch.register_type_for_type(op.addr.type).unallocated()
    assert isinstance(x86_reg_type, GeneralRegisterType)
    cast_op = asm.ToRegOp.get(op.addr, x86_reg_type)
    addr_x86 = cast_op.register
    value_type = op.res.type
    if isa(value_type, VectorType[FixedBitwidthType]):
        # Choose the x86 vector instruction according to the
        # abstract vector element size
        match value_type.get_element_type().bitwidth:
            case 16:
                raise DiagnosticException(
                    "Half-precision floating point vector load is not implemented yet."
                )
            case 32:
                mov = x86.ops.DM_VmovupsOp
            case 64:
                mov = x86.ops.DM_VmovupdOp
            case _:
                raise DiagnosticException(
                    "Float precision must be half, single or double."
                )
        mov_op = mov(
            addr_x86,
            memory_offset=0,
            destination=self.arch.register_type_for_type(value_type).unallocated(),
        )
    else:
        mov_op = x86.DM_MovOp(addr_x86, memory_offset=0, destination=x86_reg_type)

    res_cast_op = asm.FromRegOp.get(mov_op.results[0], value_type)
    rewriter.replace_op(op, [cast_op, mov_op, res_cast_op])

ConvertPtrToX86Pass dataclass

Bases: ModulePass

Source code in xdsl/backend/x86/lowering/convert_ptr_to_x86.py
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
@dataclass(frozen=True)
class ConvertPtrToX86Pass(ModulePass):
    name = "convert-ptr-to-x86"

    arch: str

    def apply(self, ctx: Context, op: builtin.ModuleOp) -> None:
        arch = X86Arch.arch_for_name(self.arch)
        PatternRewriteWalker(
            GreedyRewritePatternApplier(
                [
                    PtrLoadToX86(arch),
                    PtrStoreToX86(arch),
                    PtrAddToX86(arch),
                ]
            ),
            apply_recursively=False,
        ).rewrite_module(op)

name = 'convert-ptr-to-x86' class-attribute instance-attribute

arch: str instance-attribute

__init__(arch: str) -> None

apply(ctx: Context, op: builtin.ModuleOp) -> None

Source code in xdsl/backend/x86/lowering/convert_ptr_to_x86.py
133
134
135
136
137
138
139
140
141
142
143
144
def apply(self, ctx: Context, op: builtin.ModuleOp) -> None:
    arch = X86Arch.arch_for_name(self.arch)
    PatternRewriteWalker(
        GreedyRewritePatternApplier(
            [
                PtrLoadToX86(arch),
                PtrStoreToX86(arch),
                PtrAddToX86(arch),
            ]
        ),
        apply_recursively=False,
    ).rewrite_module(op)