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}