""" ALU execution engine for OR1 dataflow CPU. Pure-function ALU with no state or SimPy dependency. Implements full v0 opcode dispatch for arithmetic, logic, and routing operations. """ from cm_inst import ALUOp, ArithOp, LogicOp, RoutingOp UINT16_MASK = 0xFFFF def to_signed(val: int) -> int: """Interpret a 16-bit unsigned value as signed 2's complement.""" return val - 0x10000 if val & 0x8000 else val def _compare(op_fn, left: int, right: int) -> bool: """Helper for comparison operations with signed semantics. Args: op_fn: A comparison function (e.g., lambda a, b: a == b) left: Left operand (interpreted as signed) right: Right operand (interpreted as signed) Returns: Boolean result of the comparison """ return op_fn(to_signed(left), to_signed(right)) def execute(op: ALUOp, left: int, right: int | None, const: int | None) -> tuple[int, bool]: """ Execute an ALU operation. Returns (result & 0xFFFF, bool_out). All values stored as unsigned 16-bit. Comparisons interpret as signed 2's complement. Args: op: ALU operation (ArithOp, LogicOp, or RoutingOp) left: Left operand (always required) right: Right operand (required for dyadic ops) const: Constant field (required for shift ops and CONST op) Returns: Tuple of (result, bool_out) where: - result is masked to 16-bit unsigned - bool_out is Python bool for routing decisions """ if isinstance(op, ArithOp): return _execute_arith(op, left, right, const) if isinstance(op, LogicOp): return _execute_logic(op, left, right) if isinstance(op, RoutingOp): return _execute_routing(op, left, right, const) raise ValueError(f"Unknown ALU operation: {op}") def _execute_arith(op: ArithOp, left: int, right: int | None, const: int | None) -> tuple[int, bool]: """Execute arithmetic operations.""" match op: case ArithOp.ADD: result = (left + right) & UINT16_MASK case ArithOp.SUB: result = (left - right) & UINT16_MASK case ArithOp.INC: result = (left + 1) & UINT16_MASK case ArithOp.DEC: result = (left - 1) & UINT16_MASK case ArithOp.SHL: result = (left << const) & UINT16_MASK case ArithOp.SHR: result = (left >> const) & UINT16_MASK case ArithOp.ASR: signed = to_signed(left) result = (signed >> const) & UINT16_MASK case _: raise ValueError(f"Unknown arithmetic op: {op}") return result, False def _execute_logic(op: LogicOp, left: int, right: int | None) -> tuple[int, bool]: """Execute logic operations.""" match op: case LogicOp.AND: return (left & right) & UINT16_MASK, False case LogicOp.OR: return (left | right) & UINT16_MASK, False case LogicOp.XOR: return (left ^ right) & UINT16_MASK, False case LogicOp.NOT: return (~left) & UINT16_MASK, False case LogicOp.EQ: cmp = _compare(lambda a, b: a == b, left, right) return (0x0001 if cmp else 0x0000), cmp case LogicOp.LT: cmp = _compare(lambda a, b: a < b, left, right) return (0x0001 if cmp else 0x0000), cmp case LogicOp.LTE: cmp = _compare(lambda a, b: a <= b, left, right) return (0x0001 if cmp else 0x0000), cmp case LogicOp.GT: cmp = _compare(lambda a, b: a > b, left, right) return (0x0001 if cmp else 0x0000), cmp case LogicOp.GTE: cmp = _compare(lambda a, b: a >= b, left, right) return (0x0001 if cmp else 0x0000), cmp case _: raise ValueError(f"Unknown logic op: {op}") def _execute_routing(op: RoutingOp, left: int, right: int | None, const: int | None) -> tuple[int, bool]: """Execute routing operations.""" match op: case RoutingOp.BREQ | RoutingOp.SWEQ: cmp = _compare(lambda a, b: a == b, left, right) return left, cmp case RoutingOp.BRGT | RoutingOp.SWGT: cmp = _compare(lambda a, b: a > b, left, right) return left, cmp case RoutingOp.BRGE | RoutingOp.SWGE: cmp = _compare(lambda a, b: a >= b, left, right) return left, cmp case RoutingOp.BROF | RoutingOp.SWOF: raw = left + right cmp = raw > UINT16_MASK return left, cmp case RoutingOp.GATE: cmp = right != 0 return left, cmp case RoutingOp.PASS: return left, False case RoutingOp.CONST: return const & UINT16_MASK, False case RoutingOp.FREE_FRAME: return 0, False case RoutingOp.EXTRACT_TAG: return 0, False case RoutingOp.ALLOC_REMOTE: return 0, False case RoutingOp.SEL: cmp = left != 0 return (right if cmp else left), cmp case RoutingOp.MRGE: return left, False case _: raise ValueError(f"Unknown routing op: {op}")