diff --git a/include/cglm/affine-mat.h b/include/cglm/affine-mat.h index f58749b..8383283 100644 --- a/include/cglm/affine-mat.h +++ b/include/cglm/affine-mat.h @@ -26,6 +26,10 @@ # include "simd/avx/affine.h" #endif +#ifdef CGLM_NEON_FP +# include "simd/neon/affine.h" +#endif + /*! * @brief this is similar to glm_mat4_mul but specialized to affine transform * @@ -49,6 +53,8 @@ glm_mul(mat4 m1, mat4 m2, mat4 dest) { glm_mul_avx(m1, m2, dest); #elif defined( __SSE__ ) || defined( __SSE2__ ) glm_mul_sse2(m1, m2, dest); +#elif defined(CGLM_NEON_FP) + glm_mul_neon(m1, m2, dest); #else float a00 = m1[0][0], a01 = m1[0][1], a02 = m1[0][2], a03 = m1[0][3], a10 = m1[1][0], a11 = m1[1][1], a12 = m1[1][2], a13 = m1[1][3], diff --git a/include/cglm/simd/neon/affine.h b/include/cglm/simd/neon/affine.h new file mode 100644 index 0000000..90c9ab4 --- /dev/null +++ b/include/cglm/simd/neon/affine.h @@ -0,0 +1,51 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +#ifndef cglm_affine_neon_h +#define cglm_affine_neon_h +#if defined(__ARM_NEON_FP) + +#include "../../common.h" +#include "../intrin.h" + +CGLM_INLINE +void +glm_mul_neon(mat4 m1, mat4 m2, mat4 dest) { + /* D = R * L (Column-Major) */ + + glmm_128 l0, l1, l2, l3, r0, r1, r2, r3, v0, v1, v2, v3; + + l0 = glmm_load(m1[0]); r0 = glmm_load(m2[0]); + l1 = glmm_load(m1[1]); r1 = glmm_load(m2[1]); + l2 = glmm_load(m1[2]); r2 = glmm_load(m2[2]); + l3 = glmm_load(m1[3]); r3 = glmm_load(m2[3]); + + v0 = vmulq_f32(glmm_splat_x(r0), l0); + v1 = vmulq_f32(glmm_splat_x(r1), l0); + v2 = vmulq_f32(glmm_splat_x(r2), l0); + v3 = vmulq_f32(glmm_splat_x(r3), l0); + + v0 = glmm_fmadd(glmm_splat_y(r0), l1, v0); + v1 = glmm_fmadd(glmm_splat_y(r1), l1, v1); + v2 = glmm_fmadd(glmm_splat_y(r2), l1, v2); + v3 = glmm_fmadd(glmm_splat_y(r3), l1, v3); + + v0 = glmm_fmadd(glmm_splat_z(r0), l2, v0); + v1 = glmm_fmadd(glmm_splat_z(r1), l2, v1); + v2 = glmm_fmadd(glmm_splat_z(r2), l2, v2); + v3 = glmm_fmadd(glmm_splat_z(r3), l2, v3); + + v3 = glmm_fmadd(glmm_splat_w(r3), l3, v3); + + glmm_store(dest[0], v0); + glmm_store(dest[1], v1); + glmm_store(dest[2], v2); + glmm_store(dest[3], v3); +} + +#endif +#endif /* cglm_affine_neon_h */ diff --git a/include/cglm/simd/neon/mat4.h b/include/cglm/simd/neon/mat4.h index f1b3b60..bb00a41 100644 --- a/include/cglm/simd/neon/mat4.h +++ b/include/cglm/simd/neon/mat4.h @@ -41,7 +41,7 @@ glm_mat4_transp_neon(mat4 m, mat4 dest) { CGLM_INLINE void glm_mat4_mul_neon(mat4 m1, mat4 m2, mat4 dest) { - /* D = R * L (Column-Major) */ + /* D = R * L (Column-Major) */ glmm_128 l0, l1, l2, l3, r0, r1, r2, r3, v0, v1, v2, v3;