use super::*;
#[inline(always)]
pub unsafe fn _mm_adds_epi32x_v1(lhs: __m128i, rhs: __m128i) -> __m128i {
let res = _mm_add_epi32(lhs, rhs);
_mm_blendv_epi8x_v1(
res,
_mm_blendv_epi8x_v1(
_mm_set1_epi32(i32::MIN),
_mm_set1_epi32(i32::MAX),
_mm_signbits_epi32x_v1(res),
),
_mm_xor_si128(_mm_signbits_epi32x_v1(rhs), _mm_cmpgt_epi32(lhs, res)),
)
}
#[inline(always)]
pub unsafe fn _mm_subs_epi32x_v1(lhs: __m128i, rhs: __m128i) -> __m128i {
let res = _mm_sub_epi32(lhs, rhs);
_mm_blendv_epi8x_v1(
res,
_mm_blendv_epi8x_v1(
_mm_set1_epi32(i32::MIN),
_mm_set1_epi32(i32::MAX),
_mm_signbits_epi32x_v1(res),
),
_mm_xor_si128(_mm_cmpgt_epi32(rhs, _mm_setzero_si128()), _mm_cmpgt_epi32(lhs, res)),
)
}
#[inline(always)]
pub unsafe fn _mm_adds_epi64x_v1(lhs: __m128i, rhs: __m128i) -> __m128i {
let res = _mm_add_epi64(lhs, rhs);
_mm_blendv_epi8x_v1(
res,
_mm_blendv_epi8x_v1(
_mm_set1_epi64x(i64::MIN),
_mm_set1_epi64x(i64::MAX),
_mm_signbits_epi64x_v1(res),
),
_mm_xor_si128(_mm_signbits_epi64x_v1(rhs), _mm_cmpgt_epi64x_v1(lhs, res)),
)
}
#[inline(always)]
pub unsafe fn _mm_subs_epi64x_v1(lhs: __m128i, rhs: __m128i) -> __m128i {
let res = _mm_sub_epi64(lhs, rhs);
_mm_blendv_epi8x_v1(
res,
_mm_blendv_epi8x_v1(
_mm_set1_epi64x(i64::MIN),
_mm_set1_epi64x(i64::MAX),
_mm_signbits_epi64x_v1(res),
),
_mm_xor_si128(
_mm_cmpgt_epi64x_v1(rhs, _mm_setzero_si128()),
_mm_cmpgt_epi64x_v1(lhs, res),
),
)
}
#[inline(always)]
pub unsafe fn _mm_round_psx_v1(value: __m128) -> __m128 {
let neg_zero = _mm_set1_ps(-0.0);
let magic = _mm_set1_ps(8388608.0);
let sign = _mm_and_ps(value, neg_zero);
let abs = _mm_andnot_ps(neg_zero, value);
let rounded = _mm_sub_ps(_mm_add_ps(abs, magic), magic);
let rounded = _mm_or_ps(rounded, sign);
_mm_blendv_psx_v1(value, rounded, _mm_cmplt_ps(abs, magic))
}
#[inline(always)]
pub unsafe fn _mm_floor_psx_v1(value: __m128) -> __m128 {
let rounded = _mm_round_psx_v1(value);
_mm_sub_ps(rounded, _mm_and_ps(_mm_cmpgt_ps(rounded, value), _mm_set1_ps(1.0)))
}
#[inline(always)]
pub unsafe fn _mm_ceil_psx_v1(value: __m128) -> __m128 {
let neg_zero = _mm_set1_ps(-0.0);
_mm_xor_ps(_mm_floor_psx_v1(_mm_xor_ps(value, neg_zero)), neg_zero)
}
#[inline(always)]
pub unsafe fn _mm_trunc_psx_v1(value: __m128) -> __m128 {
let neg_zero = _mm_set1_ps(-0.0);
let magic = _mm_set1_ps(8388608.0);
let sign = _mm_and_ps(value, neg_zero);
let abs = _mm_andnot_ps(neg_zero, value);
let rounded = _mm_sub_ps(_mm_add_ps(abs, magic), magic);
let rounded = _mm_blendv_psx_v1(abs, rounded, _mm_cmplt_ps(abs, magic));
let trunced = _mm_sub_ps(rounded, _mm_and_ps(_mm_cmpgt_ps(rounded, abs), _mm_set1_ps(1.0)));
_mm_or_ps(trunced, sign)
}
#[inline(always)]
pub unsafe fn _mm_round_pdx_v1(value: __m128d) -> __m128d {
let neg_zero = _mm_set1_pd(-0.0);
let magic = _mm_set1_pd(4503599627370496.0);
let sign = _mm_and_pd(value, neg_zero);
let abs = _mm_andnot_pd(neg_zero, value);
let rounded = _mm_sub_pd(_mm_add_pd(abs, magic), magic);
let rounded = _mm_or_pd(rounded, sign);
_mm_blendv_pdx_v1(value, rounded, _mm_cmplt_pd(abs, magic))
}
#[inline(always)]
pub unsafe fn _mm_floor_pdx_v1(value: __m128d) -> __m128d {
let rounded = _mm_round_pdx_v1(value);
_mm_sub_pd(rounded, _mm_and_pd(_mm_cmpgt_pd(rounded, value), _mm_set1_pd(1.0)))
}
#[inline(always)]
pub unsafe fn _mm_ceil_pdx_v1(value: __m128d) -> __m128d {
let neg_zero = _mm_set1_pd(-0.0);
_mm_xor_pd(_mm_floor_pdx_v1(_mm_xor_pd(value, neg_zero)), neg_zero)
}
#[inline(always)]
pub unsafe fn _mm_trunc_pdx_v1(value: __m128d) -> __m128d {
let neg_zero = _mm_set1_pd(-0.0);
let magic = _mm_set1_pd(4503599627370496.0);
let sign = _mm_and_pd(value, neg_zero);
let abs = _mm_andnot_pd(neg_zero, value);
let rounded = _mm_sub_pd(_mm_add_pd(abs, magic), magic);
let rounded = _mm_blendv_pdx_v1(abs, rounded, _mm_cmplt_pd(abs, magic));
let trunced = _mm_sub_pd(rounded, _mm_and_pd(_mm_cmpgt_pd(rounded, abs), _mm_set1_pd(1.0)));
_mm_or_pd(trunced, sign)
}
#[inline(always)]
pub unsafe fn _mm_abs_epi32x_v1(value: __m128i) -> __m128i {
let m = _mm_srai_epi32(value, 31);
_mm_sub_epi32(_mm_xor_si128(value, m), m)
}
#[inline(always)]
pub unsafe fn _mm_copysign_epi32x_v1(lhs: __m128i, rhs: __m128i) -> __m128i {
let change_sign = _mm_xor_si128(_mm_srai_epi32(lhs, 31), _mm_srai_epi32(rhs, 31));
_mm_sub_epi32(_mm_xor_si128(lhs, change_sign), change_sign)
}
#[inline(always)]
pub unsafe fn _mm_signum_epi32x_v1(value: __m128i) -> __m128i {
let zero = _mm_setzero_si128();
let lt = _mm_cmpgt_epi32(zero, value); let gt = _mm_cmpgt_epi32(value, zero); _mm_sub_epi32(lt, gt)
}
#[inline(always)]
pub unsafe fn zero4_v1(value: __m128) -> __m128 {
let mask = _mm_castsi128_ps(_mm_setr_epu32x(!0, !0, !0, 0));
_mm_and_ps(value, mask)
}
#[inline(always)]
pub unsafe fn one4_v1(value: __m128) -> __m128 {
let mask = _mm_castsi128_ps(_mm_setr_epu32x(!0, !0, !0, 0));
let top_one = _mm_setr_ps(0.0, 0.0, 0.0, 1.0);
_mm_or_ps(_mm_and_ps(value, mask), top_one)
}
#[inline(always)]
pub unsafe fn dot3_v1(lhs: __m128, rhs: __m128) -> f32 {
let x2_y2_z2_w2 = _mm_mul_ps(lhs, rhs);
let y2_0_0_0 = _mm_shuffle_ps(x2_y2_z2_w2, x2_y2_z2_w2, 0b00_00_00_01);
let z2_0_0_0 = _mm_shuffle_ps(x2_y2_z2_w2, x2_y2_z2_w2, 0b00_00_00_10);
let x2y2_0_0_0 = _mm_add_ss(x2_y2_z2_w2, y2_0_0_0);
_mm_cvtss_f32(_mm_add_ss(x2y2_0_0_0, z2_0_0_0))
}
#[inline(always)]
pub unsafe fn _mm_mullo_epi64x_v1(xmm0: __m128i, xmm1: __m128i) -> __m128i {
let xmm2 = _mm_srli_epi64(xmm1, 32);
let xmm3 = _mm_srli_epi64(xmm0, 32);
let xmm2 = _mm_mul_epu32(xmm2, xmm0);
let xmm3 = _mm_mul_epu32(xmm1, xmm3);
let xmm2 = _mm_add_epi64(xmm3, xmm2);
let xmm2 = _mm_slli_epi64(xmm2, 32);
let xmm0 = _mm_mul_epu32(xmm1, xmm0);
let xmm0 = _mm_add_epi64(xmm0, xmm2);
xmm0
}
#[inline(always)]
pub unsafe fn _mm_mullo_epi32x_v1(xmm0: __m128i, xmm1: __m128i) -> __m128i {
let a13 = _mm_shuffle_epi32(xmm0, 0xF5); let b13 = _mm_shuffle_epi32(xmm1, 0xF5); let prod02 = _mm_mul_epu32(xmm0, xmm1); let prod13 = _mm_mul_epu32(a13, b13); let prod01 = _mm_unpacklo_epi32(prod02, prod13); let prod23 = _mm_unpackhi_epi32(prod02, prod13); let prod = _mm_unpacklo_epi64(prod01, prod23);
prod
}
#[inline(always)]
pub unsafe fn _mm_mul_epi32_v1(a: __m128i, b: __m128i) -> __m128i {
let prod = _mm_mul_epu32(a, b);
let a_sign = _mm_srai_epi32(a, 31);
let b_sign = _mm_srai_epi32(b, 31);
let a_correction = _mm_and_si128(a_sign, b);
let b_correction = _mm_and_si128(b_sign, a);
let correction = _mm_add_epi32(a_correction, b_correction);
_mm_sub_epi64(prod, _mm_slli_epi64(correction, 32))
}
#[inline(always)]
pub unsafe fn _mm_copysign_epi64x_v1(lhs: __m128i, rhs: __m128i) -> __m128i {
let change_sign = _mm_xor_si128(
_mm_cmpgt_epi64x_v1(rhs, _mm_set1_epi64x(-1)), _mm_cmpgt_epi64x_v1(lhs, _mm_set1_epi64x(-1)), );
_mm_add_epi64(
_mm_xor_si128(lhs, change_sign), _mm_srli_epi64(change_sign, 63), )
}
#[inline(always)]
pub unsafe fn _mm_nextupps_v1(value: __m128) -> __m128 {
let is_nan = _mm_castps_si128(_mm_cmpneq_ps(value, value));
let bits = _mm_castps_si128(value); let abs = _mm_andnot_si128(_mm_set1_epu32x(0x8000_0000), bits);
let is_infinity = _mm_cmpeq_epi32(bits, _mm_set1_epu32x(0x7F80_0000));
let unchanged = _mm_or_si128(is_nan, is_infinity);
let is_positive = _mm_cmpeq_epi32(abs, bits);
let is_zero = _mm_cmpeq_epi32(abs, _mm_setzero_si128());
let add = _mm_add_epi32(bits, _mm_set1_epi32(1));
let sub = _mm_sub_epi32(bits, _mm_set1_epi32(1));
let next_bits = _mm_blendv_epi8x_v1(sub, add, is_positive);
let next_bits = _mm_blendv_epi8x_v1(next_bits, _mm_set1_epu32x(0x1), is_zero);
_mm_castsi128_ps(_mm_blendv_epi8x_v1(next_bits, bits, unchanged))
}
#[inline(always)]
pub unsafe fn _mm_nextdownps_v1(value: __m128) -> __m128 {
let is_nan = _mm_castps_si128(_mm_cmpneq_ps(value, value));
let bits = _mm_castps_si128(value); let abs = _mm_andnot_si128(_mm_set1_epu32x(0x8000_0000u32), bits);
let is_neg_infinity = _mm_cmpeq_epi32(bits, _mm_set1_epu32x(0xFF80_0000));
let unchanged = _mm_or_si128(is_nan, is_neg_infinity);
let is_positive = _mm_cmpeq_epi32(abs, bits);
let is_zero = _mm_cmpeq_epi32(abs, _mm_setzero_si128());
let add = _mm_add_epi32(bits, _mm_set1_epi32(1));
let sub = _mm_sub_epi32(bits, _mm_set1_epi32(1));
let next_bits = _mm_blendv_epi8x_v1(add, sub, is_positive);
let next_bits = _mm_blendv_epi8x_v1(next_bits, _mm_set1_epu32x(0x1 | 0x8000_0000), is_zero);
_mm_castsi128_ps(_mm_blendv_epi8x_v1(next_bits, bits, unchanged))
}
#[inline(always)]
pub unsafe fn _mm_nextuppd_v1(value: __m128d) -> __m128d {
let is_nan = _mm_castpd_si128(_mm_cmpneq_pd(value, value));
let bits = _mm_castpd_si128(value); let abs = _mm_andnot_si128(_mm_set1_epu64x(0x8000_0000_0000_0000), bits);
let is_infinity = _mm_cmpeq_epi64x_v1(bits, _mm_set1_epu64x(0x7FF0_0000_0000_0000));
let unchanged = _mm_or_si128(is_nan, is_infinity);
let is_positive = _mm_cmpeq_epi64x_v1(abs, bits);
let is_zero = _mm_cmpeq_epi64x_v1(abs, _mm_setzero_si128());
let add = _mm_add_epi64(bits, _mm_set1_epu64x(1));
let sub = _mm_sub_epi64(bits, _mm_set1_epu64x(1));
let next_bits = _mm_blendv_epi8x_v1(sub, add, is_positive);
let next_bits = _mm_blendv_epi8x_v1(next_bits, _mm_set1_epu64x(0x1), is_zero);
_mm_castsi128_pd(_mm_blendv_epi8x_v1(next_bits, bits, unchanged))
}
#[inline(always)]
pub unsafe fn _mm_nextdownpd_v1(value: __m128d) -> __m128d {
let is_nan = _mm_castpd_si128(_mm_cmpneq_pd(value, value));
let bits = _mm_castpd_si128(value); let abs = _mm_andnot_si128(_mm_set1_epu64x(0x8000_0000_0000_0000), bits);
let is_neg_infinity = _mm_cmpeq_epi64x_v1(bits, _mm_set1_epu64x(0xFFF0_0000_0000_0000));
let unchanged = _mm_or_si128(is_nan, is_neg_infinity);
let is_positive = _mm_cmpeq_epi64x_v1(abs, bits);
let is_zero = _mm_cmpeq_epi64x_v1(abs, _mm_setzero_si128());
let add = _mm_add_epi64(bits, _mm_set1_epu64x(1));
let sub = _mm_sub_epi64(bits, _mm_set1_epu64x(1));
let next_bits = _mm_blendv_epi8x_v1(add, sub, is_positive);
let next_bits = _mm_blendv_epi8x_v1(next_bits, _mm_set1_epu64x(0x1 | 0x8000_0000_0000_0000), is_zero);
_mm_castsi128_pd(_mm_blendv_epi8x_v1(next_bits, bits, unchanged))
}
#[inline(always)]
pub unsafe fn _mm_fmadd_psx_v1(x: __m128, m: __m128, a: __m128) -> __m128 {
let x_lo = _mm_cvtps_pd(x);
let m_lo = _mm_cvtps_pd(m);
let a_lo = _mm_cvtps_pd(a);
let x_hi = _mm_cvtps_pd(_mm_movehl_ps(x, x));
let m_hi = _mm_cvtps_pd(_mm_movehl_ps(m, m));
let a_hi = _mm_cvtps_pd(_mm_movehl_ps(a, a));
let res_lo = _mm_add_pd(_mm_mul_pd(x_lo, m_lo), a_lo);
let res_hi = _mm_add_pd(_mm_mul_pd(x_hi, m_hi), a_hi);
let out_lo = _mm_cvtpd_ps(res_lo);
let out_hi = _mm_cvtpd_ps(res_hi);
_mm_movelh_ps(out_lo, out_hi)
}
#[inline(always)]
pub unsafe fn _mm_fmadd_pdx_v1(x: __m128d, m: __m128d, a: __m128d) -> __m128d {
let splitter = _mm_set1_pd(134217729.0);
let c_x = _mm_mul_pd(x, splitter);
let x_h = _mm_sub_pd(c_x, _mm_sub_pd(c_x, x));
let x_l = _mm_sub_pd(x, x_h);
let c_m = _mm_mul_pd(m, splitter);
let m_h = _mm_sub_pd(c_m, _mm_sub_pd(c_m, m));
let m_l = _mm_sub_pd(m, m_h);
let p = _mm_mul_pd(x, m);
let t1 = _mm_mul_pd(x_h, m_h);
let t2 = _mm_sub_pd(t1, p);
let t3 = _mm_mul_pd(x_h, m_l);
let t4 = _mm_mul_pd(x_l, m_h);
let t5 = _mm_mul_pd(x_l, m_l);
let e = _mm_add_pd(_mm_add_pd(_mm_add_pd(t2, t3), t4), t5);
let sum = _mm_add_pd(p, a);
let v = _mm_sub_pd(sum, p);
let z = _mm_sub_pd(sum, v); let err_a = _mm_sub_pd(a, v);
let err_p = _mm_sub_pd(p, z);
let err_add = _mm_add_pd(err_p, err_a);
let total_error = _mm_add_pd(e, err_add);
_mm_add_pd(sum, total_error)
}