Skip to content

Arm neon

arm_neon

ARM_NEON_INDEX_BY_NAME = {f'v{i}': i for i in (range(0, 32))} module-attribute

UNALLOCATED_NEON = NEONRegisterType.unallocated() module-attribute

V0 = NEONRegisterType.from_name('v0') module-attribute

V1 = NEONRegisterType.from_name('v1') module-attribute

V2 = NEONRegisterType.from_name('v2') module-attribute

V3 = NEONRegisterType.from_name('v3') module-attribute

V4 = NEONRegisterType.from_name('v4') module-attribute

V5 = NEONRegisterType.from_name('v5') module-attribute

V6 = NEONRegisterType.from_name('v6') module-attribute

V7 = NEONRegisterType.from_name('v7') module-attribute

V8 = NEONRegisterType.from_name('v8') module-attribute

V9 = NEONRegisterType.from_name('v9') module-attribute

V10 = NEONRegisterType.from_name('v10') module-attribute

V11 = NEONRegisterType.from_name('v11') module-attribute

V12 = NEONRegisterType.from_name('v12') module-attribute

V13 = NEONRegisterType.from_name('v13') module-attribute

V14 = NEONRegisterType.from_name('v14') module-attribute

V15 = NEONRegisterType.from_name('v15') module-attribute

V16 = NEONRegisterType.from_name('v16') module-attribute

V17 = NEONRegisterType.from_name('v17') module-attribute

V18 = NEONRegisterType.from_name('v18') module-attribute

V19 = NEONRegisterType.from_name('v19') module-attribute

V20 = NEONRegisterType.from_name('v20') module-attribute

V21 = NEONRegisterType.from_name('v21') module-attribute

V22 = NEONRegisterType.from_name('v22') module-attribute

V23 = NEONRegisterType.from_name('v23') module-attribute

V24 = NEONRegisterType.from_name('v24') module-attribute

V25 = NEONRegisterType.from_name('v25') module-attribute

V26 = NEONRegisterType.from_name('v26') module-attribute

V27 = NEONRegisterType.from_name('v27') module-attribute

V28 = NEONRegisterType.from_name('v28') module-attribute

V29 = NEONRegisterType.from_name('v29') module-attribute

V30 = NEONRegisterType.from_name('v30') module-attribute

V31 = NEONRegisterType.from_name('v31') module-attribute

ARM_NEON = Dialect('arm_neon', [DSSFmlaVecScalarOp, DSSFMulOp, DSDupOp, DSVecMovOp, DVarSSt1Op, DVarSLd1Op, GetRegisterOp], [NeonArrangementAttr, NEONRegisterType]) module-attribute

NEONRegisterType dataclass

Bases: ARMRegisterType

A 128-bit NEON ARM register type.

Source code in xdsl/dialects/arm_neon.py
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
@irdl_attr_definition
class NEONRegisterType(ARMRegisterType):
    """
    A 128-bit NEON ARM register type.
    """

    name = "arm_neon.reg"

    @classmethod
    def index_by_name(cls) -> dict[str, int]:
        return ARM_NEON_INDEX_BY_NAME

    @classmethod
    def infinite_register_prefix(cls):
        return "inf_"

name = 'arm_neon.reg' class-attribute instance-attribute

index_by_name() -> dict[str, int] classmethod

Source code in xdsl/dialects/arm_neon.py
52
53
54
@classmethod
def index_by_name(cls) -> dict[str, int]:
    return ARM_NEON_INDEX_BY_NAME

infinite_register_prefix() classmethod

Source code in xdsl/dialects/arm_neon.py
56
57
58
@classmethod
def infinite_register_prefix(cls):
    return "inf_"

NeonArrangement

Bases: StrEnum

The arrangement specifier for NEON instructions determines element size and count. We assume full 128-bit registers. Possible arrangements: - D → 2 double-precision floats - S → 4 single-precision floats - H → 8 half-precision floats

Source code in xdsl/dialects/arm_neon.py
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
class NeonArrangement(StrEnum):
    """
    The arrangement specifier for NEON instructions determines element size and count.
    We assume full 128-bit registers. Possible arrangements:
      - D  → 2 double-precision floats
      - S  → 4 single-precision floats
      - H  → 8 half-precision floats
    """

    D = "D"
    S = "S"
    H = "H"

    @property
    def num_elements(self):
        return _NUM_ELEMENTS_BY_ARRANGEMENT[self.name]

    @staticmethod
    def from_vec_type(vec_type: VectorType):
        arrangement = _ARRANGEMENT_BY_TYPE.get(vec_type)
        if arrangement is None:
            raise ValueError(f"Invalid vector type for ARM NEON: {vec_type}")
        return arrangement

D = 'D' class-attribute instance-attribute

S = 'S' class-attribute instance-attribute

H = 'H' class-attribute instance-attribute

num_elements property

from_vec_type(vec_type: VectorType) staticmethod

Source code in xdsl/dialects/arm_neon.py
113
114
115
116
117
118
@staticmethod
def from_vec_type(vec_type: VectorType):
    arrangement = _ARRANGEMENT_BY_TYPE.get(vec_type)
    if arrangement is None:
        raise ValueError(f"Invalid vector type for ARM NEON: {vec_type}")
    return arrangement

NeonArrangementAttr dataclass

Bases: EnumAttribute[NeonArrangement], SpacedOpaqueSyntaxAttribute

Attribute containing the arrangement specification.

Source code in xdsl/dialects/arm_neon.py
129
130
131
132
133
134
135
@irdl_attr_definition
class NeonArrangementAttr(EnumAttribute[NeonArrangement], SpacedOpaqueSyntaxAttribute):
    """
    Attribute containing the arrangement specification.
    """

    name = "arm_neon.arrangement"

name = 'arm_neon.arrangement' class-attribute instance-attribute

GetRegisterOp

Bases: ARMAsmOperation

This instruction allows us to create an SSAValue for a given register name.

Source code in xdsl/dialects/arm_neon.py
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
@irdl_op_definition
class GetRegisterOp(ARMAsmOperation):
    """
    This instruction allows us to create an SSAValue for a given register name.
    """

    name = "arm_neon.get_register"

    result = result_def(NEONRegisterType)
    assembly_format = "attr-dict `:` type($result)"

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

    def assembly_line(self):
        return None

name = 'arm_neon.get_register' class-attribute instance-attribute

result = result_def(NEONRegisterType) class-attribute instance-attribute

assembly_format = 'attr-dict `:` type($result)' class-attribute instance-attribute

__init__(register_type: NEONRegisterType)

Source code in xdsl/dialects/arm_neon.py
182
183
def __init__(self, register_type: NEONRegisterType):
    super().__init__(result_types=[register_type])

assembly_line()

Source code in xdsl/dialects/arm_neon.py
185
186
def assembly_line(self):
    return None

DSSFMulOp

Bases: ARMInstruction

Floating-point multiply. Different instruction types supported:

  1. Vector: multiplies corresponding floating-point values in the vectors in the two source NEON registers, and writes the result vector to the destination.

See external documentation.

  1. Mixed: (first source operand is a vector, second is a scalar. Destination is a vector) This instruction multiplies each of the floating-point values in the first source operand by the second source operand and writes the resulting values to the corresponding lanes of the destination. Encoding: FMUL ., ., ..

See external documentation.

Source code in xdsl/dialects/arm_neon.py
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
@irdl_op_definition
class DSSFMulOp(ARMInstruction):
    """
    Floating-point multiply. Different instruction types supported:

    1. Vector:  multiplies corresponding floating-point values in the vectors in the two
    source NEON registers, and writes the result vector to the destination.

    See external [documentation](https://developer.arm.com/documentation/100069/0606/SIMD-Vector-Instructions/FMUL--vector-).

    2. Mixed: (first source operand is a vector, second is a scalar. Destination is a vector)
    This instruction multiplies each of the floating-point values in the first source
    operand by the second source operand and writes the resulting values to the corresponding
    lanes of the destination.
    Encoding: FMUL <Vd>.<T>, <Vn>.<T>, <Vm>.<idx>.

    See external [documentation](https://developer.arm.com/documentation/ddi0602/2024-12/SIMD-FP-Instructions/FMUL--vector---Floating-point-multiply--vector--?lang=en#T_option__4).
    """

    name = "arm_neon.dss.fmul"
    d = result_def(NEONRegisterType)
    s1 = operand_def(NEONRegisterType)
    s2 = operand_def(NEONRegisterType)
    scalar_idx = opt_prop_def(IntegerAttr[i8])
    arrangement = prop_def(NeonArrangementAttr)

    assembly_format = (
        "$s1 `,` $s2 (`[` $scalar_idx^ `]`)? $arrangement attr-dict "
        "`:` functional-type(operands, $d)"
    )

    def __init__(
        self,
        s1: Operation | SSAValue,
        s2: Operation | SSAValue,
        *,
        d: NEONRegisterType,
        scalar_idx: IntegerAttr | None,
        arrangement: NeonArrangement | NeonArrangementAttr,
        comment: str | StringAttr | None = None,
    ):
        if isinstance(comment, str):
            comment = StringAttr(comment)
        if isinstance(arrangement, NeonArrangement):
            arrangement = NeonArrangementAttr(arrangement)
        super().__init__(
            operands=(s1, s2),
            attributes={
                "comment": comment,
            },
            properties={
                "scalar_idx": scalar_idx,
                "arrangement": arrangement,
            },
            result_types=(d,),
        )

    def assembly_line_args(self):
        return (
            vector_with_arrangement(self.d, self.arrangement),
            vector_with_arrangement(self.s1, self.arrangement),
            vector_with_arrangement(
                self.s2,
                self.arrangement,
                index=self.scalar_idx.value.data
                if self.scalar_idx is not None
                else None,
            ),
        )

name = 'arm_neon.dss.fmul' class-attribute instance-attribute

d = result_def(NEONRegisterType) class-attribute instance-attribute

s1 = operand_def(NEONRegisterType) class-attribute instance-attribute

s2 = operand_def(NEONRegisterType) class-attribute instance-attribute

scalar_idx = opt_prop_def(IntegerAttr[i8]) class-attribute instance-attribute

arrangement = prop_def(NeonArrangementAttr) class-attribute instance-attribute

assembly_format = '$s1 `,` $s2 (`[` $scalar_idx^ `]`)? $arrangement attr-dict `:` functional-type(operands, $d)' class-attribute instance-attribute

__init__(s1: Operation | SSAValue, s2: Operation | SSAValue, *, d: NEONRegisterType, scalar_idx: IntegerAttr | None, arrangement: NeonArrangement | NeonArrangementAttr, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/arm_neon.py
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
def __init__(
    self,
    s1: Operation | SSAValue,
    s2: Operation | SSAValue,
    *,
    d: NEONRegisterType,
    scalar_idx: IntegerAttr | None,
    arrangement: NeonArrangement | NeonArrangementAttr,
    comment: str | StringAttr | None = None,
):
    if isinstance(comment, str):
        comment = StringAttr(comment)
    if isinstance(arrangement, NeonArrangement):
        arrangement = NeonArrangementAttr(arrangement)
    super().__init__(
        operands=(s1, s2),
        attributes={
            "comment": comment,
        },
        properties={
            "scalar_idx": scalar_idx,
            "arrangement": arrangement,
        },
        result_types=(d,),
    )

assembly_line_args()

Source code in xdsl/dialects/arm_neon.py
246
247
248
249
250
251
252
253
254
255
256
257
def assembly_line_args(self):
    return (
        vector_with_arrangement(self.d, self.arrangement),
        vector_with_arrangement(self.s1, self.arrangement),
        vector_with_arrangement(
            self.s2,
            self.arrangement,
            index=self.scalar_idx.value.data
            if self.scalar_idx is not None
            else None,
        ),
    )

DSSFmlaVecScalarOp

Bases: ARMInstruction

Floating-point fused Multiply-Add to accumulator (mixed: first source operand is a vector, second is a scalar. Destination is a vector) This instruction multiplies the values in the first source operand by the second source operand, adds the accumulated value from the destination operand, and writes the resulting values to the destination. Encoding: FMLA ., ., .. Vd, Vn, Vm specify the regs. The specifier determines element arrangement (size and count). The specifier determines the index of Vm at which the second source operand (scalar) can be found, preceded by a size specifier.

See external documentation.

Source code in xdsl/dialects/arm_neon.py
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
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
@irdl_op_definition
class DSSFmlaVecScalarOp(ARMInstruction):
    """
    Floating-point fused Multiply-Add to accumulator (mixed: first source operand is a vector, second is a scalar.
    Destination is a vector)
    This instruction multiplies the values in the first source operand by the second source operand,
    adds the accumulated value from the destination operand, and writes the resulting values to the destination.
    Encoding: FMLA <Vd>.<T>, <Vn>.<T>, <Vm>.<idx>.
    Vd, Vn, Vm specify the regs. The <T> specifier determines element arrangement (size and count).
    The <idx> specifier determines the index of Vm at which the second source operand (scalar) can be found,
    preceded by a size specifier.

    See external [documentation](https://developer.arm.com/documentation/100069/0606/SIMD-Vector-Instructions/FMLA--vector-).
    """

    SAME_NEON_REGISTER_TYPE: ClassVar = VarConstraint(
        "SAME_NEON_REGISTER_TYPE", base(NEONRegisterType)
    )

    name = "arm_neon.dss.fmla"
    res = result_def(SAME_NEON_REGISTER_TYPE)
    d = operand_def(SAME_NEON_REGISTER_TYPE)
    s1 = operand_def(NEONRegisterType)
    s2 = operand_def(NEONRegisterType)
    scalar_idx = prop_def(IntegerAttr[i8])
    arrangement = prop_def(NeonArrangementAttr)

    assembly_format = (
        "$d `,` $s1 `,` $s2 `[` $scalar_idx `]` $arrangement attr-dict `:` \
        `(` type($s1) `,` type($s2) `)` `->` type($res)"
    )

    def __init__(
        self,
        d: Operation | SSAValue,
        s1: Operation | SSAValue,
        s2: Operation | SSAValue,
        *,
        res: NEONRegisterType,
        scalar_idx: IntegerAttr,
        arrangement: NeonArrangement | NeonArrangementAttr,
        comment: str | StringAttr | None = None,
    ):
        if isinstance(comment, str):
            comment = StringAttr(comment)
        if isinstance(arrangement, NeonArrangement):
            arrangement = NeonArrangementAttr(arrangement)
        super().__init__(
            operands=(d, s1, s2),
            attributes={
                "comment": comment,
            },
            properties={
                "scalar_idx": scalar_idx,
                "arrangement": arrangement,
            },
            result_types=(res,),
        )

    def assembly_instruction_name(self) -> str:
        return "fmla"

    def assembly_line_args(self):
        return (
            vector_with_arrangement(self.res, self.arrangement),
            vector_with_arrangement(self.s1, self.arrangement),
            vector_with_arrangement(
                self.s2, self.arrangement, index=self.scalar_idx.value.data
            ),
        )

SAME_NEON_REGISTER_TYPE: ClassVar = VarConstraint('SAME_NEON_REGISTER_TYPE', base(NEONRegisterType)) class-attribute instance-attribute

name = 'arm_neon.dss.fmla' class-attribute instance-attribute

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

d = operand_def(SAME_NEON_REGISTER_TYPE) class-attribute instance-attribute

s1 = operand_def(NEONRegisterType) class-attribute instance-attribute

s2 = operand_def(NEONRegisterType) class-attribute instance-attribute

scalar_idx = prop_def(IntegerAttr[i8]) class-attribute instance-attribute

arrangement = prop_def(NeonArrangementAttr) class-attribute instance-attribute

assembly_format = '$d `,` $s1 `,` $s2 `[` $scalar_idx `]` $arrangement attr-dict `:` `(` type($s1) `,` type($s2) `)` `->` type($res)' class-attribute instance-attribute

__init__(d: Operation | SSAValue, s1: Operation | SSAValue, s2: Operation | SSAValue, *, res: NEONRegisterType, scalar_idx: IntegerAttr, arrangement: NeonArrangement | NeonArrangementAttr, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/arm_neon.py
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
def __init__(
    self,
    d: Operation | SSAValue,
    s1: Operation | SSAValue,
    s2: Operation | SSAValue,
    *,
    res: NEONRegisterType,
    scalar_idx: IntegerAttr,
    arrangement: NeonArrangement | NeonArrangementAttr,
    comment: str | StringAttr | None = None,
):
    if isinstance(comment, str):
        comment = StringAttr(comment)
    if isinstance(arrangement, NeonArrangement):
        arrangement = NeonArrangementAttr(arrangement)
    super().__init__(
        operands=(d, s1, s2),
        attributes={
            "comment": comment,
        },
        properties={
            "scalar_idx": scalar_idx,
            "arrangement": arrangement,
        },
        result_types=(res,),
    )

assembly_instruction_name() -> str

Source code in xdsl/dialects/arm_neon.py
319
320
def assembly_instruction_name(self) -> str:
    return "fmla"

assembly_line_args()

Source code in xdsl/dialects/arm_neon.py
322
323
324
325
326
327
328
329
def assembly_line_args(self):
    return (
        vector_with_arrangement(self.res, self.arrangement),
        vector_with_arrangement(self.s1, self.arrangement),
        vector_with_arrangement(
            self.s2, self.arrangement, index=self.scalar_idx.value.data
        ),
    )

DSDupOp

Bases: ARMInstruction

Duplicate general-purpose register to vector.

Source code in xdsl/dialects/arm_neon.py
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
@irdl_op_definition
class DSDupOp(ARMInstruction):
    """
    Duplicate general-purpose register to vector.
    """

    name = "arm_neon.ds.dup"
    s = operand_def(IntRegisterType)
    d = result_def(NEONRegisterType)
    arrangement = prop_def(NeonArrangementAttr)

    assembly_format = "$s $arrangement attr-dict `:` type($s) `->` `(` type($d) `)`"

    def __init__(
        self,
        s: Operation | SSAValue,
        *,
        d: NEONRegisterType,
        arrangement: NeonArrangement | NeonArrangementAttr,
        comment: str | StringAttr | None = None,
    ):
        if isinstance(comment, str):
            comment = StringAttr(comment)
        if isinstance(arrangement, NeonArrangement):
            arrangement = NeonArrangementAttr(arrangement)
        super().__init__(
            operands=(s,),
            attributes={
                "comment": comment,
                "arrangement": arrangement,
            },
            result_types=(d,),
        )

    def assembly_line_args(self):
        return (
            vector_with_arrangement(self.d, self.arrangement),
            reg(self.s),
        )

name = 'arm_neon.ds.dup' class-attribute instance-attribute

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

d = result_def(NEONRegisterType) class-attribute instance-attribute

arrangement = prop_def(NeonArrangementAttr) class-attribute instance-attribute

assembly_format = '$s $arrangement attr-dict `:` type($s) `->` `(` type($d) `)`' class-attribute instance-attribute

__init__(s: Operation | SSAValue, *, d: NEONRegisterType, arrangement: NeonArrangement | NeonArrangementAttr, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/arm_neon.py
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
def __init__(
    self,
    s: Operation | SSAValue,
    *,
    d: NEONRegisterType,
    arrangement: NeonArrangement | NeonArrangementAttr,
    comment: str | StringAttr | None = None,
):
    if isinstance(comment, str):
        comment = StringAttr(comment)
    if isinstance(arrangement, NeonArrangement):
        arrangement = NeonArrangementAttr(arrangement)
    super().__init__(
        operands=(s,),
        attributes={
            "comment": comment,
            "arrangement": arrangement,
        },
        result_types=(d,),
    )

assembly_line_args()

Source code in xdsl/dialects/arm_neon.py
366
367
368
369
370
def assembly_line_args(self):
    return (
        vector_with_arrangement(self.d, self.arrangement),
        reg(self.s),
    )

DSVecMovOp

Bases: ARMInstruction

Variant of MOV instruction which extracts a value from a specified lane in a NEON register into a general-purpose register. e.g. MOV X0, V3.S[1] Set X0 to the value of the second single word (bits 32-63) in V3. This instruction is an alias of UMOV.

Source code in xdsl/dialects/arm_neon.py
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
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
@irdl_op_definition
class DSVecMovOp(ARMInstruction):
    """
    Variant of MOV instruction which extracts a value from a specified lane in a NEON
    register into a general-purpose register.
    e.g. MOV X0, V3.S[1]
    Set X0 to the value of the second single word (bits 32-63) in V3.
    This instruction is an alias of UMOV.
    """

    name = "arm_neon.dsvec.mov"
    s = operand_def(NEONRegisterType)
    d = result_def(IntRegisterType)
    scalar_idx = prop_def(IntegerAttr[i8])
    arrangement = prop_def(NeonArrangementAttr)
    assembly_format = (
        "$s `[` $scalar_idx `]` $arrangement attr-dict `:` type($s) `->` type($d)"
    )

    def __init__(
        self,
        s: Operation | SSAValue,
        *,
        d: IntRegisterType,
        arrangement: NeonArrangement | NeonArrangementAttr,
        scalar_idx: IntegerAttr,
        comment: str | StringAttr | None = None,
    ):
        if isinstance(comment, str):
            comment = StringAttr(comment)
        if isinstance(arrangement, NeonArrangement):
            arrangement = NeonArrangementAttr(arrangement)
        super().__init__(
            operands=(s,),
            attributes={
                "comment": comment,
            },
            properties={
                "arrangement": arrangement,
                "scalar_idx": scalar_idx,
            },
            result_types=(d,),
        )

    def assembly_line_args(self):
        return (
            reg(self.d),
            vector_with_arrangement(
                self.s, self.arrangement, index=self.scalar_idx.value.data
            ),
        )

name = 'arm_neon.dsvec.mov' class-attribute instance-attribute

s = operand_def(NEONRegisterType) class-attribute instance-attribute

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

scalar_idx = prop_def(IntegerAttr[i8]) class-attribute instance-attribute

arrangement = prop_def(NeonArrangementAttr) class-attribute instance-attribute

assembly_format = '$s `[` $scalar_idx `]` $arrangement attr-dict `:` type($s) `->` type($d)' class-attribute instance-attribute

__init__(s: Operation | SSAValue, *, d: IntRegisterType, arrangement: NeonArrangement | NeonArrangementAttr, scalar_idx: IntegerAttr, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/arm_neon.py
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
def __init__(
    self,
    s: Operation | SSAValue,
    *,
    d: IntRegisterType,
    arrangement: NeonArrangement | NeonArrangementAttr,
    scalar_idx: IntegerAttr,
    comment: str | StringAttr | None = None,
):
    if isinstance(comment, str):
        comment = StringAttr(comment)
    if isinstance(arrangement, NeonArrangement):
        arrangement = NeonArrangementAttr(arrangement)
    super().__init__(
        operands=(s,),
        attributes={
            "comment": comment,
        },
        properties={
            "arrangement": arrangement,
            "scalar_idx": scalar_idx,
        },
        result_types=(d,),
    )

assembly_line_args()

Source code in xdsl/dialects/arm_neon.py
417
418
419
420
421
422
423
def assembly_line_args(self):
    return (
        reg(self.d),
        vector_with_arrangement(
            self.s, self.arrangement, index=self.scalar_idx.value.data
        ),
    )

DVarSLd1Op

Bases: ARMInstruction

Neon structure load instruction reads data from memory into 64-bit Neon registers. LD1 loads data from memory into up to four registers, with no interleaving.

Source code in xdsl/dialects/arm_neon.py
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
465
466
467
468
469
470
471
472
473
474
475
476
477
@irdl_op_definition
class DVarSLd1Op(ARMInstruction):
    """
    Neon structure load instruction reads data from memory into 64-bit Neon registers.
    LD1 loads data from memory into up to four registers, with no interleaving.
    """

    name = "arm_neon.dvars.ld1"
    s = operand_def(IntRegisterType)
    dest_regs = var_result_def(NEONRegisterType)
    arrangement = prop_def(NeonArrangementAttr)

    assembly_format = " ` ` `[` $s `]` $arrangement attr-dict `:` type($s) `->` `(` type($dest_regs) `)`"

    def __init__(
        self,
        s: Operation | SSAValue,
        result_types: Sequence[Attribute],
        *,
        arrangement: NeonArrangement | NeonArrangementAttr,
        comment: str | StringAttr | None = None,
    ):
        if not (1 <= len(self.dest_regs) <= 4):
            raise ValueError(
                f"dest_regs must contain between 1 and 4 elements, but got {len(self.dest_regs)}."
            )
        if isinstance(comment, str):
            comment = StringAttr(comment)
        if isinstance(arrangement, NeonArrangement):
            arrangement = NeonArrangementAttr(arrangement)
        super().__init__(
            operands=(s,),
            attributes={
                "comment": comment,
            },
            properties={
                "arrangement": arrangement,
            },
            result_types=[result_types],
        )

    def verify_(self) -> None:
        if not (1 <= len(self.dest_regs) <= 4):
            raise VerifyException(
                f"dest_regs must contain between 1 and 4 elements, but got {len(self.dest_regs)}."
            )

    def assembly_line_args(self):
        return (
            variadic_neon_reg_arg(self.dest_regs, self.arrangement),
            f"[{reg(self.s)}]",
        )

name = 'arm_neon.dvars.ld1' class-attribute instance-attribute

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

dest_regs = var_result_def(NEONRegisterType) class-attribute instance-attribute

arrangement = prop_def(NeonArrangementAttr) class-attribute instance-attribute

assembly_format = ' ` ` `[` $s `]` $arrangement attr-dict `:` type($s) `->` `(` type($dest_regs) `)`' class-attribute instance-attribute

__init__(s: Operation | SSAValue, result_types: Sequence[Attribute], *, arrangement: NeonArrangement | NeonArrangementAttr, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/arm_neon.py
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
465
def __init__(
    self,
    s: Operation | SSAValue,
    result_types: Sequence[Attribute],
    *,
    arrangement: NeonArrangement | NeonArrangementAttr,
    comment: str | StringAttr | None = None,
):
    if not (1 <= len(self.dest_regs) <= 4):
        raise ValueError(
            f"dest_regs must contain between 1 and 4 elements, but got {len(self.dest_regs)}."
        )
    if isinstance(comment, str):
        comment = StringAttr(comment)
    if isinstance(arrangement, NeonArrangement):
        arrangement = NeonArrangementAttr(arrangement)
    super().__init__(
        operands=(s,),
        attributes={
            "comment": comment,
        },
        properties={
            "arrangement": arrangement,
        },
        result_types=[result_types],
    )

verify_() -> None

Source code in xdsl/dialects/arm_neon.py
467
468
469
470
471
def verify_(self) -> None:
    if not (1 <= len(self.dest_regs) <= 4):
        raise VerifyException(
            f"dest_regs must contain between 1 and 4 elements, but got {len(self.dest_regs)}."
        )

assembly_line_args()

Source code in xdsl/dialects/arm_neon.py
473
474
475
476
477
def assembly_line_args(self):
    return (
        variadic_neon_reg_arg(self.dest_regs, self.arrangement),
        f"[{reg(self.s)}]",
    )

DVarSSt1Op

Bases: ARMInstruction

Neon structure store instruction stores data from 64-bit Neon registers to memory. ST1 stores one to four registers of data to memory, with no interleaving.

Source code in xdsl/dialects/arm_neon.py
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
@irdl_op_definition
class DVarSSt1Op(ARMInstruction):
    """
    Neon structure store instruction stores data from 64-bit Neon registers to memory.
    ST1 stores one to four registers of data to memory, with no interleaving.
    """

    name = "arm_neon.dvars.st1"
    d = operand_def(IntRegisterType)
    src_regs = var_operand_def(NEONRegisterType)
    arrangement = prop_def(NeonArrangementAttr)

    assembly_format = "$src_regs ` ` `[` $d `]` $arrangement attr-dict `:` `(` type($src_regs) `)` `->` type($d)"

    def __init__(
        self,
        d: IntRegisterType,
        src_regs: Sequence[SSAValue],
        *,
        arrangement: NeonArrangement | NeonArrangementAttr,
        comment: str | StringAttr | None = None,
    ):
        if not (1 <= len(self.src_regs) <= 4):
            raise ValueError(
                f"src_regs must contain between 1 and 4 elements, but got {len(self.src_regs)}."
            )
        if isinstance(comment, str):
            comment = StringAttr(comment)
        if isinstance(arrangement, NeonArrangement):
            arrangement = NeonArrangementAttr(arrangement)
        super().__init__(
            operands=[*src_regs],
            attributes={
                "comment": comment,
            },
            properties={
                "arrangement": arrangement,
            },
            result_types=(d,),
        )

    def verify_(self) -> None:
        if not (1 <= len(self.src_regs) <= 4):
            raise VerifyException(
                f"src_regs must contain between 1 and 4 elements, but got {len(self.src_regs)}."
            )

    def assembly_line_args(self):
        return (
            variadic_neon_reg_arg(self.src_regs, self.arrangement),
            f"[{reg(self.d)}]",
        )

name = 'arm_neon.dvars.st1' class-attribute instance-attribute

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

src_regs = var_operand_def(NEONRegisterType) class-attribute instance-attribute

arrangement = prop_def(NeonArrangementAttr) class-attribute instance-attribute

assembly_format = '$src_regs ` ` `[` $d `]` $arrangement attr-dict `:` `(` type($src_regs) `)` `->` type($d)' class-attribute instance-attribute

__init__(d: IntRegisterType, src_regs: Sequence[SSAValue], *, arrangement: NeonArrangement | NeonArrangementAttr, comment: str | StringAttr | None = None)

Source code in xdsl/dialects/arm_neon.py
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
def __init__(
    self,
    d: IntRegisterType,
    src_regs: Sequence[SSAValue],
    *,
    arrangement: NeonArrangement | NeonArrangementAttr,
    comment: str | StringAttr | None = None,
):
    if not (1 <= len(self.src_regs) <= 4):
        raise ValueError(
            f"src_regs must contain between 1 and 4 elements, but got {len(self.src_regs)}."
        )
    if isinstance(comment, str):
        comment = StringAttr(comment)
    if isinstance(arrangement, NeonArrangement):
        arrangement = NeonArrangementAttr(arrangement)
    super().__init__(
        operands=[*src_regs],
        attributes={
            "comment": comment,
        },
        properties={
            "arrangement": arrangement,
        },
        result_types=(d,),
    )

verify_() -> None

Source code in xdsl/dialects/arm_neon.py
521
522
523
524
525
def verify_(self) -> None:
    if not (1 <= len(self.src_regs) <= 4):
        raise VerifyException(
            f"src_regs must contain between 1 and 4 elements, but got {len(self.src_regs)}."
        )

assembly_line_args()

Source code in xdsl/dialects/arm_neon.py
527
528
529
530
531
def assembly_line_args(self):
    return (
        variadic_neon_reg_arg(self.src_regs, self.arrangement),
        f"[{reg(self.d)}]",
    )

vector_with_arrangement(reg: NEONRegisterType | SSAValue, arrangement: NeonArrangementAttr, *, index: int | None = None) -> str

Source code in xdsl/dialects/arm_neon.py
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
def vector_with_arrangement(
    reg: NEONRegisterType | SSAValue,
    arrangement: NeonArrangementAttr,
    *,
    index: int | None = None,
) -> str:
    if isinstance(reg, SSAValue):
        assert isinstance(reg.type, NEONRegisterType)
        reg = reg.type
    if index is None:
        return (
            f"{reg.register_name.data}."
            f"{arrangement.data.num_elements}"
            f"{arrangement.data.name}"
        )
    else:
        return f"{reg.register_name.data}.{arrangement.data.name}[{index}]"

variadic_neon_reg_arg(regs: Sequence[SSAValue], arrangement: NeonArrangementAttr) -> str

Returns the assembly string for a variadic NEON register argument with the given arrangement.

Source code in xdsl/dialects/arm_neon.py
157
158
159
160
161
162
163
164
165
166
167
168
def variadic_neon_reg_arg(
    regs: Sequence[SSAValue],
    arrangement: NeonArrangementAttr,
) -> str:
    """
    Returns the assembly string for a variadic NEON register argument with the given arrangement.
    """
    return (
        "{"
        + ", ".join(vector_with_arrangement(register, arrangement) for register in regs)
        + "}"
    )