_NOT_SET = _NotSet()
-@plain_data(frozen=True, unsafe_hash=True)
-class AsmTemplateSegment(Generic[_RegType], metaclass=ABCMeta):
- __slots__ = "ssa_val",
-
- def __init__(self, ssa_val):
- # type: (SSAVal[_RegType]) -> None
- self.ssa_val = ssa_val
-
- def render(self, regs):
- # type: (dict[SSAVal, RegLoc]) -> str
- return self._render(regs[self.ssa_val])
-
- @abstractmethod
- def _render(self, reg):
- # type: (RegLoc) -> str
- ...
-
-
-@plain_data(frozen=True, unsafe_hash=True)
-@final
-class ATSGPR(AsmTemplateSegment[GPRRangeType]):
- __slots__ = "offset",
-
- def __init__(self, ssa_val, offset=0):
- # type: (SSAGPRRange, int) -> None
- super().__init__(ssa_val)
- self.offset = offset
-
- def _render(self, reg):
- # type: (RegLoc) -> str
- if not isinstance(reg, GPRRange):
- raise TypeError()
- return str(reg.start + self.offset)
-
-
-@plain_data(frozen=True, unsafe_hash=True)
-@final
-class ATSStackSlot(AsmTemplateSegment[StackSlotType]):
- __slots__ = ()
-
- def _render(self, reg):
- # type: (RegLoc) -> str
- if not isinstance(reg, StackSlot):
- raise TypeError()
- return f"{reg.start_slot}(1)"
-
-
-@plain_data(frozen=True, unsafe_hash=True)
-@final
-class ATSCopyGPRRange(AsmTemplateSegment["GPRRangeType | FixedGPRRangeType"]):
- __slots__ = "src_ssa_val",
-
- def __init__(self, ssa_val, src_ssa_val):
- # type: (SSAVal[GPRRangeType | FixedGPRRangeType], SSAVal[GPRRangeType | FixedGPRRangeType]) -> None
- self.ssa_val = ssa_val
- self.src_ssa_val = src_ssa_val
-
- def render(self, regs):
- # type: (dict[SSAVal, RegLoc]) -> str
- src = regs[self.src_ssa_val]
- dest = regs[self.ssa_val]
- if not isinstance(dest, GPRRange):
- raise TypeError()
- if not isinstance(src, GPRRange):
- raise TypeError()
- if src.length != dest.length:
- raise ValueError()
- if src == dest:
- return ""
- mrr = ""
- sv_ = "sv."
- if src.length == 1:
- sv_ = ""
- elif src.conflicts(dest) and src.start > dest.start:
- mrr = "/mrr"
- return f"{sv_}or{mrr} *{dest.start}, *{src.start}, *{src.start}\n"
-
- def _render(self, reg):
- # type: (RegLoc) -> str
- raise TypeError("must call self.render")
-
-
-@final
-class AsmTemplate(Sequence["str | AsmTemplateSegment"]):
- @staticmethod
- def __process_segments(segments):
- # type: (Iterable[str | AsmTemplateSegment | AsmTemplate]) -> Iterable[str | AsmTemplateSegment]
- for i in segments:
- if isinstance(i, AsmTemplate):
- yield from i
- else:
- yield i
-
- def __init__(self, segments=()):
- # type: (Iterable[str | AsmTemplateSegment | AsmTemplate]) -> None
- self.__segments = tuple(self.__process_segments(segments))
-
- def __getitem__(self, index):
- # type: (int) -> str | AsmTemplateSegment
- return self.__segments[index]
-
- def __len__(self):
- return len(self.__segments)
-
- def __iter__(self):
- return iter(self.__segments)
-
- def __hash__(self):
- return hash(self.__segments)
-
- def render(self, regs):
- # type: (dict[SSAVal, RegLoc]) -> str
- retval = [] # type: list[str]
- for segment in self:
- if isinstance(segment, AsmTemplateSegment):
- retval.append(segment.render(regs))
- else:
- retval.append(segment)
- return "".join(retval)
-
-
@final
class AsmContext:
def __init__(self, assigned_registers):