code wiki / (root) / nx_f32_hw.nx

nx_f32_hw.nx

buildroot/runtime/nx_f32_hw.nx

5722 B128 linesdepth 0pulls 0 transitivereach 513 importersview sourcekind librarytopic f32
docsdependenciesstructsconstsfunctions

about

nx_f32_hw.nx -- HARDWARE IEEE-754 f32 for NishiLang via the __f32_* compiler intrinsics (R1b -> SSE scalar-single on the CPU FPU). Distinct from nx_f32.nx, which is the i64 SOFT-FLOAT emulation of the same binary32 -- IDENTICAL bit layout (binary32 in the low 32 of an i64), so the two are bit-for-bit cross-checkable (see nx_f32_vec_gate differential). This is the FAST reusable MATH PART the sovereign renderer composes: scalar + vec3 now, mat4 next. negate = x * -1.0f (subss deferred to a perf rung). license_tier: ORIGINAL ===== DO NOT COLLAPSE THESE TWO MODULES INTO ONE (2026-08-23) =============== A tempting "optimisation" is to re-point nx_f32.nx's BODIES at the __f32_* intrinsics, so every existing nx_f32_* caller gets the hardware path for free. THAT WOULD DELETE AN ORACLE, and it was measured and refused this session: nx_f32.nx is an INDEPENDENT IEEE-754 implementation. It is the only thing in the estate that proves this hardware path is CONFORMANT rather than merely SELF-CONSISTENT. If the soft-float BECOMES the intrinsic, nx_f32_vec_gate's differential compares the hardware path AGAINST ITSELF -- every agreement goes vacuous and the estate loses its only independent check on its own float backend. A slow reference whose only remaining job is to DISAGREE with the fast one is doing the most valuable job in the codebase. The differential was measured exhaustively over every IEEE class (16x16 = 256 pairs, _offc_probe_f32equiv.nx): 254 agree BIT-FOR-BIT -- including the rounding-sensitive 1.0+2^-24 / 1.0+2^-23 and the subnormals, which REFUTES any double-rounding-through-f64 hazard -- and exactly 2 differ: inf + (-inf) yields a NaN whose SIGN BIT differs (soft-float returns a fixed POSITIVE qNaN, x86 its default NEGATIVE qNaN). IEEE-754 does not specify the sign of a NaN result, so neither is wrong. Both estate routes for observing a NaN are structurally blind to it anyway: nx_f32_classify reads only exponent+mantissa, and nx_f32_eq returns 0 for any NaN before it ever compares bits. SO: THIS IS THE FAST PATH, AND IT IS THE ONE HOT CODE SHOULD CALL. want speed -> f32_add / f32_mul / f32_div (here; one SSE instruction) want the reference oracle -> nx_f32_add / nx_f32_mul / ... (nx_f32.nx) Migrating a hot consumer from nx_f32_* to f32_* is a REVIEWABLE PER-CONSUMER decision that keeps the oracle intact. nx_f32_vec_gate's anti-vacuity tooth enforces this: collapsing the two paths turns it RED (bite-proven, exit 35). ============================================================================

dependencies 0 imports · 77 importers

nx_f32_hw.nx nishi_export_lib.nx nx_aco_gate.nx nx_compute_ladder.nx nx_compute_mt.nx nx_compute_opt2.nx nx_d3d_shade_gate.nx nx_decision_tree_gate.nx nx_differential_evolution_gate.nx nx_dxbc_exec.nx nx_expr_evolve_gate.nx

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

imports: none

imported by: nishi_export_lib.nxnx_aco_gate.nxnx_compute_ladder.nxnx_compute_mt.nxnx_compute_opt2.nxnx_d3d_shade_gate.nxnx_decision_tree_gate.nxnx_differential_evolution_gate.nxnx_dxbc_exec.nxnx_expr_evolve_gate.nxnx_expr_tree_gate.nxnx_f32_adam_gate.nxnx_f32_autograd_gate.nxnx_f32_block_gate.nxnx_f32_charlm_train_gate.nxnx_f32_crossentropy_gate.nxnx_f32_embed_lmhead_gate.nxnx_f32_gqa_gate.nxnx_f32_hw_matmul.nxnx_f32_layernorm_gate.nxnx_f32_lm_train_gate.nxnx_f32_matmul.nxnx_f32_moe_train_gate.nxnx_f32_raster_gate.nxnx_f32_rmsnorm_rope_gate.nxnx_f32_softmax_gate.nxnx_f32_swiglu_gate.nxnx_f32_train_ckpt_gate.nxnx_f32_transformer_train_gate.nxnx_f32_vec_gate.nxnx_f32_voxel_gate.nxnx_fd_f32.nxnx_fpsworld_gate.nxnx_gguf_write_gate.nxnx_gradient_boost_gate.nxnx_gradient_ml_gate.nxnx_kmeans_gate.nxnx_llm_ppl_bench_gate.nxnx_llm_wired_expand_gate.nxnx_lowrank_attn.nxnx_lowrank_kv_real.nxnx_lowrank_weight_spectrum.nxnx_machine_scientist_gate.nxnx_machine_scientist_unified_gate.nxnx_mdl_overfit_gate.nxnx_mech_engines_lib.nxnx_mesh3.nxnx_mesh_terrain_gate.nxnx_mineworld_autotest.nxnx_mineworld_wasm_vet.nxnx_mw_f32_probe.nxnx_mw_spawn_probe.nxnx_neurosym_complete_gate.nxnx_neurosym_full_gate.nxnx_par_matmul.nxnx_par_pool.nxnx_pareto_symreg_gate.nxnx_sim_repro_h2h_gate.nxnx_simulated_annealing_gate.nxnx_sphere_gate.nxnx_tool_dispatch_gate.nxnx_transformer_multilayer_gate.nxnx_voxel_world.nxnx_wasm_mineworld.nxnx_wasm_mineworld_gate.nxnx_wasm_mineworld_mod_gate.nxnx_wasm_mineworld_mp_gate.nxnx_wasm_mineworld_tick_gate.nxnx_wasm_vm.nxnx_wasm_vm.pre_metadata_20260912.nxnx_wasm_vm_bounds_20260912.nxnx_wasmcube.nxnx_wasmfps.nxnx_wasmfps_gate.nxnx_wasmvox3d.nxnx_wasmvox3d_gate.nxnx_wasmvoxel.nx

structs

none

consts

none

functions

40func f32_of(n: i64) -> i64 { return __f32_from_i64(n) } // int -> binary32 bits (cvtsi2ss)
41func f32_int(x: i64) -> i64 { return __f32_to_i64(x) } // binary32 -> int, truncate (cvttss2si)
42func f32_add(a: i64, b: i64) -> i64 { return __f32_add(a, b) } // addss
43func f32_mul(a: i64, b: i64) -> i64 { return __f32_mul(a, b) } // mulss
44func f32_div(a: i64, b: i64) -> i64 { return __f32_div(a, b) } // divss
45func f32_neg(a: i64) -> i64 { return __f32_mul(a, __f32_from_i64(0 - 1)) }
46func f32_sub(a: i64, b: i64) -> i64 { return __f32_add(a, f32_neg(b)) }
called by 127: f32_lemainf32_leginif32_lesphere+121 calls 1: f32_neg
49func v3_dot(ax: i64, ay: i64, az: i64, bx: i64, by: i64, bz: i64) -> i64
52func v3_lensq(ax: i64, ay: i64, az: i64) -> i64 { return v3_dot(ax, ay, az, ax, ay, az) }
called by 1: main calls 1: v3_dot
53func v3_cross(ax: i64, ay: i64, az: i64, bx: i64, by: i64, bz: i64, out: *i64) -> i64
called by 1: main calls 2: f32_subf32_mul
59func v3_scale(ax: i64, ay: i64, az: i64, s: i64, out: *i64) -> i64
calls 1: f32_mul
67func m4_identity(out: *i64) -> i64
77func m4_vec4(m: *i64, v: *i64, out: *i64) -> i64
89func m4_mul(a: *i64, b: *i64, out: *i64) -> i64
105func m4_translation(tx: i64, ty: i64, tz: i64, out: *i64) -> i64
calls 1: m4_identity
113func m4_roty(c: i64, s: i64, out: *i64) -> i64
called by 4: mainmainmainmain calls 2: m4_identityf32_neg
121func m4_rotx(c: i64, s: i64, out: *i64) -> i64
called by 4: mainmainmainmain calls 2: m4_identityf32_neg