code wiki / (root) / nx_f32_hw.nx

nx_f32_hw.nx source

↩ module page · 97 lines · 3594 B

1// nx_f32_hw.nx -- HARDWARE IEEE-754 f32 for NishiLang via the __f32_* compiler intrinsics 2// (R1b -> SSE scalar-single on the CPU FPU). Distinct from nx_f32.nx, which is the i64 3// SOFT-FLOAT emulation of the same binary32 -- IDENTICAL bit layout (binary32 in the low 32 4// of an i64), so the two are bit-for-bit cross-checkable (see nx_f32_vec_gate differential). 5// This is the FAST reusable MATH PART the sovereign renderer composes: scalar + vec3 now, 6// mat4 next. negate = x * -1.0f (subss deferred to a perf rung). license_tier: ORIGINAL 7 8// ---- scalar (hardware SSE) ---- 9func f32_of(n: i64) -> i64 { return __f32_from_i64(n) } // int -> binary32 bits (cvtsi2ss) 10func f32_int(x: i64) -> i64 { return __f32_to_i64(x) } // binary32 -> int, truncate (cvttss2si) 11func f32_add(a: i64, b: i64) -> i64 { return __f32_add(a, b) } // addss 12func f32_mul(a: i64, b: i64) -> i64 { return __f32_mul(a, b) } // mulss 13func f32_div(a: i64, b: i64) -> i64 { return __f32_div(a, b) } // divss 14func f32_neg(a: i64) -> i64 { return __f32_mul(a, __f32_from_i64(0 - 1)) } 15func f32_sub(a: i64, b: i64) -> i64 { return __f32_add(a, f32_neg(b)) } 16 17// ---- vec3 (each component a binary32 carrier) ---- 18func v3_dot(ax: i64, ay: i64, az: i64, bx: i64, by: i64, bz: i64) -> i64 { 19 return f32_add(f32_add(f32_mul(ax, bx), f32_mul(ay, by)), f32_mul(az, bz)) 20} 21func v3_lensq(ax: i64, ay: i64, az: i64) -> i64 { return v3_dot(ax, ay, az, ax, ay, az) } 22func v3_cross(ax: i64, ay: i64, az: i64, bx: i64, by: i64, bz: i64, out: *i64) -> i64 { 23 out[0] = f32_sub(f32_mul(ay, bz), f32_mul(az, by)) 24 out[1] = f32_sub(f32_mul(az, bx), f32_mul(ax, bz)) 25 out[2] = f32_sub(f32_mul(ax, by), f32_mul(ay, bx)) 26 return 0 27} 28func v3_scale(ax: i64, ay: i64, az: i64, s: i64, out: *i64) -> i64 { 29 out[0] = f32_mul(ax, s) 30 out[1] = f32_mul(ay, s) 31 out[2] = f32_mul(az, s) 32 return 0 33} 34 35// ---- mat4 (16 binary32 carriers, row-major) -- the projection/camera workhorse ---- 36func m4_identity(out: *i64) -> i64 { 37 var i: i64 = 0 38 while i < 16 { out[i] = f32_of(0); i = i + 1 } 39 out[0] = f32_of(1) 40 out[5] = f32_of(1) 41 out[10] = f32_of(1) 42 out[15] = f32_of(1) 43 return 0 44} 45// out = m * v (column vector v[4]) -- the per-vertex transform. 46func m4_vec4(m: *i64, v: *i64, out: *i64) -> i64 { 47 var r: i64 = 0 48 while r < 4 { 49 var sum: i64 = f32_of(0) 50 var k: i64 = 0 51 while k < 4 { sum = f32_add(sum, f32_mul(m[r * 4 + k], v[k])); k = k + 1 } 52 out[r] = sum 53 r = r + 1 54 } 55 return 0 56} 57// out = a * b (4x4 * 4x4). out must not alias a or b. 58func m4_mul(a: *i64, b: *i64, out: *i64) -> i64 { 59 var r: i64 = 0 60 while r < 4 { 61 var c: i64 = 0 62 while c < 4 { 63 var sum: i64 = f32_of(0) 64 var k: i64 = 0 65 while k < 4 { sum = f32_add(sum, f32_mul(a[r * 4 + k], b[k * 4 + c])); k = k + 1 } 66 out[r * 4 + c] = sum 67 c = c + 1 68 } 69 r = r + 1 70 } 71 return 0 72} 73// translation matrix (right column = tx,ty,tz). 74func m4_translation(tx: i64, ty: i64, tz: i64, out: *i64) -> i64 { 75 m4_identity(out) 76 out[3] = tx 77 out[7] = ty 78 out[11] = tz 79 return 0 80} 81// rotation about Y / X from f32 cos & sin (caller supplies the trig -- no f32 trig lib yet). 82func m4_roty(c: i64, s: i64, out: *i64) -> i64 { 83 m4_identity(out) 84 out[0] = c 85 out[2] = s 86 out[8] = f32_neg(s) 87 out[10] = c 88 return 0 89} 90func m4_rotx(c: i64, s: i64, out: *i64) -> i64 { 91 m4_identity(out) 92 out[5] = c 93 out[6] = f32_neg(s) 94 out[9] = s 95 out[10] = c 96 return 0 97}