code wiki / _hdl_build / nx_rv64_toolchain_gate.nx
nx_rv64_toolchain_gate.nx source
↩ module page · 72 lines · 6551 B
1// nx_rv64_toolchain_gate.nx -- END-TO-END SOVEREIGN TOOLCHAIN CLOSURE: prove the assembler and the emulator are now
2// ISA-CONSISTENT (both RV64IM) by running a REAL multiply/divide algorithm through the WHOLE pipeline --
3// text asm --(nx_rv64_asm)--> machine code --(fk_predecode)--> decoded --(tier_run: interpret cold + JIT hot)--> result.
4// The program (sum of squares 1..10 = 385, then /7 and %7) uses MUL in a hot loop (JIT-compiled) + DIV/REM (tier to
5// interp) -- exercising exactly the M extension just added to BOTH the assembler and the emulator. Closes the debt that
6// the assembler emitted only RV64I while the emulator executed RV64IM (the M-ext gates set FK_ constants directly,
7// bypassing the assembler -- this gate does NOT).
8// T1 assembler M-ext ENCODING KAT: 'mul x8,x6,x6' assembles to the exact RISC-V word 0x02630433.
9// T2 end-to-end on the golden interpreter: assembled program computes 385 / 55 / 0.
10// T3 end-to-end on the TIERED JIT engine: same result, and the MUL loop was actually JIT-compiled + run native.
11// T4 the two agree bit-for-bit (the assembler->tiered-JIT path == the golden path).
12// expect_exit: 0
13import "nx_syscalls.nx"
14import "nx_rv64_asm.nx"
15import "nx_rv64_fast.nx"
16import "nx_rv64_jit.nx"
17import "nx_rv64_tier.nx"
18
19func 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 }
20func 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 }
21func g_ph(v: i64) -> i64 { g_puts("0x" as *u8); let b: *u8=sys_mmap(20); var i: i64=7; var any: i64=0; while i>=0 { let nib: i64=(v>>(i*4))&15; if nib!=0 { any=1 } if any==1 { if nib<10 { b[0]=(48+nib) as u8 } else { b[0]=(87+nib) as u8 } sys_write(1,b,1) } i=i-1 } if any==0 { sys_write(1,"0" as *u8,1) } return 0 }
22func 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 }
23const MEMSZ: i64 = 4096
24
25func main() -> i64 {
26 g_puts("nx_rv64_toolchain_gate (end-to-end: sovereign ASSEMBLER -> machine code -> TIERED JIT, RV64IM-consistent)\n" as *u8)
27 var pass: i64=0; var total: i64=0
28 let code: *u8=sys_mmap(4096)
29 let opk: *i64=sys_mmap(128*8) as *i64; let rd: *i64=sys_mmap(128*8) as *i64; let rs1: *i64=sys_mmap(128*8) as *i64; let rs2: *i64=sys_mmap(128*8) as *i64; let imm: *i64=sys_mmap(128*8) as *i64
30
31 // T1: encoding KAT -- the assembler emits the exact RISC-V word for a MUL (ABI names: s0=x8, t1=x6). mul s0,t1,t1
32 // = funct7 0x01 | rs2 6 | rs1 6 | funct3 0 | rd 8 | opcode 0x33 = 0x02630433.
33 let nb0: i64 = rvasm_assemble_str(" mul s0, t1, t1\n" as *u8, code, 4096)
34 let word0: i64 = fk_w32(code, 0)
35 g_puts(" T1 'mul s0,t1,t1' assembled to "); g_ph(word0); g_puts(" (expect 0x2630433)\n" as *u8)
36 var t1: i64=0; if nb0==4 { if word0==0x02630433 { t1=1 } }
37 pass=pass+ck("T1: the assembler emits the EXACT RISC-V M-ext encoding (mul s0,t1,t1 = 0x02630433)" as *u8, t1); total=total+1
38
39 // the real algorithm: sum of squares 1..10 (=385) via MUL in a loop, then /7 (=55) and %7 (=0) via DIV/REM.
40 // ABI regs: t0=x5 sum, t1=x6 i, t2=x7 limit, s0=x8 i^2, s1=x9 divisor, a0=x10 quotient, a1=x11 remainder.
41 let src: *u8 = " li t0, 0\n li t1, 1\n li t2, 11\nsq:\n mul s0, t1, t1\n add t0, t0, s0\n addi t1, t1, 1\n blt t1, t2, sq\n li s1, 7\n div a0, t0, s1\n rem a1, t0, s1\n" as *u8
42 let nb: i64 = rvasm_assemble_str(src, code, 4096)
43 if nb < 0 { g_puts(" ASSEMBLE FAILED\n" as *u8); sys_exit(1); return 1 }
44 let nc: i64 = fk_predecode(code, nb, opk, rd, rs1, rs2, imm)
45
46 // T2: golden interpreter.
47 let ri: *i64=sys_mmap(32*8) as *i64; let mi: *u8=sys_mmap(MEMSZ); var z: i64=0; while z<32 { ri[z]=0; z=z+1 }
48 fk_run(opk, rd, rs1, rs2, imm, nc, ri, mi, MEMSZ, 10000000, (0 as i64) as *NxVirtioMmio)
49 g_puts(" T2 interpreter: sum(i^2,1..10)="); g_pn(ri[5]); g_puts(" 385/7="); g_pn(ri[10]); g_puts(" 385%7="); g_pn(ri[11]); g_puts(" (expect 385, 55, 0)\n" as *u8)
50 var t2: i64=0; if ri[5]==385 { if ri[10]==55 { if ri[11]==0 { t2=1 } } }
51 pass=pass+ck("T2: the ASSEMBLED program runs end-to-end on the interpreter -> 385 / 55 / 0 (real mul+div+rem algorithm)" as *u8, t2); total=total+1
52
53 // T3: tiered JIT engine (threshold 2 -> the MUL loop is JIT-compiled + run natively; div/rem tier to interp).
54 let rt: *i64=sys_mmap(32*8) as *i64; let mt: *u8=sys_mmap(MEMSZ); let stats: *i64=sys_mmap(64) as *i64; z=0; while z<32 { rt[z]=0; z=z+1 }
55 tier_run(opk, rd, rs1, rs2, imm, nc, rt, mt, MEMSZ, 10000000, (0 as i64) as *NxVirtioMmio, 2, stats)
56 g_puts(" T3 tiered JIT: sum="); g_pn(rt[5]); g_puts(" /7="); g_pn(rt[10]); g_puts(" %7="); g_pn(rt[11]); g_puts(" | loops-JIT'd="); g_pn(stats[1]); g_puts(" native-runs="); g_pn(stats[2]); g_puts("\n" as *u8)
57 var t3: i64=0; if rt[5]==385 { if rt[10]==55 { if rt[11]==0 { if stats[1]>=1 { t3=1 } } } }
58 pass=pass+ck("T3: same program on the TIERED JIT -> 385/55/0, and the MUL hot loop was JIT-compiled + run native" as *u8, t3); total=total+1
59
60 // T4: the assembler->tiered-JIT path is bit-identical to the golden path.
61 var t4: i64=0; if rt[5]==ri[5] { if rt[10]==ri[10] { if rt[11]==ri[11] { t4=1 } } }
62 pass=pass+ck("T4: the sovereign ASSEMBLER -> TIERED JIT path == the golden interpreter path (toolchain is consistent)" as *u8, t4); total=total+1
63
64 var okall: i64=0; if pass==total { okall=1 }
65 g_puts("---- nx_rv64_toolchain_gate: passed "); g_pn(pass); g_puts(" / "); g_pn(total); g_puts(" ----\n" as *u8)
66 if okall==1 {
67 let logf: i64=sys_openat_append("knowledge/status/rv64_toolchain.log" as *u8, 420)
68 if logf>=0 { let z2: i64=sys_write(logf,"NXRV64TOOLCHAIN GREEN: end-to-end RV64IM -- sovereign assembler (M-ext added) -> machine code -> tiered JIT; a real mul/div/rem algorithm (sum of squares /7) assembles + runs 385/55/0 on both interp and tiered-JIT, bit-identical. assembler+emulator ISA-consistent.\n" as *u8,290); sys_close(logf) }
69 g_puts("verdict=GREEN (end-to-end sovereign RV64IM toolchain: assembler emits M-ext, a real mul/div algorithm assembles + runs correctly through the tiered JIT, matching the golden path; assembler/emulator ISA-consistent)\n" as *u8); sys_exit(0); return 0
70 }
71 g_puts("verdict=RED\n" as *u8); sys_exit(1); return 1
72}