code wiki / _hdl_build / nx_riscv_emit.nx

nx_riscv_emit.nx source

↩ module page · 57 lines · 3787 B

1// nx_riscv_emit.nx -- SOVEREIGN RISC-V backend RUNG 1: our own rv64im encoder. Now on the GENERAL nx_riscv_lib 2// (shared enc_r/enc_i/enc_s, UI) -- only hex-print + canonical self-assert + matvec emission are local. 3// T1 the 8 core rv64im instructions each encode to their canonical machine code. 4// T2 (teeth) a wrong field (add funct7=1) != canonical add. T3 emit the no-float matvec loop to a .bin. 5// expect_exit: 0 Sovereign: nx_riscv_lib (+ nx_syscalls). 6import "nx_riscv_lib.nx" 7import "nx_syscalls.nx" 8 9func g_hex(v: i64) -> i64 { 10 let b: *u8=sys_mmap(8); var i: i64=7 11 while i>=0 { let nib: i64=(v>>((7-i)*4))&15; if nib<10 { b[i]=(48+nib) as u8 } else { b[i]=(87+nib) as u8 } i=i-1 } 12 sys_write(1,"0x" as *u8,2); sys_write(1,b,8); return 0 13} 14func assert_enc(name: *u8, got: i64, want: i64) -> i64 { 15 g_puts(" "); g_puts(name); g_puts(" = "); g_hex(got) 16 if got==want { g_puts(" == canonical "); g_hex(want); g_puts(" OK\n" as *u8); return 1 } 17 g_puts(" != canonical "); g_hex(want); g_puts(" MISMATCH\n" as *u8); return 0 18} 19func wr_word(fd: i64, w: i64) -> i64 { let b: *u8=sys_mmap(4); b[0]=(w&255) as u8; b[1]=((w>>8)&255) as u8; b[2]=((w>>16)&255) as u8; b[3]=((w>>24)&255) as u8; sys_write(fd,b,4); return 0 } 20 21func main() -> i64 { 22 g_puts("nx_riscv_emit (RUNG 1 rv64im encoder; now on the GENERAL nx_riscv_lib)\n" as *u8) 23 var pass: i64=0; var total: i64=0 24 g_puts(" -- T1: each core rv64im instruction encodes to its canonical machine code --\n" as *u8) 25 var a: i64=0 26 a=a+assert_enc("add x1,x2,x3" as *u8, enc_r(0x33,0,0,1,2,3), 0x003100b3) 27 a=a+assert_enc("sub x1,x2,x3" as *u8, enc_r(0x33,0,0x20,1,2,3), 0x403100b3) 28 a=a+assert_enc("mul x1,x2,x3" as *u8, enc_r(0x33,0,1,1,2,3), 0x023100b3) 29 a=a+assert_enc("addi x1,x2,5" as *u8, enc_i(0x13,0,1,2,5), 0x00510093) 30 a=a+assert_enc("ld x1,0(x2)" as *u8, enc_i(0x03,3,1,2,0), 0x00013083) 31 a=a+assert_enc("sd x1,0(x2)" as *u8, enc_s(0x23,3,2,1,0), 0x00113023) 32 a=a+assert_enc("srai x1,x2,16" as *u8, enc_i(0x13,5,1,2,0x410), 0x41015093) 33 a=a+assert_enc("ret(jalr x0,0(x1))" as *u8, enc_i(0x67,0,0,1,0), 0x00008067) 34 var t1: i64=0; if a==8 { t1=1 } 35 pass=pass+ck("T1: all 8 core rv64im instructions encode == canonical" as *u8, t1); total=total+1 36 37 var t2: i64=0; let bad: i64=enc_r(0x33,0,1,1,2,3); if bad != 0x003100b3 { t2=1 } 38 pass=pass+ck("T2 (teeth): add with funct7=1 does NOT match canonical add (it is mul)" as *u8, t2); total=total+1 39 40 let fd: i64=sys_openat_wr("knowledge/research/riscv_matvec.bin" as *u8, 0x1a4) 41 var t3: i64=0 42 if fd>=0 { 43 wr_word(fd, enc_i(0x03,3,11,18,0)); wr_word(fd, enc_i(0x03,3,10,8,0)); wr_word(fd, enc_r(0x33,0,1,10,10,11)) 44 wr_word(fd, enc_i(0x13,5,10,10,0x410)); wr_word(fd, enc_r(0x33,0,0,9,9,10)); wr_word(fd, enc_i(0x13,0,8,8,8)); wr_word(fd, enc_i(0x13,0,18,18,8)) 45 sys_close(fd); g_puts(" emitted 7 native rv64im words -> knowledge/research/riscv_matvec.bin\n" as *u8); t3=1 46 } 47 pass=pass+ck("T3: Q16 matvec inner loop emitted as native RISC-V" as *u8, t3); total=total+1 48 49 var okall: i64=0; if pass==total { okall=1 } 50 g_puts("---- riscv_emit: passed "); g_pn(pass); g_puts(" / "); g_pn(total); g_puts(" ----\n" as *u8) 51 if okall==1 { 52 let logf: i64=sys_openat_append("knowledge/status/riscv_emit.log" as *u8, 420) 53 if logf>=0 { let z: i64=sys_write(logf,"RISCVEMIT rung1 on nx_riscv_lib GREEN: 8 core instrs == canonical; matvec emitted\n" as *u8,78); sys_close(logf) } 54 g_puts("verdict=GREEN (RUNG 1 on the GENERAL nx_riscv_lib: our own encoder matches canonical; emits the no-float kernel)\n" as *u8); sys_exit(0); return 0 55 } 56 g_puts("verdict=RED\n" as *u8); sys_exit(1); return 1 57}