code wiki / _hdl_build / nx_evo_isa.nx
nx_evo_isa.nx source
↩ module page · 178 lines · 8646 B
1// nx_evo_isa.nx -- DEEPEST / hardware rung up: autonomous compose+derive grounded in the
2// REAL genesis ISA. The search's primitives are the actual RV64IM ALU ops that
3// rv64im_min_sim (god) executes -- ADD/SUB/MUL/AND/OR/SLT/REM/DIV on a register machine
4// (r0=0, r1=a, r2=b, r3=acc) -- NOT Claude-arbitrary arithmetic. Per seed: COMPOSE a random
5// non-trivial target RV64 program T, DERIVE a program G matching T's examples (search sees
6// only (a,b)->T(a,b)), VERIFY G==T on HELD-OUT. So the substrate's GRAMMAR is the hardware's
7// own instruction set, tracing to god. The derived organ is real RV64 machine code:
8// encodable by the enc_r we derived (compounding) and runnable on the sim (the closing rung,
9// named follow-on). op semantics are RV64-faithful (i64 = 64-bit signed; rem/div-by-0 per
10// the RISC-V spec). license_tier: ORIGINAL
11import "nx_syscalls.nx"
12import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc)
13const EVO_MAGIC_2862933555777941757: i64 = 2862933555777941757
14const EVO_MAGIC_3037000493: i64 = 3037000493
15const EVO_MAGIC_8000000: i64 = 8000000
16const EVO_MAGIC_4000000: i64 = 4000000
17const EVO_MAGIC_1000000000: i64 = 1000000000
18const EVO_MAGIC_2654435761: i64 = 2654435761
19const EVO_MAGIC_12345: i64 = 12345
20
21const NINSTR: i64 = 4
22const GLEN: i64 = 12 // NINSTR * 3 (op, rs1, rs2) per instruction; rd = r3 fixed
23const EVO_P: i64 = 320
24const EVO_G: i64 = 2000
25const EVO_T: i64 = 5
26const NTRAIN: i64 = 6
27const NPTS: i64 = 10
28
29func ia_rand(s: *i64) -> i64 { s[0] = s[0] * EVO_MAGIC_2862933555777941757 + EVO_MAGIC_3037000493; return (s[0] >> 17) & 0x3fffffff }
30func ia_abs(x: i64) -> i64 { if x < 0 { return 0 - x } return x }
31func ia_pa(i: i64) -> i64 { if i==0 {return 6} if i==1 {return 4} if i==2 {return 9} if i==3 {return 5} if i==4 {return 7} if i==5 {return 2} if i==6 {return 8} if i==7 {return 3} if i==8 {return 10} return 1 }
32func ia_pb(i: i64) -> i64 { if i==0 {return 4} if i==1 {return 7} if i==2 {return 2} if i==3 {return 9} if i==4 {return 3} if i==5 {return 5} if i==6 {return 1} if i==7 {return 6} if i==8 {return 4} return 8 }
33
34// the REAL RV64IM ALU op (semantics matched to rv64im_min_sim; i64 = 64-bit signed).
35func isa_op(op: i64, x: i64, y: i64) -> i64 {
36 if op == 0 { return x + y } // ADD
37 if op == 1 { return x - y } // SUB
38 if op == 2 { return x * y } // MUL
39 if op == 3 { return x & y } // AND
40 if op == 4 { return x | y } // OR
41 if op == 5 { if x < y { return 1 } return 0 } // SLT
42 if op == 6 { if y != 0 { return x % y } return x } // REM (rem-by-0 = x, RV spec)
43 if y != 0 { return x / y } return 0 - 1 // DIV (div-by-0 = -1, RV spec)
44}
45// select register value by index (r0=0, r1=a, r2=b, r3=acc).
46func ia_reg(idx: i64, r1: i64, r2: i64, r3: i64) -> i64 {
47 if idx == 0 { return 0 }
48 if idx == 1 { return r1 }
49 if idx == 2 { return r2 }
50 return r3
51}
52// execute a genome (RV64 register-machine program) on inputs a,b -> r3.
53func isa_eval(gen: *i64, base: i64, a: i64, b: i64) -> i64 {
54 var r3: i64 = 0
55 var j: i64 = 0
56 while j < NINSTR {
57 let op: i64 = gen[base + j*3]
58 let rs1: i64 = gen[base + j*3 + 1]
59 let rs2: i64 = gen[base + j*3 + 2]
60 let x: i64 = ia_reg(rs1, a, b, r3)
61 let y: i64 = ia_reg(rs2, a, b, r3)
62 r3 = isa_op(op, x, y)
63 j = j + 1
64 }
65 return r3
66}
67
68func isa_setinstr(gen: *i64, j: i64, state: *i64) -> i64 {
69 gen[j*3] = ia_rand(state) % 8 // op
70 gen[j*3 + 1] = ia_rand(state) % 4 // rs1 (r0..r3)
71 gen[j*3 + 2] = ia_rand(state) % 4 // rs2
72 return 0
73}
74
75// COMPOSE: random non-trivial target program (depends on both a and b).
76func isa_compose(state: *i64, T: *i64) -> i64 {
77 var tries: i64 = 0
78 while tries < 300 {
79 var j: i64 = 0
80 while j < NINSTR { isa_setinstr(T, j, state); j = j + 1 }
81 let y00: i64 = isa_eval(T, 0, 6, 4)
82 let ya: i64 = isa_eval(T, 0, 9, 4)
83 let yb: i64 = isa_eval(T, 0, 6, 9)
84 if y00 != ya { if y00 != yb { return 1 } }
85 tries = tries + 1
86 }
87 return 0
88}
89
90func isa_fit(pop: *i64, base: i64, T: *i64) -> i64 {
91 var err: i64 = 0; var i: i64 = 0
92 while i < NTRAIN {
93 let a: i64 = ia_pa(i); let b: i64 = ia_pb(i)
94 let r: i64 = isa_eval(pop, base, a, b)
95 let yv: i64 = isa_eval(T, 0, a, b)
96 var d: i64 = EVO_MAGIC_8000000
97 if r >= 0 - EVO_MAGIC_4000000 { if r <= EVO_MAGIC_4000000 { d = ia_abs(r - yv) } }
98 err = err + d; i = i + 1
99 }
100 return err
101}
102func isa_tourney(fit: *i64, state: *i64) -> i64 {
103 var bi: i64 = ia_rand(state) % EVO_P; var bd: i64 = fit[bi]; var k: i64 = 1
104 while k < EVO_T { let i: i64 = ia_rand(state) % EVO_P; if fit[i] < bd { bd = fit[i]; bi = i } k = k + 1 }
105 return bi
106}
107func isa_mut(gen: *i64, base: i64, state: *i64) -> i64 {
108 let j: i64 = ia_rand(state) % NINSTR
109 let f: i64 = ia_rand(state) % 3
110 if f == 0 { gen[base + j*3] = ia_rand(state) % 8 } else { gen[base + j*3 + f] = ia_rand(state) % 4 }
111 return 0
112}
113
114// DERIVE: search a program G matching T's examples; store in G, return best_err.
115func isa_derive(T: *i64, state: *i64, G: *i64) -> i64 {
116 let pop: *i64 = sys_mmap(EVO_P * GLEN * 8) as *i64
117 let nxt: *i64 = sys_mmap(EVO_P * GLEN * 8) as *i64
118 let fit: *i64 = sys_mmap(EVO_P * 8) as *i64
119 var p: i64 = 0
120 while p < EVO_P { var j: i64 = 0; while j < NINSTR { isa_setinstr(pop, p*4 + j, state); j = j + 1 } p = p + 1 }
121 var best_err: i64 = EVO_MAGIC_1000000000
122 var g: i64 = 0
123 while g < EVO_G {
124 var gbest: i64 = EVO_MAGIC_1000000000; var gbp: i64 = 0
125 p = 0
126 while p < EVO_P { let e: i64 = isa_fit(pop, p*GLEN, T); fit[p] = e; if e < gbest { gbest = e; gbp = p } p = p + 1 }
127 if gbest < best_err { best_err = gbest; var j: i64 = 0; while j < GLEN { G[j] = pop[gbp*GLEN + j]; j = j + 1 } }
128 if best_err == 0 { g = EVO_G } else {
129 var j2: i64 = 0; while j2 < GLEN { nxt[j2] = G[j2]; j2 = j2 + 1 }
130 p = 1
131 while p < EVO_P {
132 let pa: i64 = isa_tourney(fit, state) * GLEN
133 let pb: i64 = isa_tourney(fit, state) * GLEN
134 let cut: i64 = ((ia_rand(state) % (NINSTR - 1)) + 1) * 3
135 var jj: i64 = 0
136 while jj < GLEN { if jj < cut { nxt[p*GLEN + jj] = pop[pa + jj] } else { nxt[p*GLEN + jj] = pop[pb + jj] } jj = jj + 1 }
137 isa_mut(nxt, p*GLEN, state)
138 p = p + 1
139 }
140 var c: i64 = 0; while c < EVO_P * GLEN { pop[c] = nxt[c]; c = c + 1 }
141 g = g + 1
142 }
143 }
144 return best_err
145}
146
147func ia_p(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
148// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer
149// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the
150// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls).
151// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign.
152func ia_pn(v: i64) -> i64 { nxi_out(v); return 0 }
153
154func isa_run(seed: i64) -> i64 {
155 let state: *i64 = sys_mmap(8) as *i64; state[0] = seed * EVO_MAGIC_2654435761 + EVO_MAGIC_12345
156 let T: *i64 = sys_mmap(GLEN * 8) as *i64
157 let G: *i64 = sys_mmap(GLEN * 8) as *i64
158 if isa_compose(state, T) != 1 { ia_p("seed=" as *u8); ia_pn(seed); ia_p(" COMPOSE-FAIL\n" as *u8); return 0 }
159 let de: i64 = isa_derive(T, state, G)
160 var nmatch: i64 = 0; var i: i64 = 0
161 while i < NPTS { if isa_eval(G, 0, ia_pa(i), ia_pb(i)) == isa_eval(T, 0, ia_pa(i), ia_pb(i)) { nmatch = nmatch + 1 } i = i + 1 }
162 ia_p("seed=" as *u8); ia_pn(seed); ia_p(" derive_err=" as *u8); ia_pn(de); ia_p(" match=" as *u8); ia_pn(nmatch); ia_p("/" as *u8); ia_pn(NPTS)
163 if nmatch == NPTS { ia_p(" GREEN (real-ISA program derived)\n" as *u8); return 1 }
164 ia_p(" RED\n" as *u8); return 0
165}
166
167func main() -> i64 {
168 var ok: i64 = 0
169 if isa_run(11) == 1 { ok = ok + 1 }
170 if isa_run(22) == 1 { ok = ok + 1 }
171 if isa_run(33) == 1 { ok = ok + 1 }
172 if isa_run(44) == 1 { ok = ok + 1 }
173 if isa_run(55) == 1 { ok = ok + 1 }
174 ia_p("EVOISA: " as *u8); ia_pn(ok); ia_p("/5 random targets composed + DERIVED as real RV64-ISA programs (ops = the genesis sim's ALU) + verified on held-out\n" as *u8)
175 if ok == 5 { sys_exit(0); return 0 }
176 sys_exit(1)
177 return 1
178}