code wiki / _hdl_build / nx_rv64_fast.nx

nx_rv64_fast.nx

buildroot/runtime/_hdl_build/nx_rv64_fast.nx

24598 B350 linesdepth 4pulls 5 transitivereach 25 importersview sourcekind tooltopic rv64
docsdependenciesstructsconstsfunctions

about

nx_rv64_fast.nx -- a PREDECODED RV64 interpreter (the first perf-engineering step toward closing the QEMU-TCG gap for the sovereign emulator). Where the behavioral sim re-decodes EVERY instruction EVERY step, this DECODES ONCE (fills a decoded-op table indexed by word) then runs a tight dispatch loop -- so a hot loop pays decode cost only per STATIC instruction, not per DYNAMIC step. Deterministic + bit-exact (nx_rv64_fast_gate proves equivalence with the golden behavioral sim). RV64I base integer subset; flat memory @0x80000000; SiFive-finisher halt (store to 0x100000). NOT a JIT (emits no native code) -- the honest decode-cache rung. Device-aware: routes the virtio-MMIO window to the sovereign device model (rv64im_min_virtio), so the speedup applies to REAL driver workloads too, not just pure compute. license_tier: ORIGINAL

dependencies 4 imports · 25 importers

nx_syscalls.nx nishi_hdl_primitives.nx rv64im_min_virtio.nx nx_rvc_expand.nx nx_rv64_fast.nx nx_asm_oracle.nx nx_hwtest_matrix.nx nx_jit_ra_probe.nx nx_mulh_diag.nx nx_rv64_cjit_gate.nx nx_rv64_ctier_gate.nx nx_rv64_difftest.nx nx_rv64_fast_dev_gate.nx nx_rv64_fast_gate.nx nx_rv64_jit.nx

diagram shows first 10 each side; +0 more imports, +15 more importers in the complete lists below.

imports: nx_syscalls.nxnishi_hdl_primitives.nxrv64im_min_virtio.nxnx_rvc_expand.nx

imported by: nx_asm_oracle.nxnx_hwtest_matrix.nxnx_jit_ra_probe.nxnx_mulh_diag.nxnx_rv64_cjit_gate.nxnx_rv64_ctier_gate.nxnx_rv64_difftest.nxnx_rv64_fast_dev_gate.nxnx_rv64_fast_gate.nxnx_rv64_jit.nxnx_rv64_jit_fwd_gate.nxnx_rv64_jit_gate.nxnx_rv64_jit_mem_gate.nxnx_rv64_jit_ra_gate.nxnx_rv64_jit_w_gate.nxnx_rv64_m_gate.nxnx_rv64_mulh_gate.nxnx_rv64_qemu_fuzz.nxnx_rv64_qemu_oracle.nxnx_rv64_realc_gate.nxnx_rv64_run_bin_fast.nxnx_rv64_run_bin_tier.nxnx_rv64_tier.nxnx_rv64_tier_gate.nxnx_rv64_toolchain_gate.nx

structs

none

consts

14const FK_ILL: i64 = 0
15const FK_LUI: i64 = 1
16const FK_ADDI: i64 = 2
17const FK_ANDI: i64 = 3
18const FK_ORI: i64 = 4
19const FK_XORI: i64 = 5
20const FK_SLLI: i64 = 6
21const FK_SRLI: i64 = 7
22const FK_SRAI: i64 = 8
23const FK_ADD: i64 = 9
24const FK_SUB: i64 = 10
25const FK_AND: i64 = 11
26const FK_OR: i64 = 12
27const FK_XOR: i64 = 13
28const FK_SLL: i64 = 14
29const FK_SRL: i64 = 15
30const FK_SRA: i64 = 16
31const FK_LW: i64 = 17
32const FK_LBU: i64 = 18
33const FK_LHU: i64 = 19
34const FK_LD: i64 = 20
35const FK_SW: i64 = 21
36const FK_SB: i64 = 22
37const FK_SH: i64 = 23
38const FK_SD: i64 = 24
39const FK_BEQ: i64 = 25
40const FK_BNE: i64 = 26
41const FK_BLT: i64 = 27
42const FK_BGE: i64 = 28
43const FK_BLTU: i64 = 29
44const FK_BGEU: i64 = 30
45const FK_JAL: i64 = 31
46const FK_JALR: i64 = 32
47const FK_MUL: i64 = 33
48const FK_DIV: i64 = 34
49const FK_DIVU: i64 = 35
50const FK_REM: i64 = 36
51const FK_REMU: i64 = 37
52const FK_MULH: i64 = 38
53const FK_MULHSU: i64 = 39
54const FK_MULHU: i64 = 40
55const FK_AUIPC: i64 = 41
58const FK_ADDIW: i64 = 42
59const FK_SLLIW: i64 = 43
60const FK_SRLIW: i64 = 44
61const FK_SRAIW: i64 = 45
62const FK_ADDW: i64 = 46
63const FK_SUBW: i64 = 47
64const FK_SLLW: i64 = 48
65const FK_SRLW: i64 = 49
66const FK_SRAW: i64 = 50
67const FK_MULW: i64 = 51
68const FK_DIVW: i64 = 52
69const FK_DIVUW: i64 = 53
70const FK_REMW: i64 = 54
71const FK_REMUW: i64 = 55
72const FK_AMOW: i64 = 56 // A extension, .w (32-bit); imm holds funct5
73const FK_AMOD: i64 = 57 // A extension, .d (64-bit)
74const FK_MEMBASE: i64 = 0x80000000
75const FK_FINISHER: i64 = 0x100000
89const FK_UART_THR: i64 = 0x10000000

functions

77func fk_w32(c: *u8, o: i64) -> i64 { return (c[o] as i64)|((c[o+1] as i64)<<8)|((c[o+2] as i64)<<16)|((c[o+3] as i64)<<24) }
78func fk_sext(v: i64, bits: i64) -> i64 { let m: i64 = 1 << (bits-1); if (v & m) != 0 { return v - (1 << bits) } return v }
79func fk_imm_i(w: i64) -> i64 { return fk_sext((w>>20)&0xFFF, 12) }
called by 2: fk_predecodefk_decode_one calls 1: fk_sext
80func fk_imm_s(w: i64) -> i64 { return fk_sext((((w>>25)&0x7F)<<5)|((w>>7)&0x1F), 12) }
called by 2: fk_predecodefk_decode_one calls 1: fk_sext
81func fk_imm_b(w: i64) -> i64 { return fk_sext((((w>>31)&1)<<12)|(((w>>7)&1)<<11)|(((w>>25)&0x3F)<<5)|(((w>>8)&0xF)<<1), 13) }
called by 2: fk_predecodefk_decode_one calls 1: fk_sext
82func fk_imm_u(w: i64) -> i64 { return fk_sext(w & 0xFFFFF000, 32) }
called by 2: fk_predecodefk_decode_one calls 1: fk_sext
83func fk_imm_j(w: i64) -> i64 { return fk_sext((((w>>31)&1)<<20)|(((w>>12)&0xFF)<<12)|(((w>>20)&1)<<11)|(((w>>21)&0x3FF)<<1), 21) }
called by 2: fk_predecodefk_decode_one calls 1: fk_sext
84func fk_ltu(x: i64, y: i64) -> i64 { if (x<0) != (y<0) { if x<0 { return 0 } return 1 } if x < y { return 1 } return 0 }
85func fk_srlmask(sh: i64) -> i64 { if sh==0 { return 0-1 } return (1 << (64-sh)) - 1 }
called by 1: fk_step
86func fk_sext32(v: i64) -> i64 { return fk_sext(v & 0xffffffff, 32) } // RV64 *W result: low 32 bits sign-extended to 64
called by 2: fk_amofk_step calls 1: fk_sext
92func fk_tx_reset(buf: *u8) -> i64 { fk_txcap_ptr = buf as i64; fk_txcnt = 0; return 0 }
93func fk_tx_count() -> i64 { return fk_txcnt }
104func fk_amo(addr: i64, v: i64, f5: i64, mem: *u8, membytes: i64, width: i64) -> i64
122func udiv_mod(a: i64, b: i64, wantrem: i64) -> i64
called by 2: fk_stepmain calls 1: fk_ltu
130func sdiv64(a: i64, b: i64) -> i64 { if b==0 { return 0-1 } if a==(1<<63) { if b==(0-1) { return a } } return a/b }
called by 2: fk_stepmain
131func srem64(a: i64, b: i64) -> i64 { if b==0 { return a } if a==(1<<63) { if b==(0-1) { return 0 } } return a%b }
called by 2: fk_stepmain
135func mulhu64(a: i64, b: i64) -> i64
145func mulh64(a: i64, b: i64) -> i64 { var h: i64=mulhu64(a,b); if a<0 { h=h-b } if b<0 { h=h-a } return h }
called by 3: mainfk_stepmain calls 1: mulhu64
146func mulhsu64(a: i64, b: i64) -> i64 { var h: i64=mulhu64(a,b); if a<0 { h=h-b } return h } // a signed, b unsigned
called by 2: fk_stepmain calls 1: mulhu64
149func fk_predecode(code: *u8, nbytes: i64, opk: *i64, rd: *i64, rs1: *i64, rs2: *i64, imm: *i64) -> i64
182func fk_ld(mem: *u8, o: i64, w: i64) -> i64 { var v: i64=0; var i: i64=0; while i<w { v=v|((mem[o+i] as i64)<<(i*8)); i=i+1 } return v }
183func fk_st(mem: *u8, o: i64, w: i64, val: i64) -> i64 { var i: i64=0; while i<w { mem[o+i]=((val>>(i*8))&0xff) as u8; i=i+1 } return 0 }
called by 2: fk_amofk_step
184func fk_memok(o: i64, w: i64, membytes: i64) -> i64 { if o<0 { return 0 } if o+w>membytes { return 0 } return 1 }
called by 2: fk_amofk_step
186func fk_mmio_hit(dev: *NxVirtioMmio, addr: i64) -> i64 { if (dev as i64)==0 { return 0 } if addr < dev.base { return 0 } if addr >= dev.base + 0x100 { return 0 } return 1 }
called by 1: fk_step
191func fk_step(opk: *i64, rd: *i64, rs1: *i64, rs2: *i64, imm: *i64, idx: i64, pc: i64, ilen: i64, reg: *i64, mem: *u8, membytes: i64, dev: *NxVirtioMmio, valbox: *i64, haltbox: *i64) -> i64
266func fk_run(opk: *i64, rd: *i64, rs1: *i64, rs2: *i64, imm: *i64, ncount: i64, reg: *i64, mem: *u8, membytes: i64, maxsteps: i64, dev: *NxVirtioMmio) -> i64
287func fk_decode_one(w: i64, i: i64, opk: *i64, rd: *i64, rs1: *i64, rs2: *i64, imm: *i64) -> i64
315func fk_predecode_c(code: *u8, nbytes: i64, opk: *i64, rd: *i64, rs1: *i64, rs2: *i64, imm: *i64) -> i64
329func fk_run_c(opk: *i64, rd: *i64, rs1: *i64, rs2: *i64, imm: *i64, nhalf: i64, reg: *i64, mem: *u8, membytes: i64, maxsteps: i64, dev: *NxVirtioMmio) -> i64
called by 3: runrun_capturemain calls 2: sys_mmapfk_step
350func main() -> i64 { return 0 }