2026-02-26 14:57:16 +00:00
|
|
|
#include "float4_dispatch.h"
|
|
|
|
|
#include <emmintrin.h> // SSE2 intrinsics
|
|
|
|
|
namespace
|
|
|
|
|
{
|
|
|
|
|
typedef __m128 f32x4;
|
|
|
|
|
|
|
|
|
|
// Load 4 floats from memory into a SIMD register
|
|
|
|
|
inline f32x4 v_load(const float* p) { return _mm_loadu_ps(p); }
|
|
|
|
|
|
|
|
|
|
// Store 4 floats from SIMD register back to memory
|
|
|
|
|
inline void v_store(float* dst, f32x4 v) { _mm_storeu_ps(dst, v); }
|
|
|
|
|
|
|
|
|
|
// Broadcast a single float across all 4 lanes
|
|
|
|
|
inline f32x4 v_set1(float s) { return _mm_set1_ps(s); }
|
|
|
|
|
|
|
|
|
|
// Element-wise multiply
|
|
|
|
|
inline f32x4 v_mul(f32x4 a, f32x4 b) { return _mm_mul_ps(a, b); }
|
|
|
|
|
|
|
|
|
|
// Element-wise divide
|
|
|
|
|
inline f32x4 v_div(f32x4 a, f32x4 b) { return _mm_div_ps(a, b); }
|
|
|
|
|
|
|
|
|
|
// Element-wise add
|
|
|
|
|
inline f32x4 v_add(f32x4 a, f32x4 b) { return _mm_add_ps(a, b); }
|
|
|
|
|
|
|
|
|
|
// Element-wise subtract
|
|
|
|
|
inline f32x4 v_sub(f32x4 a, f32x4 b) { return _mm_sub_ps(a, b); }
|
|
|
|
|
|
|
|
|
|
// Horizontal sum of all 4 elements (for dot product, length, etc.)
|
|
|
|
|
inline float v_hadd4(f32x4 a)
|
|
|
|
|
{
|
|
|
|
|
__m128 shuf = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 3, 0, 1)); // swap pairs
|
|
|
|
|
__m128 sums = _mm_add_ps(a, shuf); // sums: [a0+a1 a1+a0 a2+a3 a3+a2]
|
|
|
|
|
shuf = _mm_shuffle_ps(sums, sums, _MM_SHUFFLE(1, 0, 3, 2)); // move high pair to low
|
|
|
|
|
sums = _mm_add_ps(sums, shuf); // total sum in lower float
|
|
|
|
|
return _mm_cvtss_f32(sums);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#include "../../impl/float4_impl.inl"
|
|
|
|
|
|
|
|
|
|
namespace math_backend::float4::dispatch
|
|
|
|
|
{
|
2026-02-26 16:40:01 +00:00
|
|
|
// Install SSE2 backend
|
2026-02-26 14:57:16 +00:00
|
|
|
void install_sse2()
|
|
|
|
|
{
|
2026-02-26 16:40:01 +00:00
|
|
|
gFloat4.add = float4_add_impl;
|
|
|
|
|
gFloat4.sub = float4_sub_impl;
|
|
|
|
|
gFloat4.mul = float4_mul_impl;
|
|
|
|
|
gFloat4.mul_scalar = float4_mul_scalar_impl;
|
|
|
|
|
gFloat4.div = float4_div_impl;
|
|
|
|
|
gFloat4.div_scalar = float4_div_scalar_impl;
|
|
|
|
|
gFloat4.dot = float4_dot_impl;
|
|
|
|
|
gFloat4.length = float4_length_impl;
|
2026-02-26 14:57:16 +00:00
|
|
|
gFloat4.lengthSquared = float4_length_squared_impl;
|
2026-02-26 16:40:01 +00:00
|
|
|
gFloat4.normalize = float4_normalize_impl;
|
|
|
|
|
gFloat4.lerp = float4_lerp_impl;
|
2026-02-26 14:57:16 +00:00
|
|
|
}
|
|
|
|
|
}
|