diff --git a/asm/allocate.py b/asm/allocate.py index 3d85bd0..7a9f2c4 100644 --- a/asm/allocate.py +++ b/asm/allocate.py @@ -244,6 +244,7 @@ def _compute_modes( output = OutputStyle.SINK elif has_ctx_override: output = OutputStyle.CHANGE_TAG + dest_count = 1 else: output = OutputStyle.INHERIT diff --git a/asm/codegen.py b/asm/codegen.py index a97e500..763054d 100644 --- a/asm/codegen.py +++ b/asm/codegen.py @@ -249,31 +249,39 @@ def _generate_setup_tokens( if layout is None: continue - # Write constants to frame slots - for slot_idx in layout.slot_map.const_slots: - # Find the const value for this slot - const_val = _find_const_for_slot(act_nodes, slot_idx, layout) - if const_val is not None: + # Write const and dest values per node using fref + # (slot_map regions are approximate; node fref is authoritative) + for node in act_nodes: + if node.fref is None or node.mode is None: + continue + _, has_const, dest_count = node.mode + slot = node.fref + + if has_const and isinstance(node.const, int): tokens.append(PELocalWriteToken( target=pe_id, act_id=act_id, region=1, - slot=slot_idx, - data=const_val & 0xFFFF, + slot=slot, + data=node.const & 0xFFFF, is_dest=False, )) - - # Write destinations to frame slots - for slot_idx in layout.slot_map.dest_slots: - dest = _find_dest_for_slot(act_nodes, slot_idx, layout, all_nodes, all_edges) - if dest is not None: + slot += 1 + + # Destinations from resolved dest_l/dest_r + dests = [] + if node.dest_l and hasattr(node.dest_l, 'frame_dest') and node.dest_l.frame_dest: + dests.append(node.dest_l.frame_dest) + if node.dest_r and hasattr(node.dest_r, 'frame_dest') and node.dest_r.frame_dest: + dests.append(node.dest_r.frame_dest) + for i, fd in enumerate(dests[:dest_count]): tokens.append(PELocalWriteToken( target=pe_id, act_id=act_id, region=1, - slot=slot_idx, - data=pack_flit1(dest), - is_dest=True, # AC6.4: signals PE to decode as FrameDest + slot=slot + i, + data=pack_flit1(fd), + is_dest=True, )) return tokens @@ -375,20 +383,30 @@ def generate_direct(graph: IRGraph) -> AssemblyResult: initial_tag_store[act_id] = frame_id continue - # Build frame slot values for this activation as a sparse dict + # Build frame slot values for this activation as a sparse dict. + # Walk nodes directly using their fref to place const and dest values, + # since slot_map regions are approximate (interleaved per-node layout). frame_slots_dict: dict[int, int] = {} - # Fill in constant slots - for slot_idx in layout.slot_map.const_slots: - const_val = _find_const_for_slot(act_nodes, slot_idx, layout) - if const_val is not None: - frame_slots_dict[slot_idx] = const_val & 0xFFFF - - # Fill in destination slots - for slot_idx in layout.slot_map.dest_slots: - dest = _find_dest_for_slot(act_nodes, slot_idx, layout, all_nodes, all_edges) - if dest is not None: - frame_slots_dict[slot_idx] = dest + for node in act_nodes: + if node.fref is None or node.mode is None or node.seed: + continue + _, has_const, dest_count = node.mode + slot = node.fref + + # Constant at fref position + if has_const and isinstance(node.const, int): + frame_slots_dict[slot] = node.const & 0xFFFF + slot += 1 + + # Destinations follow const (or start at fref if no const) + dests = [] + if node.dest_l and hasattr(node.dest_l, 'frame_dest') and node.dest_l.frame_dest: + dests.append(node.dest_l.frame_dest) + if node.dest_r and hasattr(node.dest_r, 'frame_dest') and node.dest_r.frame_dest: + dests.append(node.dest_r.frame_dest) + for i, fd in enumerate(dests[:dest_count]): + frame_slots_dict[slot + i] = pack_flit1(fd) initial_frames[frame_id] = frame_slots_dict initial_tag_store[act_id] = frame_id