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}