code wiki / _hdl_build / nx_mulh_diag.nx

nx_mulh_diag.nx source

↩ module page · 29 lines · 1720 B

1// nx_mulh_diag.nx -- decisive: compute mulh(0xffffffff86129b49, 0x00c50021) on the golden sim's ALU AND my fast 2// interpreter's mulh64. QEMU says the answer is -1 (0xffffffffffffffff). Whichever gives -1 is correct. expect_exit:0 3import "nx_syscalls.nx" 4import "nx_g_puts_lib.nx" 5import "nishi_hdl_primitives.nx" 6import "rv64im_min_decoder.nx" 7import "rv64im_min_alu.nx" 8import "nx_rv64_fast.nx" 9 10func g_ph16(v: i64) -> i64 { g_puts("0x" as *u8); let b: *u8=sys_mmap(20); var i: i64=15; while i>=0 { let nib: i64=(v>>(i*4))&15; if nib<10 { b[15-i]=(48+nib) as u8 } else { b[15-i]=(87+nib) as u8 } i=i-1 } b[16]=10 as u8; sys_write(1,b,17); return 0 } 11 12func main() -> i64 { 13 let a: i64 = 0-533021367140828343 // 0xffffffff86129b49 (as a negative i64 literal via wraparound below) 14 // build the exact bit patterns instead of trusting decimal: 15 let A: i64 = (0-1) ^ 0x79ed64b6 // 0xffffffff86129b49 = ~0x0000000079ed64b6 16 let B: i64 = 0x00c50021 17 g_puts("A = "); g_ph16(A) 18 g_puts("B = "); g_ph16(B) 19 g_puts("golden sim MULH = "); g_ph16(nx_rv64im_alu_compute(NX_RV64IM_ALU_MULH, A, B)) 20 g_puts("golden sim MULHU = "); g_ph16(nx_rv64im_alu_compute(NX_RV64IM_ALU_MULHU, A, B)) 21 g_puts("fast interp mulh64= "); g_ph16(mulh64(A, B)) 22 g_puts("fast interp mulhu64="); g_ph16(mulhu64(A, B)) 23 g_puts("(QEMU truth: MULH = 0xffffffffffffffff = -1)\n" as *u8) 24 // also the case the single-oracle already proved matches QEMU: 25 g_puts("golden MULHU(-1,-1)= "); g_ph16(nx_rv64im_alu_compute(NX_RV64IM_ALU_MULHU, 0-1, 0-1)) 26 g_puts("fast mulhu64(-1,-1)="); g_ph16(mulhu64(0-1, 0-1)) 27 g_puts("(QEMU truth: MULHU(-1,-1) = 0xfffffffffffffffe)\n" as *u8) 28 sys_exit(0); return 0 29}