@final
class GenericOperandDesc:
"""generic Op operand descriptor"""
- __slots__ = "ty", "fixed_loc", "sub_kinds", "tied_input_index"
-
- def __init__(self, ty, sub_kinds, fixed_loc=None, tied_input_index=None):
- # type: (GenericTy, Iterable[LocSubKind], Loc | None, int | None) -> None
+ __slots__ = "ty", "fixed_loc", "sub_kinds", "tied_input_index", "spread"
+
+ def __init__(
+ self, ty, # type: GenericTy
+ sub_kinds, # type: Iterable[LocSubKind]
+ *,
+ fixed_loc=None, # type: Loc | None
+ tied_input_index=None, # type: int | None
+ spread=False, # type: bool
+ ):
+ # type: (...) -> None
self.ty = ty
self.sub_kinds = OFSet(sub_kinds)
if len(self.sub_kinds) == 0:
if tied_input_index is not None and tied_input_index < 0:
raise ValueError("invalid tied_input_index")
self.tied_input_index = tied_input_index
+ self.spread = spread
+ if spread:
+ if self.tied_input_index is not None:
+ raise ValueError("operand can't be both spread and tied")
+ if self.fixed_loc is not None:
+ raise ValueError("operand can't be both spread and fixed")
+ if self.ty.is_vec:
+ raise ValueError("operand can't be both spread and vector")
def tied_to_input(self, tied_input_index):
# type: (int) -> Self
return GenericOperandDesc(self.ty, self.sub_kinds, fixed_loc=fixed_loc)
def instantiate(self, maxvl):
- # type: (int) -> OperandDesc
+ # type: (int) -> Iterable[OperandDesc]
+ rep_count = 1
+ if self.spread:
+ rep_count = maxvl
+ maxvl = 1
ty = self.ty.instantiate(maxvl=maxvl)
def locs():
return
for sub_kind in self.sub_kinds:
yield from sub_kind.allocatable_locs(ty)
- return OperandDesc(loc_set=LocSet(locs()),
- tied_input_index=self.tied_input_index)
+ loc_set = LocSet(locs())
+ for idx in range(rep_count):
+ if not self.spread:
+ idx = None
+ yield OperandDesc(loc_set=loc_set,
+ tied_input_index=self.tied_input_index,
+ spread_index=idx)
@plain_data(frozen=True, unsafe_hash=True)
@final
class OperandDesc:
"""Op operand descriptor"""
- __slots__ = "loc_set", "tied_input_index"
+ __slots__ = "loc_set", "tied_input_index", "spread_index"
- def __init__(self, loc_set, tied_input_index):
- # type: (LocSet, int | None) -> None
+ def __init__(self, loc_set, tied_input_index, spread_index):
+ # type: (LocSet, int | None, int | None) -> None
if len(loc_set) == 0:
raise ValueError("loc_set must not be empty")
self.loc_set = loc_set
self.tied_input_index = tied_input_index
+ if self.tied_input_index is not None and self.spread_index is not None:
+ raise ValueError("operand can't be both spread and tied")
OD_BASE_SGPR = GenericOperandDesc(
def __init__(self, demo_asm, # type: str
inputs, # type: Iterable[GenericOperandDesc]
outputs, # type: Iterable[GenericOperandDesc]
- immediates, # type: Iterable[range]
+ immediates=(), # type: Iterable[range]
is_copy=False, # type: bool
is_load_immediate=False, # type: bool
has_side_effects=False, # type: bool
# type: (...) -> None
self.demo_asm = demo_asm
self.inputs = tuple(inputs)
+ for inp in self.inputs:
+ if inp.tied_input_index is not None:
+ raise ValueError(
+ f"tied_input_index is not allowed on inputs: {inp}")
self.outputs = tuple(outputs)
+ fixed_locs = [] # type: list[tuple[Loc, int]]
+ for idx, out in enumerate(self.outputs):
+ if out.tied_input_index is not None \
+ and out.tied_input_index >= len(self.inputs):
+ raise ValueError(f"tied_input_index out of range: {out}")
+ if out.fixed_loc is not None:
+ for other_fixed_loc, other_idx in fixed_locs:
+ if not other_fixed_loc.conflicts(out.fixed_loc):
+ continue
+ raise ValueError(
+ f"conflicting fixed_locs: outputs[{idx}] and "
+ f"outputs[{other_idx}]: {out.fixed_loc} conflicts "
+ f"with {other_fixed_loc}")
+ fixed_locs.append((out.fixed_loc, idx))
self.immediates = tuple(immediates)
self.is_copy = is_copy
self.is_load_immediate = is_load_immediate
self.has_side_effects = has_side_effects
- def instantiate(self, maxvl):
- # type: (int) -> OpProperties
- raise NotImplementedError # FIXME: finish
+@plain_data(frozen=True, unsafe_hash=True)
+@final
+class OpProperties:
+ __slots__ = "kind", "inputs", "outputs"
+
+ def __init__(self, kind, maxvl):
+ # type: (OpKind, int) -> None
+ self.kind = kind
+ inputs = [] # type: list[OperandDesc]
+ for inp in self.generic.inputs:
+ inputs.extend(inp.instantiate(maxvl=maxvl))
+ self.inputs = tuple(inputs)
+ outputs = [] # type: list[OperandDesc]
+ for out in self.generic.outputs:
+ outputs.extend(out.instantiate(maxvl=maxvl))
+ self.outputs = tuple(outputs)
+
+ @property
+ def generic(self):
+ # type: () -> GenericOpProperties
+ return self.kind.properties
+
+ @property
+ def immediates(self):
+ # type: () -> tuple[range, ...]
+ return self.generic.immediates
+
+ @property
+ def demo_asm(self):
+ # type: () -> str
+ return self.generic.demo_asm
+
+ @property
+ def is_copy(self):
+ # type: () -> bool
+ return self.generic.is_copy
+
+ @property
+ def is_load_immediate(self):
+ # type: () -> bool
+ return self.generic.is_load_immediate
+
+ @property
+ def has_side_effects(self):
+ # type: () -> bool
+ return self.generic.has_side_effects
-# FIXME: add OpProperties
@unique
@final
def __init__(self, properties):
# type: (GenericOpProperties) -> None
super().__init__()
- self.properties = properties
+ self.__properties = properties
+
+ @property
+ def properties(self):
+ # type: () -> GenericOpProperties
+ return self.__properties
- SvAddE = OpProperties(
+ SvAddE = GenericOpProperties(
demo_asm="sv.adde *RT, *RA, *RB",
- inputs=(OT_VGPR, OT_VGPR, OT_CA, OT_VL),
- outputs=(OT_VGPR, OT_CA),
- immediates=(),
- constraints=(),
+ inputs=(OD_EXTRA3_VGPR, OD_EXTRA3_VGPR, OD_CA, OD_VL),
+ outputs=(OD_EXTRA3_VGPR, OD_CA),
)
- SvSubFE = OpProperties(
+ SvSubFE = GenericOpProperties(
demo_asm="sv.subfe *RT, *RA, *RB",
- inputs=(OT_VGPR, OT_VGPR, OT_CA, OT_VL),
- outputs=(OT_VGPR, OT_CA),
- immediates=(),
- constraints=(),
+ inputs=(OD_EXTRA3_VGPR, OD_EXTRA3_VGPR, OD_CA, OD_VL),
+ outputs=(OD_EXTRA3_VGPR, OD_CA),
)
- SvMAddEDU = OpProperties(
+ SvMAddEDU = GenericOpProperties(
demo_asm="sv.maddedu *RT, *RA, RB, RC",
- inputs=(OT_VGPR, OT_SGPR, OT_SGPR, OT_VL),
- outputs=(OT_VGPR, OT_SGPR),
- immediates=(),
- constraints=(),
+ inputs=(OD_EXTRA2_VGPR, OD_EXTRA2_VGPR, OD_EXTRA2_SGPR,
+ OD_EXTRA2_SGPR, OD_VL),
+ outputs=(OD_EXTRA3_VGPR, OD_EXTRA2_SGPR.tied_to_input(3)),
)
- SetVLI = OpProperties(
+ SetVLI = GenericOpProperties(
demo_asm="setvl 0, 0, imm, 0, 1, 1",
inputs=(),
- outputs=(OT_VL,),
+ outputs=(OD_VL,),
immediates=(range(1, 65),),
- constraints=(),
is_load_immediate=True,
)
- SvLI = OpProperties(
+ SvLI = GenericOpProperties(
demo_asm="sv.addi *RT, 0, imm",
- inputs=(OT_VL,),
- outputs=(OT_VGPR,),
+ inputs=(OD_VL,),
+ outputs=(OD_EXTRA3_VGPR,),
immediates=(range(-2 ** 15, 2 ** 15),),
- constraints=(),
is_load_immediate=True,
)
- LI = OpProperties(
+ LI = GenericOpProperties(
demo_asm="addi RT, 0, imm",
inputs=(),
- outputs=(OT_SGPR,),
+ outputs=(OD_BASE_SGPR,),
immediates=(range(-2 ** 15, 2 ** 15),),
- constraints=(),
is_load_immediate=True,
)
- SvMv = OpProperties(
- demo_asm="sv.or *RT, *src, *src",
- inputs=(OT_VGPR, OT_VL),
- outputs=(OT_VGPR,),
- immediates=(),
- constraints=(),
+ VecCopyToReg = GenericOpProperties(
+ demo_asm="sv.mv dest, src",
+ inputs=(GenericOperandDesc(
+ ty=GenericTy(BaseTy.I64, is_vec=True),
+ sub_kinds=(LocSubKind.SV_EXTRA3_VGPR, LocSubKind.StackI64),
+ ), OD_VL),
+ outputs=(OD_EXTRA3_VGPR,),
is_copy=True,
)
- Mv = OpProperties(
- demo_asm="mv RT, src",
- inputs=(OT_SGPR,),
- outputs=(OT_SGPR,),
- immediates=(),
- constraints=(),
+ VecCopyFromReg = GenericOpProperties(
+ demo_asm="sv.mv dest, src",
+ inputs=(OD_EXTRA3_VGPR, OD_VL),
+ outputs=(GenericOperandDesc(
+ ty=GenericTy(BaseTy.I64, is_vec=True),
+ sub_kinds=(LocSubKind.SV_EXTRA3_VGPR, LocSubKind.StackI64),
+ ),),
is_copy=True,
)
+ CopyToReg = GenericOpProperties(
+ demo_asm="mv dest, src",
+ inputs=(GenericOperandDesc(
+ ty=GenericTy(BaseTy.I64, is_vec=False),
+ sub_kinds=(LocSubKind.SV_EXTRA3_SGPR, LocSubKind.BASE_GPR,
+ LocSubKind.StackI64),
+ ),),
+ outputs=(GenericOperandDesc(
+ ty=GenericTy(BaseTy.I64, is_vec=False),
+ sub_kinds=(LocSubKind.SV_EXTRA3_SGPR, LocSubKind.BASE_GPR),
+ ),),
+ is_copy=True,
+ )
+ CopyFromReg = GenericOpProperties(
+ demo_asm="mv dest, src",
+ inputs=(GenericOperandDesc(
+ ty=GenericTy(BaseTy.I64, is_vec=False),
+ sub_kinds=(LocSubKind.SV_EXTRA3_SGPR, LocSubKind.BASE_GPR),
+ ),),
+ outputs=(GenericOperandDesc(
+ ty=GenericTy(BaseTy.I64, is_vec=False),
+ sub_kinds=(LocSubKind.SV_EXTRA3_SGPR, LocSubKind.BASE_GPR,
+ LocSubKind.StackI64),
+ ),),
+ is_copy=True,
+ )
+ Concat = GenericOpProperties(
+ demo_asm="sv.mv dest, src",
+ inputs=(GenericOperandDesc(
+ ty=GenericTy(BaseTy.I64, is_vec=False),
+ sub_kinds=(LocSubKind.SV_EXTRA3_VGPR,),
+ spread=True,
+ ), OD_VL),
+ outputs=(OD_EXTRA3_VGPR,),
+ is_copy=True,
+ )
+ Spread = GenericOpProperties(
+ demo_asm="sv.mv dest, src",
+ inputs=(OD_EXTRA3_VGPR, OD_VL),
+ outputs=(GenericOperandDesc(
+ ty=GenericTy(BaseTy.I64, is_vec=False),
+ sub_kinds=(LocSubKind.SV_EXTRA3_VGPR,),
+ spread=True,
+ ),),
+ is_copy=True,
+ )
+
+
+# FIXME: rewrite from here
@plain_data(frozen=True, unsafe_hash=True, repr=False)