nx_codon.nx source
↩ module page · 152 lines · 5082 B
1// nx_codon.nx -- smallest re-targetable IR atom (silicon emission unit).
2//
3// Biology: codons are 3-nucleotide units that ribosomes translate
4// into amino acids. Nishi codon is the smallest unit nx_ribosome
5// (and the existing nxc2 codegen backends) translate into target
6// machine code. ONE codon = ONE primitive operation emittable to any
7// of the 14 nxc2 backends + the future SILICON_HDL backend.
8//
9// Per [[feedback-pathway-tropism-block-composition-location-agnostic]]
10// vision: same .nx pathway runs on Cortex-M0+ (Thumb), x86_64,
11// PTX (NVIDIA GPU), and Nishi silicon HDL -- because the underlying
12// codons are the substrate's invariant. Codons compose into the
13// rest of the cell's behavior.
14//
15// V1 ships:
16// - sealed enum NxCodonOp (13 ops sufficient to express any cell)
17// - struct NxCodon (op + operand_a + operand_b + target_hint)
18// - struct NxCodonStream (ordered sequence of codons)
19// - append + iterate + validate verbs
20//
21// Per Captain Moroni doctrine: codons are PURE DATA. They describe
22// what to compute, not how -- the ribosome translates per-target.
23// Substrate cannot embed offensive ops in codons because the op set
24// is sealed (no DRONE_STRIKE / FIRMWARE_INJECT / etc).
25
26import "nx_syscalls.nx"
27import "nx_tier.nx"
28import "nx_ribosome.nx"
29
30// ===== Sealed enum: NxCodonOp =====================================
31
32const NX_OP_NOP: nx_int = 0
33const NX_OP_ADD: nx_int = 1
34const NX_OP_SUB: nx_int = 2
35const NX_OP_MUL: nx_int = 3
36const NX_OP_SHL: nx_int = 4
37const NX_OP_SHR: nx_int = 5
38const NX_OP_AND: nx_int = 6
39const NX_OP_OR: nx_int = 7
40const NX_OP_XOR: nx_int = 8
41const NX_OP_LOAD: nx_int = 9
42const NX_OP_STORE: nx_int = 10
43const NX_OP_BRANCH: nx_int = 11
44const NX_OP_CALL: nx_int = 12
45const NX_OP_RET: nx_int = 13
46const NX_OP_N_OPS: nx_int = 14
47
48const NX_CODON_OK: nx_int = 0
49const NX_CODON_ERR_FULL: nx_int = 1
50const NX_CODON_ERR_BAD_OP: nx_int = 2
51const NX_CODON_ERR_BAD_TARG: nx_int = 3
52
53struct NxCodon {
54 op: nx_int,
55 operand_a: nx_size,
56 operand_b: nx_size,
57 target_hint: nx_int, // NX_RBT_* preference from ribosome
58}
59
60struct NxCodonStream {
61 codons: *NxCodon,
62 capacity: nx_size,
63 count: nx_size,
64}
65
66const NX_CODON_BYTES: nx_size = 32
67
68func nx_op_is_valid(o: nx_int) -> nx_int {
69 if o < 0 { return 0 }
70 if o >= NX_OP_N_OPS { return 0 }
71 return 1
72}
73
74func nx_codon_stream_new(capacity: nx_size) -> *NxCodonStream {
75 let s: *NxCodonStream = (sys_mmap(24)) as *NxCodonStream
76 let bytes: nx_size = capacity * NX_CODON_BYTES
77 s.codons = (sys_mmap(bytes)) as *NxCodon
78 s.capacity = capacity
79 s.count = 0
80 return s
81}
82
83func _codon_at(s: *NxCodonStream, idx: nx_size) -> *NxCodon {
84 return (s.codons as i64 + (idx as i64) * NX_CODON_BYTES) as *NxCodon
85}
86
87// ===== nx_codon_emit ==============================================
88//
89// Append a codon to the stream. target_hint may be NX_RBT_N_TARGETS
90// meaning "no preference; ribosome picks" or a specific NX_RBT_* value.
91
92func nx_codon_emit(s: *NxCodonStream,
93 op: nx_int,
94 operand_a: nx_size,
95 operand_b: nx_size,
96 target_hint: nx_int) -> nx_int {
97 if nx_op_is_valid(op) == 0 { return NX_CODON_ERR_BAD_OP }
98 if s.count >= s.capacity { return NX_CODON_ERR_FULL }
99 if target_hint != NX_RBT_N_TARGETS {
100 if nx_rbt_is_valid(target_hint) == 0 { return NX_CODON_ERR_BAD_TARG }
101 }
102 let c: *NxCodon = _codon_at(s, s.count)
103 c.op = op
104 c.operand_a = operand_a
105 c.operand_b = operand_b
106 c.target_hint = target_hint
107 s.count = s.count + 1
108 return NX_CODON_OK
109}
110
111func nx_codon_at(s: *NxCodonStream, idx: nx_size) -> *NxCodon {
112 if idx >= s.count { return (0 as i64) as *NxCodon }
113 return _codon_at(s, idx)
114}
115
116func nx_codon_stream_length(s: *NxCodonStream) -> nx_size {
117 return s.count
118}
119
120// ===== nx_codon_count_by_op =======================================
121//
122// Forensic / metric query: how many of each op-kind are in this
123// stream? Used by metabolism to characterize cell hot-paths.
124
125func nx_codon_count_by_op(s: *NxCodonStream, op: nx_int) -> nx_int {
126 var hits: nx_int = 0
127 var i: nx_size = 0
128 while i < s.count {
129 let c: *NxCodon = _codon_at(s, i)
130 if c.op == op { hits = hits + 1 }
131 i = i + 1
132 }
133 return hits
134}
135
136// ===== nx_codon_resolve_target ====================================
137//
138// For codon at idx: if target_hint is N_TARGETS, fall back to
139// nx_ribosome_default_for_tier with the supplied tier. If hint is
140// explicit, return it. This is how a cell's codon stream becomes
141// concretely backend-targeted at codegen time.
142
143func nx_codon_resolve_target(s: *NxCodonStream,
144 idx: nx_size,
145 tier: nx_int) -> nx_int {
146 if idx >= s.count { return NX_RBT_X86_64 }
147 let c: *NxCodon = _codon_at(s, idx)
148 if c.target_hint == NX_RBT_N_TARGETS {
149 return nx_ribosome_default_for_tier(tier)
150 }
151 return c.target_hint
152}