Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP]: Initialise arm_cf and begin beq implementation #3760

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions tests/filecheck/dialects/arm_cf/arm_cf_ops.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// RUN: XDSL_ROUNDTRIP
// RUN: XDSL_GENERIC_ROUNDTRIP
// RUN: xdsl-opt -t arm-asm %s | filecheck %s --check-prefix=CHECK-ASM


// CHECK: builtin.module {
// CHECK-NEXT: arm_func.func @main() {
// CHECK-NEXT: %x1 = arm.get_register : !arm.reg<x1>
// CHECK-NEXT: %x2 = arm.get_register : !arm.reg<x2>
// CHECK-NEXT: arm_cf.beq %x1, %x2, ^0 : (!arm.reg<x1>, !arm.reg<x2>)
// CHECK-NEXT: ^0:
// CHECK-NEXT: arm.label "testlabel" {comment = "this is a label"}
// CHECK-NEXT: arm_func.return
// CHECK-NEXT: }
// CHECK-NEXT: }

// CHECK-GENERIC: "builtin.module"() ({
// CHECK-GENERIC-NEXT: "arm_func.func"() ({
// CHECK-GENERIC-NEXT: %x1 = "arm.get_register"() : () -> !arm.reg<x1>
// CHECK-GENERIC-NEXT: %x2 = "arm.get_register"() : () -> !arm.reg<x2>
// CHECK-GENERIC-NEXT: "arm_cf.beq"(%x1, %x2) [^0] : (!arm.reg<x1>, !arm.reg<x2>) -> ()
// CHECK-GENERIC-NEXT: ^0:
// CHECK-GENERIC-NEXT: "arm.label"() <{label = "testlabel"}> {comment = "this is a label"} : () -> ()
// CHECK-GENERIC-NEXT: "arm_func.return"() : () -> ()
// CHECK-GENERIC-NEXT: }) {sym_name = "main", function_type = () -> ()} : () -> ()
// CHECK-GENERIC-NEXT: }) : () -> ()

// CHECK-ASM: main:
// CHECK-ASM-NEXT: beq x1, x2, testlabel
// CHECK-ASM-NEXT: testlabel: # this is a label
// CHECK-ASM-NEXT: ret

arm_func.func @main() {
%x1 = arm.get_register : !arm.reg<x1>
%x2 = arm.get_register : !arm.reg<x2>
arm_cf.beq %x1, %x2, ^bb0 : (!arm.reg<x1>, !arm.reg<x2>)
^bb0:
arm.label "testlabel" {comment = "this is a label"}
arm_func.return
}
5 changes: 5 additions & 0 deletions tests/test_assembly_arg_str.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ def test_assembly_arg_str_ARMRegister():
assert assembly_arg_str(arg) == "x0"


def test_assembly_arg_str_str():
arg = "string_arg"
assert assembly_arg_str(arg) == "string_arg"


def test_assembly_arg_str_SSAValue_valid():
arg = TestSSAValue(IntRegisterType("x1"))
assert assembly_arg_str(arg) == "x1"
Expand Down
6 changes: 6 additions & 0 deletions xdsl/dialects/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ def get_arm():

return ARM

def get_arm_cf():
from xdsl.dialects.arm_cf import ARM_CF

return ARM_CF

def get_arm_func():
from xdsl.dialects.arm_func import ARM_FUNC

Expand Down Expand Up @@ -334,6 +339,7 @@ def get_transform():
"air": get_air,
"arith": get_arith,
"arm": get_arm,
"arm_cf": get_arm_cf,
"arm_func": get_arm_func,
"bufferization": get_bufferization,
"builtin": get_builtin,
Expand Down
4 changes: 3 additions & 1 deletion xdsl/dialects/arm/assembly.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
from xdsl.dialects.arm.register import ARMRegisterType
from xdsl.ir import SSAValue

AssemblyInstructionArg: TypeAlias = ARMRegisterType | SSAValue
AssemblyInstructionArg: TypeAlias = ARMRegisterType | SSAValue | str


def assembly_arg_str(arg: AssemblyInstructionArg) -> str:
if isinstance(arg, ARMRegisterType):
reg = arg.register_name
return reg
elif isinstance(arg, str):
return arg
else: # SSAValue
if isinstance(arg.type, ARMRegisterType):
reg = arg.type.register_name
Expand Down
65 changes: 65 additions & 0 deletions xdsl/dialects/arm_cf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
from xdsl.dialects import arm
from xdsl.dialects.builtin import StringAttr
from xdsl.interpreter import Successor
from xdsl.ir import Dialect, Operation, SSAValue
from xdsl.irdl import (
irdl_op_definition,
operand_def,
successor_def,
traits_def,
)
from xdsl.traits import IsTerminator


@irdl_op_definition
class BEqOp(arm.ops.ARMInstruction):
"""
Branch if equal
https://developer.arm.com/documentation/den0042/a/Unified-Assembly-Language-Instructions/Instruction-set-basics/Conditional-execution
"""

name = "arm_cf.beq"
s1 = operand_def(arm.register.IntRegisterType)
s2 = operand_def(arm.register.IntRegisterType)

then_block = successor_def()

traits = traits_def(
IsTerminator(),
)

assembly_format = (
"$s1 `,` $s2 `,` $then_block attr-dict `:` `(` type($s1) `,` type($s2) `)`"
)

def __init__(
self,
s1: Operation | SSAValue,
s2: Operation | SSAValue,
then_block: Successor,
*,
comment: str | StringAttr | None = None,
):
if isinstance(comment, str):
comment = StringAttr(comment)

super().__init__(
operands=[s1, s2],
attributes={
"comment": comment,
},
successors=(then_block),
)

def assembly_line_args(self):
then_label = self.then_block.first_op
assert isinstance(then_label, arm.ops.LabelOp)
return (self.s1, self.s2, then_label.label.data)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to allow both str and StringAttr here

Suggested change
return (self.s1, self.s2, then_label.label.data)
return (self.s1, self.s2, then_label.label)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great to address this before merging, I'm actually leaning towards not allowing strings here at all, requiring the label attribute directly.



ARM_CF = Dialect(
"arm_cf",
[
BEqOp,
],
)
Loading