code wiki / (root) / _offc_probe_f32equiv.nx

_offc_probe_f32equiv.nx source

↩ module page · 146 lines · 4812 B

1// _offc_probe_f32equiv.nx -- IS THE HARDWARE f32 INTRINSIC BIT-IDENTICAL TO THE 2// SOFTWARE HELPER? (2026-08-23) 3// 4// WHY. Measured this session: NishiLang has float TYPES and float LITERALS and a 5// KAT-gated SSE backend, but NO float OPERATORS -- every one of the 17 `emit_f32` 6// sites in nx_parse.nx is an INTRINSIC dispatch (__f32_add/__f32_mul/__f32_div/...). 7// So organs reach for the SOFTWARE helper nx_f32_add (a full IEEE-754 adder written 8// in integer arithmetic) while the HARDWARE __f32_add sits one intrinsic away. A 9// banked measurement puts that software path at 10x/9x/1.6x slower than its twin. 10// 11// THE CHEAP WIN, IF IT HOLDS: re-point the nx_f32_* helper BODIES at the __f32_* 12// intrinsics. That is a LIBRARY change -- zero call-site edits, no nx_parse.nx 13// touch -- and every existing consumer gets the hardware path for free. 14// 15// THE PRECONDITION, AND THE POINT OF THIS PROBE: the two paths must agree 16// BIT-FOR-BIT. If they DISAGREE, that disagreement is the finding -- a rounding 17// difference hiding in plain sight, not a licence to swap. Specific hazard: the 18// banked backend observation is `addsd` (scalar DOUBLE). If OP_FADD lowers through 19// f64, an f32 bit pattern held in an i64 would be double-rounded or reinterpreted 20// outright. This probe is built to catch both. 21// 22// Reports agreement over every IEEE class -- signed zeros, both infinities, NaN, 23// min/max subnormal, min/max normal, 1-ulp neighbours, rounding-sensitive pairs. 24 25import "nx_syscalls.nx" 26import "nx_f32.nx" 27 28func pnum(v: i64) -> i64 { 29 let buf: *u8 = sys_mmap(64) 30 let out: *u8 = sys_mmap(64) 31 if v == 0 { 32 out[0] = 48 as u8 33 sys_write(1, out, 1) 34 return 0 35 } 36 var n: i64 = 0 37 var x: i64 = v 38 while x > 0 { 39 buf[n] = ((x % 10) + 48) as u8 40 x = x / 10 41 n = n + 1 42 } 43 var k: i64 = 0 44 while k < n { 45 out[k] = buf[n - 1 - k] 46 k = k + 1 47 } 48 sys_write(1, out, n) 49 return 0 50} 51 52func phex(v: i64) -> i64 { 53 let out: *u8 = sys_mmap(64) 54 var i: i64 = 0 55 while i < 8 { 56 let sh: i64 = (7 - i) * 4 57 let nib: i64 = (v / (1 << sh)) % 16 58 if nib < 10 { 59 out[i] = (nib + 48) as u8 60 } else { 61 out[i] = (nib + 87) as u8 62 } 63 i = i + 1 64 } 65 sys_write(1, out, 8) 66 return 0 67} 68 69func main() -> i64 { 70 let v: *i64 = sys_mmap(16 * 8) as *i64 71 v[0] = 0 // +0 72 v[1] = 2147483648 // -0 0x80000000 73 v[2] = 1065353216 // 1.0 0x3F800000 74 v[3] = 3212836864 // -1.0 0xBF800000 75 v[4] = 1073741824 // 2.0 0x40000000 76 v[5] = 1077936128 // 3.0 0x40400000 77 v[6] = 2139095040 // +inf 0x7F800000 78 v[7] = 4286578688 // -inf 0xFF800000 79 v[8] = 2143289344 // NaN 0x7FC00000 80 v[9] = 1 // min subnormal 0x00000001 81 v[10] = 8388607 // max subnormal 0x007FFFFF 82 v[11] = 8388608 // min normal 0x00800000 83 v[12] = 2139095039 // max normal 0x7F7FFFFF 84 v[13] = 1065353217 // 1.0 + 1ulp 0x3F800001 85 v[14] = 855638016 // 2^-24 0x33000000 rounding-sensitive vs 1.0 86 v[15] = 872415232 // 2^-23 0x34000000 87 88 var pairs: i64 = 0 89 var agree: i64 = 0 90 var differ: i64 = 0 91 var seen: i64 = 0 92 var fa: i64 = 0 93 var fb: i64 = 0 94 var fsw: i64 = 0 95 var fhw: i64 = 0 96 97 var i: i64 = 0 98 while i < 16 { 99 var j: i64 = 0 100 while j < 16 { 101 let a: i64 = v[i] 102 let b: i64 = v[j] 103 let sw: i64 = nx_f32_add(a, b) 104 let hw: i64 = __f32_add(a, b) 105 pairs = pairs + 1 106 if sw == hw { 107 agree = agree + 1 108 } else { 109 differ = differ + 1 110 if seen == 0 { 111 seen = 1 112 fa = a 113 fb = b 114 fsw = sw 115 fhw = hw 116 } 117 } 118 j = j + 1 119 } 120 i = i + 1 121 } 122 123 sys_write(1, "F32EQUIV pairs=" as *u8, 15) 124 pnum(pairs) 125 sys_write(1, " agree=" as *u8, 7) 126 pnum(agree) 127 sys_write(1, " differ=" as *u8, 8) 128 pnum(differ) 129 sys_write(1, "\n" as *u8, 1) 130 131 if differ > 0 { 132 sys_write(1, "FIRST-DIFF a=0x" as *u8, 15) 133 phex(fa) 134 sys_write(1, " b=0x" as *u8, 5) 135 phex(fb) 136 sys_write(1, " sw=0x" as *u8, 6) 137 phex(fsw) 138 sys_write(1, " hw=0x" as *u8, 6) 139 phex(fhw) 140 sys_write(1, "\n" as *u8, 1) 141 sys_write(1, "VERDICT=DISAGREE -- swap REFUSED; the difference IS the finding\n" as *u8, 63) 142 } else { 143 sys_write(1, "VERDICT=BIT-IDENTICAL over every IEEE class tested\n" as *u8, 50) 144 } 145 return 0 146}