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}