diff --git a/fearless_simd/src/generated/avx2.rs b/fearless_simd/src/generated/avx2.rs index 3a636dd6..a284f0e3 100644 --- a/fearless_simd/src/generated/avx2.rs +++ b/fearless_simd/src/generated/avx2.rs @@ -2217,6 +2217,20 @@ impl Simd for Avx2 { kernel(self, a) } #[inline(always)] + fn from_vector_mask8x16(self, vector: i8x16) -> mask8x16 { + mask8x16 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask8x16(self, a: mask8x16) -> i8x16 { + i8x16 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask8x16(self, a: &mut mask8x16, index: usize, value: bool) -> () { assert!( index < 16usize, @@ -3618,6 +3632,20 @@ impl Simd for Avx2 { kernel(self, a) } #[inline(always)] + fn from_vector_mask16x8(self, vector: i16x8) -> mask16x8 { + mask16x8 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask16x8(self, a: mask16x8) -> i16x8 { + i16x8 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask16x8(self, a: &mut mask16x8, index: usize, value: bool) -> () { assert!( index < 8usize, @@ -4999,6 +5027,20 @@ impl Simd for Avx2 { kernel(self, a) } #[inline(always)] + fn from_vector_mask32x4(self, vector: i32x4) -> mask32x4 { + mask32x4 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask32x4(self, a: mask32x4) -> i32x4 { + i32x4 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask32x4(self, a: &mut mask32x4, index: usize, value: bool) -> () { assert!( index < 4usize, @@ -7082,6 +7124,20 @@ impl Simd for Avx2 { kernel(self, a) } #[inline(always)] + fn from_vector_mask64x2(self, vector: i64x2) -> mask64x2 { + mask64x2 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask64x2(self, a: mask64x2) -> i64x2 { + i64x2 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask64x2(self, a: &mut mask64x2, index: usize, value: bool) -> () { assert!( index < 2usize, @@ -9350,6 +9406,20 @@ impl Simd for Avx2 { kernel(self, a) } #[inline(always)] + fn from_vector_mask8x32(self, vector: i8x32) -> mask8x32 { + mask8x32 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask8x32(self, a: mask8x32) -> i8x32 { + i8x32 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask8x32(self, a: &mut mask8x32, index: usize, value: bool) -> () { assert!( index < 32usize, @@ -10683,6 +10753,20 @@ impl Simd for Avx2 { kernel(self, a) } #[inline(always)] + fn from_vector_mask16x16(self, vector: i16x16) -> mask16x16 { + mask16x16 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask16x16(self, a: mask16x16) -> i16x16 { + i16x16 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask16x16(self, a: &mut mask16x16, index: usize, value: bool) -> () { assert!( index < 16usize, @@ -12065,6 +12149,20 @@ impl Simd for Avx2 { kernel(self, a) } #[inline(always)] + fn from_vector_mask32x8(self, vector: i32x8) -> mask32x8 { + mask32x8 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask32x8(self, a: mask32x8) -> i32x8 { + i32x8 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask32x8(self, a: &mut mask32x8, index: usize, value: bool) -> () { assert!( index < 8usize, @@ -14166,6 +14264,20 @@ impl Simd for Avx2 { kernel(self, a) } #[inline(always)] + fn from_vector_mask64x4(self, vector: i64x4) -> mask64x4 { + mask64x4 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask64x4(self, a: mask64x4) -> i64x4 { + i64x4 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask64x4(self, a: &mut mask64x4, index: usize, value: bool) -> () { assert!( index < 4usize, @@ -15326,6 +15438,20 @@ impl Simd for Avx2 { kernel(self, bits) } #[inline(always)] + fn from_vector_mask8x64(self, vector: i8x64) -> mask8x64 { + mask8x64 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask8x64(self, a: mask8x64) -> i8x64 { + i8x64 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask8x64(self, a: &mut mask8x64, index: usize, value: bool) -> () { assert!( index < 64usize, @@ -15554,6 +15680,20 @@ impl Simd for Avx2 { kernel(self, a) } #[inline(always)] + fn from_vector_mask16x32(self, vector: i16x32) -> mask16x32 { + mask16x32 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask16x32(self, a: mask16x32) -> i16x32 { + i16x32 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask16x32(self, a: &mut mask16x32, index: usize, value: bool) -> () { assert!( index < 32usize, @@ -15975,6 +16115,20 @@ impl Simd for Avx2 { kernel(self, bits) } #[inline(always)] + fn from_vector_mask32x16(self, vector: i32x16) -> mask32x16 { + mask32x16 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask32x16(self, a: mask32x16) -> i32x16 { + i32x16 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask32x16(self, a: &mut mask32x16, index: usize, value: bool) -> () { assert!( index < 16usize, @@ -16602,6 +16756,20 @@ impl Simd for Avx2 { kernel(self, bits) } #[inline(always)] + fn from_vector_mask64x8(self, vector: i64x8) -> mask64x8 { + mask64x8 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask64x8(self, a: mask64x8) -> i64x8 { + i64x8 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask64x8(self, a: &mut mask64x8, index: usize, value: bool) -> () { assert!( index < 8usize, diff --git a/fearless_simd/src/generated/avx512.rs b/fearless_simd/src/generated/avx512.rs index 4681fe04..c01ea051 100644 --- a/fearless_simd/src/generated/avx512.rs +++ b/fearless_simd/src/generated/avx512.rs @@ -2503,6 +2503,26 @@ impl Simd for Avx512 { u64::from((a).val) & 65535u64 } #[inline(always)] + fn from_vector_mask8x16(self, vector: i8x16) -> mask8x16 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, vector: i8x16) -> mask8x16 { + _mm_movepi8_mask(vector.into()).simd_into(token) + } + ); + kernel(self, vector) + } + #[inline(always)] + fn to_vector_mask8x16(self, a: mask8x16) -> i8x16 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: mask8x16) -> i8x16 { + _mm_movm_epi8(a.val).simd_into(token) + } + ); + kernel(self, a) + } + #[inline(always)] fn set_mask8x16(self, a: &mut mask8x16, index: usize, value: bool) -> () { assert!( index < 16usize, @@ -3861,6 +3881,26 @@ impl Simd for Avx512 { u64::from((a).val) & 255u64 } #[inline(always)] + fn from_vector_mask16x8(self, vector: i16x8) -> mask16x8 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, vector: i16x8) -> mask16x8 { + _mm_movepi16_mask(vector.into()).simd_into(token) + } + ); + kernel(self, vector) + } + #[inline(always)] + fn to_vector_mask16x8(self, a: mask16x8) -> i16x8 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: mask16x8) -> i16x8 { + _mm_movm_epi16(a.val).simd_into(token) + } + ); + kernel(self, a) + } + #[inline(always)] fn set_mask16x8(self, a: &mut mask16x8, index: usize, value: bool) -> () { assert!( index < 8usize, @@ -5212,6 +5252,26 @@ impl Simd for Avx512 { u64::from((a).val) & 15u64 } #[inline(always)] + fn from_vector_mask32x4(self, vector: i32x4) -> mask32x4 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, vector: i32x4) -> mask32x4 { + _mm_movepi32_mask(vector.into()).simd_into(token) + } + ); + kernel(self, vector) + } + #[inline(always)] + fn to_vector_mask32x4(self, a: mask32x4) -> i32x4 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: mask32x4) -> i32x4 { + _mm_movm_epi32(a.val).simd_into(token) + } + ); + kernel(self, a) + } + #[inline(always)] fn set_mask32x4(self, a: &mut mask32x4, index: usize, value: bool) -> () { assert!( index < 4usize, @@ -7220,6 +7280,26 @@ impl Simd for Avx512 { u64::from((a).val) & 3u64 } #[inline(always)] + fn from_vector_mask64x2(self, vector: i64x2) -> mask64x2 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, vector: i64x2) -> mask64x2 { + _mm_movepi64_mask(vector.into()).simd_into(token) + } + ); + kernel(self, vector) + } + #[inline(always)] + fn to_vector_mask64x2(self, a: mask64x2) -> i64x2 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: mask64x2) -> i64x2 { + _mm_movm_epi64(a.val).simd_into(token) + } + ); + kernel(self, a) + } + #[inline(always)] fn set_mask64x2(self, a: &mut mask64x2, index: usize, value: bool) -> () { assert!( index < 2usize, @@ -9398,6 +9478,26 @@ impl Simd for Avx512 { u64::from((a).val) & 4294967295u64 } #[inline(always)] + fn from_vector_mask8x32(self, vector: i8x32) -> mask8x32 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, vector: i8x32) -> mask8x32 { + _mm256_movepi8_mask(vector.into()).simd_into(token) + } + ); + kernel(self, vector) + } + #[inline(always)] + fn to_vector_mask8x32(self, a: mask8x32) -> i8x32 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: mask8x32) -> i8x32 { + _mm256_movm_epi8(a.val).simd_into(token) + } + ); + kernel(self, a) + } + #[inline(always)] fn set_mask8x32(self, a: &mut mask8x32, index: usize, value: bool) -> () { assert!( index < 32usize, @@ -10728,6 +10828,26 @@ impl Simd for Avx512 { u64::from((a).val) & 65535u64 } #[inline(always)] + fn from_vector_mask16x16(self, vector: i16x16) -> mask16x16 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, vector: i16x16) -> mask16x16 { + _mm256_movepi16_mask(vector.into()).simd_into(token) + } + ); + kernel(self, vector) + } + #[inline(always)] + fn to_vector_mask16x16(self, a: mask16x16) -> i16x16 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: mask16x16) -> i16x16 { + _mm256_movm_epi16(a.val).simd_into(token) + } + ); + kernel(self, a) + } + #[inline(always)] fn set_mask16x16(self, a: &mut mask16x16, index: usize, value: bool) -> () { assert!( index < 16usize, @@ -12057,6 +12177,26 @@ impl Simd for Avx512 { u64::from((a).val) & 255u64 } #[inline(always)] + fn from_vector_mask32x8(self, vector: i32x8) -> mask32x8 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, vector: i32x8) -> mask32x8 { + _mm256_movepi32_mask(vector.into()).simd_into(token) + } + ); + kernel(self, vector) + } + #[inline(always)] + fn to_vector_mask32x8(self, a: mask32x8) -> i32x8 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: mask32x8) -> i32x8 { + _mm256_movm_epi32(a.val).simd_into(token) + } + ); + kernel(self, a) + } + #[inline(always)] fn set_mask32x8(self, a: &mut mask32x8, index: usize, value: bool) -> () { assert!( index < 8usize, @@ -14020,6 +14160,26 @@ impl Simd for Avx512 { u64::from((a).val) & 15u64 } #[inline(always)] + fn from_vector_mask64x4(self, vector: i64x4) -> mask64x4 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, vector: i64x4) -> mask64x4 { + _mm256_movepi64_mask(vector.into()).simd_into(token) + } + ); + kernel(self, vector) + } + #[inline(always)] + fn to_vector_mask64x4(self, a: mask64x4) -> i64x4 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: mask64x4) -> i64x4 { + _mm256_movm_epi64(a.val).simd_into(token) + } + ); + kernel(self, a) + } + #[inline(always)] fn set_mask64x4(self, a: &mut mask64x4, index: usize, value: bool) -> () { assert!( index < 4usize, @@ -16257,6 +16417,26 @@ impl Simd for Avx512 { u64::from((a).val) & u64::MAX } #[inline(always)] + fn from_vector_mask8x64(self, vector: i8x64) -> mask8x64 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, vector: i8x64) -> mask8x64 { + _mm512_movepi8_mask(vector.into()).simd_into(token) + } + ); + kernel(self, vector) + } + #[inline(always)] + fn to_vector_mask8x64(self, a: mask8x64) -> i8x64 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: mask8x64) -> i8x64 { + _mm512_movm_epi8(a.val).simd_into(token) + } + ); + kernel(self, a) + } + #[inline(always)] fn set_mask8x64(self, a: &mut mask8x64, index: usize, value: bool) -> () { assert!( index < 64usize, @@ -17601,6 +17781,26 @@ impl Simd for Avx512 { u64::from((a).val) & 4294967295u64 } #[inline(always)] + fn from_vector_mask16x32(self, vector: i16x32) -> mask16x32 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, vector: i16x32) -> mask16x32 { + _mm512_movepi16_mask(vector.into()).simd_into(token) + } + ); + kernel(self, vector) + } + #[inline(always)] + fn to_vector_mask16x32(self, a: mask16x32) -> i16x32 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: mask16x32) -> i16x32 { + _mm512_movm_epi16(a.val).simd_into(token) + } + ); + kernel(self, a) + } + #[inline(always)] fn set_mask16x32(self, a: &mut mask16x32, index: usize, value: bool) -> () { assert!( index < 32usize, @@ -18959,6 +19159,26 @@ impl Simd for Avx512 { u64::from((a).val) & 65535u64 } #[inline(always)] + fn from_vector_mask32x16(self, vector: i32x16) -> mask32x16 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, vector: i32x16) -> mask32x16 { + _mm512_movepi32_mask(vector.into()).simd_into(token) + } + ); + kernel(self, vector) + } + #[inline(always)] + fn to_vector_mask32x16(self, a: mask32x16) -> i32x16 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: mask32x16) -> i32x16 { + _mm512_movm_epi32(a.val).simd_into(token) + } + ); + kernel(self, a) + } + #[inline(always)] fn set_mask32x16(self, a: &mut mask32x16, index: usize, value: bool) -> () { assert!( index < 16usize, @@ -20945,6 +21165,26 @@ impl Simd for Avx512 { u64::from((a).val) & 255u64 } #[inline(always)] + fn from_vector_mask64x8(self, vector: i64x8) -> mask64x8 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, vector: i64x8) -> mask64x8 { + _mm512_movepi64_mask(vector.into()).simd_into(token) + } + ); + kernel(self, vector) + } + #[inline(always)] + fn to_vector_mask64x8(self, a: mask64x8) -> i64x8 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: mask64x8) -> i64x8 { + _mm512_movm_epi64(a.val).simd_into(token) + } + ); + kernel(self, a) + } + #[inline(always)] fn set_mask64x8(self, a: &mut mask64x8, index: usize, value: bool) -> () { assert!( index < 8usize, diff --git a/fearless_simd/src/generated/fallback.rs b/fearless_simd/src/generated/fallback.rs index 9edd51df..b6150aaf 100644 --- a/fearless_simd/src/generated/fallback.rs +++ b/fearless_simd/src/generated/fallback.rs @@ -2723,6 +2723,20 @@ impl Simd for Fallback { bits } #[inline(always)] + fn from_vector_mask8x16(self, vector: i8x16) -> mask8x16 { + mask8x16 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask8x16(self, a: mask8x16) -> i8x16 { + i8x16 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask8x16(self, a: &mut mask8x16, index: usize, value: bool) -> () { assert!( index < 16usize, @@ -4479,6 +4493,20 @@ impl Simd for Fallback { bits } #[inline(always)] + fn from_vector_mask16x8(self, vector: i16x8) -> mask16x8 { + mask16x8 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask16x8(self, a: mask16x8) -> i16x8 { + i16x8 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask16x8(self, a: &mut mask16x8, index: usize, value: bool) -> () { assert!( index < 8usize, @@ -5691,6 +5719,20 @@ impl Simd for Fallback { bits } #[inline(always)] + fn from_vector_mask32x4(self, vector: i32x4) -> mask32x4 { + mask32x4 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask32x4(self, a: mask32x4) -> i32x4 { + i32x4 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask32x4(self, a: &mut mask32x4, index: usize, value: bool) -> () { assert!( index < 4usize, @@ -7003,6 +7045,20 @@ impl Simd for Fallback { bits } #[inline(always)] + fn from_vector_mask64x2(self, vector: i64x2) -> mask64x2 { + mask64x2 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask64x2(self, a: mask64x2) -> i64x2 { + i64x2 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask64x2(self, a: &mut mask64x2, index: usize, value: bool) -> () { assert!( index < 2usize, @@ -7450,6 +7506,20 @@ impl Simd for Fallback { (b0.simd_into(self), b1.simd_into(self)) } #[inline(always)] + fn from_vector_mask8x32(self, vector: i8x32) -> mask8x32 { + mask8x32 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask8x32(self, a: mask8x32) -> i8x32 { + i8x32 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask8x32(self, a: &mut mask8x32, index: usize, value: bool) -> () { assert!( index < 32usize, @@ -7650,6 +7720,20 @@ impl Simd for Fallback { (b0.simd_into(self), b1.simd_into(self)) } #[inline(always)] + fn from_vector_mask16x16(self, vector: i16x16) -> mask16x16 { + mask16x16 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask16x16(self, a: mask16x16) -> i16x16 { + i16x16 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask16x16(self, a: &mut mask16x16, index: usize, value: bool) -> () { assert!( index < 16usize, @@ -7850,6 +7934,20 @@ impl Simd for Fallback { (b0.simd_into(self), b1.simd_into(self)) } #[inline(always)] + fn from_vector_mask32x8(self, vector: i32x8) -> mask32x8 { + mask32x8 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask32x8(self, a: mask32x8) -> i32x8 { + i32x8 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask32x8(self, a: &mut mask32x8, index: usize, value: bool) -> () { assert!( index < 8usize, @@ -8154,6 +8252,20 @@ impl Simd for Fallback { (b0.simd_into(self), b1.simd_into(self)) } #[inline(always)] + fn from_vector_mask64x4(self, vector: i64x4) -> mask64x4 { + mask64x4 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask64x4(self, a: mask64x4) -> i64x4 { + i64x4 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask64x4(self, a: &mut mask64x4, index: usize, value: bool) -> () { assert!( index < 4usize, @@ -8501,6 +8613,20 @@ impl Simd for Fallback { (b0.simd_into(self), b1.simd_into(self)) } #[inline(always)] + fn from_vector_mask8x64(self, vector: i8x64) -> mask8x64 { + mask8x64 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask8x64(self, a: mask8x64) -> i8x64 { + i8x64 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask8x64(self, a: &mut mask8x64, index: usize, value: bool) -> () { assert!( index < 64usize, @@ -8680,6 +8806,20 @@ impl Simd for Fallback { (b0.simd_into(self), b1.simd_into(self)) } #[inline(always)] + fn from_vector_mask16x32(self, vector: i16x32) -> mask16x32 { + mask16x32 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask16x32(self, a: mask16x32) -> i16x32 { + i16x32 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask16x32(self, a: &mut mask16x32, index: usize, value: bool) -> () { assert!( index < 32usize, @@ -8859,6 +8999,20 @@ impl Simd for Fallback { (b0.simd_into(self), b1.simd_into(self)) } #[inline(always)] + fn from_vector_mask32x16(self, vector: i32x16) -> mask32x16 { + mask32x16 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask32x16(self, a: mask32x16) -> i32x16 { + i32x16 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask32x16(self, a: &mut mask32x16, index: usize, value: bool) -> () { assert!( index < 16usize, @@ -9135,6 +9289,20 @@ impl Simd for Fallback { (b0.simd_into(self), b1.simd_into(self)) } #[inline(always)] + fn from_vector_mask64x8(self, vector: i64x8) -> mask64x8 { + mask64x8 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask64x8(self, a: mask64x8) -> i64x8 { + i64x8 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask64x8(self, a: &mut mask64x8, index: usize, value: bool) -> () { assert!( index < 8usize, diff --git a/fearless_simd/src/generated/neon.rs b/fearless_simd/src/generated/neon.rs index 931bf675..41d3c27e 100644 --- a/fearless_simd/src/generated/neon.rs +++ b/fearless_simd/src/generated/neon.rs @@ -1798,6 +1798,20 @@ impl Simd for Neon { kernel(self, a) } #[inline(always)] + fn from_vector_mask8x16(self, vector: i8x16) -> mask8x16 { + mask8x16 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask8x16(self, a: mask8x16) -> i8x16 { + i8x16 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask8x16(self, a: &mut mask8x16, index: usize, value: bool) -> () { assert!( index < 16usize, @@ -3042,6 +3056,20 @@ impl Simd for Neon { kernel(self, a) } #[inline(always)] + fn from_vector_mask16x8(self, vector: i16x8) -> mask16x8 { + mask16x8 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask16x8(self, a: mask16x8) -> i16x8 { + i16x8 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask16x8(self, a: &mut mask16x8, index: usize, value: bool) -> () { assert!( index < 8usize, @@ -4315,6 +4343,20 @@ impl Simd for Neon { kernel(self, a) } #[inline(always)] + fn from_vector_mask32x4(self, vector: i32x4) -> mask32x4 { + mask32x4 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask32x4(self, a: mask32x4) -> i32x4 { + i32x4 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask32x4(self, a: &mut mask32x4, index: usize, value: bool) -> () { assert!( index < 4usize, @@ -6124,6 +6166,20 @@ impl Simd for Neon { kernel(self, a) } #[inline(always)] + fn from_vector_mask64x2(self, vector: i64x2) -> mask64x2 { + mask64x2 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask64x2(self, a: mask64x2) -> i64x2 { + i64x2 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask64x2(self, a: &mut mask64x2, index: usize, value: bool) -> () { assert!( index < 2usize, @@ -6820,6 +6876,20 @@ impl Simd for Neon { kernel(self, a) } #[inline(always)] + fn from_vector_mask8x32(self, vector: i8x32) -> mask8x32 { + mask8x32 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask8x32(self, a: mask8x32) -> i8x32 { + i8x32 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask8x32(self, a: &mut mask8x32, index: usize, value: bool) -> () { assert!( index < 32usize, @@ -7116,6 +7186,20 @@ impl Simd for Neon { kernel(self, a) } #[inline(always)] + fn from_vector_mask16x16(self, vector: i16x16) -> mask16x16 { + mask16x16 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask16x16(self, a: mask16x16) -> i16x16 { + i16x16 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask16x16(self, a: &mut mask16x16, index: usize, value: bool) -> () { assert!( index < 16usize, @@ -7412,6 +7496,20 @@ impl Simd for Neon { kernel(self, a) } #[inline(always)] + fn from_vector_mask32x8(self, vector: i32x8) -> mask32x8 { + mask32x8 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask32x8(self, a: mask32x8) -> i32x8 { + i32x8 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask32x8(self, a: &mut mask32x8, index: usize, value: bool) -> () { assert!( index < 8usize, @@ -7849,6 +7947,20 @@ impl Simd for Neon { kernel(self, a) } #[inline(always)] + fn from_vector_mask64x4(self, vector: i64x4) -> mask64x4 { + mask64x4 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask64x4(self, a: mask64x4) -> i64x4 { + i64x4 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask64x4(self, a: &mut mask64x4, index: usize, value: bool) -> () { assert!( index < 4usize, @@ -8466,6 +8578,20 @@ impl Simd for Neon { kernel(self, a) } #[inline(always)] + fn from_vector_mask8x64(self, vector: i8x64) -> mask8x64 { + mask8x64 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask8x64(self, a: mask8x64) -> i8x64 { + i8x64 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask8x64(self, a: &mut mask8x64, index: usize, value: bool) -> () { assert!( index < 64usize, @@ -8776,6 +8902,20 @@ impl Simd for Neon { kernel(self, a) } #[inline(always)] + fn from_vector_mask16x32(self, vector: i16x32) -> mask16x32 { + mask16x32 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask16x32(self, a: mask16x32) -> i16x32 { + i16x32 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask16x32(self, a: &mut mask16x32, index: usize, value: bool) -> () { assert!( index < 32usize, @@ -9086,6 +9226,20 @@ impl Simd for Neon { kernel(self, a) } #[inline(always)] + fn from_vector_mask32x16(self, vector: i32x16) -> mask32x16 { + mask32x16 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask32x16(self, a: mask32x16) -> i32x16 { + i32x16 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask32x16(self, a: &mut mask32x16, index: usize, value: bool) -> () { assert!( index < 16usize, @@ -9546,6 +9700,20 @@ impl Simd for Neon { kernel(self, a) } #[inline(always)] + fn from_vector_mask64x8(self, vector: i64x8) -> mask64x8 { + mask64x8 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask64x8(self, a: mask64x8) -> i64x8 { + i64x8 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask64x8(self, a: &mut mask64x8, index: usize, value: bool) -> () { assert!( index < 8usize, diff --git a/fearless_simd/src/generated/simd_trait.rs b/fearless_simd/src/generated/simd_trait.rs index 098a8f7e..6745b1e8 100644 --- a/fearless_simd/src/generated/simd_trait.rs +++ b/fearless_simd/src/generated/simd_trait.rs @@ -159,20 +159,20 @@ pub trait Simd: + SimdNarrow + core::ops::Neg; #[doc = r" A native-width SIMD mask with 8-bit lanes."] - type mask8s: SimdMask + type mask8s: SimdMask + Select + Select + Select + MaskWiden; #[doc = r" A native-width SIMD mask with 16-bit lanes."] - type mask16s: SimdMask + type mask16s: SimdMask + Select + Select + Select + MaskNarrow + MaskWiden; #[doc = r" A native-width SIMD mask with 32-bit lanes."] - type mask32s: SimdMask + type mask32s: SimdMask + Select + Select + Select @@ -180,7 +180,7 @@ pub trait Simd: + MaskNarrow + MaskWiden; #[doc = r" A native-width SIMD mask with 64-bit lanes."] - type mask64s: SimdMask + type mask64s: SimdMask + Select + Select + Select @@ -769,6 +769,10 @@ pub trait Simd: fn from_bitmask_mask8x16(self, bits: u64) -> mask8x16; #[doc = "Convert a SIMD mask to a compact bitmask.\n\nBit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above the number of lanes in this mask are cleared."] fn to_bitmask_mask8x16(self, a: mask8x16) -> u64; + #[doc = "Create a SIMD mask from an integer vector of the same width.\n\nA lane value of -1 means \"true\", a lane value of 0 means \"false\", and all other lane values result in unspecified behavior."] + fn from_vector_mask8x16(self, vector: i8x16) -> mask8x16; + #[doc = "Convert a SIMD mask to an integer vector of the same width.\n\n\"True\" maps to -1 and \"false\" maps to 0."] + fn to_vector_mask8x16(self, a: mask8x16) -> i8x16; #[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::LEN`, it wraps modulo `Self::LEN`."] @@ -1178,6 +1182,10 @@ pub trait Simd: fn from_bitmask_mask16x8(self, bits: u64) -> mask16x8; #[doc = "Convert a SIMD mask to a compact bitmask.\n\nBit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above the number of lanes in this mask are cleared."] fn to_bitmask_mask16x8(self, a: mask16x8) -> u64; + #[doc = "Create a SIMD mask from an integer vector of the same width.\n\nA lane value of -1 means \"true\", a lane value of 0 means \"false\", and all other lane values result in unspecified behavior."] + fn from_vector_mask16x8(self, vector: i16x8) -> mask16x8; + #[doc = "Convert a SIMD mask to an integer vector of the same width.\n\n\"True\" maps to -1 and \"false\" maps to 0."] + fn to_vector_mask16x8(self, a: mask16x8) -> i16x8; #[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::LEN`, it wraps modulo `Self::LEN`."] @@ -1593,6 +1601,10 @@ pub trait Simd: fn from_bitmask_mask32x4(self, bits: u64) -> mask32x4; #[doc = "Convert a SIMD mask to a compact bitmask.\n\nBit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above the number of lanes in this mask are cleared."] fn to_bitmask_mask32x4(self, a: mask32x4) -> u64; + #[doc = "Create a SIMD mask from an integer vector of the same width.\n\nA lane value of -1 means \"true\", a lane value of 0 means \"false\", and all other lane values result in unspecified behavior."] + fn from_vector_mask32x4(self, vector: i32x4) -> mask32x4; + #[doc = "Convert a SIMD mask to an integer vector of the same width.\n\n\"True\" maps to -1 and \"false\" maps to 0."] + fn to_vector_mask32x4(self, a: mask32x4) -> i32x4; #[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::LEN`, it wraps modulo `Self::LEN`."] @@ -2217,6 +2229,10 @@ pub trait Simd: fn from_bitmask_mask64x2(self, bits: u64) -> mask64x2; #[doc = "Convert a SIMD mask to a compact bitmask.\n\nBit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above the number of lanes in this mask are cleared."] fn to_bitmask_mask64x2(self, a: mask64x2) -> u64; + #[doc = "Create a SIMD mask from an integer vector of the same width.\n\nA lane value of -1 means \"true\", a lane value of 0 means \"false\", and all other lane values result in unspecified behavior."] + fn from_vector_mask64x2(self, vector: i64x2) -> mask64x2; + #[doc = "Convert a SIMD mask to an integer vector of the same width.\n\n\"True\" maps to -1 and \"false\" maps to 0."] + fn to_vector_mask64x2(self, a: mask64x2) -> i64x2; #[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::LEN`, it wraps modulo `Self::LEN`."] @@ -3450,6 +3466,10 @@ pub trait Simd: let hi = self.to_bitmask_mask8x16(hi); lo | (hi << 16usize) } + #[doc = "Create a SIMD mask from an integer vector of the same width.\n\nA lane value of -1 means \"true\", a lane value of 0 means \"false\", and all other lane values result in unspecified behavior."] + fn from_vector_mask8x32(self, vector: i8x32) -> mask8x32; + #[doc = "Convert a SIMD mask to an integer vector of the same width.\n\n\"True\" maps to -1 and \"false\" maps to 0."] + fn to_vector_mask8x32(self, a: mask8x32) -> i8x32; #[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::LEN`, it wraps modulo `Self::LEN`."] @@ -4352,6 +4372,10 @@ pub trait Simd: let hi = self.to_bitmask_mask16x8(hi); lo | (hi << 8usize) } + #[doc = "Create a SIMD mask from an integer vector of the same width.\n\nA lane value of -1 means \"true\", a lane value of 0 means \"false\", and all other lane values result in unspecified behavior."] + fn from_vector_mask16x16(self, vector: i16x16) -> mask16x16; + #[doc = "Convert a SIMD mask to an integer vector of the same width.\n\n\"True\" maps to -1 and \"false\" maps to 0."] + fn to_vector_mask16x16(self, a: mask16x16) -> i16x16; #[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::LEN`, it wraps modulo `Self::LEN`."] @@ -5265,6 +5289,10 @@ pub trait Simd: let hi = self.to_bitmask_mask32x4(hi); lo | (hi << 4usize) } + #[doc = "Create a SIMD mask from an integer vector of the same width.\n\nA lane value of -1 means \"true\", a lane value of 0 means \"false\", and all other lane values result in unspecified behavior."] + fn from_vector_mask32x8(self, vector: i32x8) -> mask32x8; + #[doc = "Convert a SIMD mask to an integer vector of the same width.\n\n\"True\" maps to -1 and \"false\" maps to 0."] + fn to_vector_mask32x8(self, a: mask32x8) -> i32x8; #[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::LEN`, it wraps modulo `Self::LEN`."] @@ -6653,6 +6681,10 @@ pub trait Simd: let hi = self.to_bitmask_mask64x2(hi); lo | (hi << 2usize) } + #[doc = "Create a SIMD mask from an integer vector of the same width.\n\nA lane value of -1 means \"true\", a lane value of 0 means \"false\", and all other lane values result in unspecified behavior."] + fn from_vector_mask64x4(self, vector: i64x4) -> mask64x4; + #[doc = "Convert a SIMD mask to an integer vector of the same width.\n\n\"True\" maps to -1 and \"false\" maps to 0."] + fn to_vector_mask64x4(self, a: mask64x4) -> i64x4; #[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::LEN`, it wraps modulo `Self::LEN`."] @@ -7954,6 +7986,10 @@ pub trait Simd: let hi = self.to_bitmask_mask8x32(hi); lo | (hi << 32usize) } + #[doc = "Create a SIMD mask from an integer vector of the same width.\n\nA lane value of -1 means \"true\", a lane value of 0 means \"false\", and all other lane values result in unspecified behavior."] + fn from_vector_mask8x64(self, vector: i8x64) -> mask8x64; + #[doc = "Convert a SIMD mask to an integer vector of the same width.\n\n\"True\" maps to -1 and \"false\" maps to 0."] + fn to_vector_mask8x64(self, a: mask8x64) -> i8x64; #[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::LEN`, it wraps modulo `Self::LEN`."] @@ -8862,6 +8898,10 @@ pub trait Simd: let hi = self.to_bitmask_mask16x16(hi); lo | (hi << 16usize) } + #[doc = "Create a SIMD mask from an integer vector of the same width.\n\nA lane value of -1 means \"true\", a lane value of 0 means \"false\", and all other lane values result in unspecified behavior."] + fn from_vector_mask16x32(self, vector: i16x32) -> mask16x32; + #[doc = "Convert a SIMD mask to an integer vector of the same width.\n\n\"True\" maps to -1 and \"false\" maps to 0."] + fn to_vector_mask16x32(self, a: mask16x32) -> i16x32; #[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::LEN`, it wraps modulo `Self::LEN`."] @@ -9780,6 +9820,10 @@ pub trait Simd: let hi = self.to_bitmask_mask32x8(hi); lo | (hi << 8usize) } + #[doc = "Create a SIMD mask from an integer vector of the same width.\n\nA lane value of -1 means \"true\", a lane value of 0 means \"false\", and all other lane values result in unspecified behavior."] + fn from_vector_mask32x16(self, vector: i32x16) -> mask32x16; + #[doc = "Convert a SIMD mask to an integer vector of the same width.\n\n\"True\" maps to -1 and \"false\" maps to 0."] + fn to_vector_mask32x16(self, a: mask32x16) -> i32x16; #[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::LEN`, it wraps modulo `Self::LEN`."] @@ -11160,6 +11204,10 @@ pub trait Simd: let hi = self.to_bitmask_mask64x4(hi); lo | (hi << 4usize) } + #[doc = "Create a SIMD mask from an integer vector of the same width.\n\nA lane value of -1 means \"true\", a lane value of 0 means \"false\", and all other lane values result in unspecified behavior."] + fn from_vector_mask64x8(self, vector: i64x8) -> mask64x8; + #[doc = "Convert a SIMD mask to an integer vector of the same width.\n\n\"True\" maps to -1 and \"false\" maps to 0."] + fn to_vector_mask64x8(self, a: mask64x8) -> i64x8; #[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::LEN`, it wraps modulo `Self::LEN`."] @@ -12043,7 +12091,10 @@ pub trait SimdMask: #[doc = r""] #[doc = r" False lanes are encoded as all zeroes (integer value 0), and true lanes are encoded as all ones"] #[doc = r" (integer value -1)."] - type Element: SimdElement; + type Element: SimdIntElement + core::ops::Neg; + #[doc = r" This mask's corresponding integer vector type."] + type Ints: SimdInt + + core::ops::Neg; #[doc = r" This mask type's lane count."] const LEN: usize; #[doc = r" Create a SIMD mask with all lanes set to the given boolean value."] @@ -12058,6 +12109,10 @@ pub trait SimdMask: #[doc = r" Bit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above"] #[doc = r" [`Self::LEN`] are cleared."] fn to_bitmask(self) -> u64; + #[doc = r" Create a SIMD mask from signed integer mask lanes."] + fn from_vector(v: Self::Ints) -> Self; + #[doc = r" Convert this SIMD mask to signed integer mask lanes."] + fn to_vector(self) -> Self::Ints; #[doc = r" Test whether one logical lane is set."] #[doc = r""] #[doc = r" Panics if `index` is greater than or equal to the number of lanes in the mask."] diff --git a/fearless_simd/src/generated/simd_types.rs b/fearless_simd/src/generated/simd_types.rs index 8081586a..069fa792 100644 --- a/fearless_simd/src/generated/simd_types.rs +++ b/fearless_simd/src/generated/simd_types.rs @@ -1190,6 +1190,7 @@ impl Select> for mask8x16 { } impl SimdMask for mask8x16 { type Element = i8; + type Ints = i8x16; const LEN: usize = 16; #[inline(always)] fn splat(simd: S, val: bool) -> Self { @@ -1204,6 +1205,14 @@ impl SimdMask for mask8x16 { self.simd.to_bitmask_mask8x16(self) } #[inline(always)] + fn from_vector(vector: Self::Ints) -> Self { + vector.token().from_vector_mask8x16(vector) + } + #[inline(always)] + fn to_vector(self) -> Self::Ints { + self.simd.to_vector_mask8x16(self) + } + #[inline(always)] fn set(&mut self, index: usize, value: bool) { self.simd.set_mask8x16(self, index, value); } @@ -2034,6 +2043,7 @@ impl Select> for mask16x8 { } impl SimdMask for mask16x8 { type Element = i16; + type Ints = i16x8; const LEN: usize = 8; #[inline(always)] fn splat(simd: S, val: bool) -> Self { @@ -2048,6 +2058,14 @@ impl SimdMask for mask16x8 { self.simd.to_bitmask_mask16x8(self) } #[inline(always)] + fn from_vector(vector: Self::Ints) -> Self { + vector.token().from_vector_mask16x8(vector) + } + #[inline(always)] + fn to_vector(self) -> Self::Ints { + self.simd.to_vector_mask16x8(self) + } + #[inline(always)] fn set(&mut self, index: usize, value: bool) { self.simd.set_mask16x8(self, index, value); } @@ -2885,6 +2903,7 @@ impl Select> for mask32x4 { } impl SimdMask for mask32x4 { type Element = i32; + type Ints = i32x4; const LEN: usize = 4; #[inline(always)] fn splat(simd: S, val: bool) -> Self { @@ -2899,6 +2918,14 @@ impl SimdMask for mask32x4 { self.simd.to_bitmask_mask32x4(self) } #[inline(always)] + fn from_vector(vector: Self::Ints) -> Self { + vector.token().from_vector_mask32x4(vector) + } + #[inline(always)] + fn to_vector(self) -> Self::Ints { + self.simd.to_vector_mask32x4(self) + } + #[inline(always)] fn set(&mut self, index: usize, value: bool) { self.simd.set_mask32x4(self, index, value); } @@ -4153,6 +4180,7 @@ impl Select> for mask64x2 { } impl SimdMask for mask64x2 { type Element = i64; + type Ints = i64x2; const LEN: usize = 2; #[inline(always)] fn splat(simd: S, val: bool) -> Self { @@ -4167,6 +4195,14 @@ impl SimdMask for mask64x2 { self.simd.to_bitmask_mask64x2(self) } #[inline(always)] + fn from_vector(vector: Self::Ints) -> Self { + vector.token().from_vector_mask64x2(vector) + } + #[inline(always)] + fn to_vector(self) -> Self::Ints { + self.simd.to_vector_mask64x2(self) + } + #[inline(always)] fn set(&mut self, index: usize, value: bool) { self.simd.set_mask64x2(self, index, value); } @@ -5435,6 +5471,7 @@ impl Select> for mask8x32 { } impl SimdMask for mask8x32 { type Element = i8; + type Ints = i8x32; const LEN: usize = 32; #[inline(always)] fn splat(simd: S, val: bool) -> Self { @@ -5449,6 +5486,14 @@ impl SimdMask for mask8x32 { self.simd.to_bitmask_mask8x32(self) } #[inline(always)] + fn from_vector(vector: Self::Ints) -> Self { + vector.token().from_vector_mask8x32(vector) + } + #[inline(always)] + fn to_vector(self) -> Self::Ints { + self.simd.to_vector_mask8x32(self) + } + #[inline(always)] fn set(&mut self, index: usize, value: bool) { self.simd.set_mask8x32(self, index, value); } @@ -6287,6 +6332,7 @@ impl Select> for mask16x16 { } impl SimdMask for mask16x16 { type Element = i16; + type Ints = i16x16; const LEN: usize = 16; #[inline(always)] fn splat(simd: S, val: bool) -> Self { @@ -6301,6 +6347,14 @@ impl SimdMask for mask16x16 { self.simd.to_bitmask_mask16x16(self) } #[inline(always)] + fn from_vector(vector: Self::Ints) -> Self { + vector.token().from_vector_mask16x16(vector) + } + #[inline(always)] + fn to_vector(self) -> Self::Ints { + self.simd.to_vector_mask16x16(self) + } + #[inline(always)] fn set(&mut self, index: usize, value: bool) { self.simd.set_mask16x16(self, index, value); } @@ -7152,6 +7206,7 @@ impl Select> for mask32x8 { } impl SimdMask for mask32x8 { type Element = i32; + type Ints = i32x8; const LEN: usize = 8; #[inline(always)] fn splat(simd: S, val: bool) -> Self { @@ -7166,6 +7221,14 @@ impl SimdMask for mask32x8 { self.simd.to_bitmask_mask32x8(self) } #[inline(always)] + fn from_vector(vector: Self::Ints) -> Self { + vector.token().from_vector_mask32x8(vector) + } + #[inline(always)] + fn to_vector(self) -> Self::Ints { + self.simd.to_vector_mask32x8(self) + } + #[inline(always)] fn set(&mut self, index: usize, value: bool) { self.simd.set_mask32x8(self, index, value); } @@ -8405,6 +8468,7 @@ impl Select> for mask64x4 { } impl SimdMask for mask64x4 { type Element = i64; + type Ints = i64x4; const LEN: usize = 4; #[inline(always)] fn splat(simd: S, val: bool) -> Self { @@ -8419,6 +8483,14 @@ impl SimdMask for mask64x4 { self.simd.to_bitmask_mask64x4(self) } #[inline(always)] + fn from_vector(vector: Self::Ints) -> Self { + vector.token().from_vector_mask64x4(vector) + } + #[inline(always)] + fn to_vector(self) -> Self::Ints { + self.simd.to_vector_mask64x4(self) + } + #[inline(always)] fn set(&mut self, index: usize, value: bool) { self.simd.set_mask64x4(self, index, value); } @@ -9742,6 +9814,7 @@ impl Select> for mask8x64 { } impl SimdMask for mask8x64 { type Element = i8; + type Ints = i8x64; const LEN: usize = 64; #[inline(always)] fn splat(simd: S, val: bool) -> Self { @@ -9756,6 +9829,14 @@ impl SimdMask for mask8x64 { self.simd.to_bitmask_mask8x64(self) } #[inline(always)] + fn from_vector(vector: Self::Ints) -> Self { + vector.token().from_vector_mask8x64(vector) + } + #[inline(always)] + fn to_vector(self) -> Self::Ints { + self.simd.to_vector_mask8x64(self) + } + #[inline(always)] fn set(&mut self, index: usize, value: bool) { self.simd.set_mask8x64(self, index, value); } @@ -10614,6 +10695,7 @@ impl Select> for mask16x32 { } impl SimdMask for mask16x32 { type Element = i16; + type Ints = i16x32; const LEN: usize = 32; #[inline(always)] fn splat(simd: S, val: bool) -> Self { @@ -10628,6 +10710,14 @@ impl SimdMask for mask16x32 { self.simd.to_bitmask_mask16x32(self) } #[inline(always)] + fn from_vector(vector: Self::Ints) -> Self { + vector.token().from_vector_mask16x32(vector) + } + #[inline(always)] + fn to_vector(self) -> Self::Ints { + self.simd.to_vector_mask16x32(self) + } + #[inline(always)] fn set(&mut self, index: usize, value: bool) { self.simd.set_mask16x32(self, index, value); } @@ -11485,6 +11575,7 @@ impl Select> for mask32x16 { } impl SimdMask for mask32x16 { type Element = i32; + type Ints = i32x16; const LEN: usize = 16; #[inline(always)] fn splat(simd: S, val: bool) -> Self { @@ -11499,6 +11590,14 @@ impl SimdMask for mask32x16 { self.simd.to_bitmask_mask32x16(self) } #[inline(always)] + fn from_vector(vector: Self::Ints) -> Self { + vector.token().from_vector_mask32x16(vector) + } + #[inline(always)] + fn to_vector(self) -> Self::Ints { + self.simd.to_vector_mask32x16(self) + } + #[inline(always)] fn set(&mut self, index: usize, value: bool) { self.simd.set_mask32x16(self, index, value); } @@ -12756,6 +12855,7 @@ impl Select> for mask64x8 { } impl SimdMask for mask64x8 { type Element = i64; + type Ints = i64x8; const LEN: usize = 8; #[inline(always)] fn splat(simd: S, val: bool) -> Self { @@ -12770,6 +12870,14 @@ impl SimdMask for mask64x8 { self.simd.to_bitmask_mask64x8(self) } #[inline(always)] + fn from_vector(vector: Self::Ints) -> Self { + vector.token().from_vector_mask64x8(vector) + } + #[inline(always)] + fn to_vector(self) -> Self::Ints { + self.simd.to_vector_mask64x8(self) + } + #[inline(always)] fn set(&mut self, index: usize, value: bool) { self.simd.set_mask64x8(self, index, value); } diff --git a/fearless_simd/src/generated/sse2.rs b/fearless_simd/src/generated/sse2.rs index 91803e78..9008cbb9 100644 --- a/fearless_simd/src/generated/sse2.rs +++ b/fearless_simd/src/generated/sse2.rs @@ -2485,6 +2485,20 @@ impl Simd for Sse2 { kernel(self, a) } #[inline(always)] + fn from_vector_mask8x16(self, vector: i8x16) -> mask8x16 { + mask8x16 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask8x16(self, a: mask8x16) -> i8x16 { + i8x16 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask8x16(self, a: &mut mask8x16, index: usize, value: bool) -> () { assert!( index < 16usize, @@ -3989,6 +4003,20 @@ impl Simd for Sse2 { kernel(self, a) } #[inline(always)] + fn from_vector_mask16x8(self, vector: i16x8) -> mask16x8 { + mask16x8 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask16x8(self, a: mask16x8) -> i16x8 { + i16x8 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask16x8(self, a: &mut mask16x8, index: usize, value: bool) -> () { assert!( index < 8usize, @@ -5481,6 +5509,20 @@ impl Simd for Sse2 { kernel(self, a) } #[inline(always)] + fn from_vector_mask32x4(self, vector: i32x4) -> mask32x4 { + mask32x4 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask32x4(self, a: mask32x4) -> i32x4 { + i32x4 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask32x4(self, a: &mut mask32x4, index: usize, value: bool) -> () { assert!( index < 4usize, @@ -7328,6 +7370,20 @@ impl Simd for Sse2 { kernel(self, a) } #[inline(always)] + fn from_vector_mask64x2(self, vector: i64x2) -> mask64x2 { + mask64x2 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask64x2(self, a: mask64x2) -> i64x2 { + i64x2 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask64x2(self, a: &mut mask64x2, index: usize, value: bool) -> () { assert!( index < 2usize, @@ -7875,6 +7931,20 @@ impl Simd for Sse2 { ) } #[inline(always)] + fn from_vector_mask8x32(self, vector: i8x32) -> mask8x32 { + mask8x32 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask8x32(self, a: mask8x32) -> i8x32 { + i8x32 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask8x32(self, a: &mut mask8x32, index: usize, value: bool) -> () { assert!( index < 32usize, @@ -8121,6 +8191,20 @@ impl Simd for Sse2 { kernel(self, a) } #[inline(always)] + fn from_vector_mask16x16(self, vector: i16x16) -> mask16x16 { + mask16x16 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask16x16(self, a: mask16x16) -> i16x16 { + i16x16 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask16x16(self, a: &mut mask16x16, index: usize, value: bool) -> () { assert!( index < 16usize, @@ -8354,6 +8438,20 @@ impl Simd for Sse2 { ) } #[inline(always)] + fn from_vector_mask32x8(self, vector: i32x8) -> mask32x8 { + mask32x8 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask32x8(self, a: mask32x8) -> i32x8 { + i32x8 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask32x8(self, a: &mut mask32x8, index: usize, value: bool) -> () { assert!( index < 8usize, @@ -8711,6 +8809,20 @@ impl Simd for Sse2 { ) } #[inline(always)] + fn from_vector_mask64x4(self, vector: i64x4) -> mask64x4 { + mask64x4 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask64x4(self, a: mask64x4) -> i64x4 { + i64x4 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask64x4(self, a: &mut mask64x4, index: usize, value: bool) -> () { assert!( index < 4usize, @@ -9111,6 +9223,20 @@ impl Simd for Sse2 { ) } #[inline(always)] + fn from_vector_mask8x64(self, vector: i8x64) -> mask8x64 { + mask8x64 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask8x64(self, a: mask8x64) -> i8x64 { + i8x64 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask8x64(self, a: &mut mask8x64, index: usize, value: bool) -> () { assert!( index < 64usize, @@ -9339,6 +9465,20 @@ impl Simd for Sse2 { kernel(self, a) } #[inline(always)] + fn from_vector_mask16x32(self, vector: i16x32) -> mask16x32 { + mask16x32 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask16x32(self, a: mask16x32) -> i16x32 { + i16x32 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask16x32(self, a: &mut mask16x32, index: usize, value: bool) -> () { assert!( index < 32usize, @@ -9551,6 +9691,20 @@ impl Simd for Sse2 { ) } #[inline(always)] + fn from_vector_mask32x16(self, vector: i32x16) -> mask32x16 { + mask32x16 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask32x16(self, a: mask32x16) -> i32x16 { + i32x16 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask32x16(self, a: &mut mask32x16, index: usize, value: bool) -> () { assert!( index < 16usize, @@ -9880,6 +10034,20 @@ impl Simd for Sse2 { ) } #[inline(always)] + fn from_vector_mask64x8(self, vector: i64x8) -> mask64x8 { + mask64x8 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask64x8(self, a: mask64x8) -> i64x8 { + i64x8 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask64x8(self, a: &mut mask64x8, index: usize, value: bool) -> () { assert!( index < 8usize, diff --git a/fearless_simd/src/generated/sse4_2.rs b/fearless_simd/src/generated/sse4_2.rs index 3e4c7577..eb1a4660 100644 --- a/fearless_simd/src/generated/sse4_2.rs +++ b/fearless_simd/src/generated/sse4_2.rs @@ -2224,6 +2224,20 @@ impl Simd for Sse4_2 { kernel(self, a) } #[inline(always)] + fn from_vector_mask8x16(self, vector: i8x16) -> mask8x16 { + mask8x16 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask8x16(self, a: mask8x16) -> i8x16 { + i8x16 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask8x16(self, a: &mut mask8x16, index: usize, value: bool) -> () { assert!( index < 16usize, @@ -3624,6 +3638,20 @@ impl Simd for Sse4_2 { kernel(self, a) } #[inline(always)] + fn from_vector_mask16x8(self, vector: i16x8) -> mask16x8 { + mask16x8 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask16x8(self, a: mask16x8) -> i16x8 { + i16x8 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask16x8(self, a: &mut mask16x8, index: usize, value: bool) -> () { assert!( index < 8usize, @@ -4996,6 +5024,20 @@ impl Simd for Sse4_2 { kernel(self, a) } #[inline(always)] + fn from_vector_mask32x4(self, vector: i32x4) -> mask32x4 { + mask32x4 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask32x4(self, a: mask32x4) -> i32x4 { + i32x4 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask32x4(self, a: &mut mask32x4, index: usize, value: bool) -> () { assert!( index < 4usize, @@ -7004,6 +7046,20 @@ impl Simd for Sse4_2 { kernel(self, a) } #[inline(always)] + fn from_vector_mask64x2(self, vector: i64x2) -> mask64x2 { + mask64x2 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask64x2(self, a: mask64x2) -> i64x2 { + i64x2 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask64x2(self, a: &mut mask64x2, index: usize, value: bool) -> () { assert!( index < 2usize, @@ -7729,6 +7785,20 @@ impl Simd for Sse4_2 { ) } #[inline(always)] + fn from_vector_mask8x32(self, vector: i8x32) -> mask8x32 { + mask8x32 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask8x32(self, a: mask8x32) -> i8x32 { + i8x32 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask8x32(self, a: &mut mask8x32, index: usize, value: bool) -> () { assert!( index < 32usize, @@ -7975,6 +8045,20 @@ impl Simd for Sse4_2 { kernel(self, a) } #[inline(always)] + fn from_vector_mask16x16(self, vector: i16x16) -> mask16x16 { + mask16x16 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask16x16(self, a: mask16x16) -> i16x16 { + i16x16 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask16x16(self, a: &mut mask16x16, index: usize, value: bool) -> () { assert!( index < 16usize, @@ -8208,6 +8292,20 @@ impl Simd for Sse4_2 { ) } #[inline(always)] + fn from_vector_mask32x8(self, vector: i32x8) -> mask32x8 { + mask32x8 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask32x8(self, a: mask32x8) -> i32x8 { + i32x8 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask32x8(self, a: &mut mask32x8, index: usize, value: bool) -> () { assert!( index < 8usize, @@ -8565,6 +8663,20 @@ impl Simd for Sse4_2 { ) } #[inline(always)] + fn from_vector_mask64x4(self, vector: i64x4) -> mask64x4 { + mask64x4 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask64x4(self, a: mask64x4) -> i64x4 { + i64x4 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask64x4(self, a: &mut mask64x4, index: usize, value: bool) -> () { assert!( index < 4usize, @@ -9367,6 +9479,20 @@ impl Simd for Sse4_2 { kernel(self, bits) } #[inline(always)] + fn from_vector_mask8x64(self, vector: i8x64) -> mask8x64 { + mask8x64 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask8x64(self, a: mask8x64) -> i8x64 { + i8x64 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask8x64(self, a: &mut mask8x64, index: usize, value: bool) -> () { assert!( index < 64usize, @@ -9595,6 +9721,20 @@ impl Simd for Sse4_2 { kernel(self, a) } #[inline(always)] + fn from_vector_mask16x32(self, vector: i16x32) -> mask16x32 { + mask16x32 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask16x32(self, a: mask16x32) -> i16x32 { + i16x32 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask16x32(self, a: &mut mask16x32, index: usize, value: bool) -> () { assert!( index < 32usize, @@ -9807,6 +9947,20 @@ impl Simd for Sse4_2 { ) } #[inline(always)] + fn from_vector_mask32x16(self, vector: i32x16) -> mask32x16 { + mask32x16 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask32x16(self, a: mask32x16) -> i32x16 { + i32x16 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask32x16(self, a: &mut mask32x16, index: usize, value: bool) -> () { assert!( index < 16usize, @@ -10136,6 +10290,20 @@ impl Simd for Sse4_2 { ) } #[inline(always)] + fn from_vector_mask64x8(self, vector: i64x8) -> mask64x8 { + mask64x8 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask64x8(self, a: mask64x8) -> i64x8 { + i64x8 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask64x8(self, a: &mut mask64x8, index: usize, value: bool) -> () { assert!( index < 8usize, diff --git a/fearless_simd/src/generated/wasm.rs b/fearless_simd/src/generated/wasm.rs index 940d655e..fa88ef2f 100644 --- a/fearless_simd/src/generated/wasm.rs +++ b/fearless_simd/src/generated/wasm.rs @@ -1501,6 +1501,20 @@ impl Simd for WasmSimd128 { i8x16_bitmask(a.into()) as u64 } #[inline(always)] + fn from_vector_mask8x16(self, vector: i8x16) -> mask8x16 { + mask8x16 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask8x16(self, a: mask8x16) -> i8x16 { + i8x16 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask8x16(self, a: &mut mask8x16, index: usize, value: bool) -> () { assert!( index < 16usize, @@ -2305,6 +2319,20 @@ impl Simd for WasmSimd128 { i16x8_bitmask(a.into()) as u64 } #[inline(always)] + fn from_vector_mask16x8(self, vector: i16x8) -> mask16x8 { + mask16x8 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask16x8(self, a: mask16x8) -> i16x8 { + i16x8 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask16x8(self, a: &mut mask16x8, index: usize, value: bool) -> () { assert!( index < 8usize, @@ -3097,6 +3125,20 @@ impl Simd for WasmSimd128 { i32x4_bitmask(a.into()) as u64 } #[inline(always)] + fn from_vector_mask32x4(self, vector: i32x4) -> mask32x4 { + mask32x4 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask32x4(self, a: mask32x4) -> i32x4 { + i32x4 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask32x4(self, a: &mut mask32x4, index: usize, value: bool) -> () { assert!( index < 4usize, @@ -4293,6 +4335,20 @@ impl Simd for WasmSimd128 { i64x2_bitmask(a.into()) as u64 } #[inline(always)] + fn from_vector_mask64x2(self, vector: i64x2) -> mask64x2 { + mask64x2 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask64x2(self, a: mask64x2) -> i64x2 { + i64x2 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask64x2(self, a: &mut mask64x2, index: usize, value: bool) -> () { assert!( index < 2usize, @@ -4865,6 +4921,20 @@ impl Simd for WasmSimd128 { ) } #[inline(always)] + fn from_vector_mask8x32(self, vector: i8x32) -> mask8x32 { + mask8x32 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask8x32(self, a: mask8x32) -> i8x32 { + i8x32 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask8x32(self, a: &mut mask8x32, index: usize, value: bool) -> () { assert!( index < 32usize, @@ -5114,6 +5184,20 @@ impl Simd for WasmSimd128 { ) } #[inline(always)] + fn from_vector_mask16x16(self, vector: i16x16) -> mask16x16 { + mask16x16 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask16x16(self, a: mask16x16) -> i16x16 { + i16x16 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask16x16(self, a: &mut mask16x16, index: usize, value: bool) -> () { assert!( index < 16usize, @@ -5363,6 +5447,20 @@ impl Simd for WasmSimd128 { ) } #[inline(always)] + fn from_vector_mask32x8(self, vector: i32x8) -> mask32x8 { + mask32x8 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask32x8(self, a: mask32x8) -> i32x8 { + i32x8 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask32x8(self, a: &mut mask32x8, index: usize, value: bool) -> () { assert!( index < 8usize, @@ -5735,6 +5833,20 @@ impl Simd for WasmSimd128 { ) } #[inline(always)] + fn from_vector_mask64x4(self, vector: i64x4) -> mask64x4 { + mask64x4 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask64x4(self, a: mask64x4) -> i64x4 { + i64x4 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask64x4(self, a: &mut mask64x4, index: usize, value: bool) -> () { assert!( index < 4usize, @@ -6202,6 +6314,20 @@ impl Simd for WasmSimd128 { ) } #[inline(always)] + fn from_vector_mask8x64(self, vector: i8x64) -> mask8x64 { + mask8x64 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask8x64(self, a: mask8x64) -> i8x64 { + i8x64 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask8x64(self, a: &mut mask8x64, index: usize, value: bool) -> () { assert!( index < 64usize, @@ -6430,6 +6556,20 @@ impl Simd for WasmSimd128 { ) } #[inline(always)] + fn from_vector_mask16x32(self, vector: i16x32) -> mask16x32 { + mask16x32 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask16x32(self, a: mask16x32) -> i16x32 { + i16x32 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask16x32(self, a: &mut mask16x32, index: usize, value: bool) -> () { assert!( index < 32usize, @@ -6661,6 +6801,20 @@ impl Simd for WasmSimd128 { ) } #[inline(always)] + fn from_vector_mask32x16(self, vector: i32x16) -> mask32x16 { + mask32x16 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask32x16(self, a: mask32x16) -> i32x16 { + i32x16 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask32x16(self, a: &mut mask32x16, index: usize, value: bool) -> () { assert!( index < 16usize, @@ -7005,6 +7159,20 @@ impl Simd for WasmSimd128 { ) } #[inline(always)] + fn from_vector_mask64x8(self, vector: i64x8) -> mask64x8 { + mask64x8 { + val: vector.val, + simd: self, + } + } + #[inline(always)] + fn to_vector_mask64x8(self, a: mask64x8) -> i64x8 { + i64x8 { + val: a.val, + simd: self, + } + } + #[inline(always)] fn set_mask64x8(self, a: &mut mask64x8, index: usize, value: bool) -> () { assert!( index < 8usize, diff --git a/fearless_simd_gen/src/generic.rs b/fearless_simd_gen/src/generic.rs index e130f4d5..9e32d41f 100644 --- a/fearless_simd_gen/src/generic.rs +++ b/fearless_simd_gen/src/generic.rs @@ -317,7 +317,7 @@ pub(crate) fn generic_op(op: &Op, ty: &VecType) -> TokenStream { } } } - OpSig::Unary => { + OpSig::Unary | OpSig::MaskToVector | OpSig::MaskFromVector => { let halves = if op.method == "reverse" { quote! { self.#do_half(a1), self.#do_half(a0) } } else { @@ -1105,6 +1105,27 @@ pub(crate) fn generic_mask_to_bitmask(method_sig: TokenStream, vec_ty: &VecType) } } +/// Generic mask-from-vector operation for instruction sets where masks and integer vectors are the +/// same underlying type. +pub(crate) fn generic_mask_from_vector(method_sig: TokenStream, vec_ty: &VecType) -> TokenStream { + let mask_ty_rust = vec_ty.cast(ScalarType::Mask).rust(); + quote! { + #method_sig { + #mask_ty_rust {val: vector.val, simd: self } + } + } +} +/// Generic mask-to-vector operation for instruction sets where masks and integer vectors are the +/// same underlying type. +pub(crate) fn generic_mask_to_vector(method_sig: TokenStream, mask_ty: &VecType) -> TokenStream { + let vector_ty_rust = mask_ty.cast(ScalarType::Int).rust(); + quote! { + #method_sig { + #vector_ty_rust {val: a.val, simd: self } + } + } +} + pub(crate) fn generic_mask_set(method_sig: TokenStream, vec_ty: &VecType) -> TokenStream { let scalar = vec_ty.scalar.rust(vec_ty.scalar_bits); let len = vec_ty.len; diff --git a/fearless_simd_gen/src/mk_fallback.rs b/fearless_simd_gen/src/mk_fallback.rs index 5d3ad932..ca45420a 100644 --- a/fearless_simd_gen/src/mk_fallback.rs +++ b/fearless_simd_gen/src/mk_fallback.rs @@ -3,9 +3,9 @@ use crate::arch::fallback; use crate::generic::{ - byte_compact_op, generic_classify, generic_mask_from_bitmask, generic_mask_set, - generic_mask_to_bitmask, generic_op, generic_op_name, integer_lane_mask_rotate, - integer_lane_mask_splat_arg, + byte_compact_op, generic_classify, generic_mask_from_bitmask, generic_mask_from_vector, + generic_mask_set, generic_mask_to_bitmask, generic_mask_to_vector, generic_op, generic_op_name, + integer_lane_mask_rotate, integer_lane_mask_splat_arg, }; use crate::level::Level; use crate::ops::{NarrowingMode, Op, OpSig, relaxed_narrow_method}; @@ -646,6 +646,8 @@ impl Level for Fallback { } OpSig::MaskFromBitmask => generic_mask_from_bitmask(method_sig, vec_ty), OpSig::MaskToBitmask => generic_mask_to_bitmask(method_sig, vec_ty), + OpSig::MaskFromVector => generic_mask_from_vector(method_sig, vec_ty), + OpSig::MaskToVector => generic_mask_to_vector(method_sig, vec_ty), OpSig::MaskSet => generic_mask_set(method_sig, vec_ty), OpSig::UnaryClassify => generic_classify(method_sig, method, vec_ty), OpSig::LoadInterleaved { diff --git a/fearless_simd_gen/src/mk_neon.rs b/fearless_simd_gen/src/mk_neon.rs index 8c76c555..cea26d30 100644 --- a/fearless_simd_gen/src/mk_neon.rs +++ b/fearless_simd_gen/src/mk_neon.rs @@ -6,9 +6,9 @@ use quote::{ToTokens as _, format_ident, quote}; use crate::generic::{ CompactOptions, byte_compact_op, compact_128_op, composed_compact_op, count_zeros_method, - fallback_method, generic_classify, generic_mask_set, generic_op_name, - generic_to_degrees_radians, integer_lane_mask_rotate, integer_lane_mask_splat_arg, - reverse_method, reverse_vector_mask_method, + fallback_method, generic_classify, generic_mask_from_vector, generic_mask_set, + generic_mask_to_vector, generic_op_name, generic_to_degrees_radians, 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}; @@ -917,6 +917,8 @@ impl Level for Neon { } OpSig::MaskFromBitmask => self.handle_mask_from_bitmask(op, vec_ty), OpSig::MaskToBitmask => self.handle_mask_to_bitmask(op, vec_ty), + OpSig::MaskFromVector => generic_mask_from_vector(method_sig, vec_ty), + OpSig::MaskToVector => generic_mask_to_vector(method_sig, vec_ty), OpSig::MaskSet => generic_mask_set(method_sig, vec_ty), OpSig::UnaryClassify => generic_classify(method_sig, method, vec_ty), OpSig::Interleave => { diff --git a/fearless_simd_gen/src/mk_simd_trait.rs b/fearless_simd_gen/src/mk_simd_trait.rs index 68dfcc04..94d777b9 100644 --- a/fearless_simd_gen/src/mk_simd_trait.rs +++ b/fearless_simd_gen/src/mk_simd_trait.rs @@ -152,16 +152,16 @@ pub(crate) fn mk_simd_trait() -> TokenStream { + SimdNarrow + core::ops::Neg; /// A native-width SIMD mask with 8-bit lanes. - type mask8s: SimdMask + Select + Select + Select + type mask8s: SimdMask + Select + Select + Select + MaskWiden; /// A native-width SIMD mask with 16-bit lanes. - type mask16s: SimdMask + Select + Select + Select + type mask16s: SimdMask + Select + Select + Select + MaskNarrow + MaskWiden; /// A native-width SIMD mask with 32-bit lanes. - type mask32s: SimdMask + Select + Select + Select + Select + type mask32s: SimdMask + Select + Select + Select + Select + MaskNarrow + MaskWiden; /// A native-width SIMD mask with 64-bit lanes. - type mask64s: SimdMask + Select + Select + Select + Select + type mask64s: SimdMask + Select + Select + Select + Select + MaskNarrow; /// This SIMD token's feature level. @@ -552,7 +552,12 @@ fn mk_simd_mask() -> TokenStream { /// /// False lanes are encoded as all zeroes (integer value 0), and true lanes are encoded as all ones /// (integer value -1). - type Element: SimdElement; + type Element: SimdIntElement + + core::ops::Neg; + + /// This mask's corresponding integer vector type. + type Ints: SimdInt + + core::ops::Neg; /// This mask type's lane count. const LEN: usize; @@ -572,6 +577,12 @@ fn mk_simd_mask() -> TokenStream { /// [`Self::LEN`] are cleared. fn to_bitmask(self) -> u64; + /// Create a SIMD mask from signed integer mask lanes. + fn from_vector(v: Self::Ints) -> Self; + + /// Convert this SIMD mask to signed integer mask lanes. + fn to_vector(self) -> Self::Ints; + /// Test whether one logical lane is set. /// /// Panics if `index` is greater than or equal to the number of lanes in the mask. diff --git a/fearless_simd_gen/src/mk_simd_types.rs b/fearless_simd_gen/src/mk_simd_types.rs index 1d869e72..0e4afedb 100644 --- a/fearless_simd_gen/src/mk_simd_types.rs +++ b/fearless_simd_gen/src/mk_simd_types.rs @@ -426,11 +426,15 @@ fn mask_widen_narrow_impls(ty: &VecType) -> TokenStream { fn simd_mask_impl(ty: &VecType) -> TokenStream { let name = ty.rust(); + let int_ty = ty.cast(ScalarType::Int); + let int_ty_name = int_ty.rust(); let scalar = ty.scalar.rust(ty.scalar_bits); let len = Literal::usize_unsuffixed(ty.len); let splat = generic_op_name("splat", ty); let from_bitmask_op = generic_op_name("from_bitmask", ty); let to_bitmask_op = generic_op_name("to_bitmask", ty); + let from_vector_op = generic_op_name("from_vector", ty); + let to_vector_op = generic_op_name("to_vector", ty); let set_op = generic_op_name("set", ty); let mut methods = vec![]; for op in vec_trait_ops_for(ty.scalar) { @@ -463,6 +467,7 @@ fn simd_mask_impl(ty: &VecType) -> TokenStream { quote! { impl SimdMask for #name { type Element = #scalar; + type Ints = #int_ty_name; const LEN: usize = #len; #[inline(always)] @@ -480,6 +485,16 @@ fn simd_mask_impl(ty: &VecType) -> TokenStream { self.simd.#to_bitmask_op(self) } + #[inline(always)] + fn from_vector(vector: Self::Ints) -> Self { + vector.token().#from_vector_op(vector) + } + + #[inline(always)] + fn to_vector(self) -> Self::Ints { + self.simd.#to_vector_op(self) + } + #[inline(always)] fn set(&mut self, index: usize, value: bool) { self.simd.#set_op(self, index, value); diff --git a/fearless_simd_gen/src/mk_wasm.rs b/fearless_simd_gen/src/mk_wasm.rs index c8c30778..8aaae7ce 100644 --- a/fearless_simd_gen/src/mk_wasm.rs +++ b/fearless_simd_gen/src/mk_wasm.rs @@ -8,9 +8,10 @@ use crate::arch::wasm::{arch_prefix, v128_intrinsic}; use crate::generic::{ CompactOptions, byte_compact_op, compact_128_op, composed_compact_op, concat_swizzle_dyn_precise_body, count_zeros_method, fallback_method, generic_block_combine, - generic_block_split, generic_classify, generic_mask_set, generic_op_name, generic_round, - generic_to_degrees_radians, integer_lane_mask_rotate, integer_lane_mask_splat_arg, - recursive_swizzle_dyn_precise_body, reverse_method, reverse_vector_mask_method, + generic_block_split, generic_classify, generic_mask_from_vector, generic_mask_set, + generic_mask_to_vector, generic_op_name, generic_round, generic_to_degrees_radians, + 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::{ @@ -1270,6 +1271,8 @@ impl Level for WasmSimd128 { } OpSig::MaskFromBitmask => mask_from_bitmask(method_sig, vec_ty), OpSig::MaskToBitmask => mask_to_bitmask(method_sig, vec_ty), + OpSig::MaskFromVector => generic_mask_from_vector(method_sig, vec_ty), + OpSig::MaskToVector => generic_mask_to_vector(method_sig, vec_ty), OpSig::MaskSet => generic_mask_set(method_sig, vec_ty), OpSig::UnaryClassify => generic_classify(method_sig, method, vec_ty), OpSig::LoadInterleaved { diff --git a/fearless_simd_gen/src/mk_x86.rs b/fearless_simd_gen/src/mk_x86.rs index 3a9b1fd8..bcce09e0 100644 --- a/fearless_simd_gen/src/mk_x86.rs +++ b/fearless_simd_gen/src/mk_x86.rs @@ -9,9 +9,10 @@ use crate::arch::x86::{ use crate::generic::{ byte_compact_op, compact_128_op, concat_swizzle_dyn_precise_body, count_zeros_method, fallback_method, generic_block_combine, generic_block_split, generic_classify, - generic_mask_from_bitmask, generic_mask_set, generic_op, generic_op_name, generic_round, - generic_to_degrees_radians, integer_lane_mask_rotate, integer_lane_mask_splat_arg, - recursive_swizzle_dyn_precise_body, reverse_method, reverse_vector_mask_method, + generic_mask_from_bitmask, generic_mask_from_vector, generic_mask_set, generic_mask_to_vector, + generic_op, generic_op_name, generic_round, generic_to_degrees_radians, + 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::{ @@ -22,7 +23,7 @@ use crate::types::{ScalarType, VecType}; use proc_macro2::{Ident, Literal, Span, TokenStream}; use quote::{ToTokens as _, format_ident, quote}; -#[derive(Clone, Copy, PartialEq, Eq)] +#[derive(Clone, Copy, PartialEq, Eq, Debug)] pub(crate) enum X86 { Sse2, Sse4_2, @@ -293,6 +294,7 @@ impl Level for X86 { match op.sig { OpSig::MaskFromBitmask => !self.has_specialized_mask_from_bitmask(vec_ty), OpSig::MaskToBitmask => !self.has_specialized_mask_to_bitmask(vec_ty), + OpSig::MaskFromVector | OpSig::MaskToVector => !matches!(self, Self::Avx512), _ => true, } } @@ -374,6 +376,8 @@ impl Level for X86 { } => self.handle_mask_reduce(op, vec_ty, quantifier, condition), OpSig::MaskFromBitmask => self.handle_mask_from_bitmask(op, vec_ty), OpSig::MaskToBitmask => self.handle_mask_to_bitmask(op, vec_ty), + OpSig::MaskFromVector => self.handle_mask_from_vector(op, vec_ty), + OpSig::MaskToVector => self.handle_mask_to_vector(op, vec_ty), OpSig::MaskSet if *self == Self::Avx512 && vec_ty.scalar == ScalarType::Mask => { self.handle_avx512_mask_set(method_sig, vec_ty) } @@ -2534,6 +2538,36 @@ impl X86 { } } + pub(crate) fn handle_mask_from_vector(&self, op: Op, vec_ty: &VecType) -> TokenStream { + if *self != Self::Avx512 { + return generic_mask_from_vector(op.simd_trait_method_sig(vec_ty), vec_ty); + } + + let movepi_mask = intrinsic_ident( + &format!("movepi{}", vec_ty.scalar_bits), + "mask", + vec_ty.n_bits(), + ); + self.kernel_method(op, vec_ty, |token| { + quote! { #movepi_mask(vector.into()).simd_into(#token) } + }) + } + + pub(crate) fn handle_mask_to_vector(&self, op: Op, vec_ty: &VecType) -> TokenStream { + if *self != Self::Avx512 { + return generic_mask_to_vector(op.simd_trait_method_sig(vec_ty), vec_ty); + } + + let movm = intrinsic_ident( + "movm", + op_suffix(vec_ty.scalar, vec_ty.scalar_bits, true), + vec_ty.n_bits(), + ); + self.kernel_method(op, vec_ty, |token| { + quote! { #movm(a.val).simd_into(#token) } + }) + } + pub(crate) fn handle_compare(&self, op: Op, method: &str, vec_ty: &VecType) -> TokenStream { if *self == Self::Avx512 { if vec_ty.scalar == ScalarType::Mask { diff --git a/fearless_simd_gen/src/ops.rs b/fearless_simd_gen/src/ops.rs index bbf61073..64f6987b 100644 --- a/fearless_simd_gen/src/ops.rs +++ b/fearless_simd_gen/src/ops.rs @@ -134,10 +134,14 @@ pub(crate) enum OpSig { quantifier: Quantifier, condition: bool, }, - /// Takes a compact bitmask and returns the corresponding mask vector type. + /// Takes a compact bitmask and returns its mask vector representation. MaskFromBitmask, /// Takes a mask vector type and returns its compact bitmask representation. MaskToBitmask, + /// Takes an integer vector type and converts it to the corresponding mask vector type. + MaskFromVector, + /// Takes a mask vector type and converts it to the corresponding integer vector type. + MaskToVector, /// Takes a mutable mask vector, a lane index, and a boolean, and updates the lane in place. MaskSet, /// Takes a single argument of the vector type, and returns the associated mask type. @@ -386,6 +390,14 @@ impl Op { OpSig::MaskReduce { .. } => (vec![vec], quote! { bool }), OpSig::MaskFromBitmask => (vec![quote! { u64 }], vec), OpSig::MaskToBitmask => (vec![vec], quote! { u64 }), + OpSig::MaskFromVector => { + let ints_ty = vec_ty.cast(ScalarType::Int).rust(); + (vec![quote! { #ints_ty<#simd_ty> }], vec) + } + OpSig::MaskToVector => { + let ints_ty = vec_ty.cast(ScalarType::Int).rust(); + (vec![vec], quote! { #ints_ty<#simd_ty> }) + } OpSig::MaskSet => ( vec![quote! { &mut #vec }, quote! { usize }, quote! { bool }], quote! { () }, @@ -436,7 +448,11 @@ impl Op { OpSig::Compress { merge: true } | OpSig::Expand { merge: true } => { quote! { (self, mask: Self::Mask, merge: impl SimdInto) -> Self } } - OpSig::MaskFromBitmask | OpSig::MaskToBitmask | OpSig::MaskSet => return None, + OpSig::MaskFromBitmask + | OpSig::MaskToBitmask + | OpSig::MaskFromVector + | OpSig::MaskToVector + | OpSig::MaskSet => return None, OpSig::Unary | OpSig::Cvt { .. } => { let arg0 = &arg_names[0]; quote! { (#arg0) -> Self } @@ -1001,6 +1017,18 @@ const MASK_REPRESENTATION_OPS: &[Op] = &[ OpSig::MaskToBitmask, "Convert a SIMD mask to a compact bitmask.\n\nBit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above the number of lanes in this mask are cleared.", ), + Op::new( + "from_vector", + OpKind::VecTraitMethod, + OpSig::MaskFromVector, + "Create a SIMD mask from an integer vector of the same width.\n\nA lane value of -1 means \"true\", a lane value of 0 means \"false\", and all other lane values result in unspecified behavior.", + ), + Op::new( + "to_vector", + OpKind::VecTraitMethod, + OpSig::MaskToVector, + "Convert a SIMD mask to an integer vector of the same width.\n\n\"True\" maps to -1 and \"false\" maps to 0.", + ), Op::new( "set", OpKind::AssociatedOnly, @@ -1984,6 +2012,8 @@ impl OpSig { | Self::Combine { .. } | Self::LoadInterleaved { .. } | Self::StoreInterleaved { .. } + | Self::MaskFromVector + | Self::MaskToVector | Self::MaskSet | Self::UnaryClassify | Self::RotateElements { .. } @@ -2029,6 +2059,7 @@ impl OpSig { match self { Self::Splat => &["val"], Self::MaskFromBitmask => &["bits"], + Self::MaskFromVector => &["vector"], Self::MaskSet => &["a", "index", "value"], Self::Unary | Self::Reduce { .. } @@ -2038,6 +2069,7 @@ impl OpSig { | Self::Widen { .. } | Self::MaskReduce { .. } | Self::MaskToBitmask + | Self::MaskToVector | Self::UnaryClassify => &["a"], Self::SwizzleDynWithinBlocks | Self::SwizzleDyn | Self::SwizzleDynPrecise => { &["a", "indices"] @@ -2070,6 +2102,8 @@ impl OpSig { | Self::StoreInterleaved { .. } | Self::MaskFromBitmask | Self::MaskToBitmask + | Self::MaskFromVector + | Self::MaskToVector | Self::MaskSet => &[], Self::Compress { merge: false } | Self::Expand { merge: false } => &["self", "mask"], Self::Compress { merge: true } | Self::Expand { merge: true } => { @@ -2147,6 +2181,8 @@ impl OpSig { | Self::RotateElements { .. } | Self::MaskFromBitmask | Self::MaskToBitmask + | Self::MaskFromVector + | Self::MaskToVector | Self::MaskSet | Self::LoadInterleaved { .. } | Self::StoreInterleaved { .. } diff --git a/fearless_simd_tests/tests/harness/lm_generated/mask_roundtrip.rs b/fearless_simd_tests/tests/harness/lm_generated/mask_roundtrip.rs index b7ddf59b..3c62895a 100644 --- a/fearless_simd_tests/tests/harness/lm_generated/mask_roundtrip.rs +++ b/fearless_simd_tests/tests/harness/lm_generated/mask_roundtrip.rs @@ -84,6 +84,95 @@ fn mask64x8_set_roundtrip(simd: S) { assert_mask_set_roundtrip::>(simd); } +/// Check both conversions against independently constructed lane values and bits. +fn assert_mask_vector_roundtrip>(simd: S) +where + M::Element: From + PartialEq + core::fmt::Debug, +{ + let lane_bits = u64::MAX >> (64 - M::LEN); + for bits in [ + 0, + 1, + 1 << (M::LEN - 1), + 0x5555_5555_5555_5555 & lane_bits, + 0xaaaa_aaaa_aaaa_aaaa & lane_bits, + lane_bits, + ] { + let vector = M::Ints::from_fn(simd, |i| { + if bits & (1 << i) != 0 { + (-1_i8).into() + } else { + 0_i8.into() + } + }); + assert_eq!(M::from_vector(vector).to_bitmask(), bits); + assert_eq!( + M::from_bitmask(simd, bits).to_vector().as_slice(), + vector.as_slice() + ); + } +} + +#[simd_test] +fn mask8x16_vector_roundtrip(simd: S) { + assert_mask_vector_roundtrip::>(simd); +} + +#[simd_test] +fn mask16x8_vector_roundtrip(simd: S) { + assert_mask_vector_roundtrip::>(simd); +} + +#[simd_test] +fn mask32x4_vector_roundtrip(simd: S) { + assert_mask_vector_roundtrip::>(simd); +} + +#[simd_test] +fn mask64x2_vector_roundtrip(simd: S) { + assert_mask_vector_roundtrip::>(simd); +} + +#[simd_test] +fn mask8x32_vector_roundtrip(simd: S) { + assert_mask_vector_roundtrip::>(simd); +} + +#[simd_test] +fn mask16x16_vector_roundtrip(simd: S) { + assert_mask_vector_roundtrip::>(simd); +} + +#[simd_test] +fn mask32x8_vector_roundtrip(simd: S) { + assert_mask_vector_roundtrip::>(simd); +} + +#[simd_test] +fn mask64x4_vector_roundtrip(simd: S) { + assert_mask_vector_roundtrip::>(simd); +} + +#[simd_test] +fn mask8x64_vector_roundtrip(simd: S) { + assert_mask_vector_roundtrip::>(simd); +} + +#[simd_test] +fn mask16x32_vector_roundtrip(simd: S) { + assert_mask_vector_roundtrip::>(simd); +} + +#[simd_test] +fn mask32x16_vector_roundtrip(simd: S) { + assert_mask_vector_roundtrip::>(simd); +} + +#[simd_test] +fn mask64x8_vector_roundtrip(simd: S) { + assert_mask_vector_roundtrip::>(simd); +} + #[simd_test] fn mask8x16_to_bitmask_exhaustive(simd: S) { for bits in 0..=0xffff_u64 { diff --git a/fearless_simd_tests/tests/harness/ops/mask_from_to_vector.rs b/fearless_simd_tests/tests/harness/ops/mask_from_to_vector.rs new file mode 100644 index 00000000..cf5d8845 --- /dev/null +++ b/fearless_simd_tests/tests/harness/ops/mask_from_to_vector.rs @@ -0,0 +1,137 @@ +// Copyright 2026 the Fearless_SIMD Authors +// SPDX-License-Identifier: Apache-2.0 OR MIT + +use fearless_simd::*; +use fearless_simd_dev_macros::simd_test; + +#[simd_test] +fn from_to_vector_mask32x4(simd: S) { + let values: [i32; 4] = core::array::from_fn(|i| if i % 2 == 0 { -1_i32 } else { 0_i32 }); + let a = i32x4::from_slice(simd, &values); + let mask = mask32x4::from_vector(a); + let a = mask.to_vector(); + let mut out = [0_i32; 4]; + a.store_slice(&mut out); + assert_eq!(out, values); +} + +#[simd_test] +fn from_to_vector_mask8x16(simd: S) { + let values: [i8; 16] = core::array::from_fn(|i| if i % 2 == 0 { -1_i8 } else { 0_i8 }); + let a = i8x16::from_slice(simd, &values); + let mask = mask8x16::from_vector(a); + let a = mask.to_vector(); + let mut out = [0_i8; 16]; + a.store_slice(&mut out); + assert_eq!(out, values); +} + +#[simd_test] +fn from_to_vector_mask8x32(simd: S) { + let values: [i8; 32] = core::array::from_fn(|i| if i % 2 == 0 { -1_i8 } else { 0_i8 }); + let a = i8x32::from_slice(simd, &values); + let mask = mask8x32::from_vector(a); + let a = mask.to_vector(); + let mut out = [0_i8; 32]; + a.store_slice(&mut out); + assert_eq!(out, values); +} + +#[simd_test] +fn from_to_vector_mask8x64(simd: S) { + let values: [i8; 64] = core::array::from_fn(|i| if i % 2 == 0 { -1_i8 } else { 0_i8 }); + let a = i8x64::from_slice(simd, &values); + let mask = mask8x64::from_vector(a); + let a = mask.to_vector(); + let mut out = [0_i8; 64]; + a.store_slice(&mut out); + assert_eq!(out, values); +} + +#[simd_test] +fn from_to_vector_mask16x8(simd: S) { + let values: [i16; 8] = core::array::from_fn(|i| if i % 2 == 0 { -1_i16 } else { 0_i16 }); + let a = i16x8::from_slice(simd, &values); + let mask = mask16x8::from_vector(a); + let a = mask.to_vector(); + let mut out = [0_i16; 8]; + a.store_slice(&mut out); + assert_eq!(out, values); +} + +#[simd_test] +fn from_to_vector_mask16x16(simd: S) { + let values: [i16; 16] = core::array::from_fn(|i| if i % 2 == 0 { -1_i16 } else { 0_i16 }); + let a = i16x16::from_slice(simd, &values); + let mask = mask16x16::from_vector(a); + let a = mask.to_vector(); + let mut out = [0_i16; 16]; + a.store_slice(&mut out); + assert_eq!(out, values); +} + +#[simd_test] +fn from_to_vector_mask16x32(simd: S) { + let values: [i16; 32] = core::array::from_fn(|i| if i % 2 == 0 { -1_i16 } else { 0_i16 }); + let a = i16x32::from_slice(simd, &values); + let mask = mask16x32::from_vector(a); + let a = mask.to_vector(); + let mut out = [0_i16; 32]; + a.store_slice(&mut out); + assert_eq!(out, values); +} + +#[simd_test] +fn from_to_vector_mask32x8(simd: S) { + let values: [i32; 8] = core::array::from_fn(|i| if i % 2 == 0 { -1_i32 } else { 0_i32 }); + let a = i32x8::from_slice(simd, &values); + let mask = mask32x8::from_vector(a); + let a = mask.to_vector(); + let mut out = [0_i32; 8]; + a.store_slice(&mut out); + assert_eq!(out, values); +} + +#[simd_test] +fn from_to_vector_mask32x16(simd: S) { + let values: [i32; 16] = core::array::from_fn(|i| if i % 2 == 0 { -1_i32 } else { 0_i32 }); + let a = i32x16::from_slice(simd, &values); + let mask = mask32x16::from_vector(a); + let a = mask.to_vector(); + let mut out = [0_i32; 16]; + a.store_slice(&mut out); + assert_eq!(out, values); +} + +#[simd_test] +fn from_to_vector_mask64x2(simd: S) { + let values: [i64; 2] = core::array::from_fn(|i| if i % 2 == 0 { -1_i64 } else { 0_i64 }); + let a = i64x2::from_slice(simd, &values); + let mask = mask64x2::from_vector(a); + let a = mask.to_vector(); + let mut out = [0_i64; 2]; + a.store_slice(&mut out); + assert_eq!(out, values); +} + +#[simd_test] +fn from_to_vector_mask64x4(simd: S) { + let values: [i64; 4] = core::array::from_fn(|i| if i % 2 == 0 { -1_i64 } else { 0_i64 }); + let a = i64x4::from_slice(simd, &values); + let mask = mask64x4::from_vector(a); + let a = mask.to_vector(); + let mut out = [0_i64; 4]; + a.store_slice(&mut out); + assert_eq!(out, values); +} + +#[simd_test] +fn from_to_vector_mask64x8(simd: S) { + let values: [i64; 8] = core::array::from_fn(|i| if i % 2 == 0 { -1_i64 } else { 0_i64 }); + let a = i64x8::from_slice(simd, &values); + let mask = mask64x8::from_vector(a); + let a = mask.to_vector(); + let mut out = [0_i64; 8]; + a.store_slice(&mut out); + assert_eq!(out, values); +} diff --git a/fearless_simd_tests/tests/harness/ops/mod.rs b/fearless_simd_tests/tests/harness/ops/mod.rs index 99f2a88b..03f8aee4 100644 --- a/fearless_simd_tests/tests/harness/ops/mod.rs +++ b/fearless_simd_tests/tests/harness/ops/mod.rs @@ -48,6 +48,7 @@ mod interleave; mod load_array; mod load_array_ref; mod load_four_interleaved; +mod mask_from_to_vector; mod max; mod max_precise; mod min;