|
| 1 | +#include "float4_dispatch.h" |
| 2 | +#include <arm_neon.h> |
| 3 | + |
| 4 | +namespace |
| 5 | +{ |
| 6 | + typedef float32x4_t f32x4; |
| 7 | + |
| 8 | + inline f32x4 v_load(const float* p) { return vld1q_f32(p); } |
| 9 | + inline void v_store(float* dst, f32x4 v) { vst1q_f32(dst, v); } |
| 10 | + inline f32x4 v_set1(float s) { return vdupq_n_f32(s); } |
| 11 | + |
| 12 | + inline f32x4 v_mul(f32x4 a, f32x4 b) { return vmulq_f32(a, b); } |
| 13 | + inline f32x4 v_add(f32x4 a, f32x4 b) { return vaddq_f32(a, b); } |
| 14 | + inline f32x4 v_sub(f32x4 a, f32x4 b) { return vsubq_f32(a, b); } |
| 15 | + |
| 16 | + // AArch64 native divide |
| 17 | + inline f32x4 v_div(f32x4 a, f32x4 b) |
| 18 | + { |
| 19 | + return vdivq_f32(a, b); |
| 20 | + } |
| 21 | + |
| 22 | + inline float v_hadd4(f32x4 a) |
| 23 | + { |
| 24 | + float32x2_t low = vget_low_f32(a); |
| 25 | + float32x2_t high = vget_high_f32(a); |
| 26 | + float32x2_t sum = vadd_f32(low, high); |
| 27 | + sum = vpadd_f32(sum, sum); |
| 28 | + return vget_lane_f32(sum, 0); |
| 29 | + } |
| 30 | +} |
| 31 | + |
| 32 | +#include "../../impl/float4_impl.inl" |
| 33 | + |
| 34 | +namespace math_backend::float4::dispatch |
| 35 | +{ |
| 36 | + void install_neon() |
| 37 | + { |
| 38 | + gFloat4.add = float4_add_impl; |
| 39 | + gFloat4.sub = float4_sub_impl; |
| 40 | + gFloat4.mul = float4_mul_impl; |
| 41 | + gFloat4.mul_scalar = float4_mul_scalar_impl; |
| 42 | + gFloat4.div = float4_div_impl; |
| 43 | + gFloat4.div_scalar = float4_div_scalar_impl; |
| 44 | + gFloat4.dot = float4_dot_impl; |
| 45 | + gFloat4.length = float4_length_impl; |
| 46 | + gFloat4.lengthSquared = float4_length_squared_impl; |
| 47 | + gFloat4.normalize = float4_normalize_impl; |
| 48 | + gFloat4.lerp = float4_lerp_impl; |
| 49 | + } |
| 50 | +} |
0 commit comments