code wiki / _hdl_build / nx_rv64_asm_test.nx
nx_rv64_asm_test.nx source
↩ module page · 35 lines · 3061 B
1// nx_rv64_asm_test.nx -- minimal isolation test for the RV64 assembler. Assembles 3 instructions + checks bytes.
2// expect_exit:0
3import "nx_rv64_asm.nx"
4
5func t_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
6func t_hx(v: i64) -> i64 { t_puts("0x" as *u8); let b: *u8=sys_mmap(16); var i: i64=7; var k: i64=0; while i>=0 { let nib: i64=(v>>(i*4))&15; if nib<10 { b[k]=(48+nib) as u8 } else { b[k]=(87+nib) as u8 } k=k+1; i=i-1 } sys_write(1,b,8); return 0 }
7
8func main() -> i64 {
9 let out: *u8 = sys_mmap(4096)
10 let nb: i64 = rvasm_assemble_str(" lui a0, 0x10000\n li a1, 79\n sb a1, 0(a0)\n" as *u8, out, 4096)
11 t_puts("assembled bytes="); let d: *u8=sys_mmap(8); if nb<0 { d[0]=45 as u8; sys_write(1,d,1) }
12 var m: i64=nb; if m<0 { m=0-m } var buf: *u8=sys_mmap(16); var k: i64=0; if m==0 { buf[0]=48; k=1 } var t: *u8=sys_mmap(16); var kk: i64=0; while m>0 { t[kk]=(48+(m%10)) as u8; m=m/10; kk=kk+1 } var j: i64=0; while j<kk { buf[j]=t[kk-1-j]; j=j+1 } sys_write(1,buf,kk)
13 t_puts(" words:" as *u8)
14 var i: i64=0; while i<3 { let w: i64=(out[i*4] as i64)|((out[i*4+1] as i64)<<8)|((out[i*4+2] as i64)<<16)|((out[i*4+3] as i64)<<24); t_puts(" " as *u8); t_hx(w); i=i+1 }
15 t_puts("\n" as *u8)
16 let w0: i64=(out[0] as i64)|((out[1] as i64)<<8)|((out[2] as i64)<<16)|((out[3] as i64)<<24)
17 // branch KAT: beq a0,zero,start with start@0, beq@4 -> offset -4. correct word = 0xFE050EE3
18 let ob: *u8 = sys_mmap(64)
19 let nb2: i64 = rvasm_assemble_str("start:\n addi a0, zero, 1\n beq a0, zero, start\n" as *u8, ob, 64)
20 let wb: i64=(ob[4] as i64)|((ob[5] as i64)<<8)|((ob[6] as i64)<<16)|((ob[7] as i64)<<24)
21 t_puts("beq(-4) word="); t_hx(wb); t_puts(" expected=0xfe050ee3 raw_ra_b="); t_hx(ra_b(0,10,0,0-4)); t_puts("\n" as *u8)
22 // forward branch KAT: bne @0 to end@8 -> offset +8. correct = ra_b(1,...,8)
23 let of: *u8 = sys_mmap(64)
24 let nf: i64 = rvasm_assemble_str(" bne a0, a1, done\n addi a0,a0,1\ndone:\n addi a0,a0,2\n" as *u8, of, 64)
25 let wf: i64=(of[0] as i64)|((of[1] as i64)<<8)|((of[2] as i64)<<16)|((of[3] as i64)<<24)
26 t_puts("bne(+8) word="); t_hx(wf); t_puts(" raw_ra_b(+8)="); t_hx(ra_b(1,10,11,8)); t_puts("\n" as *u8)
27 // regression: a too-large li immediate (>2047) must be REJECTED (fail-loud), not silently truncated to 0.
28 let og: *u8 = sys_mmap(64)
29 let rbig: i64 = rvasm_assemble_str(" li a0, 4096\n" as *u8, og, 64) // 4096 out of 12-bit range -> reject
30 let rok: i64 = rvasm_assemble_str(" li a0, 2047\n" as *u8, og, 64) // 2047 in range -> ok (4 bytes)
31 t_puts("li-range guard: li(4096) rc="); t_hx(rbig); t_puts(" (negative=rejected) li(2047) rc="); t_hx(rok); t_puts(" (4=ok)\n" as *u8)
32 var guard_ok: i64=0; if rbig<0 { if rok==4 { guard_ok=1 } }
33 if w0==0x10000537 { if wb==0xfe050ee3 { if guard_ok==1 { t_puts("verdict=GREEN assembler + branch encoding + li-range guard correct\n" as *u8); sys_exit(0); return 0 } } }
34 t_puts("verdict=RED\n" as *u8); sys_exit(1); return 1
35}