OR-1 dataflow CPU sketch
1from dataclasses import dataclass
2from enum import Enum, IntEnum
3from typing import Optional
4
5
6class Port(IntEnum):
7 L = 0
8 R = 1
9
10
11class MemOp(IntEnum):
12 # Tier 1 (3-bit opcode, 10-bit addr)
13 READ = 0
14 WRITE = 1
15 EXEC = 2
16 ALLOC = 3
17 FREE = 4
18 EXT = 5
19 # Tier 2 (5-bit opcode, 8-bit payload)
20 CLEAR = 6
21 RD_INC = 7
22 RD_DEC = 8
23 CMP_SW = 9
24 RAW_READ = 10
25 SET_PAGE = 11
26 WRITE_IMM = 12
27
28
29class ALUOp(IntEnum):
30 pass
31
32
33class ArithOp(ALUOp):
34 ADD = 0b00000 # 0
35 SUB = 0b00001 # 1
36 INC = 0b00010 # 2
37 DEC = 0b00011 # 3
38 # gap: 4-7 are LogicOp
39 SHL = 0b01000 # 8 (was SHIFT_L = 4)
40 SHR = 0b01001 # 9 (was SHIFT_R = 5)
41 ASR = 0b01010 # 10 (was ASHFT_R = 6)
42
43
44class LogicOp(ALUOp):
45 AND = 0b00100 # 4
46 OR = 0b00101 # 5
47 XOR = 0b00110 # 6
48 NOT = 0b00111 # 7
49 # gap: 8-10 are ArithOp shifts
50 EQ = 0b01011 # 11
51 LT = 0b01100 # 12
52 LTE = 0b01101 # 13
53 GT = 0b01110 # 14
54 GTE = 0b01111 # 15
55
56
57class RoutingOp(ALUOp):
58 BREQ = 0b10000 # 16
59 BRGT = 0b10001 # 17
60 BRGE = 0b10010 # 18
61 BROF = 0b10011 # 19
62 SWEQ = 0b10100 # 20
63 SWGT = 0b10101 # 21
64 SWGE = 0b10110 # 22
65 SWOF = 0b10111 # 23
66 GATE = 0b11000 # 24
67 SEL = 0b11001 # 25
68 MRGE = 0b11010 # 26
69 PASS = 0b11011 # 27
70 CONST = 0b11100 # 28
71 FREE_FRAME = 0b11101 # 29 (was FREE_CTX)
72 ALLOC_REMOTE = 0b11110 # 30
73 EXTRACT_TAG = 0b11111 # 31
74
75
76class OutputStyle(Enum):
77 INHERIT = 0
78 CHANGE_TAG = 1
79 SINK = 2
80
81
82class TokenKind(Enum):
83 DYADIC = 0
84 MONADIC = 1
85 INLINE = 2
86
87
88class FrameOp(IntEnum):
89 ALLOC = 0
90 FREE = 1
91 ALLOC_SHARED = 2
92 FREE_LANE = 3
93
94
95@dataclass(frozen=True)
96class FrameDest:
97 target_pe: int
98 offset: int
99 act_id: int
100 port: Port
101 token_kind: TokenKind
102
103
104FrameSlotValue = int | FrameDest | None
105
106
107@dataclass(frozen=True)
108class Instruction:
109 opcode: ALUOp | MemOp
110 output: OutputStyle
111 has_const: bool
112 dest_count: int
113 wide: bool
114 fref: int
115
116
117# Monadic ALU operations: take a single operand
118# (Defined here as the canonical source of truth for emu and asm modules)
119_MONADIC_ARITH_OPS = frozenset({
120 ArithOp.INC,
121 ArithOp.DEC,
122 ArithOp.SHL,
123 ArithOp.SHR,
124 ArithOp.ASR,
125})
126
127_MONADIC_LOGIC_OPS = frozenset({
128 LogicOp.NOT,
129})
130
131_MONADIC_ROUTING_OPS = frozenset({
132 RoutingOp.PASS,
133 RoutingOp.CONST,
134 RoutingOp.FREE_FRAME,
135 RoutingOp.ALLOC_REMOTE,
136 RoutingOp.EXTRACT_TAG,
137})
138
139
140def is_monadic_alu(op: ALUOp) -> bool:
141 """Check if an ALU operation is monadic (single operand).
142
143 This is the canonical source of truth for monadic ALU op classification.
144 emu/pe.py and asm/opcodes.py use this for ALU ops.
145
146 Args:
147 op: An ALUOp enum value (ArithOp, LogicOp, or RoutingOp)
148
149 Returns:
150 True if the operation takes a single operand, False otherwise
151 """
152 if isinstance(op, ArithOp):
153 return op in _MONADIC_ARITH_OPS
154 if isinstance(op, LogicOp):
155 return op in _MONADIC_LOGIC_OPS
156 if isinstance(op, RoutingOp):
157 return op in _MONADIC_ROUTING_OPS
158 return False