blob: f38583102b963750b0afe615f8fe8c813628bf8a [file] [log] [blame]
use crate::{
core_arch::{simd::*, simd_llvm::*, x86::*},
mem::{self, transmute},
};
#[cfg(test)]
use stdarch_test::assert_instr;
/// Computes the absolute values of packed 32-bit integers in `a`.
///
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#avx512techs=AVX512F&expand=33,34,4990,33&text=_mm512_abs_epi32)
#[inline]
#[target_feature(enable = "avx512f")]
#[cfg_attr(test, assert_instr(vpabsd))]
pub unsafe fn _mm512_abs_epi32(a: __m512i) -> __m512i {
let a = a.as_i32x16();
// all-0 is a properly initialized i32x16
let zero: i32x16 = mem::zeroed();
let sub = simd_sub(zero, a);
let cmp: i32x16 = simd_gt(a, zero);
transmute(simd_select(cmp, a, sub))
}
/// Computes the absolute value of packed 32-bit integers in `a`, and store the
/// unsigned results in `dst` using writemask `k` (elements are copied from
/// `src` when the corresponding mask bit is not set).
///
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#avx512techs=AVX512F&expand=33,34,4990,33&text=_mm512_abs_epi32)
#[inline]
#[target_feature(enable = "avx512f")]
#[cfg_attr(test, assert_instr(vpabsd))]
pub unsafe fn _mm512_mask_abs_epi32(src: __m512i, k: __mmask16, a: __m512i) -> __m512i {
let abs = _mm512_abs_epi32(a).as_i32x16();
transmute(simd_select_bitmask(k, abs, src.as_i32x16()))
}
/// Computes the absolute value of packed 32-bit integers in `a`, and store the
/// unsigned results in `dst` using zeromask `k` (elements are zeroed out when
/// the corresponding mask bit is not set).
///
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#avx512techs=AVX512F&expand=33,34,4990,33,34,35,35&text=_mm512_maskz_abs_epi32)
#[inline]
#[target_feature(enable = "avx512f")]
#[cfg_attr(test, assert_instr(vpabsd))]
pub unsafe fn _mm512_maskz_abs_epi32(k: __mmask16, a: __m512i) -> __m512i {
let abs = _mm512_abs_epi32(a).as_i32x16();
let zero = _mm512_setzero_si512().as_i32x16();
transmute(simd_select_bitmask(k, abs, zero))
}
/// Returns vector of type `__m512i` with all elements set to zero.
///
/// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#avx512techs=AVX512F&expand=33,34,4990&text=_mm512_setzero_si512)
#[inline]
#[target_feature(enable = "avx512f")]
#[cfg_attr(test, assert_instr(vxorps))]
pub unsafe fn _mm512_setzero_si512() -> __m512i {
// All-0 is a properly initialized __m512i
mem::zeroed()
}
/// Sets packed 32-bit integers in `dst` with the supplied values in reverse
/// order.
#[inline]
#[target_feature(enable = "avx512f")]
pub unsafe fn _mm512_setr_epi32(
e15: i32,
e14: i32,
e13: i32,
e12: i32,
e11: i32,
e10: i32,
e9: i32,
e8: i32,
e7: i32,
e6: i32,
e5: i32,
e4: i32,
e3: i32,
e2: i32,
e1: i32,
e0: i32,
) -> __m512i {
let r = i32x16(
e15, e14, e13, e12, e11, e10, e9, e8, e7, e6, e5, e4, e3, e2, e1, e0,
);
transmute(r)
}
/// Broadcast 64-bit integer `a` to all elements of `dst`.
#[inline]
#[target_feature(enable = "avx512f")]
pub unsafe fn _mm512_set1_epi64(a: i64) -> __m512i {
transmute(i64x8::splat(a))
}
#[cfg(test)]
mod tests {
use std;
use stdarch_test::simd_test;
use crate::core_arch::x86::*;
#[simd_test(enable = "avx512f")]
unsafe fn test_mm512_abs_epi32() {
#[rustfmt::skip]
let a = _mm512_setr_epi32(
0, 1, -1, std::i32::MAX,
std::i32::MIN, 100, -100, -32,
0, 1, -1, std::i32::MAX,
std::i32::MIN, 100, -100, -32,
);
let r = _mm512_abs_epi32(a);
let e = _mm512_setr_epi32(
0,
1,
1,
std::i32::MAX,
std::i32::MAX.wrapping_add(1),
100,
100,
32,
0,
1,
1,
std::i32::MAX,
std::i32::MAX.wrapping_add(1),
100,
100,
32,
);
assert_eq_m512i(r, e);
}
#[simd_test(enable = "avx512f")]
unsafe fn test_mm512_mask_abs_epi32() {
#[rustfmt::skip]
let a = _mm512_setr_epi32(
0, 1, -1, std::i32::MAX,
std::i32::MIN, 100, -100, -32,
0, 1, -1, std::i32::MAX,
std::i32::MIN, 100, -100, -32,
);
let r = _mm512_mask_abs_epi32(a, 0, a);
assert_eq_m512i(r, a);
let r = _mm512_mask_abs_epi32(a, 0b11111111, a);
let e = _mm512_setr_epi32(
0,
1,
1,
std::i32::MAX,
std::i32::MAX.wrapping_add(1),
100,
100,
32,
0,
1,
-1,
std::i32::MAX,
std::i32::MIN,
100,
-100,
-32,
);
assert_eq_m512i(r, e);
}
#[simd_test(enable = "avx512f")]
unsafe fn test_mm512_maskz_abs_epi32() {
#[rustfmt::skip]
let a = _mm512_setr_epi32(
0, 1, -1, std::i32::MAX,
std::i32::MIN, 100, -100, -32,
0, 1, -1, std::i32::MAX,
std::i32::MIN, 100, -100, -32,
);
let r = _mm512_maskz_abs_epi32(0, a);
assert_eq_m512i(r, _mm512_setzero_si512());
let r = _mm512_maskz_abs_epi32(0b11111111, a);
let e = _mm512_setr_epi32(
0,
1,
1,
std::i32::MAX,
std::i32::MAX.wrapping_add(1),
100,
100,
32,
0,
0,
0,
0,
0,
0,
0,
0,
);
assert_eq_m512i(r, e);
}
}