From 576d1d141eadf913ae81112534a1b6d9dc51af6e Mon Sep 17 00:00:00 2001 From: myfreeer Date: Mon, 6 Mar 2023 14:08:49 +0800 Subject: [PATCH 01/34] initial code on wasm simd128 --- include/cglm/affine-mat.h | 10 + include/cglm/simd/intrin.h | 14 +- include/cglm/simd/wasm.h | 233 +++++++++++++++++ include/cglm/simd/wasm/affine.h | 115 +++++++++ include/cglm/simd/wasm/mat2.h | 48 ++++ include/cglm/simd/wasm/mat3.h | 76 ++++++ include/cglm/simd/wasm/mat4.h | 434 ++++++++++++++++++++++++++++++++ include/cglm/simd/wasm/quat.h | 54 ++++ 8 files changed, 983 insertions(+), 1 deletion(-) create mode 100644 include/cglm/simd/wasm.h create mode 100644 include/cglm/simd/wasm/affine.h create mode 100644 include/cglm/simd/wasm/mat2.h create mode 100644 include/cglm/simd/wasm/mat3.h create mode 100644 include/cglm/simd/wasm/mat4.h create mode 100644 include/cglm/simd/wasm/quat.h diff --git a/include/cglm/affine-mat.h b/include/cglm/affine-mat.h index 75607e7..5107efc 100644 --- a/include/cglm/affine-mat.h +++ b/include/cglm/affine-mat.h @@ -30,6 +30,10 @@ # include "simd/neon/affine.h" #endif +#ifdef CGLM_SIMD_WASM +# include "simd/wasm/affine.h" +#endif + /*! * @brief this is similar to glm_mat4_mul but specialized to affine transform * @@ -53,6 +57,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(__wasm__) && defined(__wasm_simd128__) + glm_mul_wasm(m1, m2, dest); #elif defined(CGLM_NEON_FP) glm_mul_neon(m1, m2, dest); #else @@ -109,6 +115,8 @@ void glm_mul_rot(mat4 m1, mat4 m2, mat4 dest) { #if defined( __SSE__ ) || defined( __SSE2__ ) glm_mul_rot_sse2(m1, m2, dest); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glm_mul_rot_wasm(m1, m2, dest); #elif defined(CGLM_NEON_FP) glm_mul_rot_neon(m1, m2, dest); #else @@ -158,6 +166,8 @@ void glm_inv_tr(mat4 mat) { #if defined( __SSE__ ) || defined( __SSE2__ ) glm_inv_tr_sse2(mat); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glm_inv_tr_wasm(mat); #elif defined(CGLM_NEON_FP) glm_inv_tr_neon(mat); #else diff --git a/include/cglm/simd/intrin.h b/include/cglm/simd/intrin.h index bfdc94e..17998f5 100644 --- a/include/cglm/simd/intrin.h +++ b/include/cglm/simd/intrin.h @@ -99,7 +99,15 @@ # endif #endif -#if defined(CGLM_SIMD_x86) || defined(CGLM_SIMD_ARM) + +/* WebAssembly */ +#if defined(__wasm__) && defined(__wasm_simd128__) +# ifndef CGLM_SIMD_WASM +# define CGLM_SIMD_WASM +# endif +#endif + +#if defined(CGLM_SIMD_x86) || defined(CGLM_SIMD_ARM) || defined(CGLM_SIMD_WASM) # ifndef CGLM_SIMD # define CGLM_SIMD # endif @@ -113,4 +121,8 @@ # include "arm.h" #endif +#if defined(CGLM_SIMD_WASM) +# include "wasm.h" +#endif + #endif /* cglm_intrin_h */ diff --git a/include/cglm/simd/wasm.h b/include/cglm/simd/wasm.h new file mode 100644 index 0000000..dfb9490 --- /dev/null +++ b/include/cglm/simd/wasm.h @@ -0,0 +1,233 @@ + +#ifndef cglm_simd_wasm_h +#define cglm_simd_wasm_h +#include "intrin.h" +#ifdef CGLM_SIMD_WASM +#include + +#define glmm_load(p) wasm_v128_load(p) +#define glmm_store(p, a) wasm_v128_store(p, a) + +#define glmm_set1(x) wasm_f32x4_splat(x) +#define glmm_128 v128_t +#define glmm_shuffle(a, b, z, y, x, w) wasm_i32x4_shuffle(a, b, z, y, x, w) +#define glmm_shuff1(xmm, z, y, x, w) wasm_i32x4_shuffle(xmm, xmm, z, y, x, w) + +#define glmm_splat(x, lane) glmm_shuff1(x, lane, lane, lane, lane) + +#define glmm_splat_x(x) glmm_splat(x, 0) +#define glmm_splat_y(x) glmm_splat(x, 1) +#define glmm_splat_z(x) glmm_splat(x, 2) +#define glmm_splat_w(x) glmm_splat(x, 3) + +#define glmm_shuff2(a, b, z0, y0, x0, w0, z1, y1, x1, w1) \ + glmm_shuff1(wasm_i32x4_shuffle(a, b, z0, y0, x0, w0), z1, y1, x1, w1) + +#define _mm_cvtss_f32(v) wasm_f32x4_extract_lane(v, 0) + +static inline glmm_128 __attribute__((__always_inline__, __nodebug__)) +_mm_unpackhi_ps(glmm_128 __a, glmm_128 __b) +{ + return wasm_i32x4_shuffle(__a, __b, 2, 6, 3, 7); +} + +static inline glmm_128 __attribute__((__always_inline__, __nodebug__)) +_mm_unpacklo_ps(glmm_128 __a, glmm_128 __b) +{ + return wasm_i32x4_shuffle(__a, __b, 0, 4, 1, 5); +} + +static inline glmm_128 __attribute__((__always_inline__, __nodebug__)) +_mm_movehl_ps(glmm_128 __a, glmm_128 __b) +{ + return wasm_i32x4_shuffle(__a, __b, 6, 7, 2, 3); +} + +static inline glmm_128 __attribute__((__always_inline__, __nodebug__)) +_mm_movelh_ps(glmm_128 __a, glmm_128 __b) +{ + return wasm_i32x4_shuffle(__a, __b, 0, 1, 4, 5); +} + +#define _MM_TRANSPOSE4_PS(row0, row1, row2, row3) \ + do { \ + glmm_128 __row0 = (row0); \ + glmm_128 __row1 = (row1); \ + glmm_128 __row2 = (row2); \ + glmm_128 __row3 = (row3); \ + glmm_128 __tmp0 = _mm_unpacklo_ps(__row0, __row1); \ + glmm_128 __tmp1 = _mm_unpackhi_ps(__row0, __row1); \ + glmm_128 __tmp2 = _mm_unpacklo_ps(__row2, __row3); \ + glmm_128 __tmp3 = _mm_unpackhi_ps(__row2, __row3); \ + (row0) = _mm_movelh_ps(__tmp0, __tmp2); \ + (row1) = _mm_movehl_ps(__tmp2, __tmp0); \ + (row2) = _mm_movelh_ps(__tmp1, __tmp3); \ + (row3) = _mm_movehl_ps(__tmp3, __tmp1); \ + } while (0) + +static inline +glmm_128 +glmm_abs(glmm_128 x) { + return wasm_v128_andnot(wasm_f32x4_splat(-0.0f), x); +} + +static inline +glmm_128 +glmm_vhadd(glmm_128 v) { + glmm_128 x0; + x0 = wasm_f32x4_add(v, glmm_shuff1(v, 0, 1, 2, 3)); + x0 = wasm_f32x4_add(x0, glmm_shuff1(x0, 1, 0, 0, 1)); + return x0; +} + +static inline +glmm_128 +glmm_vhadds(glmm_128 v) { + glmm_128 shuf, sums; + shuf = glmm_shuff1(v, 2, 3, 0, 1); + sums = wasm_f32x4_add(v, shuf); + shuf = wasm_i32x4_shuffle(shuf, sums, 6, 7, 2, 3); + sums = wasm_f32x4_add(sums, shuf); + return sums; +} + +static inline +float +glmm_hadd(glmm_128 v) { + return _mm_cvtss_f32(glmm_vhadds(v)); +} + +static inline +glmm_128 +glmm_vhmin(glmm_128 v) { + glmm_128 x0, x1, x2; + x0 = glmm_shuff1(v, 2, 3, 2, 3); /* [2, 3, 2, 3] */ + x1 = wasm_f32x4_pmin(x0, v); /* [0|2, 1|3, 2|2, 3|3] */ + x2 = glmm_splat(x1, 1); /* [1|3, 1|3, 1|3, 1|3] */ + return wasm_f32x4_pmin(x1, x2); +} + +static inline +float +glmm_hmin(glmm_128 v) { + return _mm_cvtss_f32(glmm_vhmin(v)); +} + +static inline +glmm_128 +glmm_vhmax(glmm_128 v) { + glmm_128 x0, x1, x2; + x0 = glmm_shuff1(v, 2, 3, 2, 3); /* [2, 3, 2, 3] */ + x1 = wasm_f32x4_pmax(x0, v); /* [0|2, 1|3, 2|2, 3|3] */ + x2 = glmm_splat(x1, 1); /* [1|3, 1|3, 1|3, 1|3] */ + return wasm_f32x4_pmax(x1, x2); +} + +static inline +float +glmm_hmax(glmm_128 v) { + return wasm_f32x4_extract_lane(glmm_vhmax(v), 0); +} + +static inline +glmm_128 +glmm_vdots(glmm_128 a, glmm_128 b) { + return glmm_vhadds(wasm_f32x4_mul(a, b)); +} + +static inline +glmm_128 +glmm_vdot(glmm_128 a, glmm_128 b) { + glmm_128 x0; + x0 = wasm_f32x4_mul(a, b); + x0 = wasm_f32x4_add(x0, glmm_shuff1(x0, 1, 0, 3, 2)); + return wasm_f32x4_add(x0, glmm_shuff1(x0, 0, 1, 0, 1)); +} + +static inline +float +glmm_dot(glmm_128 a, glmm_128 b) { + return _mm_cvtss_f32(glmm_vdots(a, b)); +} + +static inline glmm_128 __attribute__((__always_inline__, __nodebug__)) +_mm_sqrt_ss(glmm_128 __a) +{ + return wasm_i32x4_shuffle(__a, wasm_f32x4_sqrt(__a), 4, 1, 2, 3); +} + +static inline +float +glmm_norm(glmm_128 a) { + return _mm_cvtss_f32(_mm_sqrt_ss(glmm_vhadds(wasm_f32x4_mul(a, a)))); +} + +static inline +float +glmm_norm2(glmm_128 a) { + return _mm_cvtss_f32(glmm_vhadds(wasm_f32x4_mul(a, a))); +} + +static inline +float +glmm_norm_one(glmm_128 a) { + return _mm_cvtss_f32(glmm_vhadds(glmm_abs(a))); +} + +static inline +float +glmm_norm_inf(glmm_128 a) { + return _mm_cvtss_f32(glmm_vhmax(glmm_abs(a))); +} + +static inline +glmm_128 +glmm_load3(float v[3]) { + glmm_128 xy = wasm_v128_load64_zero(v); + return wasm_f32x4_replace_lane(xy, 2, v[2]); +} + +static inline +void +glmm_store3(float v[3], glmm_128 vx) { + wasm_v128_store64_lane(v, vx, 0); + wasm_v128_store32_lane(&v[2], vx, 2); +} + +static inline +glmm_128 +glmm_div(glmm_128 a, glmm_128 b) { + return wasm_f32x4_div(a, b); +} + +/* enable FMA macro for MSVC? */ +#if defined(_MSC_VER) && !defined(__FMA__) && defined(__AVX2__) +# define __FMA__ 1 +#endif + +static inline +glmm_128 +glmm_fmadd(glmm_128 a, glmm_128 b, glmm_128 c) { + return wasm_f32x4_add(c, wasm_f32x4_mul(a, b)); +} + +static inline +glmm_128 +glmm_fnmadd(glmm_128 a, glmm_128 b, glmm_128 c) { + return wasm_f32x4_sub(c, wasm_f32x4_mul(a, b)); +} + +static inline +glmm_128 +glmm_fmsub(glmm_128 a, glmm_128 b, glmm_128 c) { + return wasm_f32x4_sub(wasm_f32x4_mul(a, b), c); +} + +static inline +glmm_128 +glmm_fnmsub(glmm_128 a, glmm_128 b, glmm_128 c) { + return wasm_v128_xor(wasm_f32x4_add(wasm_f32x4_mul(a, b), c), wasm_f32x4_splat(-0.0f)); +} + +#endif +#endif /* cglm_simd_wasm_h */ diff --git a/include/cglm/simd/wasm/affine.h b/include/cglm/simd/wasm/affine.h new file mode 100644 index 0000000..ca520b9 --- /dev/null +++ b/include/cglm/simd/wasm/affine.h @@ -0,0 +1,115 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +#ifndef cglm_affine_mat_wasm_h +#define cglm_affine_mat_wasm_h +#if defined(__wasm__) && defined(__wasm_simd128__) + +#include "../../common.h" +#include "../intrin.h" + +CGLM_INLINE +void +glm_mul_wasm(mat4 m1, mat4 m2, mat4 dest) { + /* D = R * L (Column-Major) */ + glmm_128 l, r0, r1, r2, r3, v0, v1, v2, v3; + + l = glmm_load(m1[0]); + r0 = glmm_load(m2[0]); + r1 = glmm_load(m2[1]); + r2 = glmm_load(m2[2]); + r3 = glmm_load(m2[3]); + + v0 = wasm_f32x4_mul(glmm_splat_x(r0), l); + v1 = wasm_f32x4_mul(glmm_splat_x(r1), l); + v2 = wasm_f32x4_mul(glmm_splat_x(r2), l); + v3 = wasm_f32x4_mul(glmm_splat_x(r3), l); + + l = glmm_load(m1[1]); + v0 = glmm_fmadd(glmm_splat_y(r0), l, v0); + v1 = glmm_fmadd(glmm_splat_y(r1), l, v1); + v2 = glmm_fmadd(glmm_splat_y(r2), l, v2); + v3 = glmm_fmadd(glmm_splat_y(r3), l, v3); + + l = glmm_load(m1[2]); + v0 = glmm_fmadd(glmm_splat_z(r0), l, v0); + v1 = glmm_fmadd(glmm_splat_z(r1), l, v1); + v2 = glmm_fmadd(glmm_splat_z(r2), l, v2); + v3 = glmm_fmadd(glmm_splat_z(r3), l, v3); + + l = glmm_load(m1[3]); + v3 = glmm_fmadd(glmm_splat_w(r3), l, v3); + + glmm_store(dest[0], v0); + glmm_store(dest[1], v1); + glmm_store(dest[2], v2); + glmm_store(dest[3], v3); +} + +CGLM_INLINE +void +glm_mul_rot_wasm(mat4 m1, mat4 m2, mat4 dest) { + /* D = R * L (Column-Major) */ + + glmm_128 l, r0, r1, r2, v0, v1, v2; + + l = glmm_load(m1[0]); + r0 = glmm_load(m2[0]); + r1 = glmm_load(m2[1]); + r2 = glmm_load(m2[2]); + + v0 = wasm_f32x4_mul(glmm_splat_x(r0), l); + v1 = wasm_f32x4_mul(glmm_splat_x(r1), l); + v2 = wasm_f32x4_mul(glmm_splat_x(r2), l); + + l = glmm_load(m1[1]); + v0 = glmm_fmadd(glmm_splat_y(r0), l, v0); + v1 = glmm_fmadd(glmm_splat_y(r1), l, v1); + v2 = glmm_fmadd(glmm_splat_y(r2), l, v2); + + l = glmm_load(m1[2]); + v0 = glmm_fmadd(glmm_splat_z(r0), l, v0); + v1 = glmm_fmadd(glmm_splat_z(r1), l, v1); + v2 = glmm_fmadd(glmm_splat_z(r2), l, v2); + + glmm_store(dest[0], v0); + glmm_store(dest[1], v1); + glmm_store(dest[2], v2); + glmm_store(dest[3], glmm_load(m1[3])); +} + +CGLM_INLINE +void +glm_inv_tr_wasm(mat4 mat) { + glmm_128 r0, r1, r2, r3, x0, x1, x2, x3, x4, x5; + + r0 = glmm_load(mat[0]); + r1 = glmm_load(mat[1]); + r2 = glmm_load(mat[2]); + r3 = glmm_load(mat[3]); + x1 = wasm_f32x4_make(1.0f, 0.0f, 0.0f, 0.0f); + + _MM_TRANSPOSE4_PS(r0, r1, r2, x1); + + x2 = glmm_shuff1(r3, 0, 0, 0, 0); + x3 = glmm_shuff1(r3, 1, 1, 1, 1); + x4 = glmm_shuff1(r3, 2, 2, 2, 2); + x5 = wasm_f32x4_splat(-0.f); + + x0 = glmm_fmadd(r0, x2, glmm_fmadd(r1, x3, wasm_f32x4_mul(r2, x4))); + x0 = wasm_v128_xor(x0, x5); + + x0 = wasm_f32x4_add(x0, x1); + + glmm_store(mat[0], r0); + glmm_store(mat[1], r1); + glmm_store(mat[2], r2); + glmm_store(mat[3], x0); +} + +#endif +#endif /* cglm_affine_mat_wasm_h */ diff --git a/include/cglm/simd/wasm/mat2.h b/include/cglm/simd/wasm/mat2.h new file mode 100644 index 0000000..42dc1f7 --- /dev/null +++ b/include/cglm/simd/wasm/mat2.h @@ -0,0 +1,48 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +#ifndef cglm_mat2_wasm_h +#define cglm_mat2_wasm_h +#if defined(__wasm__) && defined(__wasm_simd128__) + +#include "../../common.h" +#include "../intrin.h" + +CGLM_INLINE +void +glm_mat2_mul_wasm(mat2 m1, mat2 m2, mat2 dest) { + glmm_128 x0, x1, x2, x3, x4; + + x1 = glmm_load(m1[0]); /* d c b a */ + x2 = glmm_load(m2[0]); /* h g f e */ + + x3 = glmm_shuff1(x2, 2, 2, 0, 0); + x4 = glmm_shuff1(x2, 3, 3, 1, 1); + x0 = _mm_movelh_ps(x1, x1); + x2 = _mm_movehl_ps(x1, x1); + + /* + dest[0][0] = a * e + c * f; + dest[0][1] = b * e + d * f; + dest[1][0] = a * g + c * h; + dest[1][1] = b * g + d * h; + */ + x0 = glmm_fmadd(x0, x3, wasm_f32x4_mul(x2, x4)); + + glmm_store(dest[0], x0); +} + +CGLM_INLINE +void +glm_mat2_transp_wasm(mat2 m, mat2 dest) { + /* d c b a */ + /* d b c a */ + glmm_store(dest[0], glmm_shuff1(glmm_load(m[0]), 3, 1, 2, 0)); +} + +#endif +#endif /* cglm_mat2_wasm_h */ diff --git a/include/cglm/simd/wasm/mat3.h b/include/cglm/simd/wasm/mat3.h new file mode 100644 index 0000000..6e57b8e --- /dev/null +++ b/include/cglm/simd/wasm/mat3.h @@ -0,0 +1,76 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +#ifndef cglm_mat3_wasm_h +#define cglm_mat3_wasm_h +#if defined(__wasm__) && defined(__wasm_simd128__) + +#include "../../common.h" +#include "../intrin.h" + +CGLM_INLINE +void +glm_mat3_mul_wasm(mat3 m1, mat3 m2, mat3 dest) { + glmm_128 l0, l1, l2, r0, r1, r2, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9; + + l0 = wasm_v128_load(m1[0]); + l1 = wasm_v128_load(&m1[1][1]); + + r0 = wasm_v128_load(m2[0]); + r1 = wasm_v128_load(&m2[1][1]); + + x8 = glmm_shuff1(l0, 0, 2, 1, 0); /* a00 a02 a01 a00 */ + x1 = glmm_shuff1(r0, 3, 0, 0, 0); /* b10 b00 b00 b00 */ + x2 = _mm_shuffle_ps(l0, l1, _MM_SHUFFLE(1, 0, 3, 3)); /* a12 a11 a10 a10 */ + x3 = _mm_shuffle_ps(r0, r1, _MM_SHUFFLE(2, 0, 3, 1)); /* b20 b11 b10 b01 */ + x0 = _mm_mul_ps(x8, x1); + + x6 = glmm_shuff1(l0, 1, 0, 2, 1); /* a01 a00 a02 a01 */ + x7 = glmm_shuff1(x3, 3, 3, 1, 1); /* b20 b20 b10 b10 */ + l2 = wasm_v128_load32_zero(&m1[2][2]); + r2 = wasm_v128_load32_zero(&m2[2][2]); + x1 = _mm_mul_ps(x6, x7); + l2 = glmm_shuff1(l2, 0, 0, 1, 0); /* a22 a22 0.f a22 */ + r2 = glmm_shuff1(r2, 0, 0, 1, 0); /* b22 b22 0.f b22 */ + + x4 = glmm_shuff1(x2, 0, 3, 2, 0); /* a10 a12 a11 a10 */ + x5 = glmm_shuff1(x2, 2, 0, 3, 2); /* a11 a10 a12 a11 */ + x6 = glmm_shuff1(x3, 2, 0, 0, 0); /* b11 b01 b01 b01 */ + x2 = glmm_shuff1(r1, 3, 3, 0, 0); /* b21 b21 b11 b11 */ + + x8 = _mm_unpackhi_ps(x8, x4); /* a10 a00 a12 a02 */ + x9 = _mm_unpackhi_ps(x7, x2); /* b21 b20 b21 b20 */ + + x0 = glmm_fmadd(x4, x6, x0); + x1 = glmm_fmadd(x5, x2, x1); + + x2 = _mm_movehl_ps(l2, l1); /* a22 a22 a21 a20 */ + x3 = glmm_shuff1(x2, 0, 2, 1, 0); /* a20 a22 a21 a20 */ + x2 = glmm_shuff1(x2, 1, 0, 2, 1); /* a21 a20 a22 a21 */ + x4 = _mm_shuffle_ps(r0, r1, _MM_SHUFFLE(1, 1, 2, 2)); /* b12 b12 b02 b02 */ + + x5 = glmm_shuff1(x4, 3, 0, 0, 0); /* b12 b02 b02 b02 */ + x4 = _mm_movehl_ps(r2, x4); /* b22 b22 b12 b12 */ + x0 = glmm_fmadd(x3, x5, x0); + x1 = glmm_fmadd(x2, x4, x1); + + /* + Dot Product : dest[2][2] = a02 * b20 + + a12 * b21 + + a22 * b22 + + 0 * 00 */ + x2 = _mm_movelh_ps(x8, l2); /* 0.f a22 a12 a02 */ + x3 = _mm_movelh_ps(x9, r2); /* 0.f b22 b21 b20 */ + x2 = glmm_vdots(x2, x3); + + _mm_storeu_ps(&dest[0][0], x0); + _mm_storeu_ps(&dest[1][1], x1); + _mm_store_ss (&dest[2][2], x2); +} + +#endif +#endif /* cglm_mat3_wasm_h */ diff --git a/include/cglm/simd/wasm/mat4.h b/include/cglm/simd/wasm/mat4.h new file mode 100644 index 0000000..ac451af --- /dev/null +++ b/include/cglm/simd/wasm/mat4.h @@ -0,0 +1,434 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +#ifndef cglm_mat_wasm_h +#define cglm_mat_wasm_h +#if defined(__wasm__) && defined(__wasm_simd128__) + +#include "../../common.h" +#include "../intrin.h" + +#define glm_mat4_inv_precise_sse2(mat, dest) glm_mat4_inv_sse2(mat, dest) + +CGLM_INLINE +void +glm_mat4_scale_sse2(mat4 m, float s) { + glmm_128 x0; + x0 = wasm_f32x4_splat(s); + + glmm_store(m[0], wasm_f32x4_mul(glmm_load(m[0]), x0)); + glmm_store(m[1], wasm_f32x4_mul(glmm_load(m[1]), x0)); + glmm_store(m[2], wasm_f32x4_mul(glmm_load(m[2]), x0)); + glmm_store(m[3], wasm_f32x4_mul(glmm_load(m[3]), x0)); +} + +CGLM_INLINE +void +glm_mat4_transp_sse2(mat4 m, mat4 dest) { + glmm_128 r0, r1, r2, r3; + + r0 = glmm_load(m[0]); + r1 = glmm_load(m[1]); + r2 = glmm_load(m[2]); + r3 = glmm_load(m[3]); + + _MM_TRANSPOSE4_PS(r0, r1, r2, r3); + + glmm_store(dest[0], r0); + glmm_store(dest[1], r1); + glmm_store(dest[2], r2); + glmm_store(dest[3], r3); +} + +CGLM_INLINE +void +glm_mat4_mul_sse2(mat4 m1, mat4 m2, mat4 dest) { + /* D = R * L (Column-Major) */ + + glmm_128 l, r0, r1, r2, r3, v0, v1, v2, v3; + + l = glmm_load(m1[0]); + r0 = glmm_load(m2[0]); + r1 = glmm_load(m2[1]); + r2 = glmm_load(m2[2]); + r3 = glmm_load(m2[3]); + + v0 = wasm_f32x4_mul(glmm_splat_x(r0), l); + v1 = wasm_f32x4_mul(glmm_splat_x(r1), l); + v2 = wasm_f32x4_mul(glmm_splat_x(r2), l); + v3 = wasm_f32x4_mul(glmm_splat_x(r3), l); + + l = glmm_load(m1[1]); + v0 = glmm_fmadd(glmm_splat_y(r0), l, v0); + v1 = glmm_fmadd(glmm_splat_y(r1), l, v1); + v2 = glmm_fmadd(glmm_splat_y(r2), l, v2); + v3 = glmm_fmadd(glmm_splat_y(r3), l, v3); + + l = glmm_load(m1[2]); + v0 = glmm_fmadd(glmm_splat_z(r0), l, v0); + v1 = glmm_fmadd(glmm_splat_z(r1), l, v1); + v2 = glmm_fmadd(glmm_splat_z(r2), l, v2); + v3 = glmm_fmadd(glmm_splat_z(r3), l, v3); + + l = glmm_load(m1[3]); + v0 = glmm_fmadd(glmm_splat_w(r0), l, v0); + v1 = glmm_fmadd(glmm_splat_w(r1), l, v1); + v2 = glmm_fmadd(glmm_splat_w(r2), l, v2); + v3 = glmm_fmadd(glmm_splat_w(r3), l, v3); + + glmm_store(dest[0], v0); + glmm_store(dest[1], v1); + glmm_store(dest[2], v2); + glmm_store(dest[3], v3); +} + +CGLM_INLINE +void +glm_mat4_mulv_sse2(mat4 m, vec4 v, vec4 dest) { + glmm_128 x0, x1, m0, m1, m2, m3, v0, v1, v2, v3; + + m0 = glmm_load(m[0]); + m1 = glmm_load(m[1]); + m2 = glmm_load(m[2]); + m3 = glmm_load(m[3]); + + x0 = glmm_load(v); + v0 = glmm_splat_x(x0); + v1 = glmm_splat_y(x0); + v2 = glmm_splat_z(x0); + v3 = glmm_splat_w(x0); + + x1 = wasm_f32x4_mul(m3, v3); + x1 = glmm_fmadd(m2, v2, x1); + x1 = glmm_fmadd(m1, v1, x1); + x1 = glmm_fmadd(m0, v0, x1); + + glmm_store(dest, x1); +} + +CGLM_INLINE +float +glm_mat4_det_sse2(mat4 mat) { + glmm_128 r0, r1, r2, r3, x0, x1, x2; + + /* 127 <- 0, [square] det(A) = det(At) */ + r0 = glmm_load(mat[0]); /* d c b a */ + r1 = glmm_load(mat[1]); /* h g f e */ + r2 = glmm_load(mat[2]); /* l k j i */ + r3 = glmm_load(mat[3]); /* p o n m */ + + /* + t[1] = j * p - n * l; + t[2] = j * o - n * k; + t[3] = i * p - m * l; + t[4] = i * o - m * k; + */ + x0 = glmm_fnmadd(glmm_shuff1(r3, 0, 0, 1, 1), glmm_shuff1(r2, 2, 3, 2, 3), + wasm_f32x4_mul(glmm_shuff1(r2, 0, 0, 1, 1), + glmm_shuff1(r3, 2, 3, 2, 3))); + /* + t[0] = k * p - o * l; + t[0] = k * p - o * l; + t[5] = i * n - m * j; + t[5] = i * n - m * j; + */ + x1 = glmm_fnmadd(glmm_shuff1(r3, 0, 0, 2, 2), glmm_shuff1(r2, 1, 1, 3, 3), + wasm_f32x4_mul(glmm_shuff1(r2, 0, 0, 2, 2), + glmm_shuff1(r3, 1, 1, 3, 3))); + + /* + a * (f * t[0] - g * t[1] + h * t[2]) + - b * (e * t[0] - g * t[3] + h * t[4]) + + c * (e * t[1] - f * t[3] + h * t[5]) + - d * (e * t[2] - f * t[4] + g * t[5]) + */ + x2 = glmm_fnmadd(glmm_shuff1(r1, 1, 1, 2, 2), glmm_shuff1(x0, 3, 2, 2, 0), + wasm_f32x4_mul(glmm_shuff1(r1, 0, 0, 0, 1), + _mm_shuffle_ps(x1, x0, _MM_SHUFFLE(1, 0, 0, 0)))); + x2 = glmm_fmadd(glmm_shuff1(r1, 2, 3, 3, 3), + _mm_shuffle_ps(x0, x1, _MM_SHUFFLE(2, 2, 3, 1)), + x2); + + x2 = _mm_xor_ps(x2, _mm_set_ps(-0.f, 0.f, -0.f, 0.f)); + + return glmm_hadd(wasm_f32x4_mul(x2, r0)); +} + +CGLM_INLINE +void +glm_mat4_inv_fast_sse2(mat4 mat, mat4 dest) { + glmm_128 r0, r1, r2, r3, + v0, v1, v2, v3, + t0, t1, t2, t3, t4, t5, + x0, x1, x2, x3, x4, x5, x6, x7, x8, x9; + + x8 = wasm_f32x4_make(-0.f, 0.f, -0.f, 0.f); + x9 = glmm_shuff1(x8, 2, 1, 2, 1); + + /* 127 <- 0 */ + r0 = glmm_load(mat[0]); /* d c b a */ + r1 = glmm_load(mat[1]); /* h g f e */ + r2 = glmm_load(mat[2]); /* l k j i */ + r3 = glmm_load(mat[3]); /* p o n m */ + + x0 = _mm_movehl_ps(r3, r2); /* p o l k */ + x3 = _mm_movelh_ps(r2, r3); /* n m j i */ + x1 = glmm_shuff1(x0, 1, 3, 3 ,3); /* l p p p */ + x2 = glmm_shuff1(x0, 0, 2, 2, 2); /* k o o o */ + x4 = glmm_shuff1(x3, 1, 3, 3, 3); /* j n n n */ + x7 = glmm_shuff1(x3, 0, 2, 2, 2); /* i m m m */ + + x6 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(0, 0, 0, 0)); /* e e i i */ + x5 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(1, 1, 1, 1)); /* f f j j */ + x3 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(2, 2, 2, 2)); /* g g k k */ + x0 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(3, 3, 3, 3)); /* h h l l */ + + t0 = wasm_f32x4_mul(x3, x1); + t1 = wasm_f32x4_mul(x5, x1); + t2 = wasm_f32x4_mul(x5, x2); + t3 = wasm_f32x4_mul(x6, x1); + t4 = wasm_f32x4_mul(x6, x2); + t5 = wasm_f32x4_mul(x6, x4); + + /* t1[0] = k * p - o * l; + t1[0] = k * p - o * l; + t2[0] = g * p - o * h; + t3[0] = g * l - k * h; */ + t0 = glmm_fnmadd(x2, x0, t0); + + /* t1[1] = j * p - n * l; + t1[1] = j * p - n * l; + t2[1] = f * p - n * h; + t3[1] = f * l - j * h; */ + t1 = glmm_fnmadd(x4, x0, t1); + + /* t1[2] = j * o - n * k + t1[2] = j * o - n * k; + t2[2] = f * o - n * g; + t3[2] = f * k - j * g; */ + t2 = glmm_fnmadd(x4, x3, t2); + + /* t1[3] = i * p - m * l; + t1[3] = i * p - m * l; + t2[3] = e * p - m * h; + t3[3] = e * l - i * h; */ + t3 = glmm_fnmadd(x7, x0, t3); + + /* t1[4] = i * o - m * k; + t1[4] = i * o - m * k; + t2[4] = e * o - m * g; + t3[4] = e * k - i * g; */ + t4 = glmm_fnmadd(x7, x3, t4); + + /* t1[5] = i * n - m * j; + t1[5] = i * n - m * j; + t2[5] = e * n - m * f; + t3[5] = e * j - i * f; */ + t5 = glmm_fnmadd(x7, x5, t5); + + x4 = _mm_movelh_ps(r0, r1); /* f e b a */ + x5 = _mm_movehl_ps(r1, r0); /* h g d c */ + + x0 = glmm_shuff1(x4, 0, 0, 0, 2); /* a a a e */ + x1 = glmm_shuff1(x4, 1, 1, 1, 3); /* b b b f */ + x2 = glmm_shuff1(x5, 0, 0, 0, 2); /* c c c g */ + x3 = glmm_shuff1(x5, 1, 1, 1, 3); /* d d d h */ + + v2 = wasm_f32x4_mul(x0, t1); + v1 = wasm_f32x4_mul(x0, t0); + v3 = wasm_f32x4_mul(x0, t2); + v0 = wasm_f32x4_mul(x1, t0); + + v2 = glmm_fnmadd(x1, t3, v2); + v3 = glmm_fnmadd(x1, t4, v3); + v0 = glmm_fnmadd(x2, t1, v0); + v1 = glmm_fnmadd(x2, t3, v1); + + v3 = glmm_fmadd(x2, t5, v3); + v0 = glmm_fmadd(x3, t2, v0); + v2 = glmm_fmadd(x3, t5, v2); + v1 = glmm_fmadd(x3, t4, v1); + + /* + dest[0][0] = f * t1[0] - g * t1[1] + h * t1[2]; + dest[0][1] =-(b * t1[0] - c * t1[1] + d * t1[2]); + dest[0][2] = b * t2[0] - c * t2[1] + d * t2[2]; + dest[0][3] =-(b * t3[0] - c * t3[1] + d * t3[2]); */ + v0 = wasm_v128_xor(v0, x8); + + /* + dest[2][0] = e * t1[1] - f * t1[3] + h * t1[5]; + dest[2][1] =-(a * t1[1] - b * t1[3] + d * t1[5]); + dest[2][2] = a * t2[1] - b * t2[3] + d * t2[5]; + dest[2][3] =-(a * t3[1] - b * t3[3] + d * t3[5]);*/ + v2 = wasm_v128_xor(v2, x8); + + /* + dest[1][0] =-(e * t1[0] - g * t1[3] + h * t1[4]); + dest[1][1] = a * t1[0] - c * t1[3] + d * t1[4]; + dest[1][2] =-(a * t2[0] - c * t2[3] + d * t2[4]); + dest[1][3] = a * t3[0] - c * t3[3] + d * t3[4]; */ + v1 = wasm_v128_xor(v1, x9); + + /* + dest[3][0] =-(e * t1[2] - f * t1[4] + g * t1[5]); + dest[3][1] = a * t1[2] - b * t1[4] + c * t1[5]; + dest[3][2] =-(a * t2[2] - b * t2[4] + c * t2[5]); + dest[3][3] = a * t3[2] - b * t3[4] + c * t3[5]; */ + v3 = wasm_v128_xor(v3, x9); + + /* determinant */ + x0 = _mm_shuffle_ps(v0, v1, _MM_SHUFFLE(0, 0, 0, 0)); + x1 = _mm_shuffle_ps(v2, v3, _MM_SHUFFLE(0, 0, 0, 0)); + x0 = _mm_shuffle_ps(x0, x1, _MM_SHUFFLE(2, 0, 2, 0)); + + x0 = _mm_rcp_ps(glmm_vhadd(wasm_f32x4_mul(x0, r0))); + + glmm_store(dest[0], wasm_f32x4_mul(v0, x0)); + glmm_store(dest[1], wasm_f32x4_mul(v1, x0)); + glmm_store(dest[2], wasm_f32x4_mul(v2, x0)); + glmm_store(dest[3], wasm_f32x4_mul(v3, x0)); +} + +CGLM_INLINE +void +glm_mat4_inv_sse2(mat4 mat, mat4 dest) { + glmm_128 r0, r1, r2, r3, + v0, v1, v2, v3, + t0, t1, t2, t3, t4, t5, + x0, x1, x2, x3, x4, x5, x6, x7, x8, x9; + + x8 = _mm_set_ps(-0.f, 0.f, -0.f, 0.f); + x9 = glmm_shuff1(x8, 2, 1, 2, 1); + + /* 127 <- 0 */ + r0 = glmm_load(mat[0]); /* d c b a */ + r1 = glmm_load(mat[1]); /* h g f e */ + r2 = glmm_load(mat[2]); /* l k j i */ + r3 = glmm_load(mat[3]); /* p o n m */ + + x0 = _mm_movehl_ps(r3, r2); /* p o l k */ + x3 = _mm_movelh_ps(r2, r3); /* n m j i */ + x1 = glmm_shuff1(x0, 1, 3, 3 ,3); /* l p p p */ + x2 = glmm_shuff1(x0, 0, 2, 2, 2); /* k o o o */ + x4 = glmm_shuff1(x3, 1, 3, 3, 3); /* j n n n */ + x7 = glmm_shuff1(x3, 0, 2, 2, 2); /* i m m m */ + + x6 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(0, 0, 0, 0)); /* e e i i */ + x5 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(1, 1, 1, 1)); /* f f j j */ + x3 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(2, 2, 2, 2)); /* g g k k */ + x0 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(3, 3, 3, 3)); /* h h l l */ + + t0 = _mm_mul_ps(x3, x1); + t1 = _mm_mul_ps(x5, x1); + t2 = _mm_mul_ps(x5, x2); + t3 = _mm_mul_ps(x6, x1); + t4 = _mm_mul_ps(x6, x2); + t5 = _mm_mul_ps(x6, x4); + + /* t1[0] = k * p - o * l; + t1[0] = k * p - o * l; + t2[0] = g * p - o * h; + t3[0] = g * l - k * h; */ + t0 = glmm_fnmadd(x2, x0, t0); + + /* t1[1] = j * p - n * l; + t1[1] = j * p - n * l; + t2[1] = f * p - n * h; + t3[1] = f * l - j * h; */ + t1 = glmm_fnmadd(x4, x0, t1); + + /* t1[2] = j * o - n * k + t1[2] = j * o - n * k; + t2[2] = f * o - n * g; + t3[2] = f * k - j * g; */ + t2 = glmm_fnmadd(x4, x3, t2); + + /* t1[3] = i * p - m * l; + t1[3] = i * p - m * l; + t2[3] = e * p - m * h; + t3[3] = e * l - i * h; */ + t3 = glmm_fnmadd(x7, x0, t3); + + /* t1[4] = i * o - m * k; + t1[4] = i * o - m * k; + t2[4] = e * o - m * g; + t3[4] = e * k - i * g; */ + t4 = glmm_fnmadd(x7, x3, t4); + + /* t1[5] = i * n - m * j; + t1[5] = i * n - m * j; + t2[5] = e * n - m * f; + t3[5] = e * j - i * f; */ + t5 = glmm_fnmadd(x7, x5, t5); + + x4 = _mm_movelh_ps(r0, r1); /* f e b a */ + x5 = _mm_movehl_ps(r1, r0); /* h g d c */ + + x0 = glmm_shuff1(x4, 0, 0, 0, 2); /* a a a e */ + x1 = glmm_shuff1(x4, 1, 1, 1, 3); /* b b b f */ + x2 = glmm_shuff1(x5, 0, 0, 0, 2); /* c c c g */ + x3 = glmm_shuff1(x5, 1, 1, 1, 3); /* d d d h */ + + v2 = _mm_mul_ps(x0, t1); + v1 = _mm_mul_ps(x0, t0); + v3 = _mm_mul_ps(x0, t2); + v0 = _mm_mul_ps(x1, t0); + + v2 = glmm_fnmadd(x1, t3, v2); + v3 = glmm_fnmadd(x1, t4, v3); + v0 = glmm_fnmadd(x2, t1, v0); + v1 = glmm_fnmadd(x2, t3, v1); + + v3 = glmm_fmadd(x2, t5, v3); + v0 = glmm_fmadd(x3, t2, v0); + v2 = glmm_fmadd(x3, t5, v2); + v1 = glmm_fmadd(x3, t4, v1); + + /* + dest[0][0] = f * t1[0] - g * t1[1] + h * t1[2]; + dest[0][1] =-(b * t1[0] - c * t1[1] + d * t1[2]); + dest[0][2] = b * t2[0] - c * t2[1] + d * t2[2]; + dest[0][3] =-(b * t3[0] - c * t3[1] + d * t3[2]); */ + v0 = _mm_xor_ps(v0, x8); + + /* + dest[2][0] = e * t1[1] - f * t1[3] + h * t1[5]; + dest[2][1] =-(a * t1[1] - b * t1[3] + d * t1[5]); + dest[2][2] = a * t2[1] - b * t2[3] + d * t2[5]; + dest[2][3] =-(a * t3[1] - b * t3[3] + d * t3[5]);*/ + v2 = _mm_xor_ps(v2, x8); + + /* + dest[1][0] =-(e * t1[0] - g * t1[3] + h * t1[4]); + dest[1][1] = a * t1[0] - c * t1[3] + d * t1[4]; + dest[1][2] =-(a * t2[0] - c * t2[3] + d * t2[4]); + dest[1][3] = a * t3[0] - c * t3[3] + d * t3[4]; */ + v1 = _mm_xor_ps(v1, x9); + + /* + dest[3][0] =-(e * t1[2] - f * t1[4] + g * t1[5]); + dest[3][1] = a * t1[2] - b * t1[4] + c * t1[5]; + dest[3][2] =-(a * t2[2] - b * t2[4] + c * t2[5]); + dest[3][3] = a * t3[2] - b * t3[4] + c * t3[5]; */ + v3 = _mm_xor_ps(v3, x9); + + /* determinant */ + x0 = _mm_shuffle_ps(v0, v1, _MM_SHUFFLE(0, 0, 0, 0)); + x1 = _mm_shuffle_ps(v2, v3, _MM_SHUFFLE(0, 0, 0, 0)); + x0 = _mm_shuffle_ps(x0, x1, _MM_SHUFFLE(2, 0, 2, 0)); + + x0 = _mm_div_ps(_mm_set1_ps(1.0f), glmm_vhadd(_mm_mul_ps(x0, r0))); + + glmm_store(dest[0], _mm_mul_ps(v0, x0)); + glmm_store(dest[1], _mm_mul_ps(v1, x0)); + glmm_store(dest[2], _mm_mul_ps(v2, x0)); + glmm_store(dest[3], _mm_mul_ps(v3, x0)); +} + +#endif +#endif /* cglm_mat_wasm_h */ diff --git a/include/cglm/simd/wasm/quat.h b/include/cglm/simd/wasm/quat.h new file mode 100644 index 0000000..a052189 --- /dev/null +++ b/include/cglm/simd/wasm/quat.h @@ -0,0 +1,54 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +#ifndef cglm_quat_wasm_h +#define cglm_quat_wasm_h +#if defined(__wasm__) && defined(__wasm_simd128__) + +#include "../../common.h" +#include "../intrin.h" + +CGLM_INLINE +void +glm_quat_mul_sse2(versor p, versor q, versor dest) { + /* + + (a1 b2 + b1 a2 + c1 d2 − d1 c2)i + + (a1 c2 − b1 d2 + c1 a2 + d1 b2)j + + (a1 d2 + b1 c2 − c1 b2 + d1 a2)k + a1 a2 − b1 b2 − c1 c2 − d1 d2 + */ + + glmm_128 xp, xq, x1, x2, x3, r, x, y, z; + + xp = glmm_load(p); /* 3 2 1 0 */ + xq = glmm_load(q); + x1 = wasm_f32x4_make(-0.f, 0.f, -0.f, 0.f); /* TODO: _mm_set1_ss() + shuff ? */ + r = wasm_f32x4_mul(glmm_splat_w(xp), xq); + + x2 = _mm_unpackhi_ps(x1, x1); + x3 = glmm_shuff1(x1, 3, 2, 0, 1); + x = glmm_splat_x(xp); + y = glmm_splat_y(xp); + z = glmm_splat_z(xp); + + x = wasm_v128_xor(x, x1); + y = wasm_v128_xor(y, x2); + z = wasm_v128_xor(z, x3); + + x1 = glmm_shuff1(xq, 0, 1, 2, 3); + x2 = glmm_shuff1(xq, 1, 0, 3, 2); + x3 = glmm_shuff1(xq, 2, 3, 0, 1); + + r = glmm_fmadd(x, x1, r); + r = glmm_fmadd(y, x2, r); + r = glmm_fmadd(z, x3, r); + + glmm_store(dest, r); +} + +#endif +#endif /* cglm_quat_wasm_h */ From 2bc9573e1a238d4480d64574c59821be0aa486e9 Mon Sep 17 00:00:00 2001 From: myfreeer Date: Mon, 6 Mar 2023 16:08:50 +0800 Subject: [PATCH 02/34] simd128: include a fix --- include/cglm/simd/wasm.h | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/include/cglm/simd/wasm.h b/include/cglm/simd/wasm.h index dfb9490..be94a92 100644 --- a/include/cglm/simd/wasm.h +++ b/include/cglm/simd/wasm.h @@ -10,8 +10,17 @@ #define glmm_set1(x) wasm_f32x4_splat(x) #define glmm_128 v128_t -#define glmm_shuffle(a, b, z, y, x, w) wasm_i32x4_shuffle(a, b, z, y, x, w) -#define glmm_shuff1(xmm, z, y, x, w) wasm_i32x4_shuffle(xmm, xmm, z, y, x, w) + +#define _MM_SHUFFLE(w, z, y, x) (((w) << 6) | ((z) << 4) | ((y) << 2) | (x)) + +#define _mm_shuffle_ps(__a, __b, __mask) \ + ((glmm_128)wasm_i32x4_shuffle(__a, __b, \ + (((__mask) >> 0) & 0x3) + 0, \ + (((__mask) >> 2) & 0x3) + 0, \ + (((__mask) >> 4) & 0x3) + 4, \ + (((__mask) >> 6) & 0x3) + 4)) + +#define glmm_shuff1(xmm, z, y, x, w) _mm_shuffle_ps(xmm, xmm, _MM_SHUFFLE(z, y, x, w)) #define glmm_splat(x, lane) glmm_shuff1(x, lane, lane, lane, lane) @@ -21,7 +30,8 @@ #define glmm_splat_w(x) glmm_splat(x, 3) #define glmm_shuff2(a, b, z0, y0, x0, w0, z1, y1, x1, w1) \ - glmm_shuff1(wasm_i32x4_shuffle(a, b, z0, y0, x0, w0), z1, y1, x1, w1) + glmm_shuff1(_mm_shuffle_ps(a, b, _MM_SHUFFLE(z0, y0, x0, w0)), \ + z1, y1, x1, w1) #define _mm_cvtss_f32(v) wasm_f32x4_extract_lane(v, 0) @@ -86,7 +96,7 @@ glmm_vhadds(glmm_128 v) { glmm_128 shuf, sums; shuf = glmm_shuff1(v, 2, 3, 0, 1); sums = wasm_f32x4_add(v, shuf); - shuf = wasm_i32x4_shuffle(shuf, sums, 6, 7, 2, 3); + shuf = _mm_movehl_ps(shuf, sums); sums = wasm_f32x4_add(sums, shuf); return sums; } From da5f18f10f5021cfd26c2d1d3f203a9085075e23 Mon Sep 17 00:00:00 2001 From: myfreeer Date: Mon, 6 Mar 2023 16:18:33 +0800 Subject: [PATCH 03/34] simd128: fix tests for glm_inv_tr --- include/cglm/simd/wasm.h | 28 ++++++++++++++++++++++++++-- include/cglm/simd/wasm/affine.h | 2 +- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/include/cglm/simd/wasm.h b/include/cglm/simd/wasm.h index be94a92..2e45593 100644 --- a/include/cglm/simd/wasm.h +++ b/include/cglm/simd/wasm.h @@ -59,6 +59,30 @@ _mm_movelh_ps(glmm_128 __a, glmm_128 __b) return wasm_i32x4_shuffle(__a, __b, 0, 1, 4, 5); } +static __inline__ glmm_128 __attribute__((__always_inline__, __nodebug__)) +_mm_move_ss(glmm_128 __a, glmm_128 __b) +{ + return (glmm_128)wasm_i32x4_shuffle(__a, __b, 4, 1, 2, 3); +} + +static __inline__ glmm_128 __attribute__((__always_inline__, __nodebug__)) +_mm_add_ps(glmm_128 __a, glmm_128 __b) +{ + return (glmm_128)wasm_f32x4_add((glmm_128)__a, (glmm_128)__b); +} + +static __inline__ glmm_128 __attribute__((__always_inline__, __nodebug__)) +_mm_add_ss(glmm_128 __a, glmm_128 __b) +{ + return _mm_move_ss(__a, _mm_add_ps(__a, __b)); +} + +static __inline__ glmm_128 __attribute__((__always_inline__, __nodebug__)) +_mm_set_ps(float __z, float __y, float __x, float __w) +{ + return (glmm_128)wasm_f32x4_make(__w, __x, __y, __z); +} + #define _MM_TRANSPOSE4_PS(row0, row1, row2, row3) \ do { \ glmm_128 __row0 = (row0); \ @@ -97,7 +121,7 @@ glmm_vhadds(glmm_128 v) { shuf = glmm_shuff1(v, 2, 3, 0, 1); sums = wasm_f32x4_add(v, shuf); shuf = _mm_movehl_ps(shuf, sums); - sums = wasm_f32x4_add(sums, shuf); + sums = _mm_add_ss(sums, shuf); return sums; } @@ -130,7 +154,7 @@ glmm_vhmax(glmm_128 v) { x0 = glmm_shuff1(v, 2, 3, 2, 3); /* [2, 3, 2, 3] */ x1 = wasm_f32x4_pmax(x0, v); /* [0|2, 1|3, 2|2, 3|3] */ x2 = glmm_splat(x1, 1); /* [1|3, 1|3, 1|3, 1|3] */ - return wasm_f32x4_pmax(x1, x2); + return _mm_move_ss(x1, wasm_f32x4_pmax(x1, x2)); } static inline diff --git a/include/cglm/simd/wasm/affine.h b/include/cglm/simd/wasm/affine.h index ca520b9..b0919f5 100644 --- a/include/cglm/simd/wasm/affine.h +++ b/include/cglm/simd/wasm/affine.h @@ -91,7 +91,7 @@ glm_inv_tr_wasm(mat4 mat) { r1 = glmm_load(mat[1]); r2 = glmm_load(mat[2]); r3 = glmm_load(mat[3]); - x1 = wasm_f32x4_make(1.0f, 0.0f, 0.0f, 0.0f); + x1 = _mm_set_ps(1.0f, 0.0f, 0.0f, 0.0f); _MM_TRANSPOSE4_PS(r0, r1, r2, x1); From 5d60c17435b1cdfddf02b1a0a739110271acdc00 Mon Sep 17 00:00:00 2001 From: myfreeer Date: Mon, 6 Mar 2023 16:23:51 +0800 Subject: [PATCH 04/34] simd128: fix tests for vec4_norm_one and vec4_norm_inf --- include/cglm/simd/wasm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/cglm/simd/wasm.h b/include/cglm/simd/wasm.h index 2e45593..a915164 100644 --- a/include/cglm/simd/wasm.h +++ b/include/cglm/simd/wasm.h @@ -102,7 +102,7 @@ _mm_set_ps(float __z, float __y, float __x, float __w) static inline glmm_128 glmm_abs(glmm_128 x) { - return wasm_v128_andnot(wasm_f32x4_splat(-0.0f), x); + return wasm_v128_andnot(x, wasm_f32x4_splat(-0.0f)); } static inline From 84c521c2039cd0636d00e5a4314faa4ece99d6f9 Mon Sep 17 00:00:00 2001 From: myfreeer Date: Mon, 6 Mar 2023 16:40:45 +0800 Subject: [PATCH 05/34] simd128: enable in mat4 --- include/cglm/mat4.h | 30 +++++++++++++++++++ include/cglm/simd/wasm.h | 23 +++++++------- include/cglm/simd/wasm/mat4.h | 56 +++++++++++++++++------------------ 3 files changed, 70 insertions(+), 39 deletions(-) diff --git a/include/cglm/mat4.h b/include/cglm/mat4.h index c7c8abd..5eb2879 100644 --- a/include/cglm/mat4.h +++ b/include/cglm/mat4.h @@ -64,6 +64,10 @@ # include "simd/neon/mat4.h" #endif +#ifdef CGLM_SIMD_WASM +# include "simd/wasm/mat4.h" +#endif + #ifdef DEBUG # include #endif @@ -129,6 +133,11 @@ glm_mat4_copy(mat4 mat, mat4 dest) { glmm_store(dest[1], glmm_load(mat[1])); glmm_store(dest[2], glmm_load(mat[2])); glmm_store(dest[3], glmm_load(mat[3])); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glmm_store(dest[0], glmm_load(mat[0])); + glmm_store(dest[1], glmm_load(mat[1])); + glmm_store(dest[2], glmm_load(mat[2])); + glmm_store(dest[3], glmm_load(mat[3])); #elif defined(CGLM_NEON_FP) vst1q_f32(dest[0], vld1q_f32(mat[0])); vst1q_f32(dest[1], vld1q_f32(mat[1])); @@ -199,6 +208,13 @@ glm_mat4_zero(mat4 mat) { glmm_store(mat[1], x0); glmm_store(mat[2], x0); glmm_store(mat[3], x0); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glmm_128 x0; + x0 = wasm_f32x4_const(0.f, 0.f, 0.f, 0.f); + glmm_store(mat[0], x0); + glmm_store(mat[1], x0); + glmm_store(mat[2], x0); + glmm_store(mat[3], x0); #elif defined(CGLM_NEON_FP) glmm_128 x0; x0 = vdupq_n_f32(0.0f); @@ -301,6 +317,8 @@ glm_mat4_mul(mat4 m1, mat4 m2, mat4 dest) { glm_mat4_mul_avx(m1, m2, dest); #elif defined( __SSE__ ) || defined( __SSE2__ ) glm_mat4_mul_sse2(m1, m2, dest); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glm_mat4_mul_wasm(m1, m2, dest); #elif defined(CGLM_NEON_FP) glm_mat4_mul_neon(m1, m2, dest); #else @@ -379,6 +397,8 @@ void glm_mat4_mulv(mat4 m, vec4 v, vec4 dest) { #if defined( __SSE__ ) || defined( __SSE2__ ) glm_mat4_mulv_sse2(m, v, dest); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glm_mat4_mulv_wasm(m, v, dest); #elif defined(CGLM_NEON_FP) glm_mat4_mulv_neon(m, v, dest); #else @@ -499,6 +519,8 @@ void glm_mat4_transpose_to(mat4 m, mat4 dest) { #if defined( __SSE__ ) || defined( __SSE2__ ) glm_mat4_transp_sse2(m, dest); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glm_mat4_transp_wasm(m, dest); #elif defined(CGLM_NEON_FP) glm_mat4_transp_neon(m, dest); #else @@ -523,6 +545,8 @@ void glm_mat4_transpose(mat4 m) { #if defined( __SSE__ ) || defined( __SSE2__ ) glm_mat4_transp_sse2(m, m); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glm_mat4_transp_wasm(m, m); #elif defined(CGLM_NEON_FP) glm_mat4_transp_neon(m, m); #else @@ -564,6 +588,8 @@ glm_mat4_scale(mat4 m, float s) { glm_mat4_scale_avx(m, s); #elif defined( __SSE__ ) || defined( __SSE2__ ) glm_mat4_scale_sse2(m, s); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glm_mat4_scale_wasm(m, s); #elif defined(CGLM_NEON_FP) glm_mat4_scale_neon(m, s); #else @@ -583,6 +609,8 @@ float glm_mat4_det(mat4 mat) { #if defined( __SSE__ ) || defined( __SSE2__ ) return glm_mat4_det_sse2(mat); +#elif defined(__wasm__) && defined(__wasm_simd128__) + return glm_mat4_det_wasm(mat); #elif defined(CGLM_NEON_FP) return glm_mat4_det_neon(mat); #else @@ -681,6 +709,8 @@ void glm_mat4_inv_fast(mat4 mat, mat4 dest) { #if defined( __SSE__ ) || defined( __SSE2__ ) glm_mat4_inv_fast_sse2(mat, dest); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glm_mat4_inv_fast_wasm(mat, dest); #else glm_mat4_inv(mat, dest); #endif diff --git a/include/cglm/simd/wasm.h b/include/cglm/simd/wasm.h index a915164..87c350e 100644 --- a/include/cglm/simd/wasm.h +++ b/include/cglm/simd/wasm.h @@ -83,6 +83,18 @@ _mm_set_ps(float __z, float __y, float __x, float __w) return (glmm_128)wasm_f32x4_make(__w, __x, __y, __z); } +static inline glmm_128 __attribute__((__always_inline__, __nodebug__)) +_mm_sqrt_ss(glmm_128 __a) +{ + return wasm_i32x4_shuffle(__a, wasm_f32x4_sqrt(__a), 4, 1, 2, 3); +} + +static __inline__ glmm_128 __attribute__((__always_inline__, __nodebug__)) +_mm_rcp_ps(glmm_128 __a) +{ + return (glmm_128)wasm_f32x4_div((v128_t)wasm_f32x4_splat(1.0f), (v128_t)__a); +} + #define _MM_TRANSPOSE4_PS(row0, row1, row2, row3) \ do { \ glmm_128 __row0 = (row0); \ @@ -184,12 +196,6 @@ glmm_dot(glmm_128 a, glmm_128 b) { return _mm_cvtss_f32(glmm_vdots(a, b)); } -static inline glmm_128 __attribute__((__always_inline__, __nodebug__)) -_mm_sqrt_ss(glmm_128 __a) -{ - return wasm_i32x4_shuffle(__a, wasm_f32x4_sqrt(__a), 4, 1, 2, 3); -} - static inline float glmm_norm(glmm_128 a) { @@ -234,11 +240,6 @@ glmm_div(glmm_128 a, glmm_128 b) { return wasm_f32x4_div(a, b); } -/* enable FMA macro for MSVC? */ -#if defined(_MSC_VER) && !defined(__FMA__) && defined(__AVX2__) -# define __FMA__ 1 -#endif - static inline glmm_128 glmm_fmadd(glmm_128 a, glmm_128 b, glmm_128 c) { diff --git a/include/cglm/simd/wasm/mat4.h b/include/cglm/simd/wasm/mat4.h index ac451af..a1d13ea 100644 --- a/include/cglm/simd/wasm/mat4.h +++ b/include/cglm/simd/wasm/mat4.h @@ -12,11 +12,11 @@ #include "../../common.h" #include "../intrin.h" -#define glm_mat4_inv_precise_sse2(mat, dest) glm_mat4_inv_sse2(mat, dest) +#define glm_mat4_inv_precise_wasm(mat, dest) glm_mat4_inv_wasm(mat, dest) CGLM_INLINE void -glm_mat4_scale_sse2(mat4 m, float s) { +glm_mat4_scale_wasm(mat4 m, float s) { glmm_128 x0; x0 = wasm_f32x4_splat(s); @@ -28,7 +28,7 @@ glm_mat4_scale_sse2(mat4 m, float s) { CGLM_INLINE void -glm_mat4_transp_sse2(mat4 m, mat4 dest) { +glm_mat4_transp_wasm(mat4 m, mat4 dest) { glmm_128 r0, r1, r2, r3; r0 = glmm_load(m[0]); @@ -46,7 +46,7 @@ glm_mat4_transp_sse2(mat4 m, mat4 dest) { CGLM_INLINE void -glm_mat4_mul_sse2(mat4 m1, mat4 m2, mat4 dest) { +glm_mat4_mul_wasm(mat4 m1, mat4 m2, mat4 dest) { /* D = R * L (Column-Major) */ glmm_128 l, r0, r1, r2, r3, v0, v1, v2, v3; @@ -88,7 +88,7 @@ glm_mat4_mul_sse2(mat4 m1, mat4 m2, mat4 dest) { CGLM_INLINE void -glm_mat4_mulv_sse2(mat4 m, vec4 v, vec4 dest) { +glm_mat4_mulv_wasm(mat4 m, vec4 v, vec4 dest) { glmm_128 x0, x1, m0, m1, m2, m3, v0, v1, v2, v3; m0 = glmm_load(m[0]); @@ -112,7 +112,7 @@ glm_mat4_mulv_sse2(mat4 m, vec4 v, vec4 dest) { CGLM_INLINE float -glm_mat4_det_sse2(mat4 mat) { +glm_mat4_det_wasm(mat4 mat) { glmm_128 r0, r1, r2, r3, x0, x1, x2; /* 127 <- 0, [square] det(A) = det(At) */ @@ -153,14 +153,14 @@ glm_mat4_det_sse2(mat4 mat) { _mm_shuffle_ps(x0, x1, _MM_SHUFFLE(2, 2, 3, 1)), x2); - x2 = _mm_xor_ps(x2, _mm_set_ps(-0.f, 0.f, -0.f, 0.f)); + x2 = wasm_v128_xor(x2, _mm_set_ps(-0.f, 0.f, -0.f, 0.f)); return glmm_hadd(wasm_f32x4_mul(x2, r0)); } CGLM_INLINE void -glm_mat4_inv_fast_sse2(mat4 mat, mat4 dest) { +glm_mat4_inv_fast_wasm(mat4 mat, mat4 dest) { glmm_128 r0, r1, r2, r3, v0, v1, v2, v3, t0, t1, t2, t3, t4, t5, @@ -296,7 +296,7 @@ glm_mat4_inv_fast_sse2(mat4 mat, mat4 dest) { CGLM_INLINE void -glm_mat4_inv_sse2(mat4 mat, mat4 dest) { +glm_mat4_inv_wasm(mat4 mat, mat4 dest) { glmm_128 r0, r1, r2, r3, v0, v1, v2, v3, t0, t1, t2, t3, t4, t5, @@ -323,12 +323,12 @@ glm_mat4_inv_sse2(mat4 mat, mat4 dest) { x3 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(2, 2, 2, 2)); /* g g k k */ x0 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(3, 3, 3, 3)); /* h h l l */ - t0 = _mm_mul_ps(x3, x1); - t1 = _mm_mul_ps(x5, x1); - t2 = _mm_mul_ps(x5, x2); - t3 = _mm_mul_ps(x6, x1); - t4 = _mm_mul_ps(x6, x2); - t5 = _mm_mul_ps(x6, x4); + t0 = wasm_f32x4_mul(x3, x1); + t1 = wasm_f32x4_mul(x5, x1); + t2 = wasm_f32x4_mul(x5, x2); + t3 = wasm_f32x4_mul(x6, x1); + t4 = wasm_f32x4_mul(x6, x2); + t5 = wasm_f32x4_mul(x6, x4); /* t1[0] = k * p - o * l; t1[0] = k * p - o * l; @@ -374,10 +374,10 @@ glm_mat4_inv_sse2(mat4 mat, mat4 dest) { x2 = glmm_shuff1(x5, 0, 0, 0, 2); /* c c c g */ x3 = glmm_shuff1(x5, 1, 1, 1, 3); /* d d d h */ - v2 = _mm_mul_ps(x0, t1); - v1 = _mm_mul_ps(x0, t0); - v3 = _mm_mul_ps(x0, t2); - v0 = _mm_mul_ps(x1, t0); + v2 = wasm_f32x4_mul(x0, t1); + v1 = wasm_f32x4_mul(x0, t0); + v3 = wasm_f32x4_mul(x0, t2); + v0 = wasm_f32x4_mul(x1, t0); v2 = glmm_fnmadd(x1, t3, v2); v3 = glmm_fnmadd(x1, t4, v3); @@ -394,40 +394,40 @@ glm_mat4_inv_sse2(mat4 mat, mat4 dest) { dest[0][1] =-(b * t1[0] - c * t1[1] + d * t1[2]); dest[0][2] = b * t2[0] - c * t2[1] + d * t2[2]; dest[0][3] =-(b * t3[0] - c * t3[1] + d * t3[2]); */ - v0 = _mm_xor_ps(v0, x8); + v0 = wasm_v128_xor(v0, x8); /* dest[2][0] = e * t1[1] - f * t1[3] + h * t1[5]; dest[2][1] =-(a * t1[1] - b * t1[3] + d * t1[5]); dest[2][2] = a * t2[1] - b * t2[3] + d * t2[5]; dest[2][3] =-(a * t3[1] - b * t3[3] + d * t3[5]);*/ - v2 = _mm_xor_ps(v2, x8); + v2 = wasm_v128_xor(v2, x8); /* dest[1][0] =-(e * t1[0] - g * t1[3] + h * t1[4]); dest[1][1] = a * t1[0] - c * t1[3] + d * t1[4]; dest[1][2] =-(a * t2[0] - c * t2[3] + d * t2[4]); dest[1][3] = a * t3[0] - c * t3[3] + d * t3[4]; */ - v1 = _mm_xor_ps(v1, x9); + v1 = wasm_v128_xor(v1, x9); /* dest[3][0] =-(e * t1[2] - f * t1[4] + g * t1[5]); dest[3][1] = a * t1[2] - b * t1[4] + c * t1[5]; dest[3][2] =-(a * t2[2] - b * t2[4] + c * t2[5]); dest[3][3] = a * t3[2] - b * t3[4] + c * t3[5]; */ - v3 = _mm_xor_ps(v3, x9); + v3 = wasm_v128_xor(v3, x9); /* determinant */ x0 = _mm_shuffle_ps(v0, v1, _MM_SHUFFLE(0, 0, 0, 0)); x1 = _mm_shuffle_ps(v2, v3, _MM_SHUFFLE(0, 0, 0, 0)); x0 = _mm_shuffle_ps(x0, x1, _MM_SHUFFLE(2, 0, 2, 0)); - x0 = _mm_div_ps(_mm_set1_ps(1.0f), glmm_vhadd(_mm_mul_ps(x0, r0))); + x0 = wasm_f32x4_div(wasm_f32x4_splat(1.0f), glmm_vhadd(wasm_f32x4_mul(x0, r0))); - glmm_store(dest[0], _mm_mul_ps(v0, x0)); - glmm_store(dest[1], _mm_mul_ps(v1, x0)); - glmm_store(dest[2], _mm_mul_ps(v2, x0)); - glmm_store(dest[3], _mm_mul_ps(v3, x0)); + glmm_store(dest[0], wasm_f32x4_mul(v0, x0)); + glmm_store(dest[1], wasm_f32x4_mul(v1, x0)); + glmm_store(dest[2], wasm_f32x4_mul(v2, x0)); + glmm_store(dest[3], wasm_f32x4_mul(v3, x0)); } #endif From a0dd85f3d1f9b66c2cbb40b29f0b3ccd529b4c29 Mon Sep 17 00:00:00 2001 From: myfreeer Date: Mon, 6 Mar 2023 16:46:48 +0800 Subject: [PATCH 06/34] simd128: enable in quat --- include/cglm/quat.h | 20 ++++++++++++++++++++ include/cglm/simd/wasm/quat.h | 4 ++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/include/cglm/quat.h b/include/cglm/quat.h index c76fa03..cec3a90 100644 --- a/include/cglm/quat.h +++ b/include/cglm/quat.h @@ -70,6 +70,10 @@ # include "simd/neon/quat.h" #endif +#ifdef CGLM_SIMD_WASM +# include "simd/wasm/quat.h" +#endif + CGLM_INLINE void glm_quat_normalize(versor q); /* @@ -252,6 +256,20 @@ glm_quat_normalize_to(versor q, versor dest) { } glmm_store(dest, _mm_div_ps(x0, _mm_sqrt_ps(xdot))); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glmm_128 xdot, x0; + float dot; + + x0 = glmm_load(q); + xdot = glmm_vdot(x0, x0); + dot = _mm_cvtss_f32(xdot); + + if (dot <= 0.0f) { + glm_quat_identity(dest); + return; + } + + glmm_store(dest, wasm_f32x4_div(x0, wasm_f32x4_sqrt(xdot))); #else float dot; @@ -440,6 +458,8 @@ glm_quat_mul(versor p, versor q, versor dest) { */ #if defined( __SSE__ ) || defined( __SSE2__ ) glm_quat_mul_sse2(p, q, dest); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glm_quat_mul_wasm(p, q, dest); #elif defined(CGLM_NEON_FP) glm_quat_mul_neon(p, q, dest); #else diff --git a/include/cglm/simd/wasm/quat.h b/include/cglm/simd/wasm/quat.h index a052189..8367214 100644 --- a/include/cglm/simd/wasm/quat.h +++ b/include/cglm/simd/wasm/quat.h @@ -14,7 +14,7 @@ CGLM_INLINE void -glm_quat_mul_sse2(versor p, versor q, versor dest) { +glm_quat_mul_wasm(versor p, versor q, versor dest) { /* + (a1 b2 + b1 a2 + c1 d2 − d1 c2)i + (a1 c2 − b1 d2 + c1 a2 + d1 b2)j @@ -26,7 +26,7 @@ glm_quat_mul_sse2(versor p, versor q, versor dest) { xp = glmm_load(p); /* 3 2 1 0 */ xq = glmm_load(q); - x1 = wasm_f32x4_make(-0.f, 0.f, -0.f, 0.f); /* TODO: _mm_set1_ss() + shuff ? */ + x1 = _mm_set_ps(-0.f, 0.f, -0.f, 0.f); /* TODO: _mm_set1_ss() + shuff ? */ r = wasm_f32x4_mul(glmm_splat_w(xp), xq); x2 = _mm_unpackhi_ps(x1, x1); From fdef58bd1aef34b8d401579fd44f2b7f3dea9c26 Mon Sep 17 00:00:00 2001 From: myfreeer Date: Mon, 6 Mar 2023 16:50:37 +0800 Subject: [PATCH 07/34] simd128: enable in mat3 --- include/cglm/mat3.h | 6 ++++++ include/cglm/simd/wasm.h | 17 ++++++++++++++++- include/cglm/simd/wasm/mat3.h | 4 ++-- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/include/cglm/mat3.h b/include/cglm/mat3.h index 0b29f97..cbfab30 100644 --- a/include/cglm/mat3.h +++ b/include/cglm/mat3.h @@ -42,6 +42,10 @@ # include "simd/sse2/mat3.h" #endif +#ifdef CGLM_SIMD_WASM +# include "simd/wasm/mat3.h" +#endif + #define GLM_MAT3_IDENTITY_INIT {{1.0f, 0.0f, 0.0f}, \ {0.0f, 1.0f, 0.0f}, \ {0.0f, 0.0f, 1.0f}} @@ -150,6 +154,8 @@ void glm_mat3_mul(mat3 m1, mat3 m2, mat3 dest) { #if defined( __SSE__ ) || defined( __SSE2__ ) glm_mat3_mul_sse2(m1, m2, dest); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glm_mat3_mul_wasm(m1, m2, dest); #else float a00 = m1[0][0], a01 = m1[0][1], a02 = m1[0][2], a10 = m1[1][0], a11 = m1[1][1], a12 = m1[1][2], diff --git a/include/cglm/simd/wasm.h b/include/cglm/simd/wasm.h index 87c350e..5015ec9 100644 --- a/include/cglm/simd/wasm.h +++ b/include/cglm/simd/wasm.h @@ -92,7 +92,22 @@ _mm_sqrt_ss(glmm_128 __a) static __inline__ glmm_128 __attribute__((__always_inline__, __nodebug__)) _mm_rcp_ps(glmm_128 __a) { - return (glmm_128)wasm_f32x4_div((v128_t)wasm_f32x4_splat(1.0f), (v128_t)__a); + return (glmm_128)wasm_f32x4_div((glmm_128)wasm_f32x4_splat(1.0f), (glmm_128)__a); +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_storeu_ps(float *__p, glmm_128 __a) +{ + struct __unaligned { + glmm_128 __v; + } __attribute__((__packed__, __may_alias__)); + ((struct __unaligned *)__p)->__v = __a; +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_store_ss(float *__p, glmm_128 __a) +{ + wasm_v128_store32_lane((void*)__p, (glmm_128)__a, 0); } #define _MM_TRANSPOSE4_PS(row0, row1, row2, row3) \ diff --git a/include/cglm/simd/wasm/mat3.h b/include/cglm/simd/wasm/mat3.h index 6e57b8e..f4d8fed 100644 --- a/include/cglm/simd/wasm/mat3.h +++ b/include/cglm/simd/wasm/mat3.h @@ -27,13 +27,13 @@ glm_mat3_mul_wasm(mat3 m1, mat3 m2, mat3 dest) { x1 = glmm_shuff1(r0, 3, 0, 0, 0); /* b10 b00 b00 b00 */ x2 = _mm_shuffle_ps(l0, l1, _MM_SHUFFLE(1, 0, 3, 3)); /* a12 a11 a10 a10 */ x3 = _mm_shuffle_ps(r0, r1, _MM_SHUFFLE(2, 0, 3, 1)); /* b20 b11 b10 b01 */ - x0 = _mm_mul_ps(x8, x1); + x0 = wasm_f32x4_mul(x8, x1); x6 = glmm_shuff1(l0, 1, 0, 2, 1); /* a01 a00 a02 a01 */ x7 = glmm_shuff1(x3, 3, 3, 1, 1); /* b20 b20 b10 b10 */ l2 = wasm_v128_load32_zero(&m1[2][2]); r2 = wasm_v128_load32_zero(&m2[2][2]); - x1 = _mm_mul_ps(x6, x7); + x1 = wasm_f32x4_mul(x6, x7); l2 = glmm_shuff1(l2, 0, 0, 1, 0); /* a22 a22 0.f a22 */ r2 = glmm_shuff1(r2, 0, 0, 1, 0); /* b22 b22 0.f b22 */ From 6b7a63953c83c0eaf27a0d9a2e4b72ac84528963 Mon Sep 17 00:00:00 2001 From: myfreeer Date: Mon, 6 Mar 2023 16:52:05 +0800 Subject: [PATCH 08/34] simd128: enable in mat2 --- include/cglm/mat2.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/cglm/mat2.h b/include/cglm/mat2.h index 871d6bd..9f430fb 100644 --- a/include/cglm/mat2.h +++ b/include/cglm/mat2.h @@ -44,6 +44,10 @@ # include "simd/neon/mat2.h" #endif +#ifdef CGLM_SIMD_WASM +# include "simd/wasm/mat2.h" +#endif + #define GLM_MAT2_IDENTITY_INIT {{1.0f, 0.0f}, {0.0f, 1.0f}} #define GLM_MAT2_ZERO_INIT {{0.0f, 0.0f}, {0.0f, 0.0f}} @@ -134,6 +138,8 @@ void glm_mat2_mul(mat2 m1, mat2 m2, mat2 dest) { #if defined( __SSE__ ) || defined( __SSE2__ ) glm_mat2_mul_sse2(m1, m2, dest); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glm_mat2_mul_wasm(m1, m2, dest); #elif defined(CGLM_NEON_FP) glm_mat2_mul_neon(m1, m2, dest); #else From 71c585b159e56cbafaf28504321e46f278b97d71 Mon Sep 17 00:00:00 2001 From: myfreeer Date: Mon, 6 Mar 2023 17:07:45 +0800 Subject: [PATCH 09/34] simd128: enable in headers --- include/cglm/mat2.h | 4 +++ include/cglm/simd/wasm.h | 2 +- include/cglm/vec4-ext.h | 10 +++++++ include/cglm/vec4.h | 61 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 1 deletion(-) diff --git a/include/cglm/mat2.h b/include/cglm/mat2.h index 9f430fb..dc71185 100644 --- a/include/cglm/mat2.h +++ b/include/cglm/mat2.h @@ -168,6 +168,8 @@ void glm_mat2_transpose_to(mat2 m, mat2 dest) { #if defined( __SSE__ ) || defined( __SSE2__ ) glm_mat2_transp_sse2(m, dest); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glm_mat2_transp_wasm(m, dest); #else dest[0][0] = m[0][0]; dest[0][1] = m[1][0]; @@ -230,6 +232,8 @@ void glm_mat2_scale(mat2 m, float s) { #if defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(m[0], _mm_mul_ps(_mm_loadu_ps(m[0]), _mm_set1_ps(s))); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glmm_store(m[0], wasm_f32x4_mul(wasm_v128_load(m[0]), wasm_f32x4_splat(s))); #elif defined(CGLM_NEON_FP) vst1q_f32(m[0], vmulq_f32(vld1q_f32(m[0]), vdupq_n_f32(s))); #else diff --git a/include/cglm/simd/wasm.h b/include/cglm/simd/wasm.h index 5015ec9..f6403d1 100644 --- a/include/cglm/simd/wasm.h +++ b/include/cglm/simd/wasm.h @@ -6,7 +6,7 @@ #include #define glmm_load(p) wasm_v128_load(p) -#define glmm_store(p, a) wasm_v128_store(p, a) +#define glmm_store(p, a) wasm_v128_store(p, (a)) #define glmm_set1(x) wasm_f32x4_splat(x) #define glmm_128 v128_t diff --git a/include/cglm/vec4-ext.h b/include/cglm/vec4-ext.h index e4e20cb..06b6210 100644 --- a/include/cglm/vec4-ext.h +++ b/include/cglm/vec4-ext.h @@ -47,6 +47,8 @@ void glm_vec4_broadcast(float val, vec4 d) { #if defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(d, _mm_set1_ps(val)); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glmm_store(d, wasm_f32x4_splat(val)); #else d[0] = d[1] = d[2] = d[3] = val; #endif @@ -63,6 +65,8 @@ void glm_vec4_fill(vec4 v, float val) { #if defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(v, _mm_set1_ps(val)); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glmm_store(v, wasm_f32x4_splat(val)); #else v[0] = v[1] = v[2] = v[3] = val; #endif @@ -249,6 +253,8 @@ void glm_vec4_abs(vec4 v, vec4 dest) { #if defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(dest, glmm_abs(glmm_load(v))); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glmm_store(dest, glmm_abs(glmm_load(v))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vabsq_f32(vld1q_f32(v))); #else @@ -286,6 +292,8 @@ float glm_vec4_hadd(vec4 v) { #if defined( __SSE__ ) || defined( __SSE2__ ) return glmm_hadd(glmm_load(v)); +#elif defined(__wasm__) && defined(__wasm_simd128__) + return glmm_hadd(glmm_load(v)); #else return v[0] + v[1] + v[2] + v[3]; #endif @@ -302,6 +310,8 @@ void glm_vec4_sqrt(vec4 v, vec4 dest) { #if defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(dest, _mm_sqrt_ps(glmm_load(v))); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glmm_store(dest, wasm_f32x4_sqrt(glmm_load(v))); #else dest[0] = sqrtf(v[0]); dest[1] = sqrtf(v[1]); diff --git a/include/cglm/vec4.h b/include/cglm/vec4.h index 8e95ec5..587597e 100644 --- a/include/cglm/vec4.h +++ b/include/cglm/vec4.h @@ -139,6 +139,8 @@ void glm_vec4_copy(vec4 v, vec4 dest) { #if defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(dest, glmm_load(v)); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glmm_store(dest, glmm_load(v)); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vld1q_f32(v)); #else @@ -176,6 +178,8 @@ void glm_vec4_zero(vec4 v) { #if defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(v, _mm_setzero_ps()); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glmm_store(v, wasm_f32x4_const(0.f, 0.f, 0.f, 0.f)); #elif defined(CGLM_NEON_FP) vst1q_f32(v, vdupq_n_f32(0.0f)); #else @@ -196,6 +200,8 @@ void glm_vec4_one(vec4 v) { #if defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(v, _mm_set1_ps(1.0f)); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glmm_store(v, wasm_f32x4_splat(1.0f)); #elif defined(CGLM_NEON_FP) vst1q_f32(v, vdupq_n_f32(1.0f)); #else @@ -322,6 +328,8 @@ void glm_vec4_add(vec4 a, vec4 b, vec4 dest) { #if defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(dest, _mm_add_ps(glmm_load(a), glmm_load(b))); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glmm_store(dest, _mm_add_ps(glmm_load(a), glmm_load(b))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vaddq_f32(vld1q_f32(a), vld1q_f32(b))); #else @@ -344,6 +352,8 @@ void glm_vec4_adds(vec4 v, float s, vec4 dest) { #if defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(dest, _mm_add_ps(glmm_load(v), _mm_set1_ps(s))); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glmm_store(dest, wasm_f32x4_add(glmm_load(v), wasm_f32x4_splat(s))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vaddq_f32(vld1q_f32(v), vdupq_n_f32(s))); #else @@ -366,6 +376,8 @@ void glm_vec4_sub(vec4 a, vec4 b, vec4 dest) { #if defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(dest, _mm_sub_ps(glmm_load(a), glmm_load(b))); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glmm_store(dest, wasm_f32x4_sub(glmm_load(a), glmm_load(b))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vsubq_f32(vld1q_f32(a), vld1q_f32(b))); #else @@ -388,6 +400,8 @@ void glm_vec4_subs(vec4 v, float s, vec4 dest) { #if defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(dest, _mm_sub_ps(glmm_load(v), _mm_set1_ps(s))); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glmm_store(dest, wasm_f32x4_sub(glmm_load(v), wasm_f32x4_splat(s))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vsubq_f32(vld1q_f32(v), vdupq_n_f32(s))); #else @@ -432,6 +446,8 @@ void glm_vec4_scale(vec4 v, float s, vec4 dest) { #if defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(dest, _mm_mul_ps(glmm_load(v), _mm_set1_ps(s))); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glmm_store(dest, wasm_f32x4_mul(glmm_load(v), wasm_f32x4_splat(s))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vmulq_f32(vld1q_f32(v), vdupq_n_f32(s))); #else @@ -495,6 +511,8 @@ void glm_vec4_divs(vec4 v, float s, vec4 dest) { #if defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(dest, _mm_div_ps(glmm_load(v), _mm_set1_ps(s))); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glmm_store(dest, wasm_f32x4_div(glmm_load(v), wasm_f32x4_splat(s))); #else glm_vec4_scale(v, 1.0f / s, dest); #endif @@ -516,6 +534,10 @@ glm_vec4_addadd(vec4 a, vec4 b, vec4 dest) { glmm_store(dest, _mm_add_ps(glmm_load(dest), _mm_add_ps(glmm_load(a), glmm_load(b)))); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glmm_store(dest, wasm_f32x4_add(glmm_load(dest), + wasm_f32x4_add(glmm_load(a), + glmm_load(b)))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vaddq_f32(vld1q_f32(dest), vaddq_f32(vld1q_f32(a), @@ -544,6 +566,10 @@ glm_vec4_subadd(vec4 a, vec4 b, vec4 dest) { glmm_store(dest, _mm_add_ps(glmm_load(dest), _mm_sub_ps(glmm_load(a), glmm_load(b)))); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glmm_store(dest, wasm_f32x4_add(glmm_load(dest), + wasm_f32x4_sub(glmm_load(a), + glmm_load(b)))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vaddq_f32(vld1q_f32(dest), vsubq_f32(vld1q_f32(a), @@ -616,6 +642,10 @@ glm_vec4_maxadd(vec4 a, vec4 b, vec4 dest) { glmm_store(dest, _mm_add_ps(glmm_load(dest), _mm_max_ps(glmm_load(a), glmm_load(b)))); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glmm_store(dest, wasm_f32x4_add(glmm_load(dest), + wasm_f32x4_max(glmm_load(a), + glmm_load(b)))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vaddq_f32(vld1q_f32(dest), vmaxq_f32(vld1q_f32(a), @@ -644,6 +674,10 @@ glm_vec4_minadd(vec4 a, vec4 b, vec4 dest) { glmm_store(dest, _mm_add_ps(glmm_load(dest), _mm_min_ps(glmm_load(a), glmm_load(b)))); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glmm_store(dest, wasm_f32x4_add(glmm_load(dest), + wasm_f32x4_min(glmm_load(a), + glmm_load(b)))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vaddq_f32(vld1q_f32(dest), vminq_f32(vld1q_f32(a), @@ -667,6 +701,8 @@ void glm_vec4_negate_to(vec4 v, vec4 dest) { #if defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(dest, _mm_xor_ps(glmm_load(v), _mm_set1_ps(-0.0f))); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glmm_store(dest, wasm_v128_xor(glmm_load(v), wasm_f32x4_splat(-0.0f))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vnegq_f32(vld1q_f32(v))); #else @@ -711,6 +747,20 @@ glm_vec4_normalize_to(vec4 v, vec4 dest) { } glmm_store(dest, _mm_div_ps(x0, _mm_sqrt_ps(xdot))); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glmm_128 xdot, x0; + float dot; + + x0 = glmm_load(v); + xdot = glmm_vdot(x0, x0); + dot = _mm_cvtss_f32(xdot); + + if (dot == 0.0f) { + glmm_store(dest, wasm_f32x4_const(0.f, 0.f, 0.f, 0.f)); + return; + } + + glmm_store(dest, wasm_f32x4_div(x0, wasm_f32x4_sqrt(xdot))); #else float norm; @@ -748,6 +798,8 @@ float glm_vec4_distance(vec4 a, vec4 b) { #if defined( __SSE__ ) || defined( __SSE2__ ) return glmm_norm(_mm_sub_ps(glmm_load(a), glmm_load(b))); +#elif defined(__wasm__) && defined(__wasm_simd128__) + return glmm_norm(wasm_f32x4_sub(glmm_load(a), glmm_load(b))); #elif defined(CGLM_NEON_FP) return glmm_norm(vsubq_f32(glmm_load(a), glmm_load(b))); #else @@ -770,6 +822,8 @@ float glm_vec4_distance2(vec4 a, vec4 b) { #if defined( __SSE__ ) || defined( __SSE2__ ) return glmm_norm2(_mm_sub_ps(glmm_load(a), glmm_load(b))); +#elif defined(__wasm__) && defined(__wasm_simd128__) + return glmm_norm2(wasm_f32x4_sub(glmm_load(a), glmm_load(b))); #elif defined(CGLM_NEON_FP) return glmm_norm2(vsubq_f32(glmm_load(a), glmm_load(b))); #else @@ -792,6 +846,8 @@ void glm_vec4_maxv(vec4 a, vec4 b, vec4 dest) { #if defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(dest, _mm_max_ps(glmm_load(a), glmm_load(b))); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glmm_store(dest, wasm_f32x4_max(glmm_load(a), glmm_load(b))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vmaxq_f32(vld1q_f32(a), vld1q_f32(b))); #else @@ -814,6 +870,8 @@ void glm_vec4_minv(vec4 a, vec4 b, vec4 dest) { #if defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(dest, _mm_min_ps(glmm_load(a), glmm_load(b))); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glmm_store(dest, wasm_f32x4_min(glmm_load(a), glmm_load(b))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vminq_f32(vld1q_f32(a), vld1q_f32(b))); #else @@ -837,6 +895,9 @@ glm_vec4_clamp(vec4 v, float minVal, float maxVal) { #if defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(v, _mm_min_ps(_mm_max_ps(glmm_load(v), _mm_set1_ps(minVal)), _mm_set1_ps(maxVal))); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glmm_store(v, wasm_f32x4_min(wasm_f32x4_max(glmm_load(v), wasm_f32x4_splat(minVal)), + wasm_f32x4_splat(maxVal))); #elif defined(CGLM_NEON_FP) vst1q_f32(v, vminq_f32(vmaxq_f32(vld1q_f32(v), vdupq_n_f32(minVal)), vdupq_n_f32(maxVal))); From 03c7bee86386d0fd40a903471a1b43b5a8c190ee Mon Sep 17 00:00:00 2001 From: myfreeer Date: Sun, 19 Mar 2023 11:33:01 +0800 Subject: [PATCH 10/34] simd128: inline some functions --- include/cglm/simd/wasm.h | 28 +++------------------------- include/cglm/vec4.h | 2 +- 2 files changed, 4 insertions(+), 26 deletions(-) diff --git a/include/cglm/simd/wasm.h b/include/cglm/simd/wasm.h index f6403d1..9c7787f 100644 --- a/include/cglm/simd/wasm.h +++ b/include/cglm/simd/wasm.h @@ -29,10 +29,6 @@ #define glmm_splat_z(x) glmm_splat(x, 2) #define glmm_splat_w(x) glmm_splat(x, 3) -#define glmm_shuff2(a, b, z0, y0, x0, w0, z1, y1, x1, w1) \ - glmm_shuff1(_mm_shuffle_ps(a, b, _MM_SHUFFLE(z0, y0, x0, w0)), \ - z1, y1, x1, w1) - #define _mm_cvtss_f32(v) wasm_f32x4_extract_lane(v, 0) static inline glmm_128 __attribute__((__always_inline__, __nodebug__)) @@ -59,24 +55,6 @@ _mm_movelh_ps(glmm_128 __a, glmm_128 __b) return wasm_i32x4_shuffle(__a, __b, 0, 1, 4, 5); } -static __inline__ glmm_128 __attribute__((__always_inline__, __nodebug__)) -_mm_move_ss(glmm_128 __a, glmm_128 __b) -{ - return (glmm_128)wasm_i32x4_shuffle(__a, __b, 4, 1, 2, 3); -} - -static __inline__ glmm_128 __attribute__((__always_inline__, __nodebug__)) -_mm_add_ps(glmm_128 __a, glmm_128 __b) -{ - return (glmm_128)wasm_f32x4_add((glmm_128)__a, (glmm_128)__b); -} - -static __inline__ glmm_128 __attribute__((__always_inline__, __nodebug__)) -_mm_add_ss(glmm_128 __a, glmm_128 __b) -{ - return _mm_move_ss(__a, _mm_add_ps(__a, __b)); -} - static __inline__ glmm_128 __attribute__((__always_inline__, __nodebug__)) _mm_set_ps(float __z, float __y, float __x, float __w) { @@ -92,7 +70,7 @@ _mm_sqrt_ss(glmm_128 __a) static __inline__ glmm_128 __attribute__((__always_inline__, __nodebug__)) _mm_rcp_ps(glmm_128 __a) { - return (glmm_128)wasm_f32x4_div((glmm_128)wasm_f32x4_splat(1.0f), (glmm_128)__a); + return (glmm_128)wasm_f32x4_div((glmm_128)wasm_f32x4_splat(1.0f), (glmm_128)__a); } static __inline__ void __attribute__((__always_inline__, __nodebug__)) @@ -148,7 +126,7 @@ glmm_vhadds(glmm_128 v) { shuf = glmm_shuff1(v, 2, 3, 0, 1); sums = wasm_f32x4_add(v, shuf); shuf = _mm_movehl_ps(shuf, sums); - sums = _mm_add_ss(sums, shuf); + sums = wasm_i32x4_shuffle(sums, wasm_f32x4_add(sums, shuf), 4, 1, 2, 3); return sums; } @@ -181,7 +159,7 @@ glmm_vhmax(glmm_128 v) { x0 = glmm_shuff1(v, 2, 3, 2, 3); /* [2, 3, 2, 3] */ x1 = wasm_f32x4_pmax(x0, v); /* [0|2, 1|3, 2|2, 3|3] */ x2 = glmm_splat(x1, 1); /* [1|3, 1|3, 1|3, 1|3] */ - return _mm_move_ss(x1, wasm_f32x4_pmax(x1, x2)); + return (glmm_128) wasm_i32x4_shuffle(x1, wasm_f32x4_pmax(x1, x2), 4, 1, 2, 3); } static inline diff --git a/include/cglm/vec4.h b/include/cglm/vec4.h index 587597e..abe3aa3 100644 --- a/include/cglm/vec4.h +++ b/include/cglm/vec4.h @@ -329,7 +329,7 @@ glm_vec4_add(vec4 a, vec4 b, vec4 dest) { #if defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(dest, _mm_add_ps(glmm_load(a), glmm_load(b))); #elif defined(__wasm__) && defined(__wasm_simd128__) - glmm_store(dest, _mm_add_ps(glmm_load(a), glmm_load(b))); + glmm_store(dest, wasm_f32x4_add(glmm_load(a), glmm_load(b))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vaddq_f32(vld1q_f32(a), vld1q_f32(b))); #else From be76d96e8f725aa8041af978572c24543171e077 Mon Sep 17 00:00:00 2001 From: myfreeer Date: Sun, 19 Mar 2023 11:56:59 +0800 Subject: [PATCH 11/34] simd128: inline _mm_set_ps --- include/cglm/simd/wasm.h | 6 ------ include/cglm/simd/wasm/affine.h | 3 +-- include/cglm/simd/wasm/mat4.h | 6 +++--- include/cglm/simd/wasm/quat.h | 2 +- 4 files changed, 5 insertions(+), 12 deletions(-) diff --git a/include/cglm/simd/wasm.h b/include/cglm/simd/wasm.h index 9c7787f..a279df1 100644 --- a/include/cglm/simd/wasm.h +++ b/include/cglm/simd/wasm.h @@ -55,12 +55,6 @@ _mm_movelh_ps(glmm_128 __a, glmm_128 __b) return wasm_i32x4_shuffle(__a, __b, 0, 1, 4, 5); } -static __inline__ glmm_128 __attribute__((__always_inline__, __nodebug__)) -_mm_set_ps(float __z, float __y, float __x, float __w) -{ - return (glmm_128)wasm_f32x4_make(__w, __x, __y, __z); -} - static inline glmm_128 __attribute__((__always_inline__, __nodebug__)) _mm_sqrt_ss(glmm_128 __a) { diff --git a/include/cglm/simd/wasm/affine.h b/include/cglm/simd/wasm/affine.h index b0919f5..cbf8ce4 100644 --- a/include/cglm/simd/wasm/affine.h +++ b/include/cglm/simd/wasm/affine.h @@ -91,8 +91,7 @@ glm_inv_tr_wasm(mat4 mat) { r1 = glmm_load(mat[1]); r2 = glmm_load(mat[2]); r3 = glmm_load(mat[3]); - x1 = _mm_set_ps(1.0f, 0.0f, 0.0f, 0.0f); - + x1 = wasm_f32x4_const(0.0f, 0.0f, 0.0f, 1.0f); _MM_TRANSPOSE4_PS(r0, r1, r2, x1); x2 = glmm_shuff1(r3, 0, 0, 0, 0); diff --git a/include/cglm/simd/wasm/mat4.h b/include/cglm/simd/wasm/mat4.h index a1d13ea..aa696b1 100644 --- a/include/cglm/simd/wasm/mat4.h +++ b/include/cglm/simd/wasm/mat4.h @@ -153,7 +153,7 @@ glm_mat4_det_wasm(mat4 mat) { _mm_shuffle_ps(x0, x1, _MM_SHUFFLE(2, 2, 3, 1)), x2); - x2 = wasm_v128_xor(x2, _mm_set_ps(-0.f, 0.f, -0.f, 0.f)); + x2 = wasm_v128_xor(x2, wasm_f32x4_const(0.f, -0.f, 0.f, -0.f)); return glmm_hadd(wasm_f32x4_mul(x2, r0)); } @@ -166,7 +166,7 @@ glm_mat4_inv_fast_wasm(mat4 mat, mat4 dest) { t0, t1, t2, t3, t4, t5, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9; - x8 = wasm_f32x4_make(-0.f, 0.f, -0.f, 0.f); + x8 = wasm_f32x4_const(-0.f, 0.f, -0.f, 0.f); x9 = glmm_shuff1(x8, 2, 1, 2, 1); /* 127 <- 0 */ @@ -302,7 +302,7 @@ glm_mat4_inv_wasm(mat4 mat, mat4 dest) { t0, t1, t2, t3, t4, t5, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9; - x8 = _mm_set_ps(-0.f, 0.f, -0.f, 0.f); + x8 = wasm_f32x4_const(0.f, -0.f, 0.f, -0.f); x9 = glmm_shuff1(x8, 2, 1, 2, 1); /* 127 <- 0 */ diff --git a/include/cglm/simd/wasm/quat.h b/include/cglm/simd/wasm/quat.h index 8367214..ccbcec2 100644 --- a/include/cglm/simd/wasm/quat.h +++ b/include/cglm/simd/wasm/quat.h @@ -26,7 +26,7 @@ glm_quat_mul_wasm(versor p, versor q, versor dest) { xp = glmm_load(p); /* 3 2 1 0 */ xq = glmm_load(q); - x1 = _mm_set_ps(-0.f, 0.f, -0.f, 0.f); /* TODO: _mm_set1_ss() + shuff ? */ + x1 = wasm_f32x4_const(0.f, -0.f, 0.f, -0.f); /* TODO: _mm_set1_ss() + shuff ? */ r = wasm_f32x4_mul(glmm_splat_w(xp), xq); x2 = _mm_unpackhi_ps(x1, x1); From e62b7820394f2f6abb2293665d96a970b31fac2e Mon Sep 17 00:00:00 2001 From: myfreeer Date: Sun, 19 Mar 2023 16:35:56 +0800 Subject: [PATCH 12/34] simd128: fix a const in glm_mat4_inv_fast_wasm making it the same as glm_mat4_inv_wasm, does not make any difference in tests --- include/cglm/simd/wasm/mat4.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/cglm/simd/wasm/mat4.h b/include/cglm/simd/wasm/mat4.h index aa696b1..847c6c3 100644 --- a/include/cglm/simd/wasm/mat4.h +++ b/include/cglm/simd/wasm/mat4.h @@ -166,7 +166,7 @@ glm_mat4_inv_fast_wasm(mat4 mat, mat4 dest) { t0, t1, t2, t3, t4, t5, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9; - x8 = wasm_f32x4_const(-0.f, 0.f, -0.f, 0.f); + x8 = wasm_f32x4_const(0.f, -0.f, 0.f, -0.f); x9 = glmm_shuff1(x8, 2, 1, 2, 1); /* 127 <- 0 */ From f24ec41a26ff215e772a90b5e71c9aaaef66e25b Mon Sep 17 00:00:00 2001 From: myfreeer Date: Sun, 26 Mar 2023 17:57:29 +0800 Subject: [PATCH 13/34] simd128: inline _mm_shuffle_ps for glmm_shuff1 --- include/cglm/simd/wasm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/cglm/simd/wasm.h b/include/cglm/simd/wasm.h index a279df1..38c992e 100644 --- a/include/cglm/simd/wasm.h +++ b/include/cglm/simd/wasm.h @@ -20,7 +20,7 @@ (((__mask) >> 4) & 0x3) + 4, \ (((__mask) >> 6) & 0x3) + 4)) -#define glmm_shuff1(xmm, z, y, x, w) _mm_shuffle_ps(xmm, xmm, _MM_SHUFFLE(z, y, x, w)) +#define glmm_shuff1(xmm, z, y, x, w) wasm_i32x4_shuffle(xmm, xmm, w, x, y, z) #define glmm_splat(x, lane) glmm_shuff1(x, lane, lane, lane, lane) From 84b482971d818ed9bd2ee6d7a0072644c249d524 Mon Sep 17 00:00:00 2001 From: myfreeer Date: Sun, 26 Mar 2023 19:17:40 +0800 Subject: [PATCH 14/34] simd128: inline _mm_shuffle_ps --- include/cglm/simd/wasm.h | 9 --------- include/cglm/simd/wasm/mat3.h | 6 +++--- include/cglm/simd/wasm/mat4.h | 32 ++++++++++++++++---------------- 3 files changed, 19 insertions(+), 28 deletions(-) diff --git a/include/cglm/simd/wasm.h b/include/cglm/simd/wasm.h index 38c992e..21ba62d 100644 --- a/include/cglm/simd/wasm.h +++ b/include/cglm/simd/wasm.h @@ -11,15 +11,6 @@ #define glmm_set1(x) wasm_f32x4_splat(x) #define glmm_128 v128_t -#define _MM_SHUFFLE(w, z, y, x) (((w) << 6) | ((z) << 4) | ((y) << 2) | (x)) - -#define _mm_shuffle_ps(__a, __b, __mask) \ - ((glmm_128)wasm_i32x4_shuffle(__a, __b, \ - (((__mask) >> 0) & 0x3) + 0, \ - (((__mask) >> 2) & 0x3) + 0, \ - (((__mask) >> 4) & 0x3) + 4, \ - (((__mask) >> 6) & 0x3) + 4)) - #define glmm_shuff1(xmm, z, y, x, w) wasm_i32x4_shuffle(xmm, xmm, w, x, y, z) #define glmm_splat(x, lane) glmm_shuff1(x, lane, lane, lane, lane) diff --git a/include/cglm/simd/wasm/mat3.h b/include/cglm/simd/wasm/mat3.h index f4d8fed..412ad8a 100644 --- a/include/cglm/simd/wasm/mat3.h +++ b/include/cglm/simd/wasm/mat3.h @@ -25,8 +25,8 @@ glm_mat3_mul_wasm(mat3 m1, mat3 m2, mat3 dest) { x8 = glmm_shuff1(l0, 0, 2, 1, 0); /* a00 a02 a01 a00 */ x1 = glmm_shuff1(r0, 3, 0, 0, 0); /* b10 b00 b00 b00 */ - x2 = _mm_shuffle_ps(l0, l1, _MM_SHUFFLE(1, 0, 3, 3)); /* a12 a11 a10 a10 */ - x3 = _mm_shuffle_ps(r0, r1, _MM_SHUFFLE(2, 0, 3, 1)); /* b20 b11 b10 b01 */ + x2 = wasm_i32x4_shuffle(l0, l1, 3, 3, 4, 5); /* a12 a11 a10 a10 */ + x3 = wasm_i32x4_shuffle(r0, r1, 1, 3, 4, 6); /* b20 b11 b10 b01 */ x0 = wasm_f32x4_mul(x8, x1); x6 = glmm_shuff1(l0, 1, 0, 2, 1); /* a01 a00 a02 a01 */ @@ -51,7 +51,7 @@ glm_mat3_mul_wasm(mat3 m1, mat3 m2, mat3 dest) { x2 = _mm_movehl_ps(l2, l1); /* a22 a22 a21 a20 */ x3 = glmm_shuff1(x2, 0, 2, 1, 0); /* a20 a22 a21 a20 */ x2 = glmm_shuff1(x2, 1, 0, 2, 1); /* a21 a20 a22 a21 */ - x4 = _mm_shuffle_ps(r0, r1, _MM_SHUFFLE(1, 1, 2, 2)); /* b12 b12 b02 b02 */ + x4 = wasm_i32x4_shuffle(r0, r1, 2, 2, 5, 5); /* b12 b12 b02 b02 */ x5 = glmm_shuff1(x4, 3, 0, 0, 0); /* b12 b02 b02 b02 */ x4 = _mm_movehl_ps(r2, x4); /* b22 b22 b12 b12 */ diff --git a/include/cglm/simd/wasm/mat4.h b/include/cglm/simd/wasm/mat4.h index 847c6c3..35d5854 100644 --- a/include/cglm/simd/wasm/mat4.h +++ b/include/cglm/simd/wasm/mat4.h @@ -148,9 +148,9 @@ glm_mat4_det_wasm(mat4 mat) { */ x2 = glmm_fnmadd(glmm_shuff1(r1, 1, 1, 2, 2), glmm_shuff1(x0, 3, 2, 2, 0), wasm_f32x4_mul(glmm_shuff1(r1, 0, 0, 0, 1), - _mm_shuffle_ps(x1, x0, _MM_SHUFFLE(1, 0, 0, 0)))); + wasm_i32x4_shuffle(x1, x0, 0, 0, 4, 5))); x2 = glmm_fmadd(glmm_shuff1(r1, 2, 3, 3, 3), - _mm_shuffle_ps(x0, x1, _MM_SHUFFLE(2, 2, 3, 1)), + wasm_i32x4_shuffle(x0, x1, 1, 3, 6, 6), x2); x2 = wasm_v128_xor(x2, wasm_f32x4_const(0.f, -0.f, 0.f, -0.f)); @@ -182,10 +182,10 @@ glm_mat4_inv_fast_wasm(mat4 mat, mat4 dest) { x4 = glmm_shuff1(x3, 1, 3, 3, 3); /* j n n n */ x7 = glmm_shuff1(x3, 0, 2, 2, 2); /* i m m m */ - x6 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(0, 0, 0, 0)); /* e e i i */ - x5 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(1, 1, 1, 1)); /* f f j j */ - x3 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(2, 2, 2, 2)); /* g g k k */ - x0 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(3, 3, 3, 3)); /* h h l l */ + x6 = wasm_i32x4_shuffle(r2, r1, 0, 0, 4, 4); /* e e i i */ + x5 = wasm_i32x4_shuffle(r2, r1, 1, 1, 5, 5); /* f f j j */ + x3 = wasm_i32x4_shuffle(r2, r1, 2, 2, 6, 6); /* g g k k */ + x0 = wasm_i32x4_shuffle(r2, r1, 3, 3, 7, 7); /* h h l l */ t0 = wasm_f32x4_mul(x3, x1); t1 = wasm_f32x4_mul(x5, x1); @@ -282,9 +282,9 @@ glm_mat4_inv_fast_wasm(mat4 mat, mat4 dest) { v3 = wasm_v128_xor(v3, x9); /* determinant */ - x0 = _mm_shuffle_ps(v0, v1, _MM_SHUFFLE(0, 0, 0, 0)); - x1 = _mm_shuffle_ps(v2, v3, _MM_SHUFFLE(0, 0, 0, 0)); - x0 = _mm_shuffle_ps(x0, x1, _MM_SHUFFLE(2, 0, 2, 0)); + x0 = wasm_i32x4_shuffle(v0, v1, 0, 0, 4, 4); + x1 = wasm_i32x4_shuffle(v2, v3, 0, 0, 4, 4); + x0 = wasm_i32x4_shuffle(x0, x1, 0, 2, 4, 6); x0 = _mm_rcp_ps(glmm_vhadd(wasm_f32x4_mul(x0, r0))); @@ -318,10 +318,10 @@ glm_mat4_inv_wasm(mat4 mat, mat4 dest) { x4 = glmm_shuff1(x3, 1, 3, 3, 3); /* j n n n */ x7 = glmm_shuff1(x3, 0, 2, 2, 2); /* i m m m */ - x6 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(0, 0, 0, 0)); /* e e i i */ - x5 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(1, 1, 1, 1)); /* f f j j */ - x3 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(2, 2, 2, 2)); /* g g k k */ - x0 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(3, 3, 3, 3)); /* h h l l */ + x6 = wasm_i32x4_shuffle(r2, r1, 0, 0, 4, 4); /* e e i i */ + x5 = wasm_i32x4_shuffle(r2, r1, 1, 1, 5, 5); /* f f j j */ + x3 = wasm_i32x4_shuffle(r2, r1, 2, 2, 6, 6); /* g g k k */ + x0 = wasm_i32x4_shuffle(r2, r1, 3, 3, 7, 7); /* h h l l */ t0 = wasm_f32x4_mul(x3, x1); t1 = wasm_f32x4_mul(x5, x1); @@ -418,9 +418,9 @@ glm_mat4_inv_wasm(mat4 mat, mat4 dest) { v3 = wasm_v128_xor(v3, x9); /* determinant */ - x0 = _mm_shuffle_ps(v0, v1, _MM_SHUFFLE(0, 0, 0, 0)); - x1 = _mm_shuffle_ps(v2, v3, _MM_SHUFFLE(0, 0, 0, 0)); - x0 = _mm_shuffle_ps(x0, x1, _MM_SHUFFLE(2, 0, 2, 0)); + x0 = wasm_i32x4_shuffle(v0, v1, 0, 0, 4, 4); + x1 = wasm_i32x4_shuffle(v2, v3, 0, 0, 4, 4); + x0 = wasm_i32x4_shuffle(x0, x1, 0, 2, 4, 6); x0 = wasm_f32x4_div(wasm_f32x4_splat(1.0f), glmm_vhadd(wasm_f32x4_mul(x0, r0))); From 998d9626a242dce56bbbe8819f7a31bd0150518e Mon Sep 17 00:00:00 2001 From: myfreeer Date: Sun, 26 Mar 2023 19:22:24 +0800 Subject: [PATCH 15/34] simd128: inline _mm_unpackhi_ps and _mm_unpacklo_ps --- include/cglm/simd/wasm.h | 20 ++++---------------- include/cglm/simd/wasm/mat3.h | 6 ++++-- include/cglm/simd/wasm/quat.h | 4 ++-- 3 files changed, 10 insertions(+), 20 deletions(-) diff --git a/include/cglm/simd/wasm.h b/include/cglm/simd/wasm.h index 21ba62d..4ade269 100644 --- a/include/cglm/simd/wasm.h +++ b/include/cglm/simd/wasm.h @@ -22,18 +22,6 @@ #define _mm_cvtss_f32(v) wasm_f32x4_extract_lane(v, 0) -static inline glmm_128 __attribute__((__always_inline__, __nodebug__)) -_mm_unpackhi_ps(glmm_128 __a, glmm_128 __b) -{ - return wasm_i32x4_shuffle(__a, __b, 2, 6, 3, 7); -} - -static inline glmm_128 __attribute__((__always_inline__, __nodebug__)) -_mm_unpacklo_ps(glmm_128 __a, glmm_128 __b) -{ - return wasm_i32x4_shuffle(__a, __b, 0, 4, 1, 5); -} - static inline glmm_128 __attribute__((__always_inline__, __nodebug__)) _mm_movehl_ps(glmm_128 __a, glmm_128 __b) { @@ -79,10 +67,10 @@ _mm_store_ss(float *__p, glmm_128 __a) glmm_128 __row1 = (row1); \ glmm_128 __row2 = (row2); \ glmm_128 __row3 = (row3); \ - glmm_128 __tmp0 = _mm_unpacklo_ps(__row0, __row1); \ - glmm_128 __tmp1 = _mm_unpackhi_ps(__row0, __row1); \ - glmm_128 __tmp2 = _mm_unpacklo_ps(__row2, __row3); \ - glmm_128 __tmp3 = _mm_unpackhi_ps(__row2, __row3); \ + glmm_128 __tmp0 = wasm_i32x4_shuffle(__row0, __row1, 0, 4, 1, 5); \ + glmm_128 __tmp1 = wasm_i32x4_shuffle(__row0, __row1, 2, 6, 3, 7); \ + glmm_128 __tmp2 = wasm_i32x4_shuffle(__row2, __row3, 0, 4, 1, 5); \ + glmm_128 __tmp3 = wasm_i32x4_shuffle(__row2, __row3, 2, 6, 3, 7); \ (row0) = _mm_movelh_ps(__tmp0, __tmp2); \ (row1) = _mm_movehl_ps(__tmp2, __tmp0); \ (row2) = _mm_movelh_ps(__tmp1, __tmp3); \ diff --git a/include/cglm/simd/wasm/mat3.h b/include/cglm/simd/wasm/mat3.h index 412ad8a..621d2bd 100644 --- a/include/cglm/simd/wasm/mat3.h +++ b/include/cglm/simd/wasm/mat3.h @@ -42,8 +42,10 @@ glm_mat3_mul_wasm(mat3 m1, mat3 m2, mat3 dest) { x6 = glmm_shuff1(x3, 2, 0, 0, 0); /* b11 b01 b01 b01 */ x2 = glmm_shuff1(r1, 3, 3, 0, 0); /* b21 b21 b11 b11 */ - x8 = _mm_unpackhi_ps(x8, x4); /* a10 a00 a12 a02 */ - x9 = _mm_unpackhi_ps(x7, x2); /* b21 b20 b21 b20 */ + // x8 = _mm_unpackhi_ps(x8, x4); + // x9 = _mm_unpackhi_ps(x7, x2); + x8 = wasm_i32x4_shuffle(x8, x4, 2, 6, 3, 7); /* a10 a00 a12 a02 */ + x9 = wasm_i32x4_shuffle(x7, x2, 2, 6, 3, 7); /* b21 b20 b21 b20 */ x0 = glmm_fmadd(x4, x6, x0); x1 = glmm_fmadd(x5, x2, x1); diff --git a/include/cglm/simd/wasm/quat.h b/include/cglm/simd/wasm/quat.h index ccbcec2..f8434f1 100644 --- a/include/cglm/simd/wasm/quat.h +++ b/include/cglm/simd/wasm/quat.h @@ -28,8 +28,8 @@ glm_quat_mul_wasm(versor p, versor q, versor dest) { xq = glmm_load(q); x1 = wasm_f32x4_const(0.f, -0.f, 0.f, -0.f); /* TODO: _mm_set1_ss() + shuff ? */ r = wasm_f32x4_mul(glmm_splat_w(xp), xq); - - x2 = _mm_unpackhi_ps(x1, x1); + // x2 = _mm_unpackhi_ps(x1, x1); + x2 = wasm_i32x4_shuffle(x1, x1, 2, 6, 3, 7); x3 = glmm_shuff1(x1, 3, 2, 0, 1); x = glmm_splat_x(xp); y = glmm_splat_y(xp); From 3845345f4cb5a3df9aae0e4efd601db48306f0bf Mon Sep 17 00:00:00 2001 From: myfreeer Date: Wed, 29 Mar 2023 20:12:51 +0800 Subject: [PATCH 16/34] simd128: inline _mm_storeu_ps and _mm_store_ss --- include/cglm/simd/wasm.h | 31 +++++++++---------------------- include/cglm/simd/wasm/mat3.h | 9 ++++++--- 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/include/cglm/simd/wasm.h b/include/cglm/simd/wasm.h index 4ade269..0e11735 100644 --- a/include/cglm/simd/wasm.h +++ b/include/cglm/simd/wasm.h @@ -46,21 +46,6 @@ _mm_rcp_ps(glmm_128 __a) return (glmm_128)wasm_f32x4_div((glmm_128)wasm_f32x4_splat(1.0f), (glmm_128)__a); } -static __inline__ void __attribute__((__always_inline__, __nodebug__)) -_mm_storeu_ps(float *__p, glmm_128 __a) -{ - struct __unaligned { - glmm_128 __v; - } __attribute__((__packed__, __may_alias__)); - ((struct __unaligned *)__p)->__v = __a; -} - -static __inline__ void __attribute__((__always_inline__, __nodebug__)) -_mm_store_ss(float *__p, glmm_128 __a) -{ - wasm_v128_store32_lane((void*)__p, (glmm_128)__a, 0); -} - #define _MM_TRANSPOSE4_PS(row0, row1, row2, row3) \ do { \ glmm_128 __row0 = (row0); \ @@ -80,7 +65,7 @@ _mm_store_ss(float *__p, glmm_128 __a) static inline glmm_128 glmm_abs(glmm_128 x) { - return wasm_v128_andnot(x, wasm_f32x4_splat(-0.0f)); + return wasm_v128_andnot(x, wasm_f32x4_const_splat(-0.0f)); } static inline @@ -114,8 +99,8 @@ glmm_128 glmm_vhmin(glmm_128 v) { glmm_128 x0, x1, x2; x0 = glmm_shuff1(v, 2, 3, 2, 3); /* [2, 3, 2, 3] */ - x1 = wasm_f32x4_pmin(x0, v); /* [0|2, 1|3, 2|2, 3|3] */ - x2 = glmm_splat(x1, 1); /* [1|3, 1|3, 1|3, 1|3] */ + x1 = wasm_f32x4_pmin(x0, v); /* [0|2, 1|3, 2|2, 3|3] */ + x2 = glmm_splat(x1, 1); /* [1|3, 1|3, 1|3, 1|3] */ return wasm_f32x4_pmin(x1, x2); } @@ -130,9 +115,10 @@ glmm_128 glmm_vhmax(glmm_128 v) { glmm_128 x0, x1, x2; x0 = glmm_shuff1(v, 2, 3, 2, 3); /* [2, 3, 2, 3] */ - x1 = wasm_f32x4_pmax(x0, v); /* [0|2, 1|3, 2|2, 3|3] */ - x2 = glmm_splat(x1, 1); /* [1|3, 1|3, 1|3, 1|3] */ - return (glmm_128) wasm_i32x4_shuffle(x1, wasm_f32x4_pmax(x1, x2), 4, 1, 2, 3); + x1 = wasm_f32x4_pmax(x0, v); /* [0|2, 1|3, 2|2, 3|3] */ + x2 = glmm_splat(x1, 1); /* [1|3, 1|3, 1|3, 1|3] */ + // _mm_max_ss + return wasm_i32x4_shuffle(x1, wasm_f32x4_pmax(x1, x2), 4, 1, 2, 3); } static inline @@ -227,7 +213,8 @@ glmm_fmsub(glmm_128 a, glmm_128 b, glmm_128 c) { static inline glmm_128 glmm_fnmsub(glmm_128 a, glmm_128 b, glmm_128 c) { - return wasm_v128_xor(wasm_f32x4_add(wasm_f32x4_mul(a, b), c), wasm_f32x4_splat(-0.0f)); + return wasm_v128_xor(wasm_f32x4_add(wasm_f32x4_mul(a, b), c), + wasm_f32x4_const_splat(-0.0f)); } #endif diff --git a/include/cglm/simd/wasm/mat3.h b/include/cglm/simd/wasm/mat3.h index 621d2bd..25b911c 100644 --- a/include/cglm/simd/wasm/mat3.h +++ b/include/cglm/simd/wasm/mat3.h @@ -69,9 +69,12 @@ glm_mat3_mul_wasm(mat3 m1, mat3 m2, mat3 dest) { x3 = _mm_movelh_ps(x9, r2); /* 0.f b22 b21 b20 */ x2 = glmm_vdots(x2, x3); - _mm_storeu_ps(&dest[0][0], x0); - _mm_storeu_ps(&dest[1][1], x1); - _mm_store_ss (&dest[2][2], x2); + // _mm_storeu_ps(&dest[0][0], x0); + wasm_v128_store(&dest[0][0], x0); + // _mm_storeu_ps(&dest[1][1], x1); + wasm_v128_store(&dest[1][1], x1); + // _mm_store_ss (&dest[2][2], x2); + wasm_v128_store32_lane(&dest[2][2], x2, 0); } #endif From e27f80b0bba0ca003aa8c77806436b2eb96b6e0a Mon Sep 17 00:00:00 2001 From: myfreeer Date: Wed, 29 Mar 2023 20:16:16 +0800 Subject: [PATCH 17/34] simd128: inline _mm_rcp_ps --- include/cglm/simd/wasm.h | 6 ------ include/cglm/simd/wasm/mat4.h | 4 +++- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/include/cglm/simd/wasm.h b/include/cglm/simd/wasm.h index 0e11735..0259f83 100644 --- a/include/cglm/simd/wasm.h +++ b/include/cglm/simd/wasm.h @@ -40,12 +40,6 @@ _mm_sqrt_ss(glmm_128 __a) return wasm_i32x4_shuffle(__a, wasm_f32x4_sqrt(__a), 4, 1, 2, 3); } -static __inline__ glmm_128 __attribute__((__always_inline__, __nodebug__)) -_mm_rcp_ps(glmm_128 __a) -{ - return (glmm_128)wasm_f32x4_div((glmm_128)wasm_f32x4_splat(1.0f), (glmm_128)__a); -} - #define _MM_TRANSPOSE4_PS(row0, row1, row2, row3) \ do { \ glmm_128 __row0 = (row0); \ diff --git a/include/cglm/simd/wasm/mat4.h b/include/cglm/simd/wasm/mat4.h index 35d5854..ea1e90e 100644 --- a/include/cglm/simd/wasm/mat4.h +++ b/include/cglm/simd/wasm/mat4.h @@ -286,7 +286,9 @@ glm_mat4_inv_fast_wasm(mat4 mat, mat4 dest) { x1 = wasm_i32x4_shuffle(v2, v3, 0, 0, 4, 4); x0 = wasm_i32x4_shuffle(x0, x1, 0, 2, 4, 6); - x0 = _mm_rcp_ps(glmm_vhadd(wasm_f32x4_mul(x0, r0))); + // x0 = _mm_rcp_ps(glmm_vhadd(wasm_f32x4_mul(x0, r0))); + x0 = wasm_f32x4_div(wasm_f32x4_const_splat(1.0f), + glmm_vhadd(wasm_f32x4_mul(x0, r0))); glmm_store(dest[0], wasm_f32x4_mul(v0, x0)); glmm_store(dest[1], wasm_f32x4_mul(v1, x0)); From 5c7cd42407ff031838178648b4cd59549247ffe6 Mon Sep 17 00:00:00 2001 From: myfreeer Date: Wed, 29 Mar 2023 20:22:03 +0800 Subject: [PATCH 18/34] simd128: inline _mm_sqrt_ss --- include/cglm/simd/wasm.h | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/include/cglm/simd/wasm.h b/include/cglm/simd/wasm.h index 0259f83..1567d0e 100644 --- a/include/cglm/simd/wasm.h +++ b/include/cglm/simd/wasm.h @@ -34,12 +34,6 @@ _mm_movelh_ps(glmm_128 __a, glmm_128 __b) return wasm_i32x4_shuffle(__a, __b, 0, 1, 4, 5); } -static inline glmm_128 __attribute__((__always_inline__, __nodebug__)) -_mm_sqrt_ss(glmm_128 __a) -{ - return wasm_i32x4_shuffle(__a, wasm_f32x4_sqrt(__a), 4, 1, 2, 3); -} - #define _MM_TRANSPOSE4_PS(row0, row1, row2, row3) \ do { \ glmm_128 __row0 = (row0); \ @@ -145,7 +139,9 @@ glmm_dot(glmm_128 a, glmm_128 b) { static inline float glmm_norm(glmm_128 a) { - return _mm_cvtss_f32(_mm_sqrt_ss(glmm_vhadds(wasm_f32x4_mul(a, a)))); + glmm_128 x0; + x0 = glmm_vhadds(wasm_f32x4_mul(a, a)); + return _mm_cvtss_f32(wasm_i32x4_shuffle(x0, wasm_f32x4_sqrt(x0),4, 1, 2, 3)); } static inline From 3aca10ecda6f4a5cd76561c1d837b912bb4c6201 Mon Sep 17 00:00:00 2001 From: myfreeer Date: Wed, 29 Mar 2023 20:41:47 +0800 Subject: [PATCH 19/34] simd128: minor lint --- include/cglm/simd/wasm/affine.h | 2 +- include/cglm/vec4.h | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/include/cglm/simd/wasm/affine.h b/include/cglm/simd/wasm/affine.h index cbf8ce4..ebf05fc 100644 --- a/include/cglm/simd/wasm/affine.h +++ b/include/cglm/simd/wasm/affine.h @@ -97,7 +97,7 @@ glm_inv_tr_wasm(mat4 mat) { x2 = glmm_shuff1(r3, 0, 0, 0, 0); x3 = glmm_shuff1(r3, 1, 1, 1, 1); x4 = glmm_shuff1(r3, 2, 2, 2, 2); - x5 = wasm_f32x4_splat(-0.f); + x5 = wasm_f32x4_const_splat(-0.f); x0 = glmm_fmadd(r0, x2, glmm_fmadd(r1, x3, wasm_f32x4_mul(r2, x4))); x0 = wasm_v128_xor(x0, x5); diff --git a/include/cglm/vec4.h b/include/cglm/vec4.h index abe3aa3..9e552ba 100644 --- a/include/cglm/vec4.h +++ b/include/cglm/vec4.h @@ -162,10 +162,15 @@ glm_vec4_copy(vec4 v, vec4 dest) { CGLM_INLINE void glm_vec4_ucopy(vec4 v, vec4 dest) { +#if defined(__wasm__) && defined(__wasm_simd128__) + // note here wasm v128.load/v128.store support unaligned loads and stores + wasm_v128_store(dest, wasm_v128_load(v)); +#else dest[0] = v[0]; dest[1] = v[1]; dest[2] = v[2]; dest[3] = v[3]; +#endif } /*! @@ -179,7 +184,7 @@ glm_vec4_zero(vec4 v) { #if defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(v, _mm_setzero_ps()); #elif defined(__wasm__) && defined(__wasm_simd128__) - glmm_store(v, wasm_f32x4_const(0.f, 0.f, 0.f, 0.f)); + glmm_store(v, wasm_f32x4_const_splat(0.f)); #elif defined(CGLM_NEON_FP) vst1q_f32(v, vdupq_n_f32(0.0f)); #else @@ -201,7 +206,7 @@ glm_vec4_one(vec4 v) { #if defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(v, _mm_set1_ps(1.0f)); #elif defined(__wasm__) && defined(__wasm_simd128__) - glmm_store(v, wasm_f32x4_splat(1.0f)); + glmm_store(v, wasm_f32x4_const_splat(1.0f)); #elif defined(CGLM_NEON_FP) vst1q_f32(v, vdupq_n_f32(1.0f)); #else @@ -424,6 +429,8 @@ void glm_vec4_mul(vec4 a, vec4 b, vec4 dest) { #if defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(dest, _mm_mul_ps(glmm_load(a), glmm_load(b))); +#elif defined(__wasm__) && defined(__wasm_simd128__) + glmm_store(dest, wasm_f32x4_mul(glmm_load(a), glmm_load(b))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vmulq_f32(vld1q_f32(a), vld1q_f32(b))); #else @@ -702,7 +709,7 @@ glm_vec4_negate_to(vec4 v, vec4 dest) { #if defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(dest, _mm_xor_ps(glmm_load(v), _mm_set1_ps(-0.0f))); #elif defined(__wasm__) && defined(__wasm_simd128__) - glmm_store(dest, wasm_v128_xor(glmm_load(v), wasm_f32x4_splat(-0.0f))); + glmm_store(dest, wasm_v128_xor(glmm_load(v), wasm_f32x4_const_splat(-0.0f))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vnegq_f32(vld1q_f32(v))); #else @@ -756,7 +763,7 @@ glm_vec4_normalize_to(vec4 v, vec4 dest) { dot = _mm_cvtss_f32(xdot); if (dot == 0.0f) { - glmm_store(dest, wasm_f32x4_const(0.f, 0.f, 0.f, 0.f)); + glmm_store(dest, wasm_f32x4_const_splat(0.f)); return; } From 5e05eec6d6e04e044108d6f4ddf3e22ef9590790 Mon Sep 17 00:00:00 2001 From: myfreeer Date: Sat, 1 Apr 2023 19:03:48 +0800 Subject: [PATCH 20/34] simd128: inline _MM_TRANSPOSE4_PS --- include/cglm/simd/wasm.h | 16 ---------------- include/cglm/simd/wasm/affine.h | 11 ++++++++++- include/cglm/simd/wasm/mat4.h | 12 ++++++++++-- 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/include/cglm/simd/wasm.h b/include/cglm/simd/wasm.h index 1567d0e..82bc4ae 100644 --- a/include/cglm/simd/wasm.h +++ b/include/cglm/simd/wasm.h @@ -34,22 +34,6 @@ _mm_movelh_ps(glmm_128 __a, glmm_128 __b) return wasm_i32x4_shuffle(__a, __b, 0, 1, 4, 5); } -#define _MM_TRANSPOSE4_PS(row0, row1, row2, row3) \ - do { \ - glmm_128 __row0 = (row0); \ - glmm_128 __row1 = (row1); \ - glmm_128 __row2 = (row2); \ - glmm_128 __row3 = (row3); \ - glmm_128 __tmp0 = wasm_i32x4_shuffle(__row0, __row1, 0, 4, 1, 5); \ - glmm_128 __tmp1 = wasm_i32x4_shuffle(__row0, __row1, 2, 6, 3, 7); \ - glmm_128 __tmp2 = wasm_i32x4_shuffle(__row2, __row3, 0, 4, 1, 5); \ - glmm_128 __tmp3 = wasm_i32x4_shuffle(__row2, __row3, 2, 6, 3, 7); \ - (row0) = _mm_movelh_ps(__tmp0, __tmp2); \ - (row1) = _mm_movehl_ps(__tmp2, __tmp0); \ - (row2) = _mm_movelh_ps(__tmp1, __tmp3); \ - (row3) = _mm_movehl_ps(__tmp3, __tmp1); \ - } while (0) - static inline glmm_128 glmm_abs(glmm_128 x) { diff --git a/include/cglm/simd/wasm/affine.h b/include/cglm/simd/wasm/affine.h index ebf05fc..4fa2c44 100644 --- a/include/cglm/simd/wasm/affine.h +++ b/include/cglm/simd/wasm/affine.h @@ -92,7 +92,16 @@ glm_inv_tr_wasm(mat4 mat) { r2 = glmm_load(mat[2]); r3 = glmm_load(mat[3]); x1 = wasm_f32x4_const(0.0f, 0.0f, 0.0f, 1.0f); - _MM_TRANSPOSE4_PS(r0, r1, r2, x1); + + // _MM_TRANSPOSE4_PS(r0, r1, r2, x1); + x2 = wasm_i32x4_shuffle(r0, r1, 0, 4, 1, 5); + x3 = wasm_i32x4_shuffle(r0, r1, 2, 6, 3, 7); + x4 = wasm_i32x4_shuffle(r2, x1, 0, 4, 1, 5); + x5 = wasm_i32x4_shuffle(r2, x1, 2, 6, 3, 7); + r0 = _mm_movelh_ps(x2, x4); + r1 = _mm_movehl_ps(x4, x2); + r2 = _mm_movelh_ps(x3, x5); + x1 = _mm_movehl_ps(x5, x3); x2 = glmm_shuff1(r3, 0, 0, 0, 0); x3 = glmm_shuff1(r3, 1, 1, 1, 1); diff --git a/include/cglm/simd/wasm/mat4.h b/include/cglm/simd/wasm/mat4.h index ea1e90e..b90daee 100644 --- a/include/cglm/simd/wasm/mat4.h +++ b/include/cglm/simd/wasm/mat4.h @@ -29,14 +29,22 @@ glm_mat4_scale_wasm(mat4 m, float s) { CGLM_INLINE void glm_mat4_transp_wasm(mat4 m, mat4 dest) { - glmm_128 r0, r1, r2, r3; + glmm_128 r0, r1, r2, r3, tmp0, tmp1, tmp2, tmp3; r0 = glmm_load(m[0]); r1 = glmm_load(m[1]); r2 = glmm_load(m[2]); r3 = glmm_load(m[3]); - _MM_TRANSPOSE4_PS(r0, r1, r2, r3); + // _MM_TRANSPOSE4_PS(r0, r1, r2, r3); + tmp0 = wasm_i32x4_shuffle(r0, r1, 0, 4, 1, 5); + tmp1 = wasm_i32x4_shuffle(r0, r1, 2, 6, 3, 7); + tmp2 = wasm_i32x4_shuffle(r2, r3, 0, 4, 1, 5); + tmp3 = wasm_i32x4_shuffle(r2, r3, 2, 6, 3, 7); + r0 = _mm_movelh_ps(tmp0, tmp2); + r1 = _mm_movehl_ps(tmp2, tmp0); + r2 = _mm_movelh_ps(tmp1, tmp3); + r3 = _mm_movehl_ps(tmp3, tmp1); glmm_store(dest[0], r0); glmm_store(dest[1], r1); From e40b477929be138f75cdcd4db43f2987fbe9aea5 Mon Sep 17 00:00:00 2001 From: myfreeer Date: Sat, 1 Apr 2023 19:19:49 +0800 Subject: [PATCH 21/34] simd128: inline _mm_movelh_ps --- include/cglm/simd/wasm.h | 6 ------ include/cglm/simd/wasm/affine.h | 6 ++++-- include/cglm/simd/wasm/mat2.h | 3 ++- include/cglm/simd/wasm/mat3.h | 10 ++++++---- include/cglm/simd/wasm/mat4.h | 20 ++++++++++++-------- 5 files changed, 24 insertions(+), 21 deletions(-) diff --git a/include/cglm/simd/wasm.h b/include/cglm/simd/wasm.h index 82bc4ae..ba621dd 100644 --- a/include/cglm/simd/wasm.h +++ b/include/cglm/simd/wasm.h @@ -28,12 +28,6 @@ _mm_movehl_ps(glmm_128 __a, glmm_128 __b) return wasm_i32x4_shuffle(__a, __b, 6, 7, 2, 3); } -static inline glmm_128 __attribute__((__always_inline__, __nodebug__)) -_mm_movelh_ps(glmm_128 __a, glmm_128 __b) -{ - return wasm_i32x4_shuffle(__a, __b, 0, 1, 4, 5); -} - static inline glmm_128 glmm_abs(glmm_128 x) { diff --git a/include/cglm/simd/wasm/affine.h b/include/cglm/simd/wasm/affine.h index 4fa2c44..9471592 100644 --- a/include/cglm/simd/wasm/affine.h +++ b/include/cglm/simd/wasm/affine.h @@ -98,9 +98,11 @@ glm_inv_tr_wasm(mat4 mat) { x3 = wasm_i32x4_shuffle(r0, r1, 2, 6, 3, 7); x4 = wasm_i32x4_shuffle(r2, x1, 0, 4, 1, 5); x5 = wasm_i32x4_shuffle(r2, x1, 2, 6, 3, 7); - r0 = _mm_movelh_ps(x2, x4); + // r0 = _mm_movelh_ps(x2, x4); + r0 = wasm_i32x4_shuffle(x2, x4, 0, 1, 4, 5); r1 = _mm_movehl_ps(x4, x2); - r2 = _mm_movelh_ps(x3, x5); + // r2 = _mm_movelh_ps(x3, x5); + r2 = wasm_i32x4_shuffle(x3, x5, 0, 1, 4, 5); x1 = _mm_movehl_ps(x5, x3); x2 = glmm_shuff1(r3, 0, 0, 0, 0); diff --git a/include/cglm/simd/wasm/mat2.h b/include/cglm/simd/wasm/mat2.h index 42dc1f7..6c3f5fb 100644 --- a/include/cglm/simd/wasm/mat2.h +++ b/include/cglm/simd/wasm/mat2.h @@ -22,7 +22,8 @@ glm_mat2_mul_wasm(mat2 m1, mat2 m2, mat2 dest) { x3 = glmm_shuff1(x2, 2, 2, 0, 0); x4 = glmm_shuff1(x2, 3, 3, 1, 1); - x0 = _mm_movelh_ps(x1, x1); + // x0 = _mm_movelh_ps(x1, x1); + x0 = wasm_i32x4_shuffle(x1, x1, 0, 1, 4, 5); x2 = _mm_movehl_ps(x1, x1); /* diff --git a/include/cglm/simd/wasm/mat3.h b/include/cglm/simd/wasm/mat3.h index 25b911c..62d179c 100644 --- a/include/cglm/simd/wasm/mat3.h +++ b/include/cglm/simd/wasm/mat3.h @@ -25,8 +25,8 @@ glm_mat3_mul_wasm(mat3 m1, mat3 m2, mat3 dest) { x8 = glmm_shuff1(l0, 0, 2, 1, 0); /* a00 a02 a01 a00 */ x1 = glmm_shuff1(r0, 3, 0, 0, 0); /* b10 b00 b00 b00 */ - x2 = wasm_i32x4_shuffle(l0, l1, 3, 3, 4, 5); /* a12 a11 a10 a10 */ - x3 = wasm_i32x4_shuffle(r0, r1, 1, 3, 4, 6); /* b20 b11 b10 b01 */ + x2 = wasm_i32x4_shuffle(l0, l1, 3, 3, 4, 5); /* a12 a11 a10 a10 */ + x3 = wasm_i32x4_shuffle(r0, r1, 1, 3, 4, 6); /* b20 b11 b10 b01 */ x0 = wasm_f32x4_mul(x8, x1); x6 = glmm_shuff1(l0, 1, 0, 2, 1); /* a01 a00 a02 a01 */ @@ -65,8 +65,10 @@ glm_mat3_mul_wasm(mat3 m1, mat3 m2, mat3 dest) { a12 * b21 + a22 * b22 + 0 * 00 */ - x2 = _mm_movelh_ps(x8, l2); /* 0.f a22 a12 a02 */ - x3 = _mm_movelh_ps(x9, r2); /* 0.f b22 b21 b20 */ + // x2 = _mm_movelh_ps(x8, l2); + // x3 = _mm_movelh_ps(x9, r2); + x2 = wasm_i32x4_shuffle(x8, l2, 0, 1, 4, 5); /* 0.f a22 a12 a02 */ + x3 = wasm_i32x4_shuffle(x9, r2, 0, 1, 4, 5); /* 0.f b22 b21 b20 */ x2 = glmm_vdots(x2, x3); // _mm_storeu_ps(&dest[0][0], x0); diff --git a/include/cglm/simd/wasm/mat4.h b/include/cglm/simd/wasm/mat4.h index b90daee..4b3cde5 100644 --- a/include/cglm/simd/wasm/mat4.h +++ b/include/cglm/simd/wasm/mat4.h @@ -41,9 +41,11 @@ glm_mat4_transp_wasm(mat4 m, mat4 dest) { tmp1 = wasm_i32x4_shuffle(r0, r1, 2, 6, 3, 7); tmp2 = wasm_i32x4_shuffle(r2, r3, 0, 4, 1, 5); tmp3 = wasm_i32x4_shuffle(r2, r3, 2, 6, 3, 7); - r0 = _mm_movelh_ps(tmp0, tmp2); + // r0 = _mm_movelh_ps(tmp0, tmp2); + r0 = wasm_i32x4_shuffle(tmp0, tmp2, 0, 1, 4, 5); r1 = _mm_movehl_ps(tmp2, tmp0); - r2 = _mm_movelh_ps(tmp1, tmp3); + // r2 = _mm_movelh_ps(tmp1, tmp3); + r2 = wasm_i32x4_shuffle(tmp1, tmp3, 0, 1, 4, 5); r3 = _mm_movehl_ps(tmp3, tmp1); glmm_store(dest[0], r0); @@ -184,7 +186,8 @@ glm_mat4_inv_fast_wasm(mat4 mat, mat4 dest) { r3 = glmm_load(mat[3]); /* p o n m */ x0 = _mm_movehl_ps(r3, r2); /* p o l k */ - x3 = _mm_movelh_ps(r2, r3); /* n m j i */ + // x3 = _mm_movelh_ps(r2, r3); + x3 = wasm_i32x4_shuffle(r2, r3, 0, 1, 4, 5); /* n m j i */ x1 = glmm_shuff1(x0, 1, 3, 3 ,3); /* l p p p */ x2 = glmm_shuff1(x0, 0, 2, 2, 2); /* k o o o */ x4 = glmm_shuff1(x3, 1, 3, 3, 3); /* j n n n */ @@ -237,8 +240,8 @@ glm_mat4_inv_fast_wasm(mat4 mat, mat4 dest) { t2[5] = e * n - m * f; t3[5] = e * j - i * f; */ t5 = glmm_fnmadd(x7, x5, t5); - - x4 = _mm_movelh_ps(r0, r1); /* f e b a */ + // x4 = _mm_movelh_ps(r0, r1); + x4 = wasm_i32x4_shuffle(r0, r1, 0, 1, 4, 5); /* f e b a */ x5 = _mm_movehl_ps(r1, r0); /* h g d c */ x0 = glmm_shuff1(x4, 0, 0, 0, 2); /* a a a e */ @@ -322,7 +325,8 @@ glm_mat4_inv_wasm(mat4 mat, mat4 dest) { r3 = glmm_load(mat[3]); /* p o n m */ x0 = _mm_movehl_ps(r3, r2); /* p o l k */ - x3 = _mm_movelh_ps(r2, r3); /* n m j i */ + // x3 = _mm_movelh_ps(r2, r3); + x3 = wasm_i32x4_shuffle(r2, r3, 0, 1, 4, 5); /* n m j i */ x1 = glmm_shuff1(x0, 1, 3, 3 ,3); /* l p p p */ x2 = glmm_shuff1(x0, 0, 2, 2, 2); /* k o o o */ x4 = glmm_shuff1(x3, 1, 3, 3, 3); /* j n n n */ @@ -375,8 +379,8 @@ glm_mat4_inv_wasm(mat4 mat, mat4 dest) { t2[5] = e * n - m * f; t3[5] = e * j - i * f; */ t5 = glmm_fnmadd(x7, x5, t5); - - x4 = _mm_movelh_ps(r0, r1); /* f e b a */ + // x4 = _mm_movelh_ps(r0, r1); + x4 = wasm_i32x4_shuffle(r0, r1, 0, 1, 4, 5); /* f e b a */ x5 = _mm_movehl_ps(r1, r0); /* h g d c */ x0 = glmm_shuff1(x4, 0, 0, 0, 2); /* a a a e */ From 48d6ab79bd9b64e3de7b796974333e55f053cc7d Mon Sep 17 00:00:00 2001 From: myfreeer Date: Sat, 1 Apr 2023 19:28:45 +0800 Subject: [PATCH 22/34] simd128: inline _mm_movehl_ps --- include/cglm/simd/wasm.h | 9 ++---- include/cglm/simd/wasm/affine.h | 9 ++++-- include/cglm/simd/wasm/mat2.h | 3 +- include/cglm/simd/wasm/mat3.h | 8 +++-- include/cglm/simd/wasm/mat4.h | 56 ++++++++++++++++++--------------- 5 files changed, 45 insertions(+), 40 deletions(-) diff --git a/include/cglm/simd/wasm.h b/include/cglm/simd/wasm.h index ba621dd..25bf1b9 100644 --- a/include/cglm/simd/wasm.h +++ b/include/cglm/simd/wasm.h @@ -22,12 +22,6 @@ #define _mm_cvtss_f32(v) wasm_f32x4_extract_lane(v, 0) -static inline glmm_128 __attribute__((__always_inline__, __nodebug__)) -_mm_movehl_ps(glmm_128 __a, glmm_128 __b) -{ - return wasm_i32x4_shuffle(__a, __b, 6, 7, 2, 3); -} - static inline glmm_128 glmm_abs(glmm_128 x) { @@ -49,7 +43,8 @@ glmm_vhadds(glmm_128 v) { glmm_128 shuf, sums; shuf = glmm_shuff1(v, 2, 3, 0, 1); sums = wasm_f32x4_add(v, shuf); - shuf = _mm_movehl_ps(shuf, sums); + // shuf = _mm_movehl_ps(shuf, sums); + shuf = wasm_i32x4_shuffle(shuf, sums, 6, 7, 2, 3); sums = wasm_i32x4_shuffle(sums, wasm_f32x4_add(sums, shuf), 4, 1, 2, 3); return sums; } diff --git a/include/cglm/simd/wasm/affine.h b/include/cglm/simd/wasm/affine.h index 9471592..518cf64 100644 --- a/include/cglm/simd/wasm/affine.h +++ b/include/cglm/simd/wasm/affine.h @@ -100,17 +100,20 @@ glm_inv_tr_wasm(mat4 mat) { x5 = wasm_i32x4_shuffle(r2, x1, 2, 6, 3, 7); // r0 = _mm_movelh_ps(x2, x4); r0 = wasm_i32x4_shuffle(x2, x4, 0, 1, 4, 5); - r1 = _mm_movehl_ps(x4, x2); + // r1 = _mm_movehl_ps(x4, x2); + r1 = wasm_i32x4_shuffle(x4, x2, 6, 7, 2, 3); // r2 = _mm_movelh_ps(x3, x5); r2 = wasm_i32x4_shuffle(x3, x5, 0, 1, 4, 5); - x1 = _mm_movehl_ps(x5, x3); + // x1 = _mm_movehl_ps(x5, x3); + x1 = wasm_i32x4_shuffle(x5, x3, 6, 7, 2, 3); x2 = glmm_shuff1(r3, 0, 0, 0, 0); x3 = glmm_shuff1(r3, 1, 1, 1, 1); x4 = glmm_shuff1(r3, 2, 2, 2, 2); x5 = wasm_f32x4_const_splat(-0.f); - x0 = glmm_fmadd(r0, x2, glmm_fmadd(r1, x3, wasm_f32x4_mul(r2, x4))); + x0 = glmm_fmadd(r0, x2, + glmm_fmadd(r1, x3, wasm_f32x4_mul(r2, x4))); x0 = wasm_v128_xor(x0, x5); x0 = wasm_f32x4_add(x0, x1); diff --git a/include/cglm/simd/wasm/mat2.h b/include/cglm/simd/wasm/mat2.h index 6c3f5fb..9caefd1 100644 --- a/include/cglm/simd/wasm/mat2.h +++ b/include/cglm/simd/wasm/mat2.h @@ -24,7 +24,8 @@ glm_mat2_mul_wasm(mat2 m1, mat2 m2, mat2 dest) { x4 = glmm_shuff1(x2, 3, 3, 1, 1); // x0 = _mm_movelh_ps(x1, x1); x0 = wasm_i32x4_shuffle(x1, x1, 0, 1, 4, 5); - x2 = _mm_movehl_ps(x1, x1); + // x2 = _mm_movehl_ps(x1, x1); + x2 = wasm_i32x4_shuffle(x1, x1, 6, 7, 2, 3); /* dest[0][0] = a * e + c * f; diff --git a/include/cglm/simd/wasm/mat3.h b/include/cglm/simd/wasm/mat3.h index 62d179c..835f5a3 100644 --- a/include/cglm/simd/wasm/mat3.h +++ b/include/cglm/simd/wasm/mat3.h @@ -50,13 +50,15 @@ glm_mat3_mul_wasm(mat3 m1, mat3 m2, mat3 dest) { x0 = glmm_fmadd(x4, x6, x0); x1 = glmm_fmadd(x5, x2, x1); - x2 = _mm_movehl_ps(l2, l1); /* a22 a22 a21 a20 */ + // x2 = _mm_movehl_ps(l2, l1); + x2 = wasm_i32x4_shuffle(l2, l1, 6, 7, 2, 3); /* a22 a22 a21 a20 */ x3 = glmm_shuff1(x2, 0, 2, 1, 0); /* a20 a22 a21 a20 */ x2 = glmm_shuff1(x2, 1, 0, 2, 1); /* a21 a20 a22 a21 */ - x4 = wasm_i32x4_shuffle(r0, r1, 2, 2, 5, 5); /* b12 b12 b02 b02 */ + x4 = wasm_i32x4_shuffle(r0, r1, 2, 2, 5, 5); /* b12 b12 b02 b02 */ x5 = glmm_shuff1(x4, 3, 0, 0, 0); /* b12 b02 b02 b02 */ - x4 = _mm_movehl_ps(r2, x4); /* b22 b22 b12 b12 */ + // x4 = _mm_movehl_ps(r2, x4); + x4 = wasm_i32x4_shuffle(r2, x4, 6, 7, 2, 3); /* b22 b22 b12 b12 */ x0 = glmm_fmadd(x3, x5, x0); x1 = glmm_fmadd(x2, x4, x1); diff --git a/include/cglm/simd/wasm/mat4.h b/include/cglm/simd/wasm/mat4.h index 4b3cde5..f86a4ff 100644 --- a/include/cglm/simd/wasm/mat4.h +++ b/include/cglm/simd/wasm/mat4.h @@ -43,10 +43,12 @@ glm_mat4_transp_wasm(mat4 m, mat4 dest) { tmp3 = wasm_i32x4_shuffle(r2, r3, 2, 6, 3, 7); // r0 = _mm_movelh_ps(tmp0, tmp2); r0 = wasm_i32x4_shuffle(tmp0, tmp2, 0, 1, 4, 5); - r1 = _mm_movehl_ps(tmp2, tmp0); + // r1 = _mm_movehl_ps(tmp2, tmp0); + r1 = wasm_i32x4_shuffle(tmp2, tmp0, 6, 7, 2, 3); // r2 = _mm_movelh_ps(tmp1, tmp3); r2 = wasm_i32x4_shuffle(tmp1, tmp3, 0, 1, 4, 5); - r3 = _mm_movehl_ps(tmp3, tmp1); + // r3 = _mm_movehl_ps(tmp3, tmp1); + r3 = wasm_i32x4_shuffle(tmp3, tmp1, 6, 7, 2, 3); glmm_store(dest[0], r0); glmm_store(dest[1], r1); @@ -184,8 +186,8 @@ glm_mat4_inv_fast_wasm(mat4 mat, mat4 dest) { r1 = glmm_load(mat[1]); /* h g f e */ r2 = glmm_load(mat[2]); /* l k j i */ r3 = glmm_load(mat[3]); /* p o n m */ - - x0 = _mm_movehl_ps(r3, r2); /* p o l k */ + // x0 = _mm_movehl_ps(r3, r2); + x0 = wasm_i32x4_shuffle(r3, r2, 6, 7, 2, 3); /* p o l k */ // x3 = _mm_movelh_ps(r2, r3); x3 = wasm_i32x4_shuffle(r2, r3, 0, 1, 4, 5); /* n m j i */ x1 = glmm_shuff1(x0, 1, 3, 3 ,3); /* l p p p */ @@ -193,10 +195,10 @@ glm_mat4_inv_fast_wasm(mat4 mat, mat4 dest) { x4 = glmm_shuff1(x3, 1, 3, 3, 3); /* j n n n */ x7 = glmm_shuff1(x3, 0, 2, 2, 2); /* i m m m */ - x6 = wasm_i32x4_shuffle(r2, r1, 0, 0, 4, 4); /* e e i i */ - x5 = wasm_i32x4_shuffle(r2, r1, 1, 1, 5, 5); /* f f j j */ - x3 = wasm_i32x4_shuffle(r2, r1, 2, 2, 6, 6); /* g g k k */ - x0 = wasm_i32x4_shuffle(r2, r1, 3, 3, 7, 7); /* h h l l */ + x6 = wasm_i32x4_shuffle(r2, r1, 0, 0, 4, 4); /* e e i i */ + x5 = wasm_i32x4_shuffle(r2, r1, 1, 1, 5, 5); /* f f j j */ + x3 = wasm_i32x4_shuffle(r2, r1, 2, 2, 6, 6); /* g g k k */ + x0 = wasm_i32x4_shuffle(r2, r1, 3, 3, 7, 7); /* h h l l */ t0 = wasm_f32x4_mul(x3, x1); t1 = wasm_f32x4_mul(x5, x1); @@ -241,13 +243,14 @@ glm_mat4_inv_fast_wasm(mat4 mat, mat4 dest) { t3[5] = e * j - i * f; */ t5 = glmm_fnmadd(x7, x5, t5); // x4 = _mm_movelh_ps(r0, r1); - x4 = wasm_i32x4_shuffle(r0, r1, 0, 1, 4, 5); /* f e b a */ - x5 = _mm_movehl_ps(r1, r0); /* h g d c */ + x4 = wasm_i32x4_shuffle(r0, r1, 0, 1, 4, 5); /* f e b a */ + // x5 = _mm_movehl_ps(r1, r0); + x5 = wasm_i32x4_shuffle(r1, r0, 6, 7, 2, 3); /* h g d c */ - x0 = glmm_shuff1(x4, 0, 0, 0, 2); /* a a a e */ - x1 = glmm_shuff1(x4, 1, 1, 1, 3); /* b b b f */ - x2 = glmm_shuff1(x5, 0, 0, 0, 2); /* c c c g */ - x3 = glmm_shuff1(x5, 1, 1, 1, 3); /* d d d h */ + x0 = glmm_shuff1(x4, 0, 0, 0, 2); /* a a a e */ + x1 = glmm_shuff1(x4, 1, 1, 1, 3); /* b b b f */ + x2 = glmm_shuff1(x5, 0, 0, 0, 2); /* c c c g */ + x3 = glmm_shuff1(x5, 1, 1, 1, 3); /* d d d h */ v2 = wasm_f32x4_mul(x0, t1); v1 = wasm_f32x4_mul(x0, t0); @@ -323,8 +326,8 @@ glm_mat4_inv_wasm(mat4 mat, mat4 dest) { r1 = glmm_load(mat[1]); /* h g f e */ r2 = glmm_load(mat[2]); /* l k j i */ r3 = glmm_load(mat[3]); /* p o n m */ - - x0 = _mm_movehl_ps(r3, r2); /* p o l k */ + // x0 = _mm_movehl_ps(r3, r2); + x0 = wasm_i32x4_shuffle(r3, r2, 6, 7, 2, 3); /* p o l k */ // x3 = _mm_movelh_ps(r2, r3); x3 = wasm_i32x4_shuffle(r2, r3, 0, 1, 4, 5); /* n m j i */ x1 = glmm_shuff1(x0, 1, 3, 3 ,3); /* l p p p */ @@ -332,10 +335,10 @@ glm_mat4_inv_wasm(mat4 mat, mat4 dest) { x4 = glmm_shuff1(x3, 1, 3, 3, 3); /* j n n n */ x7 = glmm_shuff1(x3, 0, 2, 2, 2); /* i m m m */ - x6 = wasm_i32x4_shuffle(r2, r1, 0, 0, 4, 4); /* e e i i */ - x5 = wasm_i32x4_shuffle(r2, r1, 1, 1, 5, 5); /* f f j j */ - x3 = wasm_i32x4_shuffle(r2, r1, 2, 2, 6, 6); /* g g k k */ - x0 = wasm_i32x4_shuffle(r2, r1, 3, 3, 7, 7); /* h h l l */ + x6 = wasm_i32x4_shuffle(r2, r1, 0, 0, 4, 4); /* e e i i */ + x5 = wasm_i32x4_shuffle(r2, r1, 1, 1, 5, 5); /* f f j j */ + x3 = wasm_i32x4_shuffle(r2, r1, 2, 2, 6, 6); /* g g k k */ + x0 = wasm_i32x4_shuffle(r2, r1, 3, 3, 7, 7); /* h h l l */ t0 = wasm_f32x4_mul(x3, x1); t1 = wasm_f32x4_mul(x5, x1); @@ -380,13 +383,14 @@ glm_mat4_inv_wasm(mat4 mat, mat4 dest) { t3[5] = e * j - i * f; */ t5 = glmm_fnmadd(x7, x5, t5); // x4 = _mm_movelh_ps(r0, r1); - x4 = wasm_i32x4_shuffle(r0, r1, 0, 1, 4, 5); /* f e b a */ - x5 = _mm_movehl_ps(r1, r0); /* h g d c */ + x4 = wasm_i32x4_shuffle(r0, r1, 0, 1, 4, 5); /* f e b a */ + // x5 = _mm_movehl_ps(r1, r0); + x5 = wasm_i32x4_shuffle(r1, r0, 6, 7, 2, 3); /* h g d c */ - x0 = glmm_shuff1(x4, 0, 0, 0, 2); /* a a a e */ - x1 = glmm_shuff1(x4, 1, 1, 1, 3); /* b b b f */ - x2 = glmm_shuff1(x5, 0, 0, 0, 2); /* c c c g */ - x3 = glmm_shuff1(x5, 1, 1, 1, 3); /* d d d h */ + x0 = glmm_shuff1(x4, 0, 0, 0, 2); /* a a a e */ + x1 = glmm_shuff1(x4, 1, 1, 1, 3); /* b b b f */ + x2 = glmm_shuff1(x5, 0, 0, 0, 2); /* c c c g */ + x3 = glmm_shuff1(x5, 1, 1, 1, 3); /* d d d h */ v2 = wasm_f32x4_mul(x0, t1); v1 = wasm_f32x4_mul(x0, t0); From 73adfe08c05a6882d74171ee7d7f2f4ab46c75bb Mon Sep 17 00:00:00 2001 From: myfreeer Date: Sat, 1 Apr 2023 19:34:19 +0800 Subject: [PATCH 23/34] simd128: inline _mm_cvtss_f32 --- include/cglm/quat.h | 3 ++- include/cglm/simd/wasm.h | 17 ++++++++--------- include/cglm/vec4.h | 35 +++++++++++++++++++---------------- 3 files changed, 29 insertions(+), 26 deletions(-) diff --git a/include/cglm/quat.h b/include/cglm/quat.h index cec3a90..eeee5a9 100644 --- a/include/cglm/quat.h +++ b/include/cglm/quat.h @@ -262,7 +262,8 @@ glm_quat_normalize_to(versor q, versor dest) { x0 = glmm_load(q); xdot = glmm_vdot(x0, x0); - dot = _mm_cvtss_f32(xdot); + // dot = _mm_cvtss_f32(xdot); + dot = wasm_f32x4_extract_lane(xdot, 0); if (dot <= 0.0f) { glm_quat_identity(dest); diff --git a/include/cglm/simd/wasm.h b/include/cglm/simd/wasm.h index 25bf1b9..78f4605 100644 --- a/include/cglm/simd/wasm.h +++ b/include/cglm/simd/wasm.h @@ -20,8 +20,6 @@ #define glmm_splat_z(x) glmm_splat(x, 2) #define glmm_splat_w(x) glmm_splat(x, 3) -#define _mm_cvtss_f32(v) wasm_f32x4_extract_lane(v, 0) - static inline glmm_128 glmm_abs(glmm_128 x) { @@ -52,7 +50,7 @@ glmm_vhadds(glmm_128 v) { static inline float glmm_hadd(glmm_128 v) { - return _mm_cvtss_f32(glmm_vhadds(v)); + return wasm_f32x4_extract_lane(glmm_vhadds(v), 0); } static inline @@ -68,7 +66,7 @@ glmm_vhmin(glmm_128 v) { static inline float glmm_hmin(glmm_128 v) { - return _mm_cvtss_f32(glmm_vhmin(v)); + return wasm_f32x4_extract_lane(glmm_vhmin(v), 0); } static inline @@ -106,7 +104,7 @@ glmm_vdot(glmm_128 a, glmm_128 b) { static inline float glmm_dot(glmm_128 a, glmm_128 b) { - return _mm_cvtss_f32(glmm_vdots(a, b)); + return wasm_f32x4_extract_lane(glmm_vdots(a, b), 0); } static inline @@ -114,25 +112,26 @@ float glmm_norm(glmm_128 a) { glmm_128 x0; x0 = glmm_vhadds(wasm_f32x4_mul(a, a)); - return _mm_cvtss_f32(wasm_i32x4_shuffle(x0, wasm_f32x4_sqrt(x0),4, 1, 2, 3)); + return wasm_f32x4_extract_lane( + wasm_i32x4_shuffle(x0, wasm_f32x4_sqrt(x0),4, 1, 2, 3), 0); } static inline float glmm_norm2(glmm_128 a) { - return _mm_cvtss_f32(glmm_vhadds(wasm_f32x4_mul(a, a))); + return wasm_f32x4_extract_lane(glmm_vhadds(wasm_f32x4_mul(a, a)), 0); } static inline float glmm_norm_one(glmm_128 a) { - return _mm_cvtss_f32(glmm_vhadds(glmm_abs(a))); + return wasm_f32x4_extract_lane(glmm_vhadds(glmm_abs(a)), 0); } static inline float glmm_norm_inf(glmm_128 a) { - return _mm_cvtss_f32(glmm_vhmax(glmm_abs(a))); + return wasm_f32x4_extract_lane(glmm_vhmax(glmm_abs(a)), 0); } static inline diff --git a/include/cglm/vec4.h b/include/cglm/vec4.h index 9e552ba..73a5662 100644 --- a/include/cglm/vec4.h +++ b/include/cglm/vec4.h @@ -542,9 +542,9 @@ glm_vec4_addadd(vec4 a, vec4 b, vec4 dest) { _mm_add_ps(glmm_load(a), glmm_load(b)))); #elif defined(__wasm__) && defined(__wasm_simd128__) - glmm_store(dest, wasm_f32x4_add(glmm_load(dest), - wasm_f32x4_add(glmm_load(a), - glmm_load(b)))); + glmm_store(dest, wasm_f32x4_add( + glmm_load(dest), + wasm_f32x4_add(glmm_load(a), glmm_load(b)))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vaddq_f32(vld1q_f32(dest), vaddq_f32(vld1q_f32(a), @@ -574,9 +574,9 @@ glm_vec4_subadd(vec4 a, vec4 b, vec4 dest) { _mm_sub_ps(glmm_load(a), glmm_load(b)))); #elif defined(__wasm__) && defined(__wasm_simd128__) - glmm_store(dest, wasm_f32x4_add(glmm_load(dest), - wasm_f32x4_sub(glmm_load(a), - glmm_load(b)))); + glmm_store(dest, wasm_f32x4_add( + glmm_load(dest), + wasm_f32x4_sub(glmm_load(a), glmm_load(b)))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vaddq_f32(vld1q_f32(dest), vsubq_f32(vld1q_f32(a), @@ -650,9 +650,9 @@ glm_vec4_maxadd(vec4 a, vec4 b, vec4 dest) { _mm_max_ps(glmm_load(a), glmm_load(b)))); #elif defined(__wasm__) && defined(__wasm_simd128__) - glmm_store(dest, wasm_f32x4_add(glmm_load(dest), - wasm_f32x4_max(glmm_load(a), - glmm_load(b)))); + glmm_store(dest, wasm_f32x4_add( + glmm_load(dest), + wasm_f32x4_max(glmm_load(a), glmm_load(b)))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vaddq_f32(vld1q_f32(dest), vmaxq_f32(vld1q_f32(a), @@ -682,9 +682,9 @@ glm_vec4_minadd(vec4 a, vec4 b, vec4 dest) { _mm_min_ps(glmm_load(a), glmm_load(b)))); #elif defined(__wasm__) && defined(__wasm_simd128__) - glmm_store(dest, wasm_f32x4_add(glmm_load(dest), - wasm_f32x4_min(glmm_load(a), - glmm_load(b)))); + glmm_store(dest, wasm_f32x4_add( + glmm_load(dest), + wasm_f32x4_min(glmm_load(a), glmm_load(b)))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vaddq_f32(vld1q_f32(dest), vminq_f32(vld1q_f32(a), @@ -709,7 +709,8 @@ glm_vec4_negate_to(vec4 v, vec4 dest) { #if defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(dest, _mm_xor_ps(glmm_load(v), _mm_set1_ps(-0.0f))); #elif defined(__wasm__) && defined(__wasm_simd128__) - glmm_store(dest, wasm_v128_xor(glmm_load(v), wasm_f32x4_const_splat(-0.0f))); + glmm_store(dest, wasm_v128_xor(glmm_load(v), + wasm_f32x4_const_splat(-0.0f))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vnegq_f32(vld1q_f32(v))); #else @@ -760,7 +761,8 @@ glm_vec4_normalize_to(vec4 v, vec4 dest) { x0 = glmm_load(v); xdot = glmm_vdot(x0, x0); - dot = _mm_cvtss_f32(xdot); + // dot = _mm_cvtss_f32(xdot); + dot = wasm_f32x4_extract_lane(xdot, 0); if (dot == 0.0f) { glmm_store(dest, wasm_f32x4_const_splat(0.f)); @@ -903,8 +905,9 @@ glm_vec4_clamp(vec4 v, float minVal, float maxVal) { glmm_store(v, _mm_min_ps(_mm_max_ps(glmm_load(v), _mm_set1_ps(minVal)), _mm_set1_ps(maxVal))); #elif defined(__wasm__) && defined(__wasm_simd128__) - glmm_store(v, wasm_f32x4_min(wasm_f32x4_max(glmm_load(v), wasm_f32x4_splat(minVal)), - wasm_f32x4_splat(maxVal))); + glmm_store(v, wasm_f32x4_min( + wasm_f32x4_max(glmm_load(v), wasm_f32x4_splat(minVal)), + wasm_f32x4_splat(maxVal))); #elif defined(CGLM_NEON_FP) vst1q_f32(v, vminq_f32(vmaxq_f32(vld1q_f32(v), vdupq_n_f32(minVal)), vdupq_n_f32(maxVal))); From 51ce4db82e29c9c947604efbcec3891722158a3a Mon Sep 17 00:00:00 2001 From: myfreeer Date: Sat, 1 Apr 2023 19:38:28 +0800 Subject: [PATCH 24/34] simd128: code style --- include/cglm/quat.h | 2 +- include/cglm/simd/wasm.h | 4 ++-- include/cglm/simd/wasm/affine.h | 10 +++++----- include/cglm/simd/wasm/mat2.h | 4 ++-- include/cglm/simd/wasm/mat3.h | 18 +++++++++--------- include/cglm/simd/wasm/mat4.h | 28 ++++++++++++++-------------- include/cglm/simd/wasm/quat.h | 2 +- include/cglm/vec4.h | 4 ++-- 8 files changed, 36 insertions(+), 36 deletions(-) diff --git a/include/cglm/quat.h b/include/cglm/quat.h index eeee5a9..5ce27ff 100644 --- a/include/cglm/quat.h +++ b/include/cglm/quat.h @@ -262,7 +262,7 @@ glm_quat_normalize_to(versor q, versor dest) { x0 = glmm_load(q); xdot = glmm_vdot(x0, x0); - // dot = _mm_cvtss_f32(xdot); + /* dot = _mm_cvtss_f32(xdot); */ dot = wasm_f32x4_extract_lane(xdot, 0); if (dot <= 0.0f) { diff --git a/include/cglm/simd/wasm.h b/include/cglm/simd/wasm.h index 78f4605..133f8ac 100644 --- a/include/cglm/simd/wasm.h +++ b/include/cglm/simd/wasm.h @@ -41,7 +41,7 @@ glmm_vhadds(glmm_128 v) { glmm_128 shuf, sums; shuf = glmm_shuff1(v, 2, 3, 0, 1); sums = wasm_f32x4_add(v, shuf); - // shuf = _mm_movehl_ps(shuf, sums); + /* shuf = _mm_movehl_ps(shuf, sums); */ shuf = wasm_i32x4_shuffle(shuf, sums, 6, 7, 2, 3); sums = wasm_i32x4_shuffle(sums, wasm_f32x4_add(sums, shuf), 4, 1, 2, 3); return sums; @@ -76,7 +76,7 @@ glmm_vhmax(glmm_128 v) { x0 = glmm_shuff1(v, 2, 3, 2, 3); /* [2, 3, 2, 3] */ x1 = wasm_f32x4_pmax(x0, v); /* [0|2, 1|3, 2|2, 3|3] */ x2 = glmm_splat(x1, 1); /* [1|3, 1|3, 1|3, 1|3] */ - // _mm_max_ss + /* _mm_max_ss */ return wasm_i32x4_shuffle(x1, wasm_f32x4_pmax(x1, x2), 4, 1, 2, 3); } diff --git a/include/cglm/simd/wasm/affine.h b/include/cglm/simd/wasm/affine.h index 518cf64..59b36ac 100644 --- a/include/cglm/simd/wasm/affine.h +++ b/include/cglm/simd/wasm/affine.h @@ -93,18 +93,18 @@ glm_inv_tr_wasm(mat4 mat) { r3 = glmm_load(mat[3]); x1 = wasm_f32x4_const(0.0f, 0.0f, 0.0f, 1.0f); - // _MM_TRANSPOSE4_PS(r0, r1, r2, x1); + /* _MM_TRANSPOSE4_PS(r0, r1, r2, x1); */ x2 = wasm_i32x4_shuffle(r0, r1, 0, 4, 1, 5); x3 = wasm_i32x4_shuffle(r0, r1, 2, 6, 3, 7); x4 = wasm_i32x4_shuffle(r2, x1, 0, 4, 1, 5); x5 = wasm_i32x4_shuffle(r2, x1, 2, 6, 3, 7); - // r0 = _mm_movelh_ps(x2, x4); + /* r0 = _mm_movelh_ps(x2, x4); */ r0 = wasm_i32x4_shuffle(x2, x4, 0, 1, 4, 5); - // r1 = _mm_movehl_ps(x4, x2); + /* r1 = _mm_movehl_ps(x4, x2); */ r1 = wasm_i32x4_shuffle(x4, x2, 6, 7, 2, 3); - // r2 = _mm_movelh_ps(x3, x5); + /* r2 = _mm_movelh_ps(x3, x5); */ r2 = wasm_i32x4_shuffle(x3, x5, 0, 1, 4, 5); - // x1 = _mm_movehl_ps(x5, x3); + /* x1 = _mm_movehl_ps(x5, x3); */ x1 = wasm_i32x4_shuffle(x5, x3, 6, 7, 2, 3); x2 = glmm_shuff1(r3, 0, 0, 0, 0); diff --git a/include/cglm/simd/wasm/mat2.h b/include/cglm/simd/wasm/mat2.h index 9caefd1..80ce0fb 100644 --- a/include/cglm/simd/wasm/mat2.h +++ b/include/cglm/simd/wasm/mat2.h @@ -22,9 +22,9 @@ glm_mat2_mul_wasm(mat2 m1, mat2 m2, mat2 dest) { x3 = glmm_shuff1(x2, 2, 2, 0, 0); x4 = glmm_shuff1(x2, 3, 3, 1, 1); - // x0 = _mm_movelh_ps(x1, x1); + /* x0 = _mm_movelh_ps(x1, x1); */ x0 = wasm_i32x4_shuffle(x1, x1, 0, 1, 4, 5); - // x2 = _mm_movehl_ps(x1, x1); + /* x2 = _mm_movehl_ps(x1, x1); */ x2 = wasm_i32x4_shuffle(x1, x1, 6, 7, 2, 3); /* diff --git a/include/cglm/simd/wasm/mat3.h b/include/cglm/simd/wasm/mat3.h index 835f5a3..dfe192d 100644 --- a/include/cglm/simd/wasm/mat3.h +++ b/include/cglm/simd/wasm/mat3.h @@ -42,22 +42,22 @@ glm_mat3_mul_wasm(mat3 m1, mat3 m2, mat3 dest) { x6 = glmm_shuff1(x3, 2, 0, 0, 0); /* b11 b01 b01 b01 */ x2 = glmm_shuff1(r1, 3, 3, 0, 0); /* b21 b21 b11 b11 */ - // x8 = _mm_unpackhi_ps(x8, x4); - // x9 = _mm_unpackhi_ps(x7, x2); + /* x8 = _mm_unpackhi_ps(x8, x4); */ + /* x9 = _mm_unpackhi_ps(x7, x2); */ x8 = wasm_i32x4_shuffle(x8, x4, 2, 6, 3, 7); /* a10 a00 a12 a02 */ x9 = wasm_i32x4_shuffle(x7, x2, 2, 6, 3, 7); /* b21 b20 b21 b20 */ x0 = glmm_fmadd(x4, x6, x0); x1 = glmm_fmadd(x5, x2, x1); - // x2 = _mm_movehl_ps(l2, l1); + /* x2 = _mm_movehl_ps(l2, l1); */ x2 = wasm_i32x4_shuffle(l2, l1, 6, 7, 2, 3); /* a22 a22 a21 a20 */ x3 = glmm_shuff1(x2, 0, 2, 1, 0); /* a20 a22 a21 a20 */ x2 = glmm_shuff1(x2, 1, 0, 2, 1); /* a21 a20 a22 a21 */ x4 = wasm_i32x4_shuffle(r0, r1, 2, 2, 5, 5); /* b12 b12 b02 b02 */ x5 = glmm_shuff1(x4, 3, 0, 0, 0); /* b12 b02 b02 b02 */ - // x4 = _mm_movehl_ps(r2, x4); + /* x4 = _mm_movehl_ps(r2, x4); */ x4 = wasm_i32x4_shuffle(r2, x4, 6, 7, 2, 3); /* b22 b22 b12 b12 */ x0 = glmm_fmadd(x3, x5, x0); x1 = glmm_fmadd(x2, x4, x1); @@ -67,17 +67,17 @@ glm_mat3_mul_wasm(mat3 m1, mat3 m2, mat3 dest) { a12 * b21 + a22 * b22 + 0 * 00 */ - // x2 = _mm_movelh_ps(x8, l2); - // x3 = _mm_movelh_ps(x9, r2); + /* x2 = _mm_movelh_ps(x8, l2); */ + /* x3 = _mm_movelh_ps(x9, r2); */ x2 = wasm_i32x4_shuffle(x8, l2, 0, 1, 4, 5); /* 0.f a22 a12 a02 */ x3 = wasm_i32x4_shuffle(x9, r2, 0, 1, 4, 5); /* 0.f b22 b21 b20 */ x2 = glmm_vdots(x2, x3); - // _mm_storeu_ps(&dest[0][0], x0); + /* _mm_storeu_ps(&dest[0][0], x0); */ wasm_v128_store(&dest[0][0], x0); - // _mm_storeu_ps(&dest[1][1], x1); + /* _mm_storeu_ps(&dest[1][1], x1); */ wasm_v128_store(&dest[1][1], x1); - // _mm_store_ss (&dest[2][2], x2); + /* _mm_store_ss (&dest[2][2], x2); */ wasm_v128_store32_lane(&dest[2][2], x2, 0); } diff --git a/include/cglm/simd/wasm/mat4.h b/include/cglm/simd/wasm/mat4.h index f86a4ff..3711843 100644 --- a/include/cglm/simd/wasm/mat4.h +++ b/include/cglm/simd/wasm/mat4.h @@ -36,18 +36,18 @@ glm_mat4_transp_wasm(mat4 m, mat4 dest) { r2 = glmm_load(m[2]); r3 = glmm_load(m[3]); - // _MM_TRANSPOSE4_PS(r0, r1, r2, r3); + /* _MM_TRANSPOSE4_PS(r0, r1, r2, r3); */ tmp0 = wasm_i32x4_shuffle(r0, r1, 0, 4, 1, 5); tmp1 = wasm_i32x4_shuffle(r0, r1, 2, 6, 3, 7); tmp2 = wasm_i32x4_shuffle(r2, r3, 0, 4, 1, 5); tmp3 = wasm_i32x4_shuffle(r2, r3, 2, 6, 3, 7); - // r0 = _mm_movelh_ps(tmp0, tmp2); + /* r0 = _mm_movelh_ps(tmp0, tmp2); */ r0 = wasm_i32x4_shuffle(tmp0, tmp2, 0, 1, 4, 5); - // r1 = _mm_movehl_ps(tmp2, tmp0); + /* r1 = _mm_movehl_ps(tmp2, tmp0); */ r1 = wasm_i32x4_shuffle(tmp2, tmp0, 6, 7, 2, 3); - // r2 = _mm_movelh_ps(tmp1, tmp3); + /* r2 = _mm_movelh_ps(tmp1, tmp3); */ r2 = wasm_i32x4_shuffle(tmp1, tmp3, 0, 1, 4, 5); - // r3 = _mm_movehl_ps(tmp3, tmp1); + /* r3 = _mm_movehl_ps(tmp3, tmp1); */ r3 = wasm_i32x4_shuffle(tmp3, tmp1, 6, 7, 2, 3); glmm_store(dest[0], r0); @@ -186,9 +186,9 @@ glm_mat4_inv_fast_wasm(mat4 mat, mat4 dest) { r1 = glmm_load(mat[1]); /* h g f e */ r2 = glmm_load(mat[2]); /* l k j i */ r3 = glmm_load(mat[3]); /* p o n m */ - // x0 = _mm_movehl_ps(r3, r2); + /* x0 = _mm_movehl_ps(r3, r2); */ x0 = wasm_i32x4_shuffle(r3, r2, 6, 7, 2, 3); /* p o l k */ - // x3 = _mm_movelh_ps(r2, r3); + /* x3 = _mm_movelh_ps(r2, r3); */ x3 = wasm_i32x4_shuffle(r2, r3, 0, 1, 4, 5); /* n m j i */ x1 = glmm_shuff1(x0, 1, 3, 3 ,3); /* l p p p */ x2 = glmm_shuff1(x0, 0, 2, 2, 2); /* k o o o */ @@ -242,9 +242,9 @@ glm_mat4_inv_fast_wasm(mat4 mat, mat4 dest) { t2[5] = e * n - m * f; t3[5] = e * j - i * f; */ t5 = glmm_fnmadd(x7, x5, t5); - // x4 = _mm_movelh_ps(r0, r1); + /* x4 = _mm_movelh_ps(r0, r1); */ x4 = wasm_i32x4_shuffle(r0, r1, 0, 1, 4, 5); /* f e b a */ - // x5 = _mm_movehl_ps(r1, r0); + /* x5 = _mm_movehl_ps(r1, r0); */ x5 = wasm_i32x4_shuffle(r1, r0, 6, 7, 2, 3); /* h g d c */ x0 = glmm_shuff1(x4, 0, 0, 0, 2); /* a a a e */ @@ -300,7 +300,7 @@ glm_mat4_inv_fast_wasm(mat4 mat, mat4 dest) { x1 = wasm_i32x4_shuffle(v2, v3, 0, 0, 4, 4); x0 = wasm_i32x4_shuffle(x0, x1, 0, 2, 4, 6); - // x0 = _mm_rcp_ps(glmm_vhadd(wasm_f32x4_mul(x0, r0))); + /* x0 = _mm_rcp_ps(glmm_vhadd(wasm_f32x4_mul(x0, r0))); */ x0 = wasm_f32x4_div(wasm_f32x4_const_splat(1.0f), glmm_vhadd(wasm_f32x4_mul(x0, r0))); @@ -326,9 +326,9 @@ glm_mat4_inv_wasm(mat4 mat, mat4 dest) { r1 = glmm_load(mat[1]); /* h g f e */ r2 = glmm_load(mat[2]); /* l k j i */ r3 = glmm_load(mat[3]); /* p o n m */ - // x0 = _mm_movehl_ps(r3, r2); + /* x0 = _mm_movehl_ps(r3, r2); */ x0 = wasm_i32x4_shuffle(r3, r2, 6, 7, 2, 3); /* p o l k */ - // x3 = _mm_movelh_ps(r2, r3); + /* x3 = _mm_movelh_ps(r2, r3); */ x3 = wasm_i32x4_shuffle(r2, r3, 0, 1, 4, 5); /* n m j i */ x1 = glmm_shuff1(x0, 1, 3, 3 ,3); /* l p p p */ x2 = glmm_shuff1(x0, 0, 2, 2, 2); /* k o o o */ @@ -382,9 +382,9 @@ glm_mat4_inv_wasm(mat4 mat, mat4 dest) { t2[5] = e * n - m * f; t3[5] = e * j - i * f; */ t5 = glmm_fnmadd(x7, x5, t5); - // x4 = _mm_movelh_ps(r0, r1); + /* x4 = _mm_movelh_ps(r0, r1); */ x4 = wasm_i32x4_shuffle(r0, r1, 0, 1, 4, 5); /* f e b a */ - // x5 = _mm_movehl_ps(r1, r0); + /* x5 = _mm_movehl_ps(r1, r0); */ x5 = wasm_i32x4_shuffle(r1, r0, 6, 7, 2, 3); /* h g d c */ x0 = glmm_shuff1(x4, 0, 0, 0, 2); /* a a a e */ diff --git a/include/cglm/simd/wasm/quat.h b/include/cglm/simd/wasm/quat.h index f8434f1..927ea21 100644 --- a/include/cglm/simd/wasm/quat.h +++ b/include/cglm/simd/wasm/quat.h @@ -28,7 +28,7 @@ glm_quat_mul_wasm(versor p, versor q, versor dest) { xq = glmm_load(q); x1 = wasm_f32x4_const(0.f, -0.f, 0.f, -0.f); /* TODO: _mm_set1_ss() + shuff ? */ r = wasm_f32x4_mul(glmm_splat_w(xp), xq); - // x2 = _mm_unpackhi_ps(x1, x1); + /* x2 = _mm_unpackhi_ps(x1, x1); */ x2 = wasm_i32x4_shuffle(x1, x1, 2, 6, 3, 7); x3 = glmm_shuff1(x1, 3, 2, 0, 1); x = glmm_splat_x(xp); diff --git a/include/cglm/vec4.h b/include/cglm/vec4.h index 73a5662..d6ee080 100644 --- a/include/cglm/vec4.h +++ b/include/cglm/vec4.h @@ -163,7 +163,7 @@ CGLM_INLINE void glm_vec4_ucopy(vec4 v, vec4 dest) { #if defined(__wasm__) && defined(__wasm_simd128__) - // note here wasm v128.load/v128.store support unaligned loads and stores + /* note here wasm v128.load/v128.store support unaligned loads and stores */ wasm_v128_store(dest, wasm_v128_load(v)); #else dest[0] = v[0]; @@ -761,7 +761,7 @@ glm_vec4_normalize_to(vec4 v, vec4 dest) { x0 = glmm_load(v); xdot = glmm_vdot(x0, x0); - // dot = _mm_cvtss_f32(xdot); + /* dot = _mm_cvtss_f32(xdot); */ dot = wasm_f32x4_extract_lane(xdot, 0); if (dot == 0.0f) { From 7ca9a64ecf9cdc0f9871272a7a18dd8f2f073df1 Mon Sep 17 00:00:00 2001 From: myfreeer Date: Sat, 1 Apr 2023 19:38:57 +0800 Subject: [PATCH 25/34] simd128: code style --- include/cglm/simd/wasm.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/cglm/simd/wasm.h b/include/cglm/simd/wasm.h index 133f8ac..02f17e5 100644 --- a/include/cglm/simd/wasm.h +++ b/include/cglm/simd/wasm.h @@ -1,3 +1,9 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ #ifndef cglm_simd_wasm_h #define cglm_simd_wasm_h From 3a9e4df3932c26013bbda901db10f2d203712b28 Mon Sep 17 00:00:00 2001 From: myfreeer Date: Sun, 2 Apr 2023 12:39:20 +0800 Subject: [PATCH 26/34] simd128: handle both sse2 and simd128 enabled by Emscripten https://github.com/recp/cglm/pull/286#issuecomment-1492985403 --- include/cglm/affine-mat.h | 18 ++-- include/cglm/mat2.h | 19 +++-- include/cglm/mat3.h | 6 +- include/cglm/mat4.h | 68 +++++++-------- include/cglm/quat.h | 36 ++++---- include/cglm/simd/intrin.h | 2 +- include/cglm/vec4-ext.h | 26 +++--- include/cglm/vec4.h | 166 ++++++++++++++++++------------------- 8 files changed, 171 insertions(+), 170 deletions(-) diff --git a/include/cglm/affine-mat.h b/include/cglm/affine-mat.h index 5107efc..1cd4973 100644 --- a/include/cglm/affine-mat.h +++ b/include/cglm/affine-mat.h @@ -53,12 +53,12 @@ CGLM_INLINE void glm_mul(mat4 m1, mat4 m2, mat4 dest) { -#ifdef __AVX__ +#if defined(__wasm__) && defined(__wasm_simd128__) + glm_mul_wasm(m1, m2, dest); +#elif defined(__AVX__) glm_mul_avx(m1, m2, dest); #elif defined( __SSE__ ) || defined( __SSE2__ ) glm_mul_sse2(m1, m2, dest); -#elif defined(__wasm__) && defined(__wasm_simd128__) - glm_mul_wasm(m1, m2, dest); #elif defined(CGLM_NEON_FP) glm_mul_neon(m1, m2, dest); #else @@ -113,10 +113,10 @@ glm_mul(mat4 m1, mat4 m2, mat4 dest) { CGLM_INLINE void glm_mul_rot(mat4 m1, mat4 m2, mat4 dest) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - glm_mul_rot_sse2(m1, m2, dest); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glm_mul_rot_wasm(m1, m2, dest); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + glm_mul_rot_sse2(m1, m2, dest); #elif defined(CGLM_NEON_FP) glm_mul_rot_neon(m1, m2, dest); #else @@ -164,10 +164,10 @@ glm_mul_rot(mat4 m1, mat4 m2, mat4 dest) { CGLM_INLINE void glm_inv_tr(mat4 mat) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - glm_inv_tr_sse2(mat); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glm_inv_tr_wasm(mat); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + glm_inv_tr_sse2(mat); #elif defined(CGLM_NEON_FP) glm_inv_tr_neon(mat); #else diff --git a/include/cglm/mat2.h b/include/cglm/mat2.h index dc71185..918e965 100644 --- a/include/cglm/mat2.h +++ b/include/cglm/mat2.h @@ -136,10 +136,10 @@ glm_mat2_zero(mat2 mat) { CGLM_INLINE void glm_mat2_mul(mat2 m1, mat2 m2, mat2 dest) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - glm_mat2_mul_sse2(m1, m2, dest); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glm_mat2_mul_wasm(m1, m2, dest); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + glm_mat2_mul_sse2(m1, m2, dest); #elif defined(CGLM_NEON_FP) glm_mat2_mul_neon(m1, m2, dest); #else @@ -166,10 +166,10 @@ glm_mat2_mul(mat2 m1, mat2 m2, mat2 dest) { CGLM_INLINE void glm_mat2_transpose_to(mat2 m, mat2 dest) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - glm_mat2_transp_sse2(m, dest); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glm_mat2_transp_wasm(m, dest); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + glm_mat2_transp_sse2(m, dest); #else dest[0][0] = m[0][0]; dest[0][1] = m[1][0]; @@ -230,10 +230,11 @@ glm_mat2_trace(mat2 m) { CGLM_INLINE void glm_mat2_scale(mat2 m, float s) { -#if defined( __SSE__ ) || defined( __SSE2__ ) +#if defined(__wasm__) && defined(__wasm_simd128__) + glmm_store(m[0], wasm_f32x4_mul(wasm_v128_load(m[0]), + wasm_f32x4_splat(s))); +#elif defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(m[0], _mm_mul_ps(_mm_loadu_ps(m[0]), _mm_set1_ps(s))); -#elif defined(__wasm__) && defined(__wasm_simd128__) - glmm_store(m[0], wasm_f32x4_mul(wasm_v128_load(m[0]), wasm_f32x4_splat(s))); #elif defined(CGLM_NEON_FP) vst1q_f32(m[0], vmulq_f32(vld1q_f32(m[0]), vdupq_n_f32(s))); #else diff --git a/include/cglm/mat3.h b/include/cglm/mat3.h index cbfab30..69f0454 100644 --- a/include/cglm/mat3.h +++ b/include/cglm/mat3.h @@ -152,10 +152,10 @@ glm_mat3_zero(mat3 mat) { CGLM_INLINE void glm_mat3_mul(mat3 m1, mat3 m2, mat3 dest) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - glm_mat3_mul_sse2(m1, m2, dest); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glm_mat3_mul_wasm(m1, m2, dest); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + glm_mat3_mul_sse2(m1, m2, dest); #else float a00 = m1[0][0], a01 = m1[0][1], a02 = m1[0][2], a10 = m1[1][0], a11 = m1[1][1], a12 = m1[1][2], diff --git a/include/cglm/mat4.h b/include/cglm/mat4.h index 5eb2879..c75dfa5 100644 --- a/include/cglm/mat4.h +++ b/include/cglm/mat4.h @@ -125,15 +125,15 @@ glm_mat4_ucopy(mat4 mat, mat4 dest) { CGLM_INLINE void glm_mat4_copy(mat4 mat, mat4 dest) { -#ifdef __AVX__ - glmm_store256(dest[0], glmm_load256(mat[0])); - glmm_store256(dest[2], glmm_load256(mat[2])); -#elif defined( __SSE__ ) || defined( __SSE2__ ) +#if defined(__wasm__) && defined(__wasm_simd128__) glmm_store(dest[0], glmm_load(mat[0])); glmm_store(dest[1], glmm_load(mat[1])); glmm_store(dest[2], glmm_load(mat[2])); glmm_store(dest[3], glmm_load(mat[3])); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#elif defined(__AVX__) + glmm_store256(dest[0], glmm_load256(mat[0])); + glmm_store256(dest[2], glmm_load256(mat[2])); +#elif defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(dest[0], glmm_load(mat[0])); glmm_store(dest[1], glmm_load(mat[1])); glmm_store(dest[2], glmm_load(mat[2])); @@ -196,7 +196,14 @@ glm_mat4_identity_array(mat4 * __restrict mat, size_t count) { CGLM_INLINE void glm_mat4_zero(mat4 mat) { -#ifdef __AVX__ +#if defined(__wasm__) && defined(__wasm_simd128__) + glmm_128 x0; + x0 = wasm_f32x4_const(0.f, 0.f, 0.f, 0.f); + glmm_store(mat[0], x0); + glmm_store(mat[1], x0); + glmm_store(mat[2], x0); + glmm_store(mat[3], x0); +#elif defined(__AVX__) __m256 y0; y0 = _mm256_setzero_ps(); glmm_store256(mat[0], y0); @@ -208,13 +215,6 @@ glm_mat4_zero(mat4 mat) { glmm_store(mat[1], x0); glmm_store(mat[2], x0); glmm_store(mat[3], x0); -#elif defined(__wasm__) && defined(__wasm_simd128__) - glmm_128 x0; - x0 = wasm_f32x4_const(0.f, 0.f, 0.f, 0.f); - glmm_store(mat[0], x0); - glmm_store(mat[1], x0); - glmm_store(mat[2], x0); - glmm_store(mat[3], x0); #elif defined(CGLM_NEON_FP) glmm_128 x0; x0 = vdupq_n_f32(0.0f); @@ -313,12 +313,12 @@ glm_mat4_ins3(mat3 mat, mat4 dest) { CGLM_INLINE void glm_mat4_mul(mat4 m1, mat4 m2, mat4 dest) { -#ifdef __AVX__ +#if defined(__wasm__) && defined(__wasm_simd128__) + glm_mat4_mul_wasm(m1, m2, dest); +#elif defined(__AVX__) glm_mat4_mul_avx(m1, m2, dest); #elif defined( __SSE__ ) || defined( __SSE2__ ) glm_mat4_mul_sse2(m1, m2, dest); -#elif defined(__wasm__) && defined(__wasm_simd128__) - glm_mat4_mul_wasm(m1, m2, dest); #elif defined(CGLM_NEON_FP) glm_mat4_mul_neon(m1, m2, dest); #else @@ -395,10 +395,10 @@ glm_mat4_mulN(mat4 * __restrict matrices[], uint32_t len, mat4 dest) { CGLM_INLINE void glm_mat4_mulv(mat4 m, vec4 v, vec4 dest) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - glm_mat4_mulv_sse2(m, v, dest); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glm_mat4_mulv_wasm(m, v, dest); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + glm_mat4_mulv_sse2(m, v, dest); #elif defined(CGLM_NEON_FP) glm_mat4_mulv_neon(m, v, dest); #else @@ -517,10 +517,10 @@ glm_mat4_mulv3(mat4 m, vec3 v, float last, vec3 dest) { CGLM_INLINE void glm_mat4_transpose_to(mat4 m, mat4 dest) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - glm_mat4_transp_sse2(m, dest); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glm_mat4_transp_wasm(m, dest); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + glm_mat4_transp_sse2(m, dest); #elif defined(CGLM_NEON_FP) glm_mat4_transp_neon(m, dest); #else @@ -543,10 +543,10 @@ glm_mat4_transpose_to(mat4 m, mat4 dest) { CGLM_INLINE void glm_mat4_transpose(mat4 m) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - glm_mat4_transp_sse2(m, m); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glm_mat4_transp_wasm(m, m); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + glm_mat4_transp_sse2(m, m); #elif defined(CGLM_NEON_FP) glm_mat4_transp_neon(m, m); #else @@ -584,12 +584,12 @@ glm_mat4_scale_p(mat4 m, float s) { CGLM_INLINE void glm_mat4_scale(mat4 m, float s) { -#ifdef __AVX__ +#if defined(__wasm__) && defined(__wasm_simd128__) + glm_mat4_scale_wasm(m, s); +#elif defined(__AVX__) glm_mat4_scale_avx(m, s); #elif defined( __SSE__ ) || defined( __SSE2__ ) glm_mat4_scale_sse2(m, s); -#elif defined(__wasm__) && defined(__wasm_simd128__) - glm_mat4_scale_wasm(m, s); #elif defined(CGLM_NEON_FP) glm_mat4_scale_neon(m, s); #else @@ -607,10 +607,10 @@ glm_mat4_scale(mat4 m, float s) { CGLM_INLINE float glm_mat4_det(mat4 mat) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - return glm_mat4_det_sse2(mat); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) return glm_mat4_det_wasm(mat); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + return glm_mat4_det_sse2(mat); #elif defined(CGLM_NEON_FP) return glm_mat4_det_neon(mat); #else @@ -707,10 +707,10 @@ glm_mat4_inv(mat4 mat, mat4 dest) { CGLM_INLINE void glm_mat4_inv_fast(mat4 mat, mat4 dest) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - glm_mat4_inv_fast_sse2(mat, dest); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glm_mat4_inv_fast_wasm(mat, dest); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + glm_mat4_inv_fast_sse2(mat, dest); #else glm_mat4_inv(mat, dest); #endif diff --git a/include/cglm/quat.h b/include/cglm/quat.h index 5ce27ff..bc52a38 100644 --- a/include/cglm/quat.h +++ b/include/cglm/quat.h @@ -242,21 +242,7 @@ glm_quat_norm(versor q) { CGLM_INLINE void glm_quat_normalize_to(versor q, versor dest) { -#if defined( __SSE2__ ) || defined( __SSE2__ ) - __m128 xdot, x0; - float dot; - - x0 = glmm_load(q); - xdot = glmm_vdot(x0, x0); - dot = _mm_cvtss_f32(xdot); - - if (dot <= 0.0f) { - glm_quat_identity(dest); - return; - } - - glmm_store(dest, _mm_div_ps(x0, _mm_sqrt_ps(xdot))); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glmm_128 xdot, x0; float dot; @@ -271,6 +257,20 @@ glm_quat_normalize_to(versor q, versor dest) { } glmm_store(dest, wasm_f32x4_div(x0, wasm_f32x4_sqrt(xdot))); +#elif defined( __SSE2__ ) || defined( __SSE2__ ) + __m128 xdot, x0; + float dot; + + x0 = glmm_load(q); + xdot = glmm_vdot(x0, x0); + dot = _mm_cvtss_f32(xdot); + + if (dot <= 0.0f) { + glm_quat_identity(dest); + return; + } + + glmm_store(dest, _mm_div_ps(x0, _mm_sqrt_ps(xdot))); #else float dot; @@ -457,10 +457,10 @@ glm_quat_mul(versor p, versor q, versor dest) { + (a1 d2 + b1 c2 − c1 b2 + d1 a2)k a1 a2 − b1 b2 − c1 c2 − d1 d2 */ -#if defined( __SSE__ ) || defined( __SSE2__ ) - glm_quat_mul_sse2(p, q, dest); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glm_quat_mul_wasm(p, q, dest); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + glm_quat_mul_sse2(p, q, dest); #elif defined(CGLM_NEON_FP) glm_quat_mul_neon(p, q, dest); #else diff --git a/include/cglm/simd/intrin.h b/include/cglm/simd/intrin.h index 17998f5..bf8d119 100644 --- a/include/cglm/simd/intrin.h +++ b/include/cglm/simd/intrin.h @@ -113,7 +113,7 @@ # endif #endif -#if defined(CGLM_SIMD_x86) +#if defined(CGLM_SIMD_x86) && !defined(CGLM_SIMD_WASM) # include "x86.h" #endif diff --git a/include/cglm/vec4-ext.h b/include/cglm/vec4-ext.h index 06b6210..cccbb72 100644 --- a/include/cglm/vec4-ext.h +++ b/include/cglm/vec4-ext.h @@ -45,10 +45,10 @@ CGLM_INLINE void glm_vec4_broadcast(float val, vec4 d) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - glmm_store(d, _mm_set1_ps(val)); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glmm_store(d, wasm_f32x4_splat(val)); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + glmm_store(d, _mm_set1_ps(val)); #else d[0] = d[1] = d[2] = d[3] = val; #endif @@ -63,10 +63,10 @@ glm_vec4_broadcast(float val, vec4 d) { CGLM_INLINE void glm_vec4_fill(vec4 v, float val) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - glmm_store(v, _mm_set1_ps(val)); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glmm_store(v, wasm_f32x4_splat(val)); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + glmm_store(v, _mm_set1_ps(val)); #else v[0] = v[1] = v[2] = v[3] = val; #endif @@ -251,9 +251,9 @@ glm_vec4_sign(vec4 v, vec4 dest) { CGLM_INLINE void glm_vec4_abs(vec4 v, vec4 dest) { -#if defined( __SSE__ ) || defined( __SSE2__ ) +#if defined(__wasm__) && defined(__wasm_simd128__) glmm_store(dest, glmm_abs(glmm_load(v))); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#elif defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(dest, glmm_abs(glmm_load(v))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vabsq_f32(vld1q_f32(v))); @@ -290,9 +290,9 @@ glm_vec4_fract(vec4 v, vec4 dest) { CGLM_INLINE float glm_vec4_hadd(vec4 v) { -#if defined( __SSE__ ) || defined( __SSE2__ ) +#if defined(__wasm__) && defined(__wasm_simd128__) return glmm_hadd(glmm_load(v)); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#elif defined( __SSE__ ) || defined( __SSE2__ ) return glmm_hadd(glmm_load(v)); #else return v[0] + v[1] + v[2] + v[3]; @@ -308,10 +308,10 @@ glm_vec4_hadd(vec4 v) { CGLM_INLINE void glm_vec4_sqrt(vec4 v, vec4 dest) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - glmm_store(dest, _mm_sqrt_ps(glmm_load(v))); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glmm_store(dest, wasm_f32x4_sqrt(glmm_load(v))); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + glmm_store(dest, _mm_sqrt_ps(glmm_load(v))); #else dest[0] = sqrtf(v[0]); dest[1] = sqrtf(v[1]); diff --git a/include/cglm/vec4.h b/include/cglm/vec4.h index d6ee080..1d18625 100644 --- a/include/cglm/vec4.h +++ b/include/cglm/vec4.h @@ -137,9 +137,9 @@ glm_vec4_copy3(vec4 a, vec3 dest) { CGLM_INLINE void glm_vec4_copy(vec4 v, vec4 dest) { -#if defined( __SSE__ ) || defined( __SSE2__ ) +#if defined(__wasm__) && defined(__wasm_simd128__) glmm_store(dest, glmm_load(v)); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#elif defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(dest, glmm_load(v)); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vld1q_f32(v)); @@ -181,10 +181,10 @@ glm_vec4_ucopy(vec4 v, vec4 dest) { CGLM_INLINE void glm_vec4_zero(vec4 v) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - glmm_store(v, _mm_setzero_ps()); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glmm_store(v, wasm_f32x4_const_splat(0.f)); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + glmm_store(v, _mm_setzero_ps()); #elif defined(CGLM_NEON_FP) vst1q_f32(v, vdupq_n_f32(0.0f)); #else @@ -203,10 +203,10 @@ glm_vec4_zero(vec4 v) { CGLM_INLINE void glm_vec4_one(vec4 v) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - glmm_store(v, _mm_set1_ps(1.0f)); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glmm_store(v, wasm_f32x4_const_splat(1.0f)); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + glmm_store(v, _mm_set1_ps(1.0f)); #elif defined(CGLM_NEON_FP) vst1q_f32(v, vdupq_n_f32(1.0f)); #else @@ -331,10 +331,10 @@ glm_vec4_norm_inf(vec4 v) { CGLM_INLINE void glm_vec4_add(vec4 a, vec4 b, vec4 dest) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - glmm_store(dest, _mm_add_ps(glmm_load(a), glmm_load(b))); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glmm_store(dest, wasm_f32x4_add(glmm_load(a), glmm_load(b))); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + glmm_store(dest, _mm_add_ps(glmm_load(a), glmm_load(b))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vaddq_f32(vld1q_f32(a), vld1q_f32(b))); #else @@ -355,10 +355,10 @@ glm_vec4_add(vec4 a, vec4 b, vec4 dest) { CGLM_INLINE void glm_vec4_adds(vec4 v, float s, vec4 dest) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - glmm_store(dest, _mm_add_ps(glmm_load(v), _mm_set1_ps(s))); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glmm_store(dest, wasm_f32x4_add(glmm_load(v), wasm_f32x4_splat(s))); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + glmm_store(dest, _mm_add_ps(glmm_load(v), _mm_set1_ps(s))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vaddq_f32(vld1q_f32(v), vdupq_n_f32(s))); #else @@ -379,10 +379,10 @@ glm_vec4_adds(vec4 v, float s, vec4 dest) { CGLM_INLINE void glm_vec4_sub(vec4 a, vec4 b, vec4 dest) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - glmm_store(dest, _mm_sub_ps(glmm_load(a), glmm_load(b))); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glmm_store(dest, wasm_f32x4_sub(glmm_load(a), glmm_load(b))); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + glmm_store(dest, _mm_sub_ps(glmm_load(a), glmm_load(b))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vsubq_f32(vld1q_f32(a), vld1q_f32(b))); #else @@ -403,10 +403,10 @@ glm_vec4_sub(vec4 a, vec4 b, vec4 dest) { CGLM_INLINE void glm_vec4_subs(vec4 v, float s, vec4 dest) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - glmm_store(dest, _mm_sub_ps(glmm_load(v), _mm_set1_ps(s))); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glmm_store(dest, wasm_f32x4_sub(glmm_load(v), wasm_f32x4_splat(s))); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + glmm_store(dest, _mm_sub_ps(glmm_load(v), _mm_set1_ps(s))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vsubq_f32(vld1q_f32(v), vdupq_n_f32(s))); #else @@ -427,10 +427,10 @@ glm_vec4_subs(vec4 v, float s, vec4 dest) { CGLM_INLINE void glm_vec4_mul(vec4 a, vec4 b, vec4 dest) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - glmm_store(dest, _mm_mul_ps(glmm_load(a), glmm_load(b))); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glmm_store(dest, wasm_f32x4_mul(glmm_load(a), glmm_load(b))); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + glmm_store(dest, _mm_mul_ps(glmm_load(a), glmm_load(b))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vmulq_f32(vld1q_f32(a), vld1q_f32(b))); #else @@ -451,10 +451,10 @@ glm_vec4_mul(vec4 a, vec4 b, vec4 dest) { CGLM_INLINE void glm_vec4_scale(vec4 v, float s, vec4 dest) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - glmm_store(dest, _mm_mul_ps(glmm_load(v), _mm_set1_ps(s))); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glmm_store(dest, wasm_f32x4_mul(glmm_load(v), wasm_f32x4_splat(s))); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + glmm_store(dest, _mm_mul_ps(glmm_load(v), _mm_set1_ps(s))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vmulq_f32(vld1q_f32(v), vdupq_n_f32(s))); #else @@ -516,10 +516,10 @@ glm_vec4_div(vec4 a, vec4 b, vec4 dest) { CGLM_INLINE void glm_vec4_divs(vec4 v, float s, vec4 dest) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - glmm_store(dest, _mm_div_ps(glmm_load(v), _mm_set1_ps(s))); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glmm_store(dest, wasm_f32x4_div(glmm_load(v), wasm_f32x4_splat(s))); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + glmm_store(dest, _mm_div_ps(glmm_load(v), _mm_set1_ps(s))); #else glm_vec4_scale(v, 1.0f / s, dest); #endif @@ -537,14 +537,14 @@ glm_vec4_divs(vec4 v, float s, vec4 dest) { CGLM_INLINE void glm_vec4_addadd(vec4 a, vec4 b, vec4 dest) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - glmm_store(dest, _mm_add_ps(glmm_load(dest), - _mm_add_ps(glmm_load(a), - glmm_load(b)))); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glmm_store(dest, wasm_f32x4_add( glmm_load(dest), wasm_f32x4_add(glmm_load(a), glmm_load(b)))); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + glmm_store(dest, _mm_add_ps(glmm_load(dest), + _mm_add_ps(glmm_load(a), + glmm_load(b)))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vaddq_f32(vld1q_f32(dest), vaddq_f32(vld1q_f32(a), @@ -569,14 +569,14 @@ glm_vec4_addadd(vec4 a, vec4 b, vec4 dest) { CGLM_INLINE void glm_vec4_subadd(vec4 a, vec4 b, vec4 dest) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - glmm_store(dest, _mm_add_ps(glmm_load(dest), - _mm_sub_ps(glmm_load(a), - glmm_load(b)))); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glmm_store(dest, wasm_f32x4_add( glmm_load(dest), wasm_f32x4_sub(glmm_load(a), glmm_load(b)))); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + glmm_store(dest, _mm_add_ps(glmm_load(dest), + _mm_sub_ps(glmm_load(a), + glmm_load(b)))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vaddq_f32(vld1q_f32(dest), vsubq_f32(vld1q_f32(a), @@ -645,14 +645,14 @@ glm_vec4_muladds(vec4 a, float s, vec4 dest) { CGLM_INLINE void glm_vec4_maxadd(vec4 a, vec4 b, vec4 dest) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - glmm_store(dest, _mm_add_ps(glmm_load(dest), - _mm_max_ps(glmm_load(a), - glmm_load(b)))); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glmm_store(dest, wasm_f32x4_add( glmm_load(dest), wasm_f32x4_max(glmm_load(a), glmm_load(b)))); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + glmm_store(dest, _mm_add_ps(glmm_load(dest), + _mm_max_ps(glmm_load(a), + glmm_load(b)))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vaddq_f32(vld1q_f32(dest), vmaxq_f32(vld1q_f32(a), @@ -677,14 +677,14 @@ glm_vec4_maxadd(vec4 a, vec4 b, vec4 dest) { CGLM_INLINE void glm_vec4_minadd(vec4 a, vec4 b, vec4 dest) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - glmm_store(dest, _mm_add_ps(glmm_load(dest), - _mm_min_ps(glmm_load(a), - glmm_load(b)))); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glmm_store(dest, wasm_f32x4_add( glmm_load(dest), wasm_f32x4_min(glmm_load(a), glmm_load(b)))); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + glmm_store(dest, _mm_add_ps(glmm_load(dest), + _mm_min_ps(glmm_load(a), + glmm_load(b)))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vaddq_f32(vld1q_f32(dest), vminq_f32(vld1q_f32(a), @@ -706,11 +706,11 @@ glm_vec4_minadd(vec4 a, vec4 b, vec4 dest) { CGLM_INLINE void glm_vec4_negate_to(vec4 v, vec4 dest) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - glmm_store(dest, _mm_xor_ps(glmm_load(v), _mm_set1_ps(-0.0f))); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glmm_store(dest, wasm_v128_xor(glmm_load(v), wasm_f32x4_const_splat(-0.0f))); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + glmm_store(dest, _mm_xor_ps(glmm_load(v), _mm_set1_ps(-0.0f))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vnegq_f32(vld1q_f32(v))); #else @@ -741,21 +741,7 @@ glm_vec4_negate(vec4 v) { CGLM_INLINE void glm_vec4_normalize_to(vec4 v, vec4 dest) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - __m128 xdot, x0; - float dot; - - x0 = glmm_load(v); - xdot = glmm_vdot(x0, x0); - dot = _mm_cvtss_f32(xdot); - - if (dot == 0.0f) { - glmm_store(dest, _mm_setzero_ps()); - return; - } - - glmm_store(dest, _mm_div_ps(x0, _mm_sqrt_ps(xdot))); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glmm_128 xdot, x0; float dot; @@ -770,6 +756,20 @@ glm_vec4_normalize_to(vec4 v, vec4 dest) { } glmm_store(dest, wasm_f32x4_div(x0, wasm_f32x4_sqrt(xdot))); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + __m128 xdot, x0; + float dot; + + x0 = glmm_load(v); + xdot = glmm_vdot(x0, x0); + dot = _mm_cvtss_f32(xdot); + + if (dot == 0.0f) { + glmm_store(dest, _mm_setzero_ps()); + return; + } + + glmm_store(dest, _mm_div_ps(x0, _mm_sqrt_ps(xdot))); #else float norm; @@ -805,10 +805,10 @@ glm_vec4_normalize(vec4 v) { CGLM_INLINE float glm_vec4_distance(vec4 a, vec4 b) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - return glmm_norm(_mm_sub_ps(glmm_load(a), glmm_load(b))); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) return glmm_norm(wasm_f32x4_sub(glmm_load(a), glmm_load(b))); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + return glmm_norm(_mm_sub_ps(glmm_load(a), glmm_load(b))); #elif defined(CGLM_NEON_FP) return glmm_norm(vsubq_f32(glmm_load(a), glmm_load(b))); #else @@ -829,10 +829,10 @@ glm_vec4_distance(vec4 a, vec4 b) { CGLM_INLINE float glm_vec4_distance2(vec4 a, vec4 b) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - return glmm_norm2(_mm_sub_ps(glmm_load(a), glmm_load(b))); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) return glmm_norm2(wasm_f32x4_sub(glmm_load(a), glmm_load(b))); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + return glmm_norm2(_mm_sub_ps(glmm_load(a), glmm_load(b))); #elif defined(CGLM_NEON_FP) return glmm_norm2(vsubq_f32(glmm_load(a), glmm_load(b))); #else @@ -853,10 +853,10 @@ glm_vec4_distance2(vec4 a, vec4 b) { CGLM_INLINE void glm_vec4_maxv(vec4 a, vec4 b, vec4 dest) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - glmm_store(dest, _mm_max_ps(glmm_load(a), glmm_load(b))); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glmm_store(dest, wasm_f32x4_max(glmm_load(a), glmm_load(b))); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + glmm_store(dest, _mm_max_ps(glmm_load(a), glmm_load(b))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vmaxq_f32(vld1q_f32(a), vld1q_f32(b))); #else @@ -877,10 +877,10 @@ glm_vec4_maxv(vec4 a, vec4 b, vec4 dest) { CGLM_INLINE void glm_vec4_minv(vec4 a, vec4 b, vec4 dest) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - glmm_store(dest, _mm_min_ps(glmm_load(a), glmm_load(b))); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glmm_store(dest, wasm_f32x4_min(glmm_load(a), glmm_load(b))); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + glmm_store(dest, _mm_min_ps(glmm_load(a), glmm_load(b))); #elif defined(CGLM_NEON_FP) vst1q_f32(dest, vminq_f32(vld1q_f32(a), vld1q_f32(b))); #else @@ -901,13 +901,13 @@ glm_vec4_minv(vec4 a, vec4 b, vec4 dest) { CGLM_INLINE void glm_vec4_clamp(vec4 v, float minVal, float maxVal) { -#if defined( __SSE__ ) || defined( __SSE2__ ) - glmm_store(v, _mm_min_ps(_mm_max_ps(glmm_load(v), _mm_set1_ps(minVal)), - _mm_set1_ps(maxVal))); -#elif defined(__wasm__) && defined(__wasm_simd128__) +#if defined(__wasm__) && defined(__wasm_simd128__) glmm_store(v, wasm_f32x4_min( wasm_f32x4_max(glmm_load(v), wasm_f32x4_splat(minVal)), wasm_f32x4_splat(maxVal))); +#elif defined( __SSE__ ) || defined( __SSE2__ ) + glmm_store(v, _mm_min_ps(_mm_max_ps(glmm_load(v), _mm_set1_ps(minVal)), + _mm_set1_ps(maxVal))); #elif defined(CGLM_NEON_FP) vst1q_f32(v, vminq_f32(vmaxq_f32(vld1q_f32(v), vdupq_n_f32(minVal)), vdupq_n_f32(maxVal))); From 07bc4be18beff070ee8b0a39137c1b810e9b786c Mon Sep 17 00:00:00 2001 From: myfreeer Date: Sun, 2 Apr 2023 13:09:00 +0800 Subject: [PATCH 27/34] simd128: cmake options After this, the required options for cmake are listed below: ``` -DCMAKE_C_FLAGS="-msimd128" -DCMAKE_TOOLCHAIN_FILE=/path/to/wasi-sdk-19.0/share/cmake/wasi-sdk.cmake -DWASI_SDK_PREFIX=/path/to/wasi-sdk-19.0 -DCGLM_USE_TEST=ON ``` If compiling to wasi with simd128 support, `-DCMAKE_C_FLAGS="-msimd128"` can be removed. If tests are not needed, `-DCGLM_USE_TEST=ON` can be removed. --- CMakeLists.txt | 5 +++++ test/CMakeLists.txt | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7633d94..5594581 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,11 @@ option(CGLM_STATIC "Static build" OFF) option(CGLM_USE_C99 "" OFF) option(CGLM_USE_TEST "Enable Tests" OFF) +if(CMAKE_SYSTEM_NAME STREQUAL WASI) + set(CGLM_STATIC ON CACHE BOOL "Static option" FORCE) + set(CGLM_SHARED OFF CACHE BOOL "Shared option" FORCE) +endif() + if(NOT CGLM_STATIC AND CGLM_SHARED) set(CGLM_BUILD SHARED) else(CGLM_STATIC) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 26fef9c..0c76203 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -22,6 +22,11 @@ set(TEST_RUNNER_PARAMS "") add_executable(${TEST_MAIN} ${TESTFILES}) target_compile_definitions(${TEST_MAIN} PRIVATE CGLM_DEFINE_PRINTS=1) +if(CMAKE_SYSTEM_NAME STREQUAL WASI) + target_compile_definitions(${TEST_MAIN} PRIVATE _WASI_EMULATED_PROCESS_CLOCKS=1) + target_link_options(${TEST_MAIN} PRIVATE "-lwasi-emulated-process-clocks") +endif() + if(NOT MSVC) target_link_libraries(${TEST_MAIN} PRIVATE m) endif() From d7c0edcbd90e50e4b36f47f76853006c5abb67d7 Mon Sep 17 00:00:00 2001 From: myfreeer Date: Sat, 8 Apr 2023 13:40:46 +0800 Subject: [PATCH 28/34] simd128: minor lint --- include/cglm/mat4.h | 2 +- include/cglm/simd/wasm.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/cglm/mat4.h b/include/cglm/mat4.h index c75dfa5..932878d 100644 --- a/include/cglm/mat4.h +++ b/include/cglm/mat4.h @@ -198,7 +198,7 @@ void glm_mat4_zero(mat4 mat) { #if defined(__wasm__) && defined(__wasm_simd128__) glmm_128 x0; - x0 = wasm_f32x4_const(0.f, 0.f, 0.f, 0.f); + x0 = wasm_f32x4_const_splat(0.f); glmm_store(mat[0], x0); glmm_store(mat[1], x0); glmm_store(mat[2], x0); diff --git a/include/cglm/simd/wasm.h b/include/cglm/simd/wasm.h index 02f17e5..48cda4c 100644 --- a/include/cglm/simd/wasm.h +++ b/include/cglm/simd/wasm.h @@ -29,7 +29,7 @@ static inline glmm_128 glmm_abs(glmm_128 x) { - return wasm_v128_andnot(x, wasm_f32x4_const_splat(-0.0f)); + return wasm_f32x4_abs(x); } static inline From 18ed15c53a2bf9d09104aabcfff46d58c27f8109 Mon Sep 17 00:00:00 2001 From: myfreeer Date: Sat, 8 Apr 2023 14:05:01 +0800 Subject: [PATCH 29/34] wasm: init github action ci --- .github/workflows/cmake-wasm.yml | 57 ++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 .github/workflows/cmake-wasm.yml diff --git a/.github/workflows/cmake-wasm.yml b/.github/workflows/cmake-wasm.yml new file mode 100644 index 0000000..45d8120 --- /dev/null +++ b/.github/workflows/cmake-wasm.yml @@ -0,0 +1,57 @@ +name: CMake WebAssembly + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +env: + wasmtime_version: v7.0.0 + wasmer_version: v3.1.1 + +jobs: + build_wasi_sdk: + strategy: + matrix: + BUILD_TYPE: [Release, Debug, RelWithDebInfo, MinSizeRel] + C_FLAGS: ['', '-msimd128'] + wasi_sdk_version: [19, 20] + # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac. + # You can convert this to a matrix build if you need cross-platform coverage. + # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Downloading wasi-sdk + run: | + cd ${{github.workspace}} + wget https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${{matrix.wasi_sdk_version}}/wasi-sdk-${{matrix.wasi_sdk_version}}.0-linux.tar.gz + tar xf wasi-sdk-${{matrix.wasi_sdk_version}}.0-linux.tar.gz + + - name: Configure CMake + # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. + # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type + run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{matrix.BUILD_TYPE}} -DCMAKE_C_FLAGS="${{matrix.C_FLAGS}}" -DCMAKE_TOOLCHAIN_FILE=${{github.workspace}}/wasi-sdk-${{matrix.wasi_sdk_version}}.0/share/cmake/wasi-sdk.cmake -DWASI_SDK_PREFIX=/path/to/wasi-sdk-${{matrix.wasi_sdk_version}}.0 -DCGLM_USE_TEST=ON + + - name: Build + # Build your program with the given configuration + run: cmake --build ${{github.workspace}}/build --config ${{matrix.BUILD_TYPE}} + + - name: Test with wasmtime + run: | + cd ${{github.workspace}} + wget https://github.com/bytecodealliance/wasmtime/releases/download/${{env.wasmtime_version}}/wasmtime-${{env.wasmtime_version}}-x86_64-linux.tar.xz + tar xf wasmtime-${{env.wasmtime_version}}-x86_64-linux.tar.xz + ./wasmtime-${{env.wasmtime_version}}-x86_64-linux/wasmtime run --wasm-features simd ${{github.workspace}}/build/tests + + - name: Test with wasmer + run: | + cd ${{github.workspace}} + mkdir wasmer + cd wasmer + wget https://github.com/wasmerio/wasmer/releases/download/${{env.wasmer_version}}/wasmer-linux-amd64.tar.gz + tar xf wasmer-linux-amd64.tar.gz + ./bin/wasmer run --enable-simd ${{github.workspace}}/build/tests From 884be84506cfe5d7b509afa297b8afa9d474be18 Mon Sep 17 00:00:00 2001 From: myfreeer Date: Sat, 8 Apr 2023 14:07:00 +0800 Subject: [PATCH 30/34] wasm: fix clang path for github actions --- .github/workflows/cmake-wasm.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cmake-wasm.yml b/.github/workflows/cmake-wasm.yml index 45d8120..e9a6bf8 100644 --- a/.github/workflows/cmake-wasm.yml +++ b/.github/workflows/cmake-wasm.yml @@ -34,7 +34,7 @@ jobs: - name: Configure CMake # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type - run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{matrix.BUILD_TYPE}} -DCMAKE_C_FLAGS="${{matrix.C_FLAGS}}" -DCMAKE_TOOLCHAIN_FILE=${{github.workspace}}/wasi-sdk-${{matrix.wasi_sdk_version}}.0/share/cmake/wasi-sdk.cmake -DWASI_SDK_PREFIX=/path/to/wasi-sdk-${{matrix.wasi_sdk_version}}.0 -DCGLM_USE_TEST=ON + run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{matrix.BUILD_TYPE}} -DCMAKE_C_FLAGS="${{matrix.C_FLAGS}}" -DCMAKE_TOOLCHAIN_FILE=${{github.workspace}}/wasi-sdk-${{matrix.wasi_sdk_version}}.0/share/cmake/wasi-sdk.cmake -DWASI_SDK_PREFIX=${{github.workspace}}/wasi-sdk-${{matrix.wasi_sdk_version}}.0 -DCGLM_USE_TEST=ON - name: Build # Build your program with the given configuration From 061f096d8fb0530114a92a2e188f047176975c63 Mon Sep 17 00:00:00 2001 From: myfreeer Date: Sat, 8 Apr 2023 14:12:23 +0800 Subject: [PATCH 31/34] wasm: add --no-verbose to wget --- .github/workflows/cmake-wasm.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cmake-wasm.yml b/.github/workflows/cmake-wasm.yml index e9a6bf8..5f82cc2 100644 --- a/.github/workflows/cmake-wasm.yml +++ b/.github/workflows/cmake-wasm.yml @@ -28,7 +28,7 @@ jobs: - name: Downloading wasi-sdk run: | cd ${{github.workspace}} - wget https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${{matrix.wasi_sdk_version}}/wasi-sdk-${{matrix.wasi_sdk_version}}.0-linux.tar.gz + wget --no-verbose https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${{matrix.wasi_sdk_version}}/wasi-sdk-${{matrix.wasi_sdk_version}}.0-linux.tar.gz tar xf wasi-sdk-${{matrix.wasi_sdk_version}}.0-linux.tar.gz - name: Configure CMake @@ -43,7 +43,7 @@ jobs: - name: Test with wasmtime run: | cd ${{github.workspace}} - wget https://github.com/bytecodealliance/wasmtime/releases/download/${{env.wasmtime_version}}/wasmtime-${{env.wasmtime_version}}-x86_64-linux.tar.xz + wget --no-verbose https://github.com/bytecodealliance/wasmtime/releases/download/${{env.wasmtime_version}}/wasmtime-${{env.wasmtime_version}}-x86_64-linux.tar.xz tar xf wasmtime-${{env.wasmtime_version}}-x86_64-linux.tar.xz ./wasmtime-${{env.wasmtime_version}}-x86_64-linux/wasmtime run --wasm-features simd ${{github.workspace}}/build/tests @@ -52,6 +52,6 @@ jobs: cd ${{github.workspace}} mkdir wasmer cd wasmer - wget https://github.com/wasmerio/wasmer/releases/download/${{env.wasmer_version}}/wasmer-linux-amd64.tar.gz + wget --no-verbose https://github.com/wasmerio/wasmer/releases/download/${{env.wasmer_version}}/wasmer-linux-amd64.tar.gz tar xf wasmer-linux-amd64.tar.gz ./bin/wasmer run --enable-simd ${{github.workspace}}/build/tests From 1940f1d4bc21f9cbfeab480e520f2790de2535c8 Mon Sep 17 00:00:00 2001 From: myfreeer Date: Sat, 8 Apr 2023 15:21:29 +0800 Subject: [PATCH 32/34] wasm: build with emsdk on github actions --- .github/workflows/cmake-wasm.yml | 40 ++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/.github/workflows/cmake-wasm.yml b/.github/workflows/cmake-wasm.yml index 5f82cc2..5f7d7d0 100644 --- a/.github/workflows/cmake-wasm.yml +++ b/.github/workflows/cmake-wasm.yml @@ -43,6 +43,7 @@ jobs: - name: Test with wasmtime run: | cd ${{github.workspace}} + ls -lh ${{github.workspace}}/build/ wget --no-verbose https://github.com/bytecodealliance/wasmtime/releases/download/${{env.wasmtime_version}}/wasmtime-${{env.wasmtime_version}}-x86_64-linux.tar.xz tar xf wasmtime-${{env.wasmtime_version}}-x86_64-linux.tar.xz ./wasmtime-${{env.wasmtime_version}}-x86_64-linux/wasmtime run --wasm-features simd ${{github.workspace}}/build/tests @@ -55,3 +56,42 @@ jobs: wget --no-verbose https://github.com/wasmerio/wasmer/releases/download/${{env.wasmer_version}}/wasmer-linux-amd64.tar.gz tar xf wasmer-linux-amd64.tar.gz ./bin/wasmer run --enable-simd ${{github.workspace}}/build/tests + + build_emsdk: + strategy: + matrix: + BUILD_TYPE: [Release, Debug, RelWithDebInfo, MinSizeRel] + C_FLAGS: ['', '-msimd128', '-msse -msse2 -msimd128', '-msse -msse2 -msse3 -msse4 -msimd128'] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Setup emsdk + uses: mymindstorm/setup-emsdk@v11 + + - name: Verify emsdk + run: emcc -v + + - name: Configure CMake + # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. + # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type + run: emcmake cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{matrix.BUILD_TYPE}} -DCMAKE_C_FLAGS="${{matrix.C_FLAGS}}" -DCMAKE_EXE_LINKER_FLAGS="-s STANDALONE_WASM" -DCGLM_STATIC=ON -DCGLM_USE_TEST=ON + + - name: Build + # Build your program with the given configuration + run: cmake --build ${{github.workspace}}/build --config ${{matrix.BUILD_TYPE}} + + - name: Test with wasmtime + run: | + cd ${{github.workspace}} + ls -lh ${{github.workspace}}/build/ + wget --no-verbose https://github.com/bytecodealliance/wasmtime/releases/download/${{env.wasmtime_version}}/wasmtime-${{env.wasmtime_version}}-x86_64-linux.tar.xz + tar xf wasmtime-${{env.wasmtime_version}}-x86_64-linux.tar.xz + ./wasmtime-${{env.wasmtime_version}}-x86_64-linux/wasmtime run --wasm-features simd ${{github.workspace}}/build/tests.wasm + - name: Test with wasmer + run: | + cd ${{github.workspace}} + mkdir wasmer + cd wasmer + wget --no-verbose https://github.com/wasmerio/wasmer/releases/download/${{env.wasmer_version}}/wasmer-linux-amd64.tar.gz + tar xf wasmer-linux-amd64.tar.gz + ./bin/wasmer run --enable-simd ${{github.workspace}}/build/tests.wasm From 765771227aaac8847b645ec3152e29f92c1310a1 Mon Sep 17 00:00:00 2001 From: myfreeer Date: Sat, 8 Apr 2023 18:28:16 +0800 Subject: [PATCH 33/34] io: add case of wasm simd128 --- include/cglm/io.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/cglm/io.h b/include/cglm/io.h index 12c3db0..2b8136f 100644 --- a/include/cglm/io.h +++ b/include/cglm/io.h @@ -68,7 +68,10 @@ CGLM_INLINE void glm_arch_print_name(FILE* __restrict ostream) { -#ifdef CGLM_SIMD_x86 +#if defined(CGLM_SIMD_WASM) + fprintf(ostream, CGLM_PRINT_COLOR "\ncglm arch: wasm SIMD128" + "\n\n" CGLM_PRINT_COLOR_RESET); +#elif defined(CGLM_SIMD_x86) fprintf(ostream, CGLM_PRINT_COLOR "\ncglm arch: x86 SSE*" #ifdef __AVX__ " AVX" From 81b7c9027113b32f7a10bb5bd3b988f2a39c39ca Mon Sep 17 00:00:00 2001 From: myfreeer Date: Sat, 15 Apr 2023 22:06:04 +0800 Subject: [PATCH 34/34] simd128: simplify calls --- include/cglm/simd/wasm.h | 3 +-- include/cglm/simd/wasm/affine.h | 3 +-- include/cglm/vec4.h | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/include/cglm/simd/wasm.h b/include/cglm/simd/wasm.h index 48cda4c..648e1bb 100644 --- a/include/cglm/simd/wasm.h +++ b/include/cglm/simd/wasm.h @@ -181,8 +181,7 @@ glmm_fmsub(glmm_128 a, glmm_128 b, glmm_128 c) { static inline glmm_128 glmm_fnmsub(glmm_128 a, glmm_128 b, glmm_128 c) { - return wasm_v128_xor(wasm_f32x4_add(wasm_f32x4_mul(a, b), c), - wasm_f32x4_const_splat(-0.0f)); + return wasm_f32x4_neg(wasm_f32x4_add(wasm_f32x4_mul(a, b), c)); } #endif diff --git a/include/cglm/simd/wasm/affine.h b/include/cglm/simd/wasm/affine.h index 59b36ac..80b98fb 100644 --- a/include/cglm/simd/wasm/affine.h +++ b/include/cglm/simd/wasm/affine.h @@ -110,11 +110,10 @@ glm_inv_tr_wasm(mat4 mat) { x2 = glmm_shuff1(r3, 0, 0, 0, 0); x3 = glmm_shuff1(r3, 1, 1, 1, 1); x4 = glmm_shuff1(r3, 2, 2, 2, 2); - x5 = wasm_f32x4_const_splat(-0.f); x0 = glmm_fmadd(r0, x2, glmm_fmadd(r1, x3, wasm_f32x4_mul(r2, x4))); - x0 = wasm_v128_xor(x0, x5); + x0 = wasm_f32x4_neg(x0); x0 = wasm_f32x4_add(x0, x1); diff --git a/include/cglm/vec4.h b/include/cglm/vec4.h index 1d18625..de29941 100644 --- a/include/cglm/vec4.h +++ b/include/cglm/vec4.h @@ -707,8 +707,7 @@ CGLM_INLINE void glm_vec4_negate_to(vec4 v, vec4 dest) { #if defined(__wasm__) && defined(__wasm_simd128__) - glmm_store(dest, wasm_v128_xor(glmm_load(v), - wasm_f32x4_const_splat(-0.0f))); + glmm_store(dest, wasm_f32x4_neg(glmm_load(v))); #elif defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(dest, _mm_xor_ps(glmm_load(v), _mm_set1_ps(-0.0f))); #elif defined(CGLM_NEON_FP)