9#if defined(VECMAT_USE_F64)
13 return _mm256_loadu_pd(v->
v);
18 _mm256_storeu_pd(v->
v, x);
23 const __m256d zero = _mm256_setzero_pd();
24 const __m256d eqz = _mm256_cmp_pd(b, zero, _CMP_EQ_OQ);
25 const __m256d safe = _mm256_blendv_pd(b, _mm256_set1_pd(1.0), eqz);
26 return _mm256_andnot_pd(eqz, _mm256_div_pd(a, safe));
29static inline __m256d
sign4(__m256d x)
31 const __m256d zero = _mm256_setzero_pd();
32 const __m256d pos = _mm256_and_pd(_mm256_cmp_pd(x, zero, _CMP_GT_OQ), _mm256_set1_pd(1.0));
33 const __m256d neg = _mm256_and_pd(_mm256_cmp_pd(x, zero, _CMP_LT_OQ), _mm256_set1_pd(-1.0));
34 return _mm256_or_pd(pos, neg);
54 store4(res, _mm256_mul_pd(
load4(v), _mm256_set1_pd(s)));
60 store4(res, _mm256_setzero_pd());
63 store4(res, _mm256_div_pd(
load4(v), _mm256_set1_pd(s)));
68 store4(res, _mm256_xor_pd(
load4(v), _mm256_set1_pd(-0.0)));
73 const __m256d mask = _mm256_castsi256_pd(_mm256_set1_epi64x(0x7FFFFFFFFFFFFFFFLL));
79 const __m256d x =
load4(v);
80 const __m256d sq = _mm256_mul_pd(x, x);
81 const __m128d hi = _mm256_extractf128_pd(sq, 1);
82 const __m128d lo = _mm256_castpd256_pd128(sq);
83 __m128d sum = _mm_add_pd(lo, hi);
84 sum = _mm_add_sd(sum, _mm_unpackhi_pd(sum, sum));
85 const double len2 = _mm_cvtsd_f64(sum);
91 double y = (double)_mm_cvtss_f32(_mm_rsqrt_ss(_mm_set_ss((
float)len2)));
92 y = y * (1.5 - 0.5 * len2 * y * y);
93 y = y * (1.5 - 0.5 * len2 * y * y);
94 store4(res, _mm256_mul_pd(x, _mm256_set1_pd(y)));
109 const __m256d va =
load4(a);
110 const __m256d vb =
load4(b);
111 store4(res, _mm256_add_pd(va, _mm256_mul_pd(_mm256_set1_pd(t), _mm256_sub_pd(vb, va))));
127 store4(res, _mm256_add_pd(
load4(v), _mm256_set1_pd(s)));
132 store4(res, _mm256_sub_pd(
load4(v), _mm256_set1_pd(s)));
137 store4(res, _mm256_min_pd(_mm256_set1_pd(max), _mm256_max_pd(_mm256_set1_pd(min),
load4(v))));
142 store4(res, _mm256_min_pd(_mm256_set1_pd(1.0), _mm256_max_pd(_mm256_setzero_pd(),
load4(v))));
162 const __m256d x =
load4(v);
163 const __m256d abs_mask = _mm256_castsi256_pd(_mm256_set1_epi64x(0x7FFFFFFFFFFFFFFFLL));
164 const __m256d sign = _mm256_andnot_pd(abs_mask, x);
165 const __m256d mag = _mm256_floor_pd(_mm256_add_pd(_mm256_and_pd(x, abs_mask), _mm256_set1_pd(0.5)));
166 store4(res, _mm256_or_pd(mag, sign));
171 const __m256d x =
load4(v);
172 store4(res, _mm256_sub_pd(x, _mm256_floor_pd(x)));
178 store4(res, _mm256_mul_pd(
load4(v), _mm256_set1_pd(1.0 / v->
w)));
181 store4(res, _mm256_setzero_pd());
187 const __m128d a_lo = _mm256_castpd256_pd128(a);
188 const __m128d a_hi = _mm256_extractf128_pd(a, 1);
189 const double ax = _mm_cvtsd_f64(a_lo);
190 const double ay = _mm_cvtsd_f64(_mm_unpackhi_pd(a_lo, a_lo));
191 const double az = _mm_cvtsd_f64(a_hi);
192 const double aw = _mm_cvtsd_f64(_mm_unpackhi_pd(a_hi, a_hi));
194 const __m128d b_lo = _mm256_castpd256_pd128(b);
195 const __m128d b_hi = _mm256_extractf128_pd(b, 1);
196 const double bx = _mm_cvtsd_f64(b_lo);
197 const double by = _mm_cvtsd_f64(_mm_unpackhi_pd(b_lo, b_lo));
198 const double bz = _mm_cvtsd_f64(b_hi);
199 const double bw = _mm_cvtsd_f64(_mm_unpackhi_pd(b_hi, b_hi));
201 return _mm256_setr_pd(
202 aw * bx + ax * bw + ay * bz - az * by,
203 aw * by - ax * bz + ay * bw + az * bx,
204 aw * bz + ax * by - ay * bx + az * bw,
205 aw * bw - ax * bx - ay * by - az * bz);
210 const __m256d r =
quat_mul_avx(_mm256_loadu_pd(a->
v), _mm256_loadu_pd(b->
v));
211 _mm256_storeu_pd(res->
v, r);
223 return _mm_loadu_ps(v->
v);
228 _mm_storeu_ps(v->
v, x);
233 const __m128 zero = _mm_setzero_ps();
234 const __m128 eqz = _mm_cmpeq_ps(b, zero);
235 const __m128 safe = _mm_blendv_ps(b, _mm_set1_ps(1.0f), eqz);
236 return _mm_andnot_ps(eqz, _mm_div_ps(a, safe));
239static inline __m128
sign4(__m128 x)
241 const __m128 zero = _mm_setzero_ps();
242 const __m128 pos = _mm_and_ps(_mm_cmpgt_ps(x, zero), _mm_set1_ps(1.0f));
243 const __m128 neg = _mm_and_ps(_mm_cmplt_ps(x, zero), _mm_set1_ps(-1.0f));
244 return _mm_or_ps(pos, neg);
270 store4(res, _mm_setzero_ps());
278 store4(res, _mm_xor_ps(
load4(v), _mm_set1_ps(-0.0f)));
283 const __m128 mask = _mm_castsi128_ps(_mm_set1_epi32(0x7FFFFFFF));
289 const __m128 x =
load4(v);
290 const __m128 len2 = _mm_dp_ps(x, x, 0xFF);
291 if (_mm_cvtss_f32(len2) == 0.0f) {
295 const __m128 y = _mm_rsqrt_ps(len2);
296 const __m128 half = _mm_set1_ps(0.5f);
297 const __m128 three_halves = _mm_set1_ps(1.5f);
298 const __m128 inv = _mm_mul_ps(y, _mm_sub_ps(three_halves,
299 _mm_mul_ps(_mm_mul_ps(half, len2), _mm_mul_ps(y, y))));
300 store4(res, _mm_mul_ps(x, inv));
315 const __m128 va =
load4(a);
316 const __m128 vb =
load4(b);
317 store4(res, _mm_add_ps(va, _mm_mul_ps(_mm_set1_ps(t), _mm_sub_ps(vb, va))));
343 store4(res, _mm_min_ps(_mm_set1_ps(max), _mm_max_ps(_mm_set1_ps(min),
load4(v))));
348 store4(res, _mm_min_ps(_mm_set1_ps(1.0f), _mm_max_ps(_mm_setzero_ps(),
load4(v))));
368 const __m128 x =
load4(v);
369 const __m128 abs_mask = _mm_castsi128_ps(_mm_set1_epi32(0x7FFFFFFF));
370 const __m128 sign = _mm_andnot_ps(abs_mask, x);
371 const __m128 mag = _mm_floor_ps(_mm_add_ps(_mm_and_ps(x, abs_mask), _mm_set1_ps(0.5f)));
372 store4(res, _mm_or_ps(mag, sign));
377 const __m128 x =
load4(v);
378 store4(res, _mm_sub_ps(x, _mm_floor_ps(x)));
384 store4(res, _mm_mul_ps(
load4(v), _mm_set1_ps(1.0f / v->
w)));
387 store4(res, _mm_setzero_ps());
391static inline __m128 quat_mul_f32(__m128 a, __m128 b)
393 const __m128 aw = _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 3, 3, 3));
394 const __m128 ax = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0));
395 const __m128 ay = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1));
396 const __m128 az = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2));
398 const __m128 t1 = _mm_xor_ps(_mm_shuffle_ps(b, b, _MM_SHUFFLE(0, 1, 2, 3)),
399 _mm_set_ps(-0.0f, 0.0f, -0.0f, 0.0f));
400 const __m128 t2 = _mm_xor_ps(_mm_shuffle_ps(b, b, _MM_SHUFFLE(1, 0, 3, 2)),
401 _mm_set_ps(-0.0f, -0.0f, 0.0f, 0.0f));
402 const __m128 t3 = _mm_xor_ps(_mm_shuffle_ps(b, b, _MM_SHUFFLE(2, 3, 0, 1)),
403 _mm_set_ps(-0.0f, 0.0f, 0.0f, -0.0f));
405 __m128 r = _mm_mul_ps(aw, b);
406 r = _mm_add_ps(r, _mm_mul_ps(ax, t1));
407 r = _mm_add_ps(r, _mm_mul_ps(ay, t2));
408 r = _mm_add_ps(r, _mm_mul_ps(az, t3));
414 _mm_storeu_ps(res->
v, quat_mul_f32(_mm_loadu_ps(a->
v), _mm_loadu_ps(b->
v)));
void vec4_max_ptr_avx(vector4 *res, const vector4 *a, const vector4 *b)
void vec4_homogenize_ptr_avx(vector4 *res, const vector4 *v)
void vec4_lerp_ptr_avx(vector4 *res, const vector4 *a, const vector4 *b, const vm_float_t t)
void vec4_sub_scalar_ptr_avx(vector4 *res, const vector4 *v, const vm_float_t s)
static void store4(vector4 *v, const __m256d x)
void vec4_add_ptr_avx(vector4 *res, const vector4 *a, const vector4 *b)
void vec4_sub_ptr_avx(vector4 *res, const vector4 *a, const vector4 *b)
void vec4_normalize_ptr_avx(vector4 *res, const vector4 *v)
void vec4_div_ptr_avx(vector4 *res, const vector4 *a, const vector4 *b)
static __m256d hadamard_div(__m256d a, __m256d b)
void vec4_min_ptr_avx(vector4 *res, const vector4 *a, const vector4 *b)
static __m256d sign4(__m256d x)
void vec4_neg_ptr_avx(vector4 *res, const vector4 *v)
void vec4_round_ptr_avx(vector4 *res, const vector4 *v)
void vec4_saturate_ptr_avx(vector4 *res, const vector4 *v)
void vec4_mul_ptr_avx(vector4 *res, const vector4 *a, const vector4 *b)
void vec4_add_scalar_ptr_avx(vector4 *res, const vector4 *v, const vm_float_t s)
void vec4_abs_ptr_avx(vector4 *res, const vector4 *v)
static __m256d load4(const vector4 *v)
static __m256d quat_mul_avx(__m256d a, __m256d b)
void vec4_floor_ptr_avx(vector4 *res, const vector4 *v)
void vec4_div_scalar_ptr_avx(vector4 *res, const vector4 *v, const vm_float_t s)
void vec4_clamp_scalar_ptr_avx(vector4 *res, const vector4 *v, const vm_float_t min, const vm_float_t max)
void quat_normalize_ptr_avx(quaternion *res, const quaternion *q)
void vec4_fract_ptr_avx(vector4 *res, const vector4 *v)
void vec4_mul_scalar_ptr_avx(vector4 *res, const vector4 *v, const vm_float_t s)
void vec4_clamp_ptr_avx(vector4 *res, const vector4 *v, const vector4 *min, const vector4 *max)
void vec4_sign_ptr_avx(vector4 *res, const vector4 *v)
void quat_mul_ptr_avx(quaternion *res, const quaternion *a, const quaternion *b)
void vec4_ceil_ptr_avx(vector4 *res, const vector4 *v)
vm_float_t v[VECMAT_QUAT_SIZE]
vm_float_t v[VECMAT_VEC4_SIZE]