code wiki / _hdl_build / nx_riscv_loop.nx
nx_riscv_loop.nx source
↩ module page · 70 lines · 4410 B
1// nx_riscv_loop.nx -- SOVEREIGN RISC-V backend, RUNG 3: CONTROL FLOW. Now uses the GENERAL nx_riscv_lib for the
2// shared toolchain (encoders, lower with control flow, build_header, emulator) -- only the loop-IR + tests are local.
3// Lowers/runs: acc=0; i=1; L0: acc += i; i += 1; if i <= N goto L0; return acc (triangular sum 1..N)
4// T1 the lowered loop contains a real back-edge branch (0x63) and ends in ecall.
5// T2 run N=5 -> exit 15. T3 (teeth) re-lower N=10 -> exit 55.
6// expect_exit: 0 Sovereign: nx_riscv_lib (+ nx_syscalls).
7import "nx_riscv_lib.nx"
8import "nx_syscalls.nx"
9
10func build_loop_ir(irop: *i64, irdst: *i64, irs1: *i64, irs2: *i64, irimm: *i64, N: i64) -> i64 {
11 irop[0]=0; irdst[0]=0; irimm[0]=0 // CONST acc=0 (v0)
12 irop[1]=0; irdst[1]=1; irimm[1]=1 // CONST i=1 (v1)
13 irop[2]=0; irdst[2]=2; irimm[2]=N // CONST N (v2)
14 irop[3]=6; irimm[3]=0 // LABEL L0
15 irop[4]=2; irdst[4]=0; irs1[4]=0; irs2[4]=1 // ADD acc += i
16 irop[5]=8; irdst[5]=1; irs1[5]=1; irimm[5]=1// ADDI i += 1
17 irop[6]=7; irs1[6]=1; irs2[6]=2; irimm[6]=0 // BLE i<=N goto L0
18 irop[7]=5; irs1[7]=0 // RET acc
19 return 8
20}
21
22func gen_and_run(N: i64) -> i64 {
23 let BASE: i64=0x10000; let HDR: i64=120; let ENTRY: i64=0x10078
24 let irop: *i64=sys_mmap(8*8) as *i64; let irdst: *i64=sys_mmap(8*8) as *i64; let irs1: *i64=sys_mmap(8*8) as *i64
25 let irs2: *i64=sys_mmap(8*8) as *i64; let irimm: *i64=sys_mmap(8*8) as *i64; let labelpos: *i64=sys_mmap(8*8) as *i64
26 let preg: *i64=sys_mmap(8*8) as *i64; preg[0]=5; preg[1]=6; preg[2]=7
27 let n: i64=build_loop_ir(irop,irdst,irs1,irs2,irimm,N)
28 let m: *u8=sys_mmap(0x20000)
29 let nw: i64=lower(m, HDR, irop, irdst, irs1, irs2, irimm, n, preg, labelpos)
30 build_header(m, HDR+nw*4, ENTRY, BASE)
31 return run(m, ENTRY, BASE)
32}
33
34func main() -> i64 {
35 g_puts("nx_riscv_loop (RUNG 3 control flow; now on the GENERAL nx_riscv_lib)\n" as *u8)
36 var pass: i64=0; var total: i64=0
37 let BASE: i64=0x10000; let HDR: i64=120; let ENTRY: i64=0x10078
38 let irop: *i64=sys_mmap(8*8) as *i64; let irdst: *i64=sys_mmap(8*8) as *i64; let irs1: *i64=sys_mmap(8*8) as *i64
39 let irs2: *i64=sys_mmap(8*8) as *i64; let irimm: *i64=sys_mmap(8*8) as *i64; let labelpos: *i64=sys_mmap(8*8) as *i64
40 let preg: *i64=sys_mmap(8*8) as *i64; preg[0]=5; preg[1]=6; preg[2]=7
41 let n: i64=build_loop_ir(irop,irdst,irs1,irs2,irimm,5)
42 let m: *u8=sys_mmap(0x20000)
43 let nw: i64=lower(m, HDR, irop, irdst, irs1, irs2, irimm, n, preg, labelpos)
44 build_header(m, HDR+nw*4, ENTRY, BASE)
45 let fd: i64=sys_openat_wr("knowledge/research/riscv_loop.elf" as *u8, 0x1ed); if fd>=0 { sys_write(fd,m,HDR+nw*4); sys_close(fd) }
46 var hasbr: i64=0; var i: i64=0; while i<nw { let w: i64=(m[HDR+i*4] as i64)&127; if w==0x63 { hasbr=1 } i=i+1 }
47 let lastw: i64=(m[HDR+(nw-1)*4] as i64)&127
48 g_puts(" lowered loop -> "); g_pn(nw); g_puts(" words; has branch(0x63)="); g_pn(hasbr); g_puts("\n" as *u8)
49 var t1: i64=0; if hasbr==1 { if lastw==0x73 { t1=1 } }
50 pass=pass+ck("T1: lowered loop has a back-edge branch (0x63) and ends in ecall" as *u8, t1); total=total+1
51
52 let r5: i64=gen_and_run(5)
53 g_puts(" RAN loop N=5 -> exit = "); g_pn(r5); g_puts(" (expect 15)\n" as *u8)
54 var t2: i64=0; if r5==15 { t2=1 }
55 pass=pass+ck("T2: a LOOP lowered to RISC-V ran in-ecosystem -> exit==15 (sum 1..5)" as *u8, t2); total=total+1
56
57 let r10: i64=gen_and_run(10)
58 g_puts(" RE-LOWERED loop N=10 -> exit = "); g_pn(r10); g_puts(" (expect 55)\n" as *u8)
59 var t3: i64=0; if r10==55 { t3=1 }
60 pass=pass+ck("T3 (teeth): re-lowered N=10 -> exit==55 (real + general)" as *u8, t3); total=total+1
61
62 var okall: i64=0; if pass==total { okall=1 }
63 g_puts("---- riscv_loop: passed "); g_pn(pass); g_puts(" / "); g_pn(total); g_puts(" ----\n" as *u8)
64 if okall==1 {
65 let logf: i64=sys_openat_append("knowledge/status/riscv_loop.log" as *u8, 420)
66 if logf>=0 { let z: i64=sys_write(logf,"RISCVLOOP rung3 control-flow GREEN on nx_riscv_lib: loop sum1..5=15, N=10=55\n" as *u8,74); sys_close(logf) }
67 g_puts("verdict=GREEN (RUNG 3 on the GENERAL nx_riscv_lib: loop lowered w/ back-edge branch + run -> correct sum)\n" as *u8); sys_exit(0); return 0
68 }
69 g_puts("verdict=RED\n" as *u8); sys_exit(1); return 1
70}