code wiki / _hdl_build / nx_rv64_jit_fwd_gate.nx

nx_rv64_jit_fwd_gate.nx source

↩ module page · 75 lines · 6416 B

1// nx_rv64_jit_fwd_gate.nx -- GATE: the JIT now compiles REAL forward control flow (if/else) -- forward conditional 2// branches + unconditional jumps (JAL x0), resolved via a fixup pass -- not just backward loops. Proves it on 3// programs with forward branches (max via if/else; a loop with an inner conditional skip) equivalence-checked against 4// the golden interpreter. Closes the "forward branches" gap flagged in rung 12: the JIT can now compile arbitrary 5// intra-block control flow, the toy->tool step. expect_exit:0 6import "nx_syscalls.nx" 7import "nx_rv64_asm.nx" 8import "nx_rv64_fast.nx" 9import "nx_rv64_jit.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]=45;sys_write(1,b,1);x=0-x} 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 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 } 14 15func predec(src: *u8, code: *u8, opk: *i64, rd: *i64, rs1: *i64, rs2: *i64, imm: *i64) -> i64 { 16 let nb: i64 = rvasm_assemble_str(src, code, 4096); if nb<0 { return 0-1 } return fk_predecode(code, nb, opk, rd, rs1, rs2, imm) 17} 18func run_jit(opk: *i64, rd: *i64, rs1: *i64, rs2: *i64, imm: *i64, nc: i64, reg: *i64) -> i64 { 19 let x86: *u8=sys_mmap(65536); let x86off: *i64=sys_mmap(nc*8+64) as *i64 20 let xlen: i64 = jit_compile(opk, rd, rs1, rs2, imm, nc, x86, x86off) 21 if xlen<0 { return xlen } 22 var z: i64=0; while z<32 { reg[z]=0; z=z+1 } 23 jit_run(x86, xlen, reg); return xlen 24} 25func run_interp(opk: *i64, rd: *i64, rs1: *i64, rs2: *i64, imm: *i64, nc: i64, reg: *i64) -> i64 { 26 var z: i64=0; while z<32 { reg[z]=0; z=z+1 } 27 let mem: *u8=sys_mmap(4096); fk_run(opk, rd, rs1, rs2, imm, nc, reg, mem, 4096, 200000000, (0 as i64) as *NxVirtioMmio); return 0 28} 29 30func main() -> i64 { 31 g_puts("nx_rv64_jit_fwd_gate (JIT forward branches + jumps: compile real if/else control flow, vs the golden interpreter)\n" as *u8) 32 var pass: i64=0; var total: i64=0 33 let code: *u8=sys_mmap(4096) 34 let opk: *i64=sys_mmap(64*8) as *i64; let rd: *i64=sys_mmap(64*8) as *i64; let rs1: *i64=sys_mmap(64*8) as *i64; let rs2: *i64=sys_mmap(64*8) as *i64; let imm: *i64=sys_mmap(64*8) as *i64 35 let rj: *i64=sys_mmap(32*8) as *i64; let ri: *i64=sys_mmap(32*8) as *i64 36 37 // P1: max(30,50) via a FORWARD branch + FORWARD jump. t2=max, t3=copy. (t0=5 t1=6 t2=7 t3=28) 38 let nc1: i64 = predec(" li t0, 30\n li t1, 50\n blt t0, t1, use_t1\n addi t2, t0, 0\n j done\nuse_t1:\n addi t2, t1, 0\ndone:\n addi t3, t2, 0\n" as *u8, code, opk, rd, rs1, rs2, imm) 39 let x1: i64 = run_jit(opk,rd,rs1,rs2,imm,nc1,rj); run_interp(opk,rd,rs1,rs2,imm,nc1,ri) 40 g_puts(" P1 max(30,50): JIT t2="); g_pn(rj[7]); g_puts(" interp t2="); g_pn(ri[7]); g_puts(" (expect 50) xlen="); g_pn(x1); g_puts("\n" as *u8) 41 var t1: i64=0; if x1>0 { if rj[7]==50 { if rj[7]==ri[7] { if rj[28]==50 { t1=1 } } } } 42 pass=pass+ck("T1: forward branch + forward jump -- JIT max(30,50)==interp==50 (real if/else compiled natively)" as *u8, t1); total=total+1 43 44 // P2: count loop (backward) -- regression that backward branches still work after the forward-branch change. 45 let nc2: i64 = predec(" li t0, 0\n lui t1, 0x800\nloop:\n addi t0, t0, 1\n blt t0, t1, loop\n" as *u8, code, opk, rd, rs1, rs2, imm) 46 let x2: i64 = run_jit(opk,rd,rs1,rs2,imm,nc2,rj); run_interp(opk,rd,rs1,rs2,imm,nc2,ri) 47 var t2: i64=0; if x2>0 { if rj[5]==8388608 { if rj[5]==ri[5] { t2=1 } } } 48 g_puts(" P2 count loop (backward regression): JIT t0="); g_pn(rj[5]); g_puts(" interp t0="); g_pn(ri[5]); g_puts("\n" as *u8) 49 pass=pass+ck("T2: backward loops STILL correct after adding forward support (no regression)" as *u8, t2); total=total+1 50 51 // P3: a loop with an INNER conditional skip (forward BLT) AND the loop-back (backward BLT). sum i for i in [5,9]=35. 52 let nc3: i64 = predec(" li t0, 0\n li t1, 0\n li t2, 10\nloop3:\n li t3, 5\n blt t1, t3, skip\n add t0, t0, t1\nskip:\n addi t1, t1, 1\n blt t1, t2, loop3\n" as *u8, code, opk, rd, rs1, rs2, imm) 53 let x3: i64 = run_jit(opk,rd,rs1,rs2,imm,nc3,rj); run_interp(opk,rd,rs1,rs2,imm,nc3,ri) 54 g_puts(" P3 loop+if (sum i in [5,9]): JIT t0="); g_pn(rj[5]); g_puts(" interp t0="); g_pn(ri[5]); g_puts(" (expect 35) xlen="); g_pn(x3); g_puts("\n" as *u8) 55 var t3: i64=0; if x3>0 { if rj[5]==35 { if rj[5]==ri[5] { t3=1 } } } 56 pass=pass+ck("T3: forward + backward branches in one block -- JIT loop-with-if == interp == 35" as *u8, t3); total=total+1 57 58 // teeth: JAL-with-link (rd!=0) is unsupported (no guest PC in the JIT) -> fail-loud. 59 let bopk: *i64=sys_mmap(16) as *i64; let brd: *i64=sys_mmap(16) as *i64; let bz: *i64=sys_mmap(16) as *i64; let bimm: *i64=sys_mmap(16) as *i64 60 bopk[0]=FK_JAL; brd[0]=1; bz[0]=0; bimm[0]=4; bopk[1]=FK_ADDI; brd[1]=5; bimm[1]=0 61 let bx86: *u8=sys_mmap(256); let bx86off: *i64=sys_mmap(16) as *i64 62 let brc: i64 = jit_compile(bopk, brd, bz, bz, bimm, 2, bx86, bx86off) 63 var t4: i64=0; if brc==(0-1) { t4=1 } 64 g_puts(" teeth: JAL-with-link rc="); g_pn(brc); g_puts(" (-1=unsupported, fail-loud)\n" as *u8) 65 pass=pass+ck("T4 (teeth): JAL-with-link (rd!=0) is unsupported -> the JIT fails-loud (-1), honest about its limits" as *u8, t4); total=total+1 66 67 var okall: i64=0; if pass==total { okall=1 } 68 g_puts("---- nx_rv64_jit_fwd_gate: passed "); g_pn(pass); g_puts(" / "); g_pn(total); g_puts(" ----\n" as *u8) 69 if okall==1 { 70 let logf: i64=sys_openat_append("knowledge/status/rv64_jit_fwd.log" as *u8, 420) 71 if logf>=0 { let z2: i64=sys_write(logf,"NXRV64JITFWD GREEN: JIT now compiles FORWARD branches + unconditional jumps (fixup pass) -- real if/else + loop-with-if, equivalence-checked vs the interpreter; backward loops still correct; jal-with-link fail-loud\n" as *u8,208); sys_close(logf) } 72 g_puts("verdict=GREEN (the JIT compiles real forward control flow -- if/else + loop-with-if via a fixup pass, equivalence-checked; the toy->tool step, closes the forward-branch gap)\n" as *u8); sys_exit(0); return 0 73 } 74 g_puts("verdict=RED\n" as *u8); sys_exit(1); return 1 75}