from __future__ import annotations from collections.abc import Iterable from .decoder import H8536Decoder from .formatting import label_for from .model import Instruction from .tables import FLOW_STOP def trace(decoder: H8536Decoder, starts: Iterable[int], start_limit: int, end_limit: int) -> dict[int, Instruction]: decoded: dict[int, Instruction] = {} queue = [(addr, decoder.br) for addr in starts if start_limit <= addr < end_limit] seen_starts: set[tuple[int, int | None]] = set() while queue: pc, br = queue.pop(0) if (pc, br) in seen_starts: continue seen_starts.add((pc, br)) while start_limit <= pc < end_limit: decoder.br = br if pc in decoded: break ins = decoder.decode(pc) decoded[pc] = ins next_br = ins.br_value if ins.writes_br else br for target in ins.targets: if start_limit <= target < end_limit and (target, next_br) not in seen_starts: queue.append((target, next_br)) if ins.kind in FLOW_STOP or not ins.fallthrough: break pc = (pc + max(ins.size, 1)) & 0xFFFF br = next_br return decoded def linear_sweep(decoder: H8536Decoder, start: int, end: int) -> dict[int, Instruction]: decoded: dict[int, Instruction] = {} pc = start br = decoder.br while pc < end: decoder.br = br ins = decoder.decode(pc) decoded[pc] = ins if ins.writes_br: br = ins.br_value pc += max(ins.size, 1) return decoded def collect_labels(instructions: Iterable[Instruction], vectors: dict[int, tuple[str, int]]) -> dict[int, str]: labels: dict[int, str] = {} for _vector_addr, (name, target) in vectors.items(): labels.setdefault(target, f"vec_{name}_{target:04X}") for ins in instructions: for target in ins.targets: labels.setdefault(target, label_for(target)) return labels