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}