From d00b0be7202a593a5eb90213992a43344bafdda5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Felipe=20Quintero=20Moreano?= Date: Sun, 11 Aug 2024 19:03:11 -0500 Subject: [PATCH] Adds boolean methods to u32x4 and u32x8 (#161) * feat: Adds `all`, `any` and `none` to u32x4 * feat: Adds `all`, `any` and `none` to u32x8 --- src/u32x4_.rs | 36 ++++++++++++++++++++++++++++++++++++ src/u32x8_.rs | 30 ++++++++++++++++++++++++++++++ tests/all_tests/t_u32x4.rs | 27 +++++++++++++++++++++++++++ tests/all_tests/t_u32x8.rs | 27 +++++++++++++++++++++++++++ 4 files changed, 120 insertions(+) diff --git a/src/u32x4_.rs b/src/u32x4_.rs index 7453f66..e85b0a8 100644 --- a/src/u32x4_.rs +++ b/src/u32x4_.rs @@ -512,6 +512,42 @@ impl u32x4 { } } + #[inline] + #[must_use] + pub fn any(self) -> bool { + pick! { + if #[cfg(target_feature="sse2")] { + (move_mask_i8_m128i(self.sse) & 0b1000100010001000) != 0 + } else if #[cfg(target_feature="simd128")] { + u32x4_bitmask(self.simd) != 0 + } else { + let v : [u64;2] = cast(self); + ((v[0] | v[1]) & 0x8000000080000000) != 0 + } + } + } + + #[inline] + #[must_use] + pub fn all(self) -> bool { + pick! { + if #[cfg(target_feature="sse2")] { + (move_mask_i8_m128i(self.sse) & 0b1000100010001000) == 0b1000100010001000 + } else if #[cfg(target_feature="simd128")] { + u32x4_bitmask(self.simd) == 0b1111 + } else { + let v : [u64;2] = cast(self); + (v[0] & v[1] & 0x8000000080000000) == 0x8000000080000000 + } + } + } + + #[inline] + #[must_use] + pub fn none(self) -> bool { + !self.any() + } + #[inline] pub fn to_array(self) -> [u32; 4] { cast(self) diff --git a/src/u32x8_.rs b/src/u32x8_.rs index 78df570..5b84bfb 100644 --- a/src/u32x8_.rs +++ b/src/u32x8_.rs @@ -316,6 +316,36 @@ impl u32x8 { } } + #[inline] + #[must_use] + pub fn any(self) -> bool { + pick! { + if #[cfg(target_feature="avx2")] { + ((move_mask_i8_m256i(self.avx2) as u32) & 0b10001000100010001000100010001000) != 0 + } else { + (self.a | self.b).any() + } + } + } + + #[inline] + #[must_use] + pub fn all(self) -> bool { + pick! { + if #[cfg(target_feature="avx2")] { + ((move_mask_i8_m256i(self.avx2) as u32) & 0b10001000100010001000100010001000) == 0b10001000100010001000100010001000 + } else { + (self.a & self.b).all() + } + } + } + + #[inline] + #[must_use] + pub fn none(self) -> bool { + !self.any() + } + #[inline] pub fn to_array(self) -> [u32; 8] { cast(self) diff --git a/tests/all_tests/t_u32x4.rs b/tests/all_tests/t_u32x4.rs index f70ad7b..1f10c31 100644 --- a/tests/all_tests/t_u32x4.rs +++ b/tests/all_tests/t_u32x4.rs @@ -207,3 +207,30 @@ fn impl_u32x4_shl_each() { |a, b| a.wrapping_shl(b), ); } + +#[test] +fn test_u32x4_any() { + let a = u32x4::from([0, 0, 0, u32::MAX]); + assert!(a.any()); + // + let a = u32x4::from([0, 0, 0, 0]); + assert!(!a.any()); +} + +#[test] +fn test_u32x4_all() { + let a = u32x4::from([0, 0, 0, u32::MAX]); + assert!(!a.all()); + // + let a = u32x4::from([u32::MAX; 4]); + assert!(a.all()); +} + +#[test] +fn test_u32x4_none() { + let a = u32x4::from([0, 0, 0, u32::MAX]); + assert!(!a.none()); + // + let a = u32x4::from([0; 4]); + assert!(a.none()); +} diff --git a/tests/all_tests/t_u32x8.rs b/tests/all_tests/t_u32x8.rs index 44b324f..a7d7b81 100644 --- a/tests/all_tests/t_u32x8.rs +++ b/tests/all_tests/t_u32x8.rs @@ -245,3 +245,30 @@ fn impl_u32x8_not() { crate::test_random_vector_vs_scalar(|a: u32x8, _b| !a, |a, _b| !a); } + +#[test] +fn test_u32x8_any() { + let a = u32x8::from([0, 0, 0, u32::MAX, 0, 0, 0, 0]); + assert!(a.any()); + // + let a = u32x8::from([0, 0, 0, 0, 0, 0, 0, 0]); + assert!(!a.any()); +} + +#[test] +fn test_u32x8_all() { + let a = u32x8::from([0, 0, 0, u32::MAX, 0, 0, 0, 0]); + assert!(!a.all()); + // + let a = u32x8::from([u32::MAX; 8]); + assert!(a.all()); +} + +#[test] +fn test_u32x8_none() { + let a = u32x8::from([0, 0, 0, u32::MAX, 0, 0, 0, 0]); + assert!(!a.none()); + // + let a = u32x8::from([0; 8]); + assert!(a.none()); +}