from dataclasses import dataclass from enum import Enum, IntEnum from typing import Optional class Port(IntEnum): L = 0 R = 1 class MemOp(IntEnum): # Tier 1 (3-bit opcode, 10-bit addr) READ = 0 WRITE = 1 EXEC = 2 ALLOC = 3 FREE = 4 EXT = 5 # Tier 2 (5-bit opcode, 8-bit payload) CLEAR = 6 RD_INC = 7 RD_DEC = 8 CMP_SW = 9 RAW_READ = 10 SET_PAGE = 11 WRITE_IMM = 12 class ALUOp(IntEnum): pass class ArithOp(ALUOp): ADD = 0b00000 # 0 SUB = 0b00001 # 1 INC = 0b00010 # 2 DEC = 0b00011 # 3 # gap: 4-7 are LogicOp SHL = 0b01000 # 8 (was SHIFT_L = 4) SHR = 0b01001 # 9 (was SHIFT_R = 5) ASR = 0b01010 # 10 (was ASHFT_R = 6) class LogicOp(ALUOp): AND = 0b00100 # 4 OR = 0b00101 # 5 XOR = 0b00110 # 6 NOT = 0b00111 # 7 # gap: 8-10 are ArithOp shifts EQ = 0b01011 # 11 LT = 0b01100 # 12 LTE = 0b01101 # 13 GT = 0b01110 # 14 GTE = 0b01111 # 15 class RoutingOp(ALUOp): BREQ = 0b10000 # 16 BRGT = 0b10001 # 17 BRGE = 0b10010 # 18 BROF = 0b10011 # 19 SWEQ = 0b10100 # 20 SWGT = 0b10101 # 21 SWGE = 0b10110 # 22 SWOF = 0b10111 # 23 GATE = 0b11000 # 24 SEL = 0b11001 # 25 MRGE = 0b11010 # 26 PASS = 0b11011 # 27 CONST = 0b11100 # 28 FREE_FRAME = 0b11101 # 29 (was FREE_CTX) ALLOC_REMOTE = 0b11110 # 30 EXTRACT_TAG = 0b11111 # 31 class OutputStyle(Enum): INHERIT = 0 CHANGE_TAG = 1 SINK = 2 class TokenKind(Enum): DYADIC = 0 MONADIC = 1 INLINE = 2 class FrameOp(IntEnum): ALLOC = 0 FREE = 1 ALLOC_SHARED = 2 FREE_LANE = 3 @dataclass(frozen=True) class FrameDest: target_pe: int offset: int act_id: int port: Port token_kind: TokenKind FrameSlotValue = int | FrameDest | None @dataclass(frozen=True) class Instruction: opcode: ALUOp | MemOp output: OutputStyle has_const: bool dest_count: int wide: bool fref: int # Monadic ALU operations: take a single operand # (Defined here as the canonical source of truth for emu and asm modules) _MONADIC_ARITH_OPS = frozenset({ ArithOp.INC, ArithOp.DEC, ArithOp.SHL, ArithOp.SHR, ArithOp.ASR, }) _MONADIC_LOGIC_OPS = frozenset({ LogicOp.NOT, }) _MONADIC_ROUTING_OPS = frozenset({ RoutingOp.PASS, RoutingOp.CONST, RoutingOp.FREE_FRAME, RoutingOp.ALLOC_REMOTE, RoutingOp.EXTRACT_TAG, }) def is_monadic_alu(op: ALUOp) -> bool: """Check if an ALU operation is monadic (single operand). This is the canonical source of truth for monadic ALU op classification. emu/pe.py and asm/opcodes.py use this for ALU ops. Args: op: An ALUOp enum value (ArithOp, LogicOp, or RoutingOp) Returns: True if the operation takes a single operand, False otherwise """ if isinstance(op, ArithOp): return op in _MONADIC_ARITH_OPS if isinstance(op, LogicOp): return op in _MONADIC_LOGIC_OPS if isinstance(op, RoutingOp): return op in _MONADIC_ROUTING_OPS return False