diff --git a/fearless_simd/src/generated/avx2.rs b/fearless_simd/src/generated/avx2.rs index 1f2328d8..58863b17 100644 --- a/fearless_simd/src/generated/avx2.rs +++ b/fearless_simd/src/generated/avx2.rs @@ -1850,6 +1850,36 @@ impl Simd for Avx2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask8x16( + self, + a: mask8x16, + ) -> mask8x16 { + let int = i8x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask8x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask8x16( + self, + a: mask8x16, + ) -> mask8x16 { + let int = i8x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask8x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn and_mask8x16(self, a: mask8x16, b: mask8x16) -> mask8x16 { crate::kernel!( #[inline(always)] @@ -3053,6 +3083,36 @@ impl Simd for Avx2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask16x8( + self, + a: mask16x8, + ) -> mask16x8 { + let int = i16x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask16x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask16x8( + self, + a: mask16x8, + ) -> mask16x8 { + let int = i16x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask16x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn and_mask16x8(self, a: mask16x8, b: mask16x8) -> mask16x8 { crate::kernel!( #[inline(always)] @@ -4213,6 +4273,36 @@ impl Simd for Avx2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask32x4( + self, + a: mask32x4, + ) -> mask32x4 { + let int = i32x4 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask32x4 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask32x4( + self, + a: mask32x4, + ) -> mask32x4 { + let int = i32x4 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask32x4 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn and_mask32x4(self, a: mask32x4, b: mask32x4) -> mask32x4 { crate::kernel!( #[inline(always)] @@ -5873,6 +5963,36 @@ impl Simd for Avx2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask64x2( + self, + a: mask64x2, + ) -> mask64x2 { + let int = i64x2 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask64x2 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask64x2( + self, + a: mask64x2, + ) -> mask64x2 { + let int = i64x2 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask64x2 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn and_mask64x2(self, a: mask64x2, b: mask64x2) -> mask64x2 { crate::kernel!( #[inline(always)] @@ -7576,6 +7696,36 @@ impl Simd for Avx2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask8x32( + self, + a: mask8x32, + ) -> mask8x32 { + let int = i8x32 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask8x32 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask8x32( + self, + a: mask8x32, + ) -> mask8x32 { + let int = i8x32 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask8x32 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn and_mask8x32(self, a: mask8x32, b: mask8x32) -> mask8x32 { crate::kernel!( #[inline(always)] @@ -8715,6 +8865,36 @@ impl Simd for Avx2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask16x16( + self, + a: mask16x16, + ) -> mask16x16 { + let int = i16x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask16x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask16x16( + self, + a: mask16x16, + ) -> mask16x16 { + let int = i16x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask16x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn and_mask16x16(self, a: mask16x16, b: mask16x16) -> mask16x16 { crate::kernel!( #[inline(always)] @@ -9797,6 +9977,36 @@ impl Simd for Avx2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask32x8( + self, + a: mask32x8, + ) -> mask32x8 { + let int = i32x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask32x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask32x8( + self, + a: mask32x8, + ) -> mask32x8 { + let int = i32x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask32x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn and_mask32x8(self, a: mask32x8, b: mask32x8) -> mask32x8 { crate::kernel!( #[inline(always)] @@ -11360,6 +11570,36 @@ impl Simd for Avx2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask64x4( + self, + a: mask64x4, + ) -> mask64x4 { + let int = i64x4 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask64x4 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask64x4( + self, + a: mask64x4, + ) -> mask64x4 { + let int = i64x4 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask64x4 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn and_mask64x4(self, a: mask64x4, b: mask64x4) -> mask64x4 { crate::kernel!( #[inline(always)] @@ -11666,6 +11906,36 @@ impl Simd for Avx2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask8x64( + self, + a: mask8x64, + ) -> mask8x64 { + let int = i8x64 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask8x64 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask8x64( + self, + a: mask8x64, + ) -> mask8x64 { + let int = i8x64 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask8x64 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn split_mask8x64(self, a: mask8x64) -> (mask8x32, mask8x32) { ( mask8x32 { @@ -11764,6 +12034,36 @@ impl Simd for Avx2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask16x32( + self, + a: mask16x32, + ) -> mask16x32 { + let int = i16x32 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask16x32 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask16x32( + self, + a: mask16x32, + ) -> mask16x32 { + let int = i16x32 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask16x32 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn split_mask16x32(self, a: mask16x32) -> (mask16x16, mask16x16) { ( mask16x16 { @@ -11873,6 +12173,36 @@ impl Simd for Avx2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask32x16( + self, + a: mask32x16, + ) -> mask32x16 { + let int = i32x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask32x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask32x16( + self, + a: mask32x16, + ) -> mask32x16 { + let int = i32x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask32x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn split_mask32x16(self, a: mask32x16) -> (mask32x8, mask32x8) { ( mask32x8 { @@ -12009,6 +12339,36 @@ impl Simd for Avx2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask64x8( + self, + a: mask64x8, + ) -> mask64x8 { + let int = i64x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask64x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask64x8( + self, + a: mask64x8, + ) -> mask64x8 { + let int = i64x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask64x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn split_mask64x8(self, a: mask64x8) -> (mask64x4, mask64x4) { ( mask64x4 { diff --git a/fearless_simd/src/generated/avx512.rs b/fearless_simd/src/generated/avx512.rs index 348c9fb2..2342f97a 100644 --- a/fearless_simd/src/generated/avx512.rs +++ b/fearless_simd/src/generated/avx512.rs @@ -2012,6 +2012,26 @@ impl Simd for Avx512 { }; } #[inline(always)] + fn rotate_elements_left_mask8x16( + self, + a: mask8x16, + ) -> mask8x16 { + mask8x16 { + val: (a.val.rotate_right((OFFSET % 16) as u32)) as _, + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask8x16( + self, + a: mask8x16, + ) -> mask8x16 { + mask8x16 { + val: (a.val.rotate_left((OFFSET % 16) as u32)) as _, + simd: self, + } + } + #[inline(always)] fn and_mask8x16(self, a: mask8x16, b: mask8x16) -> mask8x16 { mask8x16 { val: ((u64::from((a).val) & u64::from((b).val)) & 65535u64) as _, @@ -3081,6 +3101,26 @@ impl Simd for Avx512 { }; } #[inline(always)] + fn rotate_elements_left_mask16x8( + self, + a: mask16x8, + ) -> mask16x8 { + mask16x8 { + val: (a.val.rotate_right((OFFSET % 8) as u32)) as _, + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask16x8( + self, + a: mask16x8, + ) -> mask16x8 { + mask16x8 { + val: (a.val.rotate_left((OFFSET % 8) as u32)) as _, + simd: self, + } + } + #[inline(always)] fn and_mask16x8(self, a: mask16x8, b: mask16x8) -> mask16x8 { mask16x8 { val: ((u64::from((a).val) & u64::from((b).val)) & 255u64) as _, @@ -4129,6 +4169,40 @@ impl Simd for Avx512 { }; } #[inline(always)] + fn rotate_elements_left_mask32x4( + self, + a: mask32x4, + ) -> mask32x4 { + let bits = u64::from((a).val) & 15u64; + let offset = OFFSET % 4; + let bits = if offset == 0 { + bits + } else { + ((bits >> offset) | (bits << (4 - offset))) & 15u64 + }; + mask32x4 { + val: (bits) as _, + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask32x4( + self, + a: mask32x4, + ) -> mask32x4 { + let bits = u64::from((a).val) & 15u64; + let offset = OFFSET % 4; + let bits = if offset == 0 { + bits + } else { + ((bits << offset) | (bits >> (4 - offset))) & 15u64 + }; + mask32x4 { + val: (bits) as _, + simd: self, + } + } + #[inline(always)] fn and_mask32x4(self, a: mask32x4, b: mask32x4) -> mask32x4 { mask32x4 { val: ((u64::from((a).val) & u64::from((b).val)) & 15u64) as _, @@ -5644,6 +5718,40 @@ impl Simd for Avx512 { }; } #[inline(always)] + fn rotate_elements_left_mask64x2( + self, + a: mask64x2, + ) -> mask64x2 { + let bits = u64::from((a).val) & 3u64; + let offset = OFFSET % 2; + let bits = if offset == 0 { + bits + } else { + ((bits >> offset) | (bits << (2 - offset))) & 3u64 + }; + mask64x2 { + val: (bits) as _, + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask64x2( + self, + a: mask64x2, + ) -> mask64x2 { + let bits = u64::from((a).val) & 3u64; + let offset = OFFSET % 2; + let bits = if offset == 0 { + bits + } else { + ((bits << offset) | (bits >> (2 - offset))) & 3u64 + }; + mask64x2 { + val: (bits) as _, + simd: self, + } + } + #[inline(always)] fn and_mask64x2(self, a: mask64x2, b: mask64x2) -> mask64x2 { mask64x2 { val: ((u64::from((a).val) & u64::from((b).val)) & 3u64) as _, @@ -7321,6 +7429,26 @@ impl Simd for Avx512 { }; } #[inline(always)] + fn rotate_elements_left_mask8x32( + self, + a: mask8x32, + ) -> mask8x32 { + mask8x32 { + val: (a.val.rotate_right((OFFSET % 32) as u32)) as _, + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask8x32( + self, + a: mask8x32, + ) -> mask8x32 { + mask8x32 { + val: (a.val.rotate_left((OFFSET % 32) as u32)) as _, + simd: self, + } + } + #[inline(always)] fn and_mask8x32(self, a: mask8x32, b: mask8x32) -> mask8x32 { mask8x32 { val: ((u64::from((a).val) & u64::from((b).val)) & 4294967295u64) as _, @@ -8382,6 +8510,26 @@ impl Simd for Avx512 { }; } #[inline(always)] + fn rotate_elements_left_mask16x16( + self, + a: mask16x16, + ) -> mask16x16 { + mask16x16 { + val: (a.val.rotate_right((OFFSET % 16) as u32)) as _, + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask16x16( + self, + a: mask16x16, + ) -> mask16x16 { + mask16x16 { + val: (a.val.rotate_left((OFFSET % 16) as u32)) as _, + simd: self, + } + } + #[inline(always)] fn and_mask16x16(self, a: mask16x16, b: mask16x16) -> mask16x16 { mask16x16 { val: ((u64::from((a).val) & u64::from((b).val)) & 65535u64) as _, @@ -9420,6 +9568,26 @@ impl Simd for Avx512 { }; } #[inline(always)] + fn rotate_elements_left_mask32x8( + self, + a: mask32x8, + ) -> mask32x8 { + mask32x8 { + val: (a.val.rotate_right((OFFSET % 8) as u32)) as _, + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask32x8( + self, + a: mask32x8, + ) -> mask32x8 { + mask32x8 { + val: (a.val.rotate_left((OFFSET % 8) as u32)) as _, + simd: self, + } + } + #[inline(always)] fn and_mask32x8(self, a: mask32x8, b: mask32x8) -> mask32x8 { mask32x8 { val: ((u64::from((a).val) & u64::from((b).val)) & 255u64) as _, @@ -10918,6 +11086,40 @@ impl Simd for Avx512 { }; } #[inline(always)] + fn rotate_elements_left_mask64x4( + self, + a: mask64x4, + ) -> mask64x4 { + let bits = u64::from((a).val) & 15u64; + let offset = OFFSET % 4; + let bits = if offset == 0 { + bits + } else { + ((bits >> offset) | (bits << (4 - offset))) & 15u64 + }; + mask64x4 { + val: (bits) as _, + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask64x4( + self, + a: mask64x4, + ) -> mask64x4 { + let bits = u64::from((a).val) & 15u64; + let offset = OFFSET % 4; + let bits = if offset == 0 { + bits + } else { + ((bits << offset) | (bits >> (4 - offset))) & 15u64 + }; + mask64x4 { + val: (bits) as _, + simd: self, + } + } + #[inline(always)] fn and_mask64x4(self, a: mask64x4, b: mask64x4) -> mask64x4 { mask64x4 { val: ((u64::from((a).val) & u64::from((b).val)) & 15u64) as _, @@ -12654,6 +12856,26 @@ impl Simd for Avx512 { }; } #[inline(always)] + fn rotate_elements_left_mask8x64( + self, + a: mask8x64, + ) -> mask8x64 { + mask8x64 { + val: a.val.rotate_right((OFFSET % 64) as u32), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask8x64( + self, + a: mask8x64, + ) -> mask8x64 { + mask8x64 { + val: a.val.rotate_left((OFFSET % 64) as u32), + simd: self, + } + } + #[inline(always)] fn and_mask8x64(self, a: mask8x64, b: mask8x64) -> mask8x64 { mask8x64 { val: (u64::from((a).val) & u64::from((b).val)) & u64::MAX, @@ -13729,6 +13951,26 @@ impl Simd for Avx512 { }; } #[inline(always)] + fn rotate_elements_left_mask16x32( + self, + a: mask16x32, + ) -> mask16x32 { + mask16x32 { + val: (a.val.rotate_right((OFFSET % 32) as u32)) as _, + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask16x32( + self, + a: mask16x32, + ) -> mask16x32 { + mask16x32 { + val: (a.val.rotate_left((OFFSET % 32) as u32)) as _, + simd: self, + } + } + #[inline(always)] fn and_mask16x32(self, a: mask16x32, b: mask16x32) -> mask16x32 { mask16x32 { val: ((u64::from((a).val) & u64::from((b).val)) & 4294967295u64) as _, @@ -14788,6 +15030,26 @@ impl Simd for Avx512 { }; } #[inline(always)] + fn rotate_elements_left_mask32x16( + self, + a: mask32x16, + ) -> mask32x16 { + mask32x16 { + val: (a.val.rotate_right((OFFSET % 16) as u32)) as _, + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask32x16( + self, + a: mask32x16, + ) -> mask32x16 { + mask32x16 { + val: (a.val.rotate_left((OFFSET % 16) as u32)) as _, + simd: self, + } + } + #[inline(always)] fn and_mask32x16(self, a: mask32x16, b: mask32x16) -> mask32x16 { mask32x16 { val: ((u64::from((a).val) & u64::from((b).val)) & 65535u64) as _, @@ -16309,6 +16571,26 @@ impl Simd for Avx512 { }; } #[inline(always)] + fn rotate_elements_left_mask64x8( + self, + a: mask64x8, + ) -> mask64x8 { + mask64x8 { + val: (a.val.rotate_right((OFFSET % 8) as u32)) as _, + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask64x8( + self, + a: mask64x8, + ) -> mask64x8 { + mask64x8 { + val: (a.val.rotate_left((OFFSET % 8) as u32)) as _, + simd: self, + } + } + #[inline(always)] fn and_mask64x8(self, a: mask64x8, b: mask64x8) -> mask64x8 { mask64x8 { val: ((u64::from((a).val) & u64::from((b).val)) & 255u64) as _, diff --git a/fearless_simd/src/generated/fallback.rs b/fearless_simd/src/generated/fallback.rs index 3e676607..d6a58aaa 100644 --- a/fearless_simd/src/generated/fallback.rs +++ b/fearless_simd/src/generated/fallback.rs @@ -2403,6 +2403,36 @@ impl Simd for Fallback { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask8x16( + self, + a: mask8x16, + ) -> mask8x16 { + let int = i8x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask8x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask8x16( + self, + a: mask8x16, + ) -> mask8x16 { + let int = i8x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask8x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn and_mask8x16(self, a: mask8x16, b: mask8x16) -> mask8x16 { [ i8::bitand(a.val.0[0usize], &b.val.0[0usize]), @@ -3902,6 +3932,36 @@ impl Simd for Fallback { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask16x8( + self, + a: mask16x8, + ) -> mask16x8 { + let int = i16x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask16x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask16x8( + self, + a: mask16x8, + ) -> mask16x8 { + let int = i16x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask16x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn and_mask16x8(self, a: mask16x8, b: mask16x8) -> mask16x8 { [ i16::bitand(a.val.0[0usize], &b.val.0[0usize]), @@ -4875,6 +4935,36 @@ impl Simd for Fallback { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask32x4( + self, + a: mask32x4, + ) -> mask32x4 { + let int = i32x4 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask32x4 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask32x4( + self, + a: mask32x4, + ) -> mask32x4 { + let int = i32x4 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask32x4 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn and_mask32x4(self, a: mask32x4, b: mask32x4) -> mask32x4 { [ i32::bitand(a.val.0[0usize], &b.val.0[0usize]), @@ -5895,6 +5985,36 @@ impl Simd for Fallback { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask64x2( + self, + a: mask64x2, + ) -> mask64x2 { + let int = i64x2 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask64x2 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask64x2( + self, + a: mask64x2, + ) -> mask64x2 { + let int = i64x2 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask64x2 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn and_mask64x2(self, a: mask64x2, b: mask64x2) -> mask64x2 { [ i64::bitand(a.val.0[0usize], &b.val.0[0usize]), @@ -6079,6 +6199,36 @@ impl Simd for Fallback { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask8x32( + self, + a: mask8x32, + ) -> mask8x32 { + let int = i8x32 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask8x32 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask8x32( + self, + a: mask8x32, + ) -> mask8x32 { + let int = i8x32 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask8x32 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn combine_mask8x32(self, a: mask8x32, b: mask8x32) -> mask8x64 { let mut result = [0; 64usize]; result[0..32usize].copy_from_slice(&a.val.0); @@ -6149,6 +6299,36 @@ impl Simd for Fallback { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask16x16( + self, + a: mask16x16, + ) -> mask16x16 { + let int = i16x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask16x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask16x16( + self, + a: mask16x16, + ) -> mask16x16 { + let int = i16x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask16x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn combine_mask16x16(self, a: mask16x16, b: mask16x16) -> mask16x32 { let mut result = [0; 32usize]; result[0..16usize].copy_from_slice(&a.val.0); @@ -6219,6 +6399,36 @@ impl Simd for Fallback { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask32x8( + self, + a: mask32x8, + ) -> mask32x8 { + let int = i32x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask32x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask32x8( + self, + a: mask32x8, + ) -> mask32x8 { + let int = i32x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask32x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn combine_mask32x8(self, a: mask32x8, b: mask32x8) -> mask32x16 { let mut result = [0; 16usize]; result[0..8usize].copy_from_slice(&a.val.0); @@ -6311,6 +6521,36 @@ impl Simd for Fallback { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask64x4( + self, + a: mask64x4, + ) -> mask64x4 { + let int = i64x4 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask64x4 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask64x4( + self, + a: mask64x4, + ) -> mask64x4 { + let int = i64x4 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask64x4 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn combine_mask64x4(self, a: mask64x4, b: mask64x4) -> mask64x8 { let mut result = [0; 8usize]; result[0..4usize].copy_from_slice(&a.val.0); @@ -6405,6 +6645,36 @@ impl Simd for Fallback { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask8x64( + self, + a: mask8x64, + ) -> mask8x64 { + let int = i8x64 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask8x64 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask8x64( + self, + a: mask8x64, + ) -> mask8x64 { + let int = i8x64 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask8x64 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn split_mask8x64(self, a: mask8x64) -> (mask8x32, mask8x32) { let mut b0 = [0; 32usize]; let mut b1 = [0; 32usize]; @@ -6454,6 +6724,36 @@ impl Simd for Fallback { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask16x32( + self, + a: mask16x32, + ) -> mask16x32 { + let int = i16x32 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask16x32 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask16x32( + self, + a: mask16x32, + ) -> mask16x32 { + let int = i16x32 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask16x32 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn split_mask16x32(self, a: mask16x32) -> (mask16x16, mask16x16) { let mut b0 = [0; 16usize]; let mut b1 = [0; 16usize]; @@ -6503,6 +6803,36 @@ impl Simd for Fallback { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask32x16( + self, + a: mask32x16, + ) -> mask32x16 { + let int = i32x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask32x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask32x16( + self, + a: mask32x16, + ) -> mask32x16 { + let int = i32x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask32x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn split_mask32x16(self, a: mask32x16) -> (mask32x8, mask32x8) { let mut b0 = [0; 8usize]; let mut b1 = [0; 8usize]; @@ -6567,6 +6897,36 @@ impl Simd for Fallback { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask64x8( + self, + a: mask64x8, + ) -> mask64x8 { + let int = i64x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask64x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask64x8( + self, + a: mask64x8, + ) -> mask64x8 { + let int = i64x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask64x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn split_mask64x8(self, a: mask64x8) -> (mask64x4, mask64x4) { let mut b0 = [0; 4usize]; let mut b1 = [0; 4usize]; diff --git a/fearless_simd/src/generated/neon.rs b/fearless_simd/src/generated/neon.rs index 096cbef2..1fbae452 100644 --- a/fearless_simd/src/generated/neon.rs +++ b/fearless_simd/src/generated/neon.rs @@ -1372,6 +1372,36 @@ impl Simd for Neon { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask8x16( + self, + a: mask8x16, + ) -> mask8x16 { + let int = i8x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask8x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask8x16( + self, + a: mask8x16, + ) -> mask8x16 { + let int = i8x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask8x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn and_mask8x16(self, a: mask8x16, b: mask8x16) -> mask8x16 { crate::kernel!( #[inline(always)] @@ -2327,6 +2357,36 @@ impl Simd for Neon { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask16x8( + self, + a: mask16x8, + ) -> mask16x8 { + let int = i16x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask16x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask16x8( + self, + a: mask16x8, + ) -> mask16x8 { + let int = i16x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask16x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn and_mask16x8(self, a: mask16x8, b: mask16x8) -> mask16x8 { crate::kernel!( #[inline(always)] @@ -3303,6 +3363,36 @@ impl Simd for Neon { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask32x4( + self, + a: mask32x4, + ) -> mask32x4 { + let int = i32x4 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask32x4 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask32x4( + self, + a: mask32x4, + ) -> mask32x4 { + let int = i32x4 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask32x4 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn and_mask32x4(self, a: mask32x4, b: mask32x4) -> mask32x4 { crate::kernel!( #[inline(always)] @@ -4688,6 +4778,36 @@ impl Simd for Neon { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask64x2( + self, + a: mask64x2, + ) -> mask64x2 { + let int = i64x2 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask64x2 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask64x2( + self, + a: mask64x2, + ) -> mask64x2 { + let int = i64x2 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask64x2 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn and_mask64x2(self, a: mask64x2, b: mask64x2) -> mask64x2 { crate::kernel!( #[inline(always)] @@ -5048,6 +5168,36 @@ impl Simd for Neon { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask8x32( + self, + a: mask8x32, + ) -> mask8x32 { + let int = i8x32 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask8x32 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask8x32( + self, + a: mask8x32, + ) -> mask8x32 { + let int = i8x32 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask8x32 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn combine_mask8x32(self, a: mask8x32, b: mask8x32) -> mask8x64 { mask8x64 { val: crate::support::Aligned512(int8x16x4_t( @@ -5214,6 +5364,36 @@ impl Simd for Neon { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask16x16( + self, + a: mask16x16, + ) -> mask16x16 { + let int = i16x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask16x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask16x16( + self, + a: mask16x16, + ) -> mask16x16 { + let int = i16x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask16x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn combine_mask16x16(self, a: mask16x16, b: mask16x16) -> mask16x32 { mask16x32 { val: crate::support::Aligned512(int16x8x4_t( @@ -5380,6 +5560,36 @@ impl Simd for Neon { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask32x8( + self, + a: mask32x8, + ) -> mask32x8 { + let int = i32x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask32x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask32x8( + self, + a: mask32x8, + ) -> mask32x8 { + let int = i32x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask32x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn combine_mask32x8(self, a: mask32x8, b: mask32x8) -> mask32x16 { mask32x16 { val: crate::support::Aligned512(int32x4x4_t( @@ -5605,6 +5815,36 @@ impl Simd for Neon { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask64x4( + self, + a: mask64x4, + ) -> mask64x4 { + let int = i64x4 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask64x4 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask64x4( + self, + a: mask64x4, + ) -> mask64x4 { + let int = i64x4 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask64x4 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn combine_mask64x4(self, a: mask64x4, b: mask64x4) -> mask64x8 { mask64x8 { val: crate::support::Aligned512(int64x2x4_t( @@ -5888,6 +6128,36 @@ impl Simd for Neon { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask8x64( + self, + a: mask8x64, + ) -> mask8x64 { + let int = i8x64 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask8x64 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask8x64( + self, + a: mask8x64, + ) -> mask8x64 { + let int = i8x64 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask8x64 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn split_mask8x64(self, a: mask8x64) -> (mask8x32, mask8x32) { ( mask8x32 { @@ -6068,6 +6338,36 @@ impl Simd for Neon { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask16x32( + self, + a: mask16x32, + ) -> mask16x32 { + let int = i16x32 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask16x32 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask16x32( + self, + a: mask16x32, + ) -> mask16x32 { + let int = i16x32 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask16x32 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn split_mask16x32(self, a: mask16x32) -> (mask16x16, mask16x16) { ( mask16x16 { @@ -6248,6 +6548,36 @@ impl Simd for Neon { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask32x16( + self, + a: mask32x16, + ) -> mask32x16 { + let int = i32x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask32x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask32x16( + self, + a: mask32x16, + ) -> mask32x16 { + let int = i32x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask32x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn split_mask32x16(self, a: mask32x16) -> (mask32x8, mask32x8) { ( mask32x8 { @@ -6496,6 +6826,36 @@ impl Simd for Neon { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask64x8( + self, + a: mask64x8, + ) -> mask64x8 { + let int = i64x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask64x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask64x8( + self, + a: mask64x8, + ) -> mask64x8 { + let int = i64x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask64x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn split_mask64x8(self, a: mask64x8) -> (mask64x4, mask64x4) { ( mask64x4 { diff --git a/fearless_simd/src/generated/simd_trait.rs b/fearless_simd/src/generated/simd_trait.rs index f1ce7214..adeb2682 100644 --- a/fearless_simd/src/generated/simd_trait.rs +++ b/fearless_simd/src/generated/simd_trait.rs @@ -570,6 +570,16 @@ pub trait Simd: fn to_bitmask_mask8x16(self, a: mask8x16) -> u64; #[doc = "Set one logical lane of a SIMD mask."] fn set_mask8x16(self, a: &mut mask8x16, index: usize, value: bool) -> (); + #[doc = "Rotate the mask elements to the left by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::N`, it wraps modulo `Self::N`."] + fn rotate_elements_left_mask8x16( + self, + a: mask8x16, + ) -> mask8x16; + #[doc = "Rotate the mask elements to the right by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::N`, it wraps modulo `Self::N`."] + fn rotate_elements_right_mask8x16( + self, + a: mask8x16, + ) -> mask8x16; #[doc = "Compute the logical AND of two masks."] fn and_mask8x16(self, a: mask8x16, b: mask8x16) -> mask8x16; #[doc = "Compute the logical OR of two masks."] @@ -841,6 +851,16 @@ pub trait Simd: fn to_bitmask_mask16x8(self, a: mask16x8) -> u64; #[doc = "Set one logical lane of a SIMD mask."] fn set_mask16x8(self, a: &mut mask16x8, index: usize, value: bool) -> (); + #[doc = "Rotate the mask elements to the left by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::N`, it wraps modulo `Self::N`."] + fn rotate_elements_left_mask16x8( + self, + a: mask16x8, + ) -> mask16x8; + #[doc = "Rotate the mask elements to the right by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::N`, it wraps modulo `Self::N`."] + fn rotate_elements_right_mask16x8( + self, + a: mask16x8, + ) -> mask16x8; #[doc = "Compute the logical AND of two masks."] fn and_mask16x8(self, a: mask16x8, b: mask16x8) -> mask16x8; #[doc = "Compute the logical OR of two masks."] @@ -1116,6 +1136,16 @@ pub trait Simd: fn to_bitmask_mask32x4(self, a: mask32x4) -> u64; #[doc = "Set one logical lane of a SIMD mask."] fn set_mask32x4(self, a: &mut mask32x4, index: usize, value: bool) -> (); + #[doc = "Rotate the mask elements to the left by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::N`, it wraps modulo `Self::N`."] + fn rotate_elements_left_mask32x4( + self, + a: mask32x4, + ) -> mask32x4; + #[doc = "Rotate the mask elements to the right by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::N`, it wraps modulo `Self::N`."] + fn rotate_elements_right_mask32x4( + self, + a: mask32x4, + ) -> mask32x4; #[doc = "Compute the logical AND of two masks."] fn and_mask32x4(self, a: mask32x4, b: mask32x4) -> mask32x4; #[doc = "Compute the logical OR of two masks."] @@ -1527,6 +1557,16 @@ pub trait Simd: fn to_bitmask_mask64x2(self, a: mask64x2) -> u64; #[doc = "Set one logical lane of a SIMD mask."] fn set_mask64x2(self, a: &mut mask64x2, index: usize, value: bool) -> (); + #[doc = "Rotate the mask elements to the left by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::N`, it wraps modulo `Self::N`."] + fn rotate_elements_left_mask64x2( + self, + a: mask64x2, + ) -> mask64x2; + #[doc = "Rotate the mask elements to the right by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::N`, it wraps modulo `Self::N`."] + fn rotate_elements_right_mask64x2( + self, + a: mask64x2, + ) -> mask64x2; #[doc = "Compute the logical AND of two masks."] fn and_mask64x2(self, a: mask64x2, b: mask64x2) -> mask64x2; #[doc = "Compute the logical OR of two masks."] @@ -2503,6 +2543,16 @@ pub trait Simd: } #[doc = "Set one logical lane of a SIMD mask."] fn set_mask8x32(self, a: &mut mask8x32, index: usize, value: bool) -> (); + #[doc = "Rotate the mask elements to the left by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::N`, it wraps modulo `Self::N`."] + fn rotate_elements_left_mask8x32( + self, + a: mask8x32, + ) -> mask8x32; + #[doc = "Rotate the mask elements to the right by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::N`, it wraps modulo `Self::N`."] + fn rotate_elements_right_mask8x32( + self, + a: mask8x32, + ) -> mask8x32; #[doc = "Compute the logical AND of two masks."] #[inline(always)] fn and_mask8x32(self, a: mask8x32, b: mask8x32) -> mask8x32 { @@ -3214,6 +3264,16 @@ pub trait Simd: } #[doc = "Set one logical lane of a SIMD mask."] fn set_mask16x16(self, a: &mut mask16x16, index: usize, value: bool) -> (); + #[doc = "Rotate the mask elements to the left by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::N`, it wraps modulo `Self::N`."] + fn rotate_elements_left_mask16x16( + self, + a: mask16x16, + ) -> mask16x16; + #[doc = "Rotate the mask elements to the right by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::N`, it wraps modulo `Self::N`."] + fn rotate_elements_right_mask16x16( + self, + a: mask16x16, + ) -> mask16x16; #[doc = "Compute the logical AND of two masks."] #[inline(always)] fn and_mask16x16(self, a: mask16x16, b: mask16x16) -> mask16x16 { @@ -3929,6 +3989,16 @@ pub trait Simd: } #[doc = "Set one logical lane of a SIMD mask."] fn set_mask32x8(self, a: &mut mask32x8, index: usize, value: bool) -> (); + #[doc = "Rotate the mask elements to the left by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::N`, it wraps modulo `Self::N`."] + fn rotate_elements_left_mask32x8( + self, + a: mask32x8, + ) -> mask32x8; + #[doc = "Rotate the mask elements to the right by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::N`, it wraps modulo `Self::N`."] + fn rotate_elements_right_mask32x8( + self, + a: mask32x8, + ) -> mask32x8; #[doc = "Compute the logical AND of two masks."] #[inline(always)] fn and_mask32x8(self, a: mask32x8, b: mask32x8) -> mask32x8 { @@ -5030,6 +5100,16 @@ pub trait Simd: } #[doc = "Set one logical lane of a SIMD mask."] fn set_mask64x4(self, a: &mut mask64x4, index: usize, value: bool) -> (); + #[doc = "Rotate the mask elements to the left by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::N`, it wraps modulo `Self::N`."] + fn rotate_elements_left_mask64x4( + self, + a: mask64x4, + ) -> mask64x4; + #[doc = "Rotate the mask elements to the right by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::N`, it wraps modulo `Self::N`."] + fn rotate_elements_right_mask64x4( + self, + a: mask64x4, + ) -> mask64x4; #[doc = "Compute the logical AND of two masks."] #[inline(always)] fn and_mask64x4(self, a: mask64x4, b: mask64x4) -> mask64x4 { @@ -6069,6 +6149,16 @@ pub trait Simd: } #[doc = "Set one logical lane of a SIMD mask."] fn set_mask8x64(self, a: &mut mask8x64, index: usize, value: bool) -> (); + #[doc = "Rotate the mask elements to the left by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::N`, it wraps modulo `Self::N`."] + fn rotate_elements_left_mask8x64( + self, + a: mask8x64, + ) -> mask8x64; + #[doc = "Rotate the mask elements to the right by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::N`, it wraps modulo `Self::N`."] + fn rotate_elements_right_mask8x64( + self, + a: mask8x64, + ) -> mask8x64; #[doc = "Compute the logical AND of two masks."] #[inline(always)] fn and_mask8x64(self, a: mask8x64, b: mask8x64) -> mask8x64 { @@ -6786,6 +6876,16 @@ pub trait Simd: } #[doc = "Set one logical lane of a SIMD mask."] fn set_mask16x32(self, a: &mut mask16x32, index: usize, value: bool) -> (); + #[doc = "Rotate the mask elements to the left by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::N`, it wraps modulo `Self::N`."] + fn rotate_elements_left_mask16x32( + self, + a: mask16x32, + ) -> mask16x32; + #[doc = "Rotate the mask elements to the right by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::N`, it wraps modulo `Self::N`."] + fn rotate_elements_right_mask16x32( + self, + a: mask16x32, + ) -> mask16x32; #[doc = "Compute the logical AND of two masks."] #[inline(always)] fn and_mask16x32(self, a: mask16x32, b: mask16x32) -> mask16x32 { @@ -7506,6 +7606,16 @@ pub trait Simd: } #[doc = "Set one logical lane of a SIMD mask."] fn set_mask32x16(self, a: &mut mask32x16, index: usize, value: bool) -> (); + #[doc = "Rotate the mask elements to the left by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::N`, it wraps modulo `Self::N`."] + fn rotate_elements_left_mask32x16( + self, + a: mask32x16, + ) -> mask32x16; + #[doc = "Rotate the mask elements to the right by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::N`, it wraps modulo `Self::N`."] + fn rotate_elements_right_mask32x16( + self, + a: mask32x16, + ) -> mask32x16; #[doc = "Compute the logical AND of two masks."] #[inline(always)] fn and_mask32x16(self, a: mask32x16, b: mask32x16) -> mask32x16 { @@ -8599,6 +8709,16 @@ pub trait Simd: } #[doc = "Set one logical lane of a SIMD mask."] fn set_mask64x8(self, a: &mut mask64x8, index: usize, value: bool) -> (); + #[doc = "Rotate the mask elements to the left by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::N`, it wraps modulo `Self::N`."] + fn rotate_elements_left_mask64x8( + self, + a: mask64x8, + ) -> mask64x8; + #[doc = "Rotate the mask elements to the right by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::N`, it wraps modulo `Self::N`."] + fn rotate_elements_right_mask64x8( + self, + a: mask64x8, + ) -> mask64x8; #[doc = "Compute the logical AND of two masks."] #[inline(always)] fn and_mask64x8(self, a: mask64x8, b: mask64x8) -> mask64x8 { @@ -9451,6 +9571,10 @@ pub trait SimdMask: #[doc = r""] #[doc = r" The slice must be exactly the size of the SIMD mask."] fn store_slice(&self, slice: &mut [Self::Element]); + #[doc = "Rotate the mask elements to the left by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::N`, it wraps modulo `Self::N`."] + fn rotate_elements_left(self) -> Self; + #[doc = "Rotate the mask elements to the right by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::N`, it wraps modulo `Self::N`."] + fn rotate_elements_right(self) -> Self; #[doc = "Reverse the order of the mask's logical lanes."] fn reverse(self) -> Self; #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."] diff --git a/fearless_simd/src/generated/simd_types.rs b/fearless_simd/src/generated/simd_types.rs index 3c69e51a..4efe309b 100644 --- a/fearless_simd/src/generated/simd_types.rs +++ b/fearless_simd/src/generated/simd_types.rs @@ -987,6 +987,14 @@ impl SimdMask for mask8x16 { *slice = (*self).into(); } #[inline(always)] + fn rotate_elements_left(self) -> Self { + self.simd.rotate_elements_left_mask8x16::(self) + } + #[inline(always)] + fn rotate_elements_right(self) -> Self { + self.simd.rotate_elements_right_mask8x16::(self) + } + #[inline(always)] fn reverse(self) -> Self { self.simd.reverse_mask8x16(self) } @@ -1675,6 +1683,14 @@ impl SimdMask for mask16x8 { *slice = (*self).into(); } #[inline(always)] + fn rotate_elements_left(self) -> Self { + self.simd.rotate_elements_left_mask16x8::(self) + } + #[inline(always)] + fn rotate_elements_right(self) -> Self { + self.simd.rotate_elements_right_mask16x8::(self) + } + #[inline(always)] fn reverse(self) -> Self { self.simd.reverse_mask16x8(self) } @@ -2363,6 +2379,14 @@ impl SimdMask for mask32x4 { *slice = (*self).into(); } #[inline(always)] + fn rotate_elements_left(self) -> Self { + self.simd.rotate_elements_left_mask32x4::(self) + } + #[inline(always)] + fn rotate_elements_right(self) -> Self { + self.simd.rotate_elements_right_mask32x4::(self) + } + #[inline(always)] fn reverse(self) -> Self { self.simd.reverse_mask32x4(self) } @@ -3375,6 +3399,14 @@ impl SimdMask for mask64x2 { *slice = (*self).into(); } #[inline(always)] + fn rotate_elements_left(self) -> Self { + self.simd.rotate_elements_left_mask64x2::(self) + } + #[inline(always)] + fn rotate_elements_right(self) -> Self { + self.simd.rotate_elements_right_mask64x2::(self) + } + #[inline(always)] fn reverse(self) -> Self { self.simd.reverse_mask64x2(self) } @@ -4408,6 +4440,14 @@ impl SimdMask for mask8x32 { *slice = (*self).into(); } #[inline(always)] + fn rotate_elements_left(self) -> Self { + self.simd.rotate_elements_left_mask8x32::(self) + } + #[inline(always)] + fn rotate_elements_right(self) -> Self { + self.simd.rotate_elements_right_mask8x32::(self) + } + #[inline(always)] fn reverse(self) -> Self { self.simd.reverse_mask8x32(self) } @@ -5104,6 +5144,14 @@ impl SimdMask for mask16x16 { *slice = (*self).into(); } #[inline(always)] + fn rotate_elements_left(self) -> Self { + self.simd.rotate_elements_left_mask16x16::(self) + } + #[inline(always)] + fn rotate_elements_right(self) -> Self { + self.simd.rotate_elements_right_mask16x16::(self) + } + #[inline(always)] fn reverse(self) -> Self { self.simd.reverse_mask16x16(self) } @@ -5806,6 +5854,14 @@ impl SimdMask for mask32x8 { *slice = (*self).into(); } #[inline(always)] + fn rotate_elements_left(self) -> Self { + self.simd.rotate_elements_left_mask32x8::(self) + } + #[inline(always)] + fn rotate_elements_right(self) -> Self { + self.simd.rotate_elements_right_mask32x8::(self) + } + #[inline(always)] fn reverse(self) -> Self { self.simd.reverse_mask32x8(self) } @@ -6803,6 +6859,14 @@ impl SimdMask for mask64x4 { *slice = (*self).into(); } #[inline(always)] + fn rotate_elements_left(self) -> Self { + self.simd.rotate_elements_left_mask64x4::(self) + } + #[inline(always)] + fn rotate_elements_right(self) -> Self { + self.simd.rotate_elements_right_mask64x4::(self) + } + #[inline(always)] fn reverse(self) -> Self { self.simd.reverse_mask64x4(self) } @@ -7891,6 +7955,14 @@ impl SimdMask for mask8x64 { *slice = (*self).into(); } #[inline(always)] + fn rotate_elements_left(self) -> Self { + self.simd.rotate_elements_left_mask8x64::(self) + } + #[inline(always)] + fn rotate_elements_right(self) -> Self { + self.simd.rotate_elements_right_mask8x64::(self) + } + #[inline(always)] fn reverse(self) -> Self { self.simd.reverse_mask8x64(self) } @@ -8607,6 +8679,14 @@ impl SimdMask for mask16x32 { *slice = (*self).into(); } #[inline(always)] + fn rotate_elements_left(self) -> Self { + self.simd.rotate_elements_left_mask16x32::(self) + } + #[inline(always)] + fn rotate_elements_right(self) -> Self { + self.simd.rotate_elements_right_mask16x32::(self) + } + #[inline(always)] fn reverse(self) -> Self { self.simd.reverse_mask16x32(self) } @@ -9315,6 +9395,14 @@ impl SimdMask for mask32x16 { *slice = (*self).into(); } #[inline(always)] + fn rotate_elements_left(self) -> Self { + self.simd.rotate_elements_left_mask32x16::(self) + } + #[inline(always)] + fn rotate_elements_right(self) -> Self { + self.simd.rotate_elements_right_mask32x16::(self) + } + #[inline(always)] fn reverse(self) -> Self { self.simd.reverse_mask32x16(self) } @@ -10330,6 +10418,14 @@ impl SimdMask for mask64x8 { *slice = (*self).into(); } #[inline(always)] + fn rotate_elements_left(self) -> Self { + self.simd.rotate_elements_left_mask64x8::(self) + } + #[inline(always)] + fn rotate_elements_right(self) -> Self { + self.simd.rotate_elements_right_mask64x8::(self) + } + #[inline(always)] fn reverse(self) -> Self { self.simd.reverse_mask64x8(self) } diff --git a/fearless_simd/src/generated/sse2.rs b/fearless_simd/src/generated/sse2.rs index ed0c46c2..a559bb52 100644 --- a/fearless_simd/src/generated/sse2.rs +++ b/fearless_simd/src/generated/sse2.rs @@ -2202,6 +2202,36 @@ impl Simd for Sse2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask8x16( + self, + a: mask8x16, + ) -> mask8x16 { + let int = i8x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask8x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask8x16( + self, + a: mask8x16, + ) -> mask8x16 { + let int = i8x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask8x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn and_mask8x16(self, a: mask8x16, b: mask8x16) -> mask8x16 { crate::kernel!( #[inline(always)] @@ -3478,6 +3508,36 @@ impl Simd for Sse2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask16x8( + self, + a: mask16x8, + ) -> mask16x8 { + let int = i16x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask16x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask16x8( + self, + a: mask16x8, + ) -> mask16x8 { + let int = i16x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask16x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn and_mask16x8(self, a: mask16x8, b: mask16x8) -> mask16x8 { crate::kernel!( #[inline(always)] @@ -4748,6 +4808,36 @@ impl Simd for Sse2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask32x4( + self, + a: mask32x4, + ) -> mask32x4 { + let int = i32x4 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask32x4 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask32x4( + self, + a: mask32x4, + ) -> mask32x4 { + let int = i32x4 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask32x4 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn and_mask32x4(self, a: mask32x4, b: mask32x4) -> mask32x4 { crate::kernel!( #[inline(always)] @@ -6261,6 +6351,36 @@ impl Simd for Sse2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask64x2( + self, + a: mask64x2, + ) -> mask64x2 { + let int = i64x2 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask64x2 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask64x2( + self, + a: mask64x2, + ) -> mask64x2 { + let int = i64x2 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask64x2 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn and_mask64x2(self, a: mask64x2, b: mask64x2) -> mask64x2 { crate::kernel!( #[inline(always)] @@ -6535,6 +6655,36 @@ impl Simd for Sse2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask8x32( + self, + a: mask8x32, + ) -> mask8x32 { + let int = i8x32 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask8x32 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask8x32( + self, + a: mask8x32, + ) -> mask8x32 { + let int = i8x32 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask8x32 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn combine_mask8x32(self, a: mask8x32, b: mask8x32) -> mask8x64 { mask8x64 { val: crate::support::Aligned512([a.val.0[0], a.val.0[1], b.val.0[0], b.val.0[1]]), @@ -6651,6 +6801,36 @@ impl Simd for Sse2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask16x16( + self, + a: mask16x16, + ) -> mask16x16 { + let int = i16x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask16x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask16x16( + self, + a: mask16x16, + ) -> mask16x16 { + let int = i16x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask16x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn combine_mask16x16(self, a: mask16x16, b: mask16x16) -> mask16x32 { mask16x32 { val: crate::support::Aligned512([a.val.0[0], a.val.0[1], b.val.0[0], b.val.0[1]]), @@ -6754,6 +6934,36 @@ impl Simd for Sse2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask32x8( + self, + a: mask32x8, + ) -> mask32x8 { + let int = i32x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask32x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask32x8( + self, + a: mask32x8, + ) -> mask32x8 { + let int = i32x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask32x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn combine_mask32x8(self, a: mask32x8, b: mask32x8) -> mask32x16 { mask32x16 { val: crate::support::Aligned512([a.val.0[0], a.val.0[1], b.val.0[0], b.val.0[1]]), @@ -6893,6 +7103,36 @@ impl Simd for Sse2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask64x4( + self, + a: mask64x4, + ) -> mask64x4 { + let int = i64x4 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask64x4 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask64x4( + self, + a: mask64x4, + ) -> mask64x4 { + let int = i64x4 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask64x4 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn combine_mask64x4(self, a: mask64x4, b: mask64x4) -> mask64x8 { mask64x8 { val: crate::support::Aligned512([a.val.0[0], a.val.0[1], b.val.0[0], b.val.0[1]]), @@ -7034,6 +7274,36 @@ impl Simd for Sse2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask8x64( + self, + a: mask8x64, + ) -> mask8x64 { + let int = i8x64 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask8x64 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask8x64( + self, + a: mask8x64, + ) -> mask8x64 { + let int = i8x64 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask8x64 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn split_mask8x64(self, a: mask8x64) -> (mask8x32, mask8x32) { ( mask8x32 { @@ -7132,6 +7402,36 @@ impl Simd for Sse2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask16x32( + self, + a: mask16x32, + ) -> mask16x32 { + let int = i16x32 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask16x32 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask16x32( + self, + a: mask16x32, + ) -> mask16x32 { + let int = i16x32 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask16x32 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn split_mask16x32(self, a: mask16x32) -> (mask16x16, mask16x16) { ( mask16x16 { @@ -7214,6 +7514,36 @@ impl Simd for Sse2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask32x16( + self, + a: mask32x16, + ) -> mask32x16 { + let int = i32x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask32x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask32x16( + self, + a: mask32x16, + ) -> mask32x16 { + let int = i32x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask32x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn split_mask32x16(self, a: mask32x16) -> (mask32x8, mask32x8) { ( mask32x8 { @@ -7325,6 +7655,36 @@ impl Simd for Sse2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask64x8( + self, + a: mask64x8, + ) -> mask64x8 { + let int = i64x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask64x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask64x8( + self, + a: mask64x8, + ) -> mask64x8 { + let int = i64x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask64x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn split_mask64x8(self, a: mask64x8) -> (mask64x4, mask64x4) { ( mask64x4 { diff --git a/fearless_simd/src/generated/sse4_2.rs b/fearless_simd/src/generated/sse4_2.rs index 21870c53..72ede6f4 100644 --- a/fearless_simd/src/generated/sse4_2.rs +++ b/fearless_simd/src/generated/sse4_2.rs @@ -2010,6 +2010,36 @@ impl Simd for Sse4_2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask8x16( + self, + a: mask8x16, + ) -> mask8x16 { + let int = i8x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask8x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask8x16( + self, + a: mask8x16, + ) -> mask8x16 { + let int = i8x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask8x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn and_mask8x16(self, a: mask8x16, b: mask8x16) -> mask8x16 { crate::kernel!( #[inline(always)] @@ -3212,6 +3242,36 @@ impl Simd for Sse4_2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask16x8( + self, + a: mask16x8, + ) -> mask16x8 { + let int = i16x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask16x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask16x8( + self, + a: mask16x8, + ) -> mask16x8 { + let int = i16x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask16x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn and_mask16x8(self, a: mask16x8, b: mask16x8) -> mask16x8 { crate::kernel!( #[inline(always)] @@ -4363,6 +4423,36 @@ impl Simd for Sse4_2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask32x4( + self, + a: mask32x4, + ) -> mask32x4 { + let int = i32x4 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask32x4 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask32x4( + self, + a: mask32x4, + ) -> mask32x4 { + let int = i32x4 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask32x4 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn and_mask32x4(self, a: mask32x4, b: mask32x4) -> mask32x4 { crate::kernel!( #[inline(always)] @@ -6046,6 +6136,36 @@ impl Simd for Sse4_2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask64x2( + self, + a: mask64x2, + ) -> mask64x2 { + let int = i64x2 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask64x2 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask64x2( + self, + a: mask64x2, + ) -> mask64x2 { + let int = i64x2 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask64x2 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn and_mask64x2(self, a: mask64x2, b: mask64x2) -> mask64x2 { crate::kernel!( #[inline(always)] @@ -6319,6 +6439,36 @@ impl Simd for Sse4_2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask8x32( + self, + a: mask8x32, + ) -> mask8x32 { + let int = i8x32 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask8x32 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask8x32( + self, + a: mask8x32, + ) -> mask8x32 { + let int = i8x32 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask8x32 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn combine_mask8x32(self, a: mask8x32, b: mask8x32) -> mask8x64 { mask8x64 { val: crate::support::Aligned512([a.val.0[0], a.val.0[1], b.val.0[0], b.val.0[1]]), @@ -6435,6 +6585,36 @@ impl Simd for Sse4_2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask16x16( + self, + a: mask16x16, + ) -> mask16x16 { + let int = i16x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask16x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask16x16( + self, + a: mask16x16, + ) -> mask16x16 { + let int = i16x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask16x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn combine_mask16x16(self, a: mask16x16, b: mask16x16) -> mask16x32 { mask16x32 { val: crate::support::Aligned512([a.val.0[0], a.val.0[1], b.val.0[0], b.val.0[1]]), @@ -6538,6 +6718,36 @@ impl Simd for Sse4_2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask32x8( + self, + a: mask32x8, + ) -> mask32x8 { + let int = i32x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask32x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask32x8( + self, + a: mask32x8, + ) -> mask32x8 { + let int = i32x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask32x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn combine_mask32x8(self, a: mask32x8, b: mask32x8) -> mask32x16 { mask32x16 { val: crate::support::Aligned512([a.val.0[0], a.val.0[1], b.val.0[0], b.val.0[1]]), @@ -6677,6 +6887,36 @@ impl Simd for Sse4_2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask64x4( + self, + a: mask64x4, + ) -> mask64x4 { + let int = i64x4 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask64x4 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask64x4( + self, + a: mask64x4, + ) -> mask64x4 { + let int = i64x4 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask64x4 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn combine_mask64x4(self, a: mask64x4, b: mask64x4) -> mask64x8 { mask64x8 { val: crate::support::Aligned512([a.val.0[0], a.val.0[1], b.val.0[0], b.val.0[1]]), @@ -6865,6 +7105,36 @@ impl Simd for Sse4_2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask8x64( + self, + a: mask8x64, + ) -> mask8x64 { + let int = i8x64 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask8x64 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask8x64( + self, + a: mask8x64, + ) -> mask8x64 { + let int = i8x64 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask8x64 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn split_mask8x64(self, a: mask8x64) -> (mask8x32, mask8x32) { ( mask8x32 { @@ -6963,6 +7233,36 @@ impl Simd for Sse4_2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask16x32( + self, + a: mask16x32, + ) -> mask16x32 { + let int = i16x32 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask16x32 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask16x32( + self, + a: mask16x32, + ) -> mask16x32 { + let int = i16x32 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask16x32 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn split_mask16x32(self, a: mask16x32) -> (mask16x16, mask16x16) { ( mask16x16 { @@ -7045,6 +7345,36 @@ impl Simd for Sse4_2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask32x16( + self, + a: mask32x16, + ) -> mask32x16 { + let int = i32x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask32x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask32x16( + self, + a: mask32x16, + ) -> mask32x16 { + let int = i32x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask32x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn split_mask32x16(self, a: mask32x16) -> (mask32x8, mask32x8) { ( mask32x8 { @@ -7156,6 +7486,36 @@ impl Simd for Sse4_2 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask64x8( + self, + a: mask64x8, + ) -> mask64x8 { + let int = i64x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask64x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask64x8( + self, + a: mask64x8, + ) -> mask64x8 { + let int = i64x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask64x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn split_mask64x8(self, a: mask64x8) -> (mask64x4, mask64x4) { ( mask64x4 { diff --git a/fearless_simd/src/generated/wasm.rs b/fearless_simd/src/generated/wasm.rs index ba07c50e..5a6a9ef2 100644 --- a/fearless_simd/src/generated/wasm.rs +++ b/fearless_simd/src/generated/wasm.rs @@ -1297,6 +1297,36 @@ impl Simd for WasmSimd128 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask8x16( + self, + a: mask8x16, + ) -> mask8x16 { + let int = i8x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask8x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask8x16( + self, + a: mask8x16, + ) -> mask8x16 { + let int = i8x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask8x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn and_mask8x16(self, a: mask8x16, b: mask8x16) -> mask8x16 { v128_and(a.into(), b.into()).simd_into(self) } @@ -1944,6 +1974,36 @@ impl Simd for WasmSimd128 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask16x8( + self, + a: mask16x8, + ) -> mask16x8 { + let int = i16x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask16x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask16x8( + self, + a: mask16x8, + ) -> mask16x8 { + let int = i16x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask16x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn and_mask16x8(self, a: mask16x8, b: mask16x8) -> mask16x8 { v128_and(a.into(), b.into()).simd_into(self) } @@ -2563,6 +2623,36 @@ impl Simd for WasmSimd128 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask32x4( + self, + a: mask32x4, + ) -> mask32x4 { + let int = i32x4 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask32x4 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask32x4( + self, + a: mask32x4, + ) -> mask32x4 { + let int = i32x4 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask32x4 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn and_mask32x4(self, a: mask32x4, b: mask32x4) -> mask32x4 { v128_and(a.into(), b.into()).simd_into(self) } @@ -3495,6 +3585,36 @@ impl Simd for WasmSimd128 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask64x2( + self, + a: mask64x2, + ) -> mask64x2 { + let int = i64x2 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask64x2 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask64x2( + self, + a: mask64x2, + ) -> mask64x2 { + let int = i64x2 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask64x2 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn and_mask64x2(self, a: mask64x2, b: mask64x2) -> mask64x2 { v128_and(a.into(), b.into()).simd_into(self) } @@ -3697,6 +3817,36 @@ impl Simd for WasmSimd128 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask8x32( + self, + a: mask8x32, + ) -> mask8x32 { + let int = i8x32 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask8x32 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask8x32( + self, + a: mask8x32, + ) -> mask8x32 { + let int = i8x32 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask8x32 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn combine_mask8x32(self, a: mask8x32, b: mask8x32) -> mask8x64 { mask8x64 { val: crate::support::Aligned512([a.val.0[0], a.val.0[1], b.val.0[0], b.val.0[1]]), @@ -3798,6 +3948,36 @@ impl Simd for WasmSimd128 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask16x16( + self, + a: mask16x16, + ) -> mask16x16 { + let int = i16x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask16x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask16x16( + self, + a: mask16x16, + ) -> mask16x16 { + let int = i16x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask16x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn combine_mask16x16(self, a: mask16x16, b: mask16x16) -> mask16x32 { mask16x32 { val: crate::support::Aligned512([a.val.0[0], a.val.0[1], b.val.0[0], b.val.0[1]]), @@ -3899,6 +4079,36 @@ impl Simd for WasmSimd128 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask32x8( + self, + a: mask32x8, + ) -> mask32x8 { + let int = i32x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask32x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask32x8( + self, + a: mask32x8, + ) -> mask32x8 { + let int = i32x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask32x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn combine_mask32x8(self, a: mask32x8, b: mask32x8) -> mask32x16 { mask32x16 { val: crate::support::Aligned512([a.val.0[0], a.val.0[1], b.val.0[0], b.val.0[1]]), @@ -4035,6 +4245,36 @@ impl Simd for WasmSimd128 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask64x4( + self, + a: mask64x4, + ) -> mask64x4 { + let int = i64x4 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask64x4 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask64x4( + self, + a: mask64x4, + ) -> mask64x4 { + let int = i64x4 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask64x4 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn combine_mask64x4(self, a: mask64x4, b: mask64x4) -> mask64x8 { mask64x8 { val: crate::support::Aligned512([a.val.0[0], a.val.0[1], b.val.0[0], b.val.0[1]]), @@ -4160,6 +4400,36 @@ impl Simd for WasmSimd128 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask8x64( + self, + a: mask8x64, + ) -> mask8x64 { + let int = i8x64 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask8x64 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask8x64( + self, + a: mask8x64, + ) -> mask8x64 { + let int = i8x64 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask8x64 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn split_mask8x64(self, a: mask8x64) -> (mask8x32, mask8x32) { ( mask8x32 { @@ -4240,6 +4510,36 @@ impl Simd for WasmSimd128 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask16x32( + self, + a: mask16x32, + ) -> mask16x32 { + let int = i16x32 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask16x32 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask16x32( + self, + a: mask16x32, + ) -> mask16x32 { + let int = i16x32 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask16x32 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn split_mask16x32(self, a: mask16x32) -> (mask16x16, mask16x16) { ( mask16x16 { @@ -4320,6 +4620,36 @@ impl Simd for WasmSimd128 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask32x16( + self, + a: mask32x16, + ) -> mask32x16 { + let int = i32x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask32x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask32x16( + self, + a: mask32x16, + ) -> mask32x16 { + let int = i32x16 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask32x16 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn split_mask32x16(self, a: mask32x16) -> (mask32x8, mask32x8) { ( mask32x8 { @@ -4428,6 +4758,36 @@ impl Simd for WasmSimd128 { *a = lanes.simd_into(self); } #[inline(always)] + fn rotate_elements_left_mask64x8( + self, + a: mask64x8, + ) -> mask64x8 { + let int = i64x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_left::(); + mask64x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] + fn rotate_elements_right_mask64x8( + self, + a: mask64x8, + ) -> mask64x8 { + let int = i64x8 { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.rotate_elements_right::(); + mask64x8 { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + #[inline(always)] fn split_mask64x8(self, a: mask64x8) -> (mask64x4, mask64x4) { ( mask64x4 { diff --git a/fearless_simd_gen/src/generic.rs b/fearless_simd_gen/src/generic.rs index a6c03d65..96383d0f 100644 --- a/fearless_simd_gen/src/generic.rs +++ b/fearless_simd_gen/src/generic.rs @@ -6,7 +6,7 @@ use quote::{ToTokens, quote}; use crate::{ level::Level, - ops::{Op, OpSig, SlideGranularity}, + ops::{ElementDirection, Op, OpSig, SlideGranularity}, types::{ScalarType, VecType}, }; @@ -190,6 +190,44 @@ pub(crate) fn integer_lane_mask_splat_arg(vec_ty: &VecType) -> TokenStream { } } +/// Rotate an integer-lane mask by bitcasting its storage to the corresponding +/// signed vector and forwarding to `SimdBase`'s element rotation. +/// +/// This is only valid for backends whose masks use full integer lanes. Compact +/// predicate masks, such as AVX-512 masks, need their own implementation. +pub(crate) fn integer_lane_mask_rotate(op: Op, vec_ty: &VecType) -> TokenStream { + assert_eq!( + vec_ty.scalar, + ScalarType::Mask, + "mask element rotation only operates on masks" + ); + let direction = match op.sig { + OpSig::RotateElements { direction } => direction, + _ => panic!("integer_lane_mask_rotate only implements mask element rotation"), + }; + let method_sig = op.simd_trait_method_sig(vec_ty); + let rotate = match direction { + ElementDirection::Left => quote! { rotate_elements_left }, + ElementDirection::Right => quote! { rotate_elements_right }, + }; + let int_ty = vec_ty.cast(ScalarType::Int).rust(); + let mask_ty = vec_ty.rust(); + + quote! { + #method_sig { + let int = #int_ty { + val: crate::transmute::checked_transmute_copy(&a.val), + simd: self, + }; + let rotated = int.#rotate::(); + #mask_ty { + val: crate::transmute::checked_transmute_copy(&rotated.val), + simd: self, + } + } + } +} + /// Generic operation implementations. /// /// Most operations are implemented using split/combine, while some forward to @@ -233,6 +271,9 @@ pub(crate) fn generic_op(op: &Op, ty: &VecType) -> TokenStream { } } } + OpSig::RotateElements { .. } => { + panic!("mask element rotation must operate on the full mask") + } OpSig::Binary => { quote! { #method_sig { diff --git a/fearless_simd_gen/src/mk_fallback.rs b/fearless_simd_gen/src/mk_fallback.rs index d4d88412..ad152faf 100644 --- a/fearless_simd_gen/src/mk_fallback.rs +++ b/fearless_simd_gen/src/mk_fallback.rs @@ -4,7 +4,7 @@ use crate::arch::fallback; use crate::generic::{ generic_mask_from_bitmask, generic_mask_set, generic_mask_to_bitmask, generic_op_name, - integer_lane_mask_splat_arg, + integer_lane_mask_rotate, integer_lane_mask_splat_arg, }; use crate::level::Level; use crate::ops::{NarrowingMode, Op, OpSig, relaxed_narrow_method}; @@ -297,6 +297,7 @@ impl Level for Fallback { fallback_reduce_min_max(method_sig, vec_ty, lane_op) } } + OpSig::RotateElements { .. } => integer_lane_mask_rotate(op, vec_ty), OpSig::Widen { target_ty } => { let scalar = target_ty.scalar.rust(target_ty.scalar_bits); let half_len = vec_ty.len / 2; diff --git a/fearless_simd_gen/src/mk_neon.rs b/fearless_simd_gen/src/mk_neon.rs index 21b5cde5..3b5b7e65 100644 --- a/fearless_simd_gen/src/mk_neon.rs +++ b/fearless_simd_gen/src/mk_neon.rs @@ -6,7 +6,8 @@ use quote::{ToTokens as _, format_ident, quote}; use crate::generic::{ count_zeros_method, fallback_method, generic_mask_set, generic_op_name, - integer_lane_mask_splat_arg, reverse_method, reverse_vector_mask_method, + integer_lane_mask_rotate, integer_lane_mask_splat_arg, reverse_method, + reverse_vector_mask_method, }; use crate::level::Level; use crate::ops::{NarrowingMode, Op, SlideGranularity, relaxed_narrow_method}; @@ -232,6 +233,7 @@ impl Level for Neon { let reduce = simple_intrinsic(intrinsic, vec_ty); self.kernel_method(op, vec_ty, |_| quote! { #reduce(a.into()) }) } + OpSig::RotateElements { .. } => integer_lane_mask_rotate(op, vec_ty), OpSig::LoadInterleaved { block_size, block_count, diff --git a/fearless_simd_gen/src/mk_simd_types.rs b/fearless_simd_gen/src/mk_simd_types.rs index db059627..cdfa8c80 100644 --- a/fearless_simd_gen/src/mk_simd_types.rs +++ b/fearless_simd_gen/src/mk_simd_types.rs @@ -396,13 +396,18 @@ fn simd_mask_impl(ty: &VecType) -> TokenStream { op.vec_trait_method_sig() }; if let Some(method_sig) = method_sig { - let call_args = sig - .forwarding_call_args() - .expect("this method can be forwarded to a specific Simd function"); + let call = if matches!(sig, OpSig::RotateElements { .. }) { + quote! { self.simd.#trait_method::(self) } + } else { + let call_args = sig + .forwarding_call_args() + .expect("this method can be forwarded to a specific Simd function"); + quote! { self.simd.#trait_method(#call_args) } + }; methods.push(quote! { #[inline(always)] #method_sig { - self.simd.#trait_method(#call_args) + #call } }); } diff --git a/fearless_simd_gen/src/mk_wasm.rs b/fearless_simd_gen/src/mk_wasm.rs index 21052fc1..46857113 100644 --- a/fearless_simd_gen/src/mk_wasm.rs +++ b/fearless_simd_gen/src/mk_wasm.rs @@ -7,7 +7,7 @@ use quote::{format_ident, quote}; use crate::arch::wasm::{arch_prefix, v128_intrinsic}; use crate::generic::{ count_zeros_method, fallback_method, generic_block_combine, generic_block_split, - generic_mask_set, generic_op_name, integer_lane_mask_splat_arg, + generic_mask_set, generic_op_name, integer_lane_mask_rotate, integer_lane_mask_splat_arg, recursive_swizzle_dyn_precise_body, reverse_method, reverse_vector_mask_method, }; use crate::level::Level; @@ -627,6 +627,7 @@ impl Level for WasmSimd128 { } } } + OpSig::RotateElements { .. } => integer_lane_mask_rotate(op, vec_ty), OpSig::Select => { // Rust includes unsigned versions of the lane select intrinsics, but they're // just aliases for the signed ones diff --git a/fearless_simd_gen/src/mk_x86.rs b/fearless_simd_gen/src/mk_x86.rs index 1bc6838a..78d2d09a 100644 --- a/fearless_simd_gen/src/mk_x86.rs +++ b/fearless_simd_gen/src/mk_x86.rs @@ -8,11 +8,14 @@ use crate::arch::x86::{ }; use crate::generic::{ count_zeros_method, fallback_method, generic_block_combine, generic_block_split, - generic_mask_from_bitmask, generic_mask_set, generic_op_name, integer_lane_mask_splat_arg, - recursive_swizzle_dyn_precise_body, reverse_method, reverse_vector_mask_method, + generic_mask_from_bitmask, generic_mask_set, generic_op_name, integer_lane_mask_rotate, + integer_lane_mask_splat_arg, recursive_swizzle_dyn_precise_body, reverse_method, + reverse_vector_mask_method, }; use crate::level::Level; -use crate::ops::{NarrowingMode, Op, OpSig, Quantifier, SlideGranularity, relaxed_narrow_method}; +use crate::ops::{ + ElementDirection, NarrowingMode, Op, OpSig, Quantifier, SlideGranularity, relaxed_narrow_method, +}; use crate::types::{ScalarType, VecType}; use proc_macro2::{Ident, Literal, Span, TokenStream}; use quote::{ToTokens as _, format_ident, quote}; @@ -325,6 +328,9 @@ impl Level for X86 { self.handle_reduce_min_max(op, vec_ty, lane_op) } } + OpSig::RotateElements { direction } => { + self.handle_mask_rotate_elements(op, vec_ty, direction) + } OpSig::Widen { target_ty } => self.handle_widen(op, vec_ty, target_ty), OpSig::Narrow { target_ty, mode } => self.handle_narrow(op, vec_ty, target_ty, mode), OpSig::Binary => self.handle_binary(op, method, vec_ty), @@ -1486,6 +1492,64 @@ impl X86 { } } + pub(crate) fn handle_mask_rotate_elements( + &self, + op: Op, + vec_ty: &VecType, + direction: ElementDirection, + ) -> TokenStream { + assert_eq!( + vec_ty.scalar, + ScalarType::Mask, + "mask element rotation only operates on masks" + ); + + if *self != Self::Avx512 { + return integer_lane_mask_rotate(op, vec_ty); + } + + let method_sig = op.simd_trait_method_sig(vec_ty); + let len = Literal::usize_unsuffixed(vec_ty.len); + + if vec_ty.len == avx512_mask_register_bits(vec_ty) { + let rotate = match direction { + // Lane zero is the low bit, so rotating elements left rotates bits right. + ElementDirection::Left => quote! { rotate_right }, + ElementDirection::Right => quote! { rotate_left }, + }; + let result = + avx512_mask_value(vec_ty, quote! { a.val.#rotate((OFFSET % #len) as u32) }); + return quote! { + #method_sig { + #result + } + }; + } + + // Two- and four-lane masks both occupy an __mmask8, so rotate within + // the logical lane width rather than the storage type's eight bits. + let lane_mask = avx512_mask_lane_bits(vec_ty); + let input = avx512_mask_bits_expr(quote! { a }); + let rotated = match direction { + ElementDirection::Left => { + quote! { ((bits >> offset) | (bits << (#len - offset))) & #lane_mask } + } + ElementDirection::Right => { + quote! { ((bits << offset) | (bits >> (#len - offset))) & #lane_mask } + } + }; + let result = avx512_mask_value(vec_ty, quote! { bits }); + + quote! { + #method_sig { + let bits = #input & #lane_mask; + let offset = OFFSET % #len; + let bits = if offset == 0 { bits } else { #rotated }; + #result + } + } + } + pub(crate) fn handle_mask_from_bitmask(&self, op: Op, vec_ty: &VecType) -> TokenStream { assert_eq!( vec_ty.scalar, diff --git a/fearless_simd_gen/src/ops.rs b/fearless_simd_gen/src/ops.rs index 9ee913ee..901b88bd 100644 --- a/fearless_simd_gen/src/ops.rs +++ b/fearless_simd_gen/src/ops.rs @@ -35,6 +35,12 @@ pub(crate) enum SlideGranularity { AcrossBlocks, } +#[derive(Clone, Copy, PartialEq, Eq)] +pub(crate) enum ElementDirection { + Left, + Right, +} + #[derive(Clone, Copy, PartialEq, Eq)] pub(crate) enum NarrowingMode { Wrap, @@ -77,6 +83,8 @@ pub(crate) enum OpSig { Deinterleave, /// Takes two arguments of a vector type, plus a const generic shift amount, and returns that same vector type. Slide { granularity: SlideGranularity }, + /// Takes a mask and a const generic offset, and rotates its logical lanes. + RotateElements { direction: ElementDirection }, /// Takes a vector and a same-width byte-index vector, and returns the original vector type with its bytes /// dynamically swizzled within each 128-bit block. SwizzleDynWithinBlocks, @@ -225,7 +233,7 @@ impl Op { body: impl FnOnce(&Ident) -> TokenStream, ) -> TokenStream { assert!( - !matches!(self.sig, OpSig::Slide { .. }), + !matches!(self.sig, OpSig::Slide { .. } | OpSig::RotateElements { .. }), "kernel! does not support const-generic methods" ); @@ -267,6 +275,7 @@ impl Op { let vec = quote! { #ty<#simd_ty> }; let const_params = match self.sig { OpSig::Slide { .. } => quote! { }, + OpSig::RotateElements { .. } => quote! { }, _ => TokenStream::new(), }; @@ -315,6 +324,7 @@ impl Op { (vec![vec.clone(), vec.clone()], quote! { (#vec, #vec) }) } OpSig::Slide { .. } => (vec![vec.clone(), vec.clone()], vec), + OpSig::RotateElements { .. } => (vec![vec.clone()], vec), OpSig::SwizzleDynWithinBlocks | OpSig::SwizzleDyn | OpSig::SwizzleDynPrecise => { let bytes_ty = vec_ty.bytes_ty().rust(); (vec![vec.clone(), quote! { #bytes_ty<#simd_ty> }], vec) @@ -407,6 +417,10 @@ impl Op { let arg1 = &arg_names[1]; quote! { (#arg0, #arg1: impl SimdInto) -> Self } } + OpSig::RotateElements { .. } => { + let arg0 = &arg_names[0]; + quote! { (#arg0) -> Self } + } OpSig::SwizzleDynWithinBlocks | OpSig::SwizzleDyn | OpSig::SwizzleDynPrecise => { let arg0 = &arg_names[0]; let arg1 = &arg_names[1]; @@ -1068,6 +1082,24 @@ macro_rules! mask_reduce_blurb { } const MASK_OPS: &[Op] = &[ + Op::new( + "rotate_elements_left", + OpKind::VecTraitMethod, + OpSig::RotateElements { + direction: ElementDirection::Left, + }, + "Rotate the mask elements to the left by `OFFSET`.\n\n\ + If `OFFSET` is greater than or equal to `Self::N`, it wraps modulo `Self::N`.", + ), + Op::new( + "rotate_elements_right", + OpKind::VecTraitMethod, + OpSig::RotateElements { + direction: ElementDirection::Right, + }, + "Rotate the mask elements to the right by `OFFSET`.\n\n\ + If `OFFSET` is greater than or equal to `Self::N`, it wraps modulo `Self::N`.", + ), Op::new( "and", OpKind::Overloaded(CoreOpTrait::BitAnd), @@ -1662,6 +1694,7 @@ impl OpSig { | Self::LoadInterleaved { .. } | Self::StoreInterleaved { .. } | Self::MaskSet + | Self::RotateElements { .. } | Self::SwizzleDyn | Self::SwizzleDynPrecise | Self::Slide { @@ -1703,6 +1736,7 @@ impl OpSig { Self::MaskSet => &["a", "index", "value"], Self::Unary | Self::Reduce { .. } + | Self::RotateElements { .. } | Self::Split { .. } | Self::Cvt { .. } | Self::Widen { .. } @@ -1735,9 +1769,11 @@ impl OpSig { | Self::MaskFromBitmask | Self::MaskToBitmask | Self::MaskSet => &[], - Self::Unary | Self::Reduce { .. } | Self::Cvt { .. } | Self::MaskReduce { .. } => { - &["self"] - } + Self::Unary + | Self::Reduce { .. } + | Self::RotateElements { .. } + | Self::Cvt { .. } + | Self::MaskReduce { .. } => &["self"], Self::Widen { .. } => &[], Self::Narrow { .. } => &[], Self::SwizzleDynWithinBlocks | Self::SwizzleDyn | Self::SwizzleDynPrecise => { @@ -1794,6 +1830,7 @@ impl OpSig { | Self::Widen { .. } | Self::Narrow { .. } | Self::Shift + | Self::RotateElements { .. } | Self::MaskFromBitmask | Self::MaskToBitmask | Self::MaskSet diff --git a/fearless_simd_tests/tests/harness/ops/rotate_elements_left.rs b/fearless_simd_tests/tests/harness/ops/rotate_elements_left.rs index e977c529..2b9270ae 100644 --- a/fearless_simd_tests/tests/harness/ops/rotate_elements_left.rs +++ b/fearless_simd_tests/tests/harness/ops/rotate_elements_left.rs @@ -420,3 +420,108 @@ fn rotate_elements_left_u64x8(simd: S) { let result = a.rotate_elements_left::<1>(); assert_eq!(result.as_slice(), expected.as_slice()); } + +// Mask coverage rows. + +#[simd_test] +fn rotate_elements_left_mask8x16(simd: S) { + let a = mask8x16::from_bitmask(simd, 0x0001); + assert_eq!(a.rotate_elements_left::<1>().to_bitmask(), 0x8000); + let b = mask8x16::from_bitmask(simd, 0x5555); + assert_eq!(b.rotate_elements_left::<1>().to_bitmask(), 0xaaaa); +} + +#[simd_test] +fn rotate_elements_left_mask16x8(simd: S) { + let a = mask16x8::from_bitmask(simd, 0x01); + assert_eq!(a.rotate_elements_left::<1>().to_bitmask(), 0x80); + let b = mask16x8::from_bitmask(simd, 0x55); + assert_eq!(b.rotate_elements_left::<1>().to_bitmask(), 0xaa); +} + +#[simd_test] +fn rotate_elements_left_mask32x4(simd: S) { + let a = mask32x4::from_bitmask(simd, 0b0001); + assert_eq!(a.rotate_elements_left::<1>().to_bitmask(), 0b1000); + assert_eq!(a.rotate_elements_left::<0>().to_bitmask(), 0b0001); + assert_eq!(a.rotate_elements_left::<4>().to_bitmask(), 0b0001); + assert_eq!(a.rotate_elements_left::<5>().to_bitmask(), 0b1000); + assert_eq!( + a.rotate_elements_left::<{ usize::MAX }>().to_bitmask(), + 0b0010 + ); + let b = mask32x4::from_bitmask(simd, 0b0101); + assert_eq!(b.rotate_elements_left::<1>().to_bitmask(), 0b1010); +} + +#[simd_test] +fn rotate_elements_left_mask64x2(simd: S) { + let a = mask64x2::from_bitmask(simd, 0b01); + assert_eq!(a.rotate_elements_left::<1>().to_bitmask(), 0b10); +} + +#[simd_test] +fn rotate_elements_left_mask8x32(simd: S) { + let a = mask8x32::from_bitmask(simd, 0x0000_0001); + assert_eq!(a.rotate_elements_left::<1>().to_bitmask(), 0x8000_0000); + let b = mask8x32::from_bitmask(simd, 0x5555_5555); + assert_eq!(b.rotate_elements_left::<1>().to_bitmask(), 0xaaaa_aaaa); +} + +#[simd_test] +fn rotate_elements_left_mask16x16(simd: S) { + let a = mask16x16::from_bitmask(simd, 0x0001); + assert_eq!(a.rotate_elements_left::<1>().to_bitmask(), 0x8000); +} + +#[simd_test] +fn rotate_elements_left_mask32x8(simd: S) { + let a = mask32x8::from_bitmask(simd, 0x01); + assert_eq!(a.rotate_elements_left::<1>().to_bitmask(), 0x80); +} + +#[simd_test] +fn rotate_elements_left_mask64x4(simd: S) { + let a = mask64x4::from_bitmask(simd, 0b0001); + assert_eq!(a.rotate_elements_left::<1>().to_bitmask(), 0b1000); +} + +#[simd_test] +fn rotate_elements_left_mask8x64(simd: S) { + let a = mask8x64::from_bitmask(simd, 0x0000_0000_0000_0001); + assert_eq!( + a.rotate_elements_left::<1>().to_bitmask(), + 0x8000_0000_0000_0000 + ); + assert_eq!( + a.rotate_elements_left::<0>().to_bitmask(), + 0x0000_0000_0000_0001 + ); + assert_eq!( + a.rotate_elements_left::<64>().to_bitmask(), + 0x0000_0000_0000_0001 + ); + let b = mask8x64::from_bitmask(simd, 0x5555_5555_5555_5555); + assert_eq!( + b.rotate_elements_left::<1>().to_bitmask(), + 0xaaaa_aaaa_aaaa_aaaa + ); +} + +#[simd_test] +fn rotate_elements_left_mask16x32(simd: S) { + let a = mask16x32::from_bitmask(simd, 0x0000_0001); + assert_eq!(a.rotate_elements_left::<1>().to_bitmask(), 0x8000_0000); +} + +#[simd_test] +fn rotate_elements_left_mask32x16(simd: S) { + let a = mask32x16::from_bitmask(simd, 0x0001); + assert_eq!(a.rotate_elements_left::<1>().to_bitmask(), 0x8000); +} + +#[simd_test] +fn rotate_elements_left_mask64x8(simd: S) { + let a = mask64x8::from_bitmask(simd, 0x01); + assert_eq!(a.rotate_elements_left::<1>().to_bitmask(), 0x80); +} diff --git a/fearless_simd_tests/tests/harness/ops/rotate_elements_right.rs b/fearless_simd_tests/tests/harness/ops/rotate_elements_right.rs index 529c57eb..3d218d84 100644 --- a/fearless_simd_tests/tests/harness/ops/rotate_elements_right.rs +++ b/fearless_simd_tests/tests/harness/ops/rotate_elements_right.rs @@ -426,3 +426,108 @@ fn rotate_elements_right_u64x8(simd: S) { let result = a.rotate_elements_right::<1>(); assert_eq!(result.as_slice(), expected.as_slice()); } + +// Mask coverage rows. + +#[simd_test] +fn rotate_elements_right_mask8x16(simd: S) { + let a = mask8x16::from_bitmask(simd, 0x8000); + assert_eq!(a.rotate_elements_right::<1>().to_bitmask(), 0x0001); + let b = mask8x16::from_bitmask(simd, 0x5555); + assert_eq!(b.rotate_elements_right::<1>().to_bitmask(), 0xaaaa); +} + +#[simd_test] +fn rotate_elements_right_mask16x8(simd: S) { + let a = mask16x8::from_bitmask(simd, 0x80); + assert_eq!(a.rotate_elements_right::<1>().to_bitmask(), 0x01); + let b = mask16x8::from_bitmask(simd, 0x55); + assert_eq!(b.rotate_elements_right::<1>().to_bitmask(), 0xaa); +} + +#[simd_test] +fn rotate_elements_right_mask32x4(simd: S) { + let a = mask32x4::from_bitmask(simd, 0b1000); + assert_eq!(a.rotate_elements_right::<1>().to_bitmask(), 0b0001); + assert_eq!(a.rotate_elements_right::<0>().to_bitmask(), 0b1000); + assert_eq!(a.rotate_elements_right::<4>().to_bitmask(), 0b1000); + assert_eq!(a.rotate_elements_right::<5>().to_bitmask(), 0b0001); + assert_eq!( + a.rotate_elements_right::<{ usize::MAX }>().to_bitmask(), + 0b0100 + ); + let b = mask32x4::from_bitmask(simd, 0b0101); + assert_eq!(b.rotate_elements_right::<1>().to_bitmask(), 0b1010); +} + +#[simd_test] +fn rotate_elements_right_mask64x2(simd: S) { + let a = mask64x2::from_bitmask(simd, 0b10); + assert_eq!(a.rotate_elements_right::<1>().to_bitmask(), 0b01); +} + +#[simd_test] +fn rotate_elements_right_mask8x32(simd: S) { + let a = mask8x32::from_bitmask(simd, 0x8000_0000); + assert_eq!(a.rotate_elements_right::<1>().to_bitmask(), 0x0000_0001); + let b = mask8x32::from_bitmask(simd, 0x5555_5555); + assert_eq!(b.rotate_elements_right::<1>().to_bitmask(), 0xaaaa_aaaa); +} + +#[simd_test] +fn rotate_elements_right_mask16x16(simd: S) { + let a = mask16x16::from_bitmask(simd, 0x8000); + assert_eq!(a.rotate_elements_right::<1>().to_bitmask(), 0x0001); +} + +#[simd_test] +fn rotate_elements_right_mask32x8(simd: S) { + let a = mask32x8::from_bitmask(simd, 0x80); + assert_eq!(a.rotate_elements_right::<1>().to_bitmask(), 0x01); +} + +#[simd_test] +fn rotate_elements_right_mask64x4(simd: S) { + let a = mask64x4::from_bitmask(simd, 0b1000); + assert_eq!(a.rotate_elements_right::<1>().to_bitmask(), 0b0001); +} + +#[simd_test] +fn rotate_elements_right_mask8x64(simd: S) { + let a = mask8x64::from_bitmask(simd, 0x8000_0000_0000_0000); + assert_eq!( + a.rotate_elements_right::<1>().to_bitmask(), + 0x0000_0000_0000_0001 + ); + assert_eq!( + a.rotate_elements_right::<0>().to_bitmask(), + 0x8000_0000_0000_0000 + ); + assert_eq!( + a.rotate_elements_right::<64>().to_bitmask(), + 0x8000_0000_0000_0000 + ); + let b = mask8x64::from_bitmask(simd, 0x5555_5555_5555_5555); + assert_eq!( + b.rotate_elements_right::<1>().to_bitmask(), + 0xaaaa_aaaa_aaaa_aaaa + ); +} + +#[simd_test] +fn rotate_elements_right_mask16x32(simd: S) { + let a = mask16x32::from_bitmask(simd, 0x8000_0000); + assert_eq!(a.rotate_elements_right::<1>().to_bitmask(), 0x0000_0001); +} + +#[simd_test] +fn rotate_elements_right_mask32x16(simd: S) { + let a = mask32x16::from_bitmask(simd, 0x8000); + assert_eq!(a.rotate_elements_right::<1>().to_bitmask(), 0x0001); +} + +#[simd_test] +fn rotate_elements_right_mask64x8(simd: S) { + let a = mask64x8::from_bitmask(simd, 0x80); + assert_eq!(a.rotate_elements_right::<1>().to_bitmask(), 0x01); +}