math backend setup

setup libraries for different simd isa's
add float4 functions for c sse2 and avx2 (placeholder file for neon to be implemented on mac)
This commit is contained in:
marauder2k7 2026-02-26 14:57:16 +00:00
parent b6ea96f367
commit e9fdffc2dd
9 changed files with 386 additions and 2 deletions

View file

@ -0,0 +1,60 @@
#include "math/public/float4_dispatch.h"
#include "math/mConstants.h"
#include <math.h>
namespace math_backend::float4::dispatch
{
void install_scalar()
{
gFloat4.add = [](const float* a, const float* b, float* r) {
for (int i = 0; i < 4; i++) r[i] = a[i] + b[i];
};
gFloat4.sub = [](const float* a, const float* b, float* r) {
for (int i = 0; i < 4; i++) r[i] = a[i] - b[i];
};
gFloat4.mul = [](const float* a, const float* b, float* r) {
for (int i = 0; i < 4; i++) r[i] = a[i] * b[i];
};
gFloat4.mul_scalar = [](const float* a, float s, float* r) {
for (int i = 0; i < 4; i++) r[i] = a[i] * s;
};
gFloat4.div = [](const float* a, const float* b, float* r) {
for (int i = 0; i < 4; i++) r[i] = a[i] / b[i];
};
gFloat4.div_scalar = [](const float* a, float s, float* r) {
for (int i = 0; i < 4; i++) r[i] = a[i] / s;
};
gFloat4.dot = [](const float* a, const float* b) {
float sum = 0.f;
for (int i = 0; i < 4; i++) sum += a[i] * b[i];
return sum;
};
gFloat4.length = [](const float* a) {
float sum = 0.f;
for (int i = 0; i < 4; i++) sum += a[i] * a[i];
return sqrtf(sum);
};
gFloat4.lengthSquared = [](const float* a) {
float sum = 0.f;
for (int i = 0; i < 4; i++) sum += a[i] * a[i];
return (sum);
};
gFloat4.normalize = [](float* a) {
float len = gFloat4.length(a);
if (len > POINT_EPSILON) for (int i = 0; i < 4; i++) a[i] /= len;
};
gFloat4.lerp = [](const float* from, const float* to, float f, float* r) {
for (int i = 0; i < 4; i++) r[i] = from[i] + (to[i] - from[i]) * f;
};
}
}

View file

@ -0,0 +1,113 @@
#pragma once
#include <cmath> // for sqrtf, etc.
namespace math_backend::float4
{
//----------------------------------------------------------
// Add two float4 vectors: r = a + b
inline void float4_add_impl(const float* a, const float* b, float* r)
{
f32x4 va = v_load(a);
f32x4 vb = v_load(b);
f32x4 vr = v_add(va, vb);
v_store(r, vr);
}
// Subtract: r = a - b
inline void float4_sub_impl(const float* a, const float* b, float* r)
{
f32x4 va = v_load(a);
f32x4 vb = v_load(b);
f32x4 vr = v_sub(va, vb);
v_store(r, vr);
}
// Multiply element-wise: r = a * b
inline void float4_mul_impl(const float* a, const float* b, float* r)
{
f32x4 va = v_load(a);
f32x4 vb = v_load(b);
f32x4 vr = v_mul(va, vb);
v_store(r, vr);
}
// Multiply by scalar: r = a * s
inline void float4_mul_scalar_impl(const float* a, float s, float* r)
{
f32x4 va = v_load(a);
f32x4 vs = v_set1(s);
f32x4 vr = v_mul(va, vs);
v_store(r, vr);
}
// Divide element-wise: r = a / b
inline void float4_div_impl(const float* a, const float* b, float* r)
{
f32x4 va = v_load(a);
f32x4 vb = v_load(b);
f32x4 vr = _mm_div_ps(va, vb);
v_store(r, vr);
}
// Divide by scalar: r = a / s
inline void float4_div_scalar_impl(const float* a, float s, float* r)
{
f32x4 va = v_load(a);
f32x4 vs = v_set1(s);
f32x4 vr = v_div(va, vs);
v_store(r, vr);
}
// Dot product: returns scalar
inline float float4_dot_impl(const float* a, const float* b)
{
f32x4 va = v_load(a);
f32x4 vb = v_load(b);
f32x4 vmul = v_mul(va, vb);
return v_hadd4(vmul);
}
// Length squared
inline float float4_length_squared_impl(const float* a)
{
return float4_dot_impl(a, a);
}
// Length
inline float float4_length_impl(const float* a)
{
return std::sqrt(float4_length_squared_impl(a));
}
// Normalize in-place
inline void float4_normalize_impl(float* a)
{
float len = float4_length_impl(a);
if (len > 1e-6f) // safe threshold
{
float4_mul_scalar_impl(a, 1.0f / len, a);
}
}
// Normalize with magnitude: r = normalize(a) * r
inline void float4_normalize_mag_impl(float* a, float r)
{
float len = float4_length_impl(a);
if (len > 1e-6f)
{
float4_mul_scalar_impl(a, r / len, a);
}
}
// Linear interpolation: r = from + (to - from) * f
inline void float4_lerp_impl(const float* from, const float* to, float f, float* r)
{
f32x4 vfrom = v_load(from);
f32x4 vto = v_load(to);
f32x4 vf = v_set1(f);
f32x4 vr = v_add(vfrom, v_mul(vf, v_sub(vto, vfrom)));
v_store(r, vr);
}
} // namespace math_backend::float4