code wiki / _hdl_build / nx_rv64_cjit_gate.nx

nx_rv64_cjit_gate.nx source

↩ module page · 66 lines · 5439 B

1// nx_rv64_cjit_gate.nx -- GATE: the compressed-region JIT compactor+relinker is CORRECT and FAST. Loads a compressed 2// (gcc -march=rv64imac) program with a HEAVY hot loop (knowledge/hw/cloop.bin, UART==QEMU 80 f4 d4 2a). Runs it on 3// fk_run_c (interpreter) AND tier_run_c (JIT via the compactor); both must equal the QEMU reference, tier_run_c must 4// actually JIT-compile the compressed hot loop (loops-JIT'd>=1), and be measurably faster (native code ran). This is 5// the compressed-loop JIT -- built, not deferred. expect_exit: 0 6import "nx_syscalls.nx" 7import "nx_rv64_fast.nx" 8import "nx_rv64_jit.nx" 9import "nx_rv64_tier.nx" 10 11func g_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 12func g_pn(v: i64) -> i64 { let b: *u8=sys_mmap(28); var x: i64=v; if x==0{b[0]=48;sys_write(1,b,1);return 0} var d: i64=0; var y: i64=x; while y>0{d=d+1;y=y/10} var i: i64=d-1; y=x; while i>=0{b[i]=(48+(y%10)) as u8;y=y/10;i=i-1} sys_write(1,b,d); return 0 } 13func g_hx(v: i64) -> i64 { let b: *u8=sys_mmap(4); let n0: i64=(v>>4)&15; let n1: i64=v&15; if n0<10 { b[0]=(48+n0) as u8 } else { b[0]=(87+n0) as u8 } if n1<10 { b[1]=(48+n1) as u8 } else { b[1]=(87+n1) as u8 } b[2]=32 as u8; sys_write(1,b,3); return 0 } 14func ck(name: *u8, c: i64) -> i64 { if c==1 { g_puts(" PASS " as *u8) } else { g_puts(" FAIL " as *u8) } g_puts(name); g_puts("\n" as *u8); return c } 15const MEMSZ: i64 = 262144 16// expected == QEMU: 80 f4 d4 2a 17func match4(tx: *u8, n: i64) -> i64 { if n!=4 { return 0 } if tx[0]!=(0x80 as u8) { return 0 } if tx[1]!=(0xf4 as u8) { return 0 } if tx[2]!=(0xd4 as u8) { return 0 } if tx[3]!=(0x2a as u8) { return 0 } return 1 } 18 19func run(useTier: i64, code: *u8, nb: i64, txbuf: *u8, stats: *i64, us: *i64) -> i64 { 20 let nslot: i64=nb/2 + 16 21 let opk: *i64=sys_mmap(nslot*8) as *i64; let rd: *i64=sys_mmap(nslot*8) as *i64; let rs1: *i64=sys_mmap(nslot*8) as *i64; let rs2: *i64=sys_mmap(nslot*8) as *i64; let imm: *i64=sys_mmap(nslot*8) as *i64 22 let nc: i64=fk_predecode_c(code, nb, opk, rd, rs1, rs2, imm) 23 let reg: *i64=sys_mmap(32*8) as *i64; let mem: *u8=sys_mmap(MEMSZ); var z: i64=0; while z<32 { reg[z]=0; z=z+1 } var m: i64=0; while m<nb { mem[m]=code[m]; m=m+1 } 24 fk_tx_reset(txbuf) 25 let t0: i64=sys_now_us() 26 if useTier==1 { tier_run_c(opk, rd, rs1, rs2, imm, nc, reg, mem, MEMSZ, 500000000, (0 as i64) as *NxVirtioMmio, 5, stats) } 27 else { fk_run_c(opk, rd, rs1, rs2, imm, nc, reg, mem, MEMSZ, 500000000, (0 as i64) as *NxVirtioMmio) } 28 us[0]=sys_now_us()-t0 29 return fk_tx_count() 30} 31 32func main() -> i64 { 33 g_puts("nx_rv64_cjit_gate (compressed-region JIT compactor+relinker: correct vs QEMU 80 f4 d4 2a + JITs the loop + faster)\n" as *u8) 34 var pass: i64=0; var total: i64=0 35 let lenbox: *i64=sys_mmap(16) as *i64 36 let code: *u8=sys_read_file("knowledge/hw/cloop.bin" as *u8, lenbox) 37 if (code as i64)==0 { g_puts(" NO cloop.bin\n" as *u8); sys_exit(1); return 1 } 38 let nb: i64=lenbox[0] 39 40 let txf: *u8=sys_mmap(64); let sf: *i64=sys_mmap(64) as *i64; let uf: *i64=sys_mmap(8) as *i64 41 let nf: i64=run(0, code, nb, txf, sf, uf) 42 g_puts(" fk_run_c (interp): UART="); var i: i64=0; while i<nf { g_hx(txf[i] as i64); i=i+1 } g_puts(" time="); g_pn(uf[0]); g_puts("us\n" as *u8) 43 let txt: *u8=sys_mmap(64); let st: *i64=sys_mmap(64) as *i64; let ut: *i64=sys_mmap(8) as *i64 44 let nt: i64=run(1, code, nb, txt, st, ut) 45 g_puts(" tier_run_c (JIT): UART="); i=0; while i<nt { g_hx(txt[i] as i64); i=i+1 } g_puts(" loops-JIT'd="); g_pn(st[1]); g_puts(" native-runs="); g_pn(st[2]); g_puts(" time="); g_pn(ut[0]); g_puts("us\n" as *u8) 46 47 var t1: i64=match4(txf, nf) 48 pass=pass+ck("T1: fk_run_c interpreter == QEMU (80 f4 d4 2a)" as *u8, t1); total=total+1 49 var t2: i64=match4(txt, nt) 50 pass=pass+ck("T2: tier_run_c (compressed JIT) == QEMU (80 f4 d4 2a) -- the compactor+relinker is CORRECT" as *u8, t2); total=total+1 51 var t3: i64=0; if st[1]>=1 { if st[2]>=1 { t3=1 } } 52 pass=pass+ck("T3: tier_run_c actually JIT-COMPILED the compressed hot loop (compactor fired -- was impossible before)" as *u8, t3); total=total+1 53 var t4: i64=0; if ut[0] < uf[0] { t4=1 } 54 var sp: i64=0; if ut[0]>0 { sp=(uf[0]*100)/ut[0] } 55 g_puts(" compressed-loop JIT speedup = "); g_pn(sp/100); g_puts("."); if sp%100<10 { g_puts("0" as *u8) } g_pn(sp%100); g_puts("x\n" as *u8) 56 pass=pass+ck("T4: the JIT'd compressed loop is measurably faster than interpretation (native code ran)" as *u8, t4); total=total+1 57 58 var okall: i64=0; if pass==total { okall=1 } 59 g_puts("---- nx_rv64_cjit_gate: passed "); g_pn(pass); g_puts(" / "); g_pn(total); g_puts(" ----\n" as *u8) 60 if okall==1 { 61 let logf: i64=sys_openat_append("knowledge/status/cjit.log" as *u8, 420) 62 if logf>=0 { let z: i64=sys_write(logf,"NXRV64CJIT GREEN: compressed-region JIT compactor+relinker -- tier_run_c JIT-compiles compressed hot loops (compact halfword region + relink branch imms to compacted-index-relative, feed unmodified jit_compile) == QEMU + faster. compressed-loop JIT BUILT, not deferred.\n" as *u8,280); sys_close(logf) } 63 g_puts("verdict=GREEN (the compressed-region JIT works: tier_run_c JIT-compiles compressed hot loops == QEMU + faster; the compactor+relinker is built + validated, not deferred)\n" as *u8); sys_exit(0); return 0 64 } 65 g_puts("verdict=RED\n" as *u8); sys_exit(1); return 1 66}