diff --git a/coresimd/ppsv/api/rotates.rs b/coresimd/ppsv/api/rotates.rs index 940f6aea25..eef0655fb7 100644 --- a/coresimd/ppsv/api/rotates.rs +++ b/coresimd/ppsv/api/rotates.rs @@ -9,8 +9,8 @@ macro_rules! impl_vector_rotates { /// the end of the resulting integer. /// /// Please note this isn't the same operation as `<<`!. Also note it - /// isn't equivalent to `slice::rotate_left` (that can be implemented - /// with vector shuffles). + /// isn't equivalent to `slice::rotate_left`, it doesn't move the vector's + /// lanes around. (that can be implemented with vector shuffles). #[inline] pub fn rotate_left(self, n: $id) -> $id { const LANE_WIDTH: $elem_ty = ::mem::size_of::<$elem_ty>() as $elem_ty * 8; diff --git a/crates/coresimd/tests/rotate_tests.rs b/crates/coresimd/tests/rotate_tests.rs new file mode 100644 index 0000000000..1666a323a7 --- /dev/null +++ b/crates/coresimd/tests/rotate_tests.rs @@ -0,0 +1,49 @@ +//! rotate instruction tests + +#![feature(stdsimd)] +#![feature(proc_macro)] +#![feature(avx512_target_feature)] +#![feature(abi_vectorcall)] + +extern crate stdsimd_test; +extern crate stdsimd; + +use stdsimd::simd::*; +use stdsimd_test::assert_instr; + +// Verify that supported hardware compiles rotates into single instructions + +#[inline] +#[cfg_attr(any(target_arch = "x86", target_arch = "x86_64"), target_feature(enable = "avx512f"))] +#[cfg_attr(any(target_arch = "x86", target_arch = "x86_64"), assert_instr(vprorvq))] +unsafe fn rotate_right_variable(x: u64x8) -> u64x8 { + x.rotate_right(u64x8::new(0, 1, 2, 3, 4, 5, 6, 7)) +} + +#[inline] +#[cfg_attr(any(target_arch = "x86", target_arch = "x86_64"), target_feature(enable = "avx512f"))] +#[cfg_attr(any(target_arch = "x86", target_arch = "x86_64"), assert_instr(vprolvq))] +unsafe fn rotate_left_variable(x: u64x8) -> u64x8 { + x.rotate_left(u64x8::new(0, 1, 2, 3, 4, 5, 6, 7)) +} + +#[inline] +#[cfg_attr(any(target_arch = "x86", target_arch = "x86_64"), target_feature(enable = "avx512f"))] +#[cfg_attr(any(target_arch = "x86", target_arch = "x86_64"), assert_instr(vprorq))] +unsafe fn rotate_right(x: u64x8) -> u64x8 { + x.rotate_right(u64x2::splat(12)) +} + +#[inline] +#[cfg_attr(any(target_arch = "x86", target_arch = "x86_64"), target_feature(enable = "avx512f"))] +#[cfg_attr(any(target_arch = "x86", target_arch = "x86_64"), assert_instr(vprolq))] +unsafe fn rotate_left(x: u64x8) -> u64x8 { + x.rotate_left(u64x2::splat(12)) +} + +#[inline] +#[cfg_attr(any(target_arch = "x86", target_arch = "x86_64"), target_feature(enable = "avx512f"))] +#[cfg_attr(any(target_arch = "x86", target_arch = "x86_64"), assert_instr(vprolq))] +unsafe fn rotate_left_x2(x: u64x2) -> u64x2 { + x.rotate_left(u64x2::splat(12)) +}