diff --git a/CHANGELOG.md b/CHANGELOG.md index ddfda363..af9fcfc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ You can find its changes [documented below](#060-2026-07-10). ### Added - Added an `Sse2` level. This is the new baseline for i686-* and x86_64-* targets, replacing `Fallback`. ([#270][] by [@Shnatsel][]) +- Added full-vector `swizzle_dyn` and `swizzle_dyn_precise` byte swizzles. `swizzle_dyn` permits implementation-defined results for out-of-range indices, while `swizzle_dyn_precise` always returns zero for them. - Added trait bounds on `SimdElement`, and introduced the `SimdIntElement` and `SimdFloatElement` subtraits. These allow generic code to access many math and utility operations on the elements of SIMD vector types. ([#302][] by [@danderson][]) ### Changed diff --git a/fearless_simd/src/generated/avx2.rs b/fearless_simd/src/generated/avx2.rs index 266be45c..1e1e1e38 100644 --- a/fearless_simd/src/generated/avx2.rs +++ b/fearless_simd/src/generated/avx2.rs @@ -212,6 +212,20 @@ impl Simd for Avx2 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_f32x4(self, a: f32x4, indices: u8x16) -> f32x4 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx2, a: f32x4, indices: u8x16) -> f32x4 { + let result = _mm_shuffle_epi8(Bytes::to_bytes(a).val.0, indices.into()); + Bytes::from_bytes(u8x16 { + val: crate::support::Aligned128(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_f32x4(self, a: f32x4, indices: u8x16) -> f32x4 { crate::kernel!( #[inline(always)] @@ -865,6 +879,20 @@ impl Simd for Avx2 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_i8x16(self, a: i8x16, indices: u8x16) -> i8x16 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx2, a: i8x16, indices: u8x16) -> i8x16 { + let result = _mm_shuffle_epi8(Bytes::to_bytes(a).val.0, indices.into()); + Bytes::from_bytes(u8x16 { + val: crate::support::Aligned128(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i8x16(self, a: i8x16, indices: u8x16) -> i8x16 { crate::kernel!( #[inline(always)] @@ -1430,6 +1458,20 @@ impl Simd for Avx2 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_u8x16(self, a: u8x16, indices: u8x16) -> u8x16 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx2, a: u8x16, indices: u8x16) -> u8x16 { + let result = _mm_shuffle_epi8(Bytes::to_bytes(a).val.0, indices.into()); + Bytes::from_bytes(u8x16 { + val: crate::support::Aligned128(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u8x16(self, a: u8x16, indices: u8x16) -> u8x16 { crate::kernel!( #[inline(always)] @@ -2135,6 +2177,20 @@ impl Simd for Avx2 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_i16x8(self, a: i16x8, indices: u8x16) -> i16x8 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx2, a: i16x8, indices: u8x16) -> i16x8 { + let result = _mm_shuffle_epi8(Bytes::to_bytes(a).val.0, indices.into()); + Bytes::from_bytes(u8x16 { + val: crate::support::Aligned128(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i16x8(self, a: i16x8, indices: u8x16) -> i16x8 { crate::kernel!( #[inline(always)] @@ -2633,6 +2689,20 @@ impl Simd for Avx2 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_u16x8(self, a: u16x8, indices: u8x16) -> u16x8 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx2, a: u16x8, indices: u8x16) -> u16x8 { + let result = _mm_shuffle_epi8(Bytes::to_bytes(a).val.0, indices.into()); + Bytes::from_bytes(u8x16 { + val: crate::support::Aligned128(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u16x8(self, a: u16x8, indices: u8x16) -> u16x8 { crate::kernel!( #[inline(always)] @@ -3281,6 +3351,20 @@ impl Simd for Avx2 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_i32x4(self, a: i32x4, indices: u8x16) -> i32x4 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx2, a: i32x4, indices: u8x16) -> i32x4 { + let result = _mm_shuffle_epi8(Bytes::to_bytes(a).val.0, indices.into()); + Bytes::from_bytes(u8x16 { + val: crate::support::Aligned128(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i32x4(self, a: i32x4, indices: u8x16) -> i32x4 { crate::kernel!( #[inline(always)] @@ -3753,6 +3837,20 @@ impl Simd for Avx2 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_u32x4(self, a: u32x4, indices: u8x16) -> u32x4 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx2, a: u32x4, indices: u8x16) -> u32x4 { + let result = _mm_shuffle_epi8(Bytes::to_bytes(a).val.0, indices.into()); + Bytes::from_bytes(u8x16 { + val: crate::support::Aligned128(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u32x4(self, a: u32x4, indices: u8x16) -> u32x4 { crate::kernel!( #[inline(always)] @@ -4389,6 +4487,20 @@ impl Simd for Avx2 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_f64x2(self, a: f64x2, indices: u8x16) -> f64x2 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx2, a: f64x2, indices: u8x16) -> f64x2 { + let result = _mm_shuffle_epi8(Bytes::to_bytes(a).val.0, indices.into()); + Bytes::from_bytes(u8x16 { + val: crate::support::Aligned128(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_f64x2(self, a: f64x2, indices: u8x16) -> f64x2 { crate::kernel!( #[inline(always)] @@ -4885,6 +4997,20 @@ impl Simd for Avx2 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_i64x2(self, a: i64x2, indices: u8x16) -> i64x2 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx2, a: i64x2, indices: u8x16) -> i64x2 { + let result = _mm_shuffle_epi8(Bytes::to_bytes(a).val.0, indices.into()); + Bytes::from_bytes(u8x16 { + val: crate::support::Aligned128(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i64x2(self, a: i64x2, indices: u8x16) -> i64x2 { crate::kernel!( #[inline(always)] @@ -5306,6 +5432,20 @@ impl Simd for Avx2 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_u64x2(self, a: u64x2, indices: u8x16) -> u64x2 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx2, a: u64x2, indices: u8x16) -> u64x2 { + let result = _mm_shuffle_epi8(Bytes::to_bytes(a).val.0, indices.into()); + Bytes::from_bytes(u8x16 { + val: crate::support::Aligned128(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u64x2(self, a: u64x2, indices: u8x16) -> u64x2 { crate::kernel!( #[inline(always)] @@ -5911,6 +6051,28 @@ impl Simd for Avx2 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_f32x8(self, a: f32x8, indices: u8x32) -> f32x8 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx2, a: f32x8, indices: u8x32) -> f32x8 { + let bytes = Bytes::to_bytes(a).val.0; + let indices = indices.into(); + let swapped = _mm256_permute2x128_si256::<0x01>(bytes, bytes); + let local = _mm256_shuffle_epi8(bytes, indices); + let remote = _mm256_shuffle_epi8(swapped, indices); + let select_remote = _mm256_slli_epi16::<3>(indices); + let flip_high_lane = _mm256_set_m128i(_mm_set1_epi8(i8::MIN), _mm_setzero_si128()); + let select_remote = _mm256_xor_si256(select_remote, flip_high_lane); + let result = _mm256_blendv_epi8(local, remote, select_remote); + Bytes::from_bytes(u8x32 { + val: crate::support::Aligned256(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_f32x8(self, a: f32x8, indices: u8x32) -> f32x8 { crate::kernel!( #[inline(always)] @@ -6613,6 +6775,28 @@ impl Simd for Avx2 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_i8x32(self, a: i8x32, indices: u8x32) -> i8x32 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx2, a: i8x32, indices: u8x32) -> i8x32 { + let bytes = Bytes::to_bytes(a).val.0; + let indices = indices.into(); + let swapped = _mm256_permute2x128_si256::<0x01>(bytes, bytes); + let local = _mm256_shuffle_epi8(bytes, indices); + let remote = _mm256_shuffle_epi8(swapped, indices); + let select_remote = _mm256_slli_epi16::<3>(indices); + let flip_high_lane = _mm256_set_m128i(_mm_set1_epi8(i8::MIN), _mm_setzero_si128()); + let select_remote = _mm256_xor_si256(select_remote, flip_high_lane); + let result = _mm256_blendv_epi8(local, remote, select_remote); + Bytes::from_bytes(u8x32 { + val: crate::support::Aligned256(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i8x32(self, a: i8x32, indices: u8x32) -> i8x32 { crate::kernel!( #[inline(always)] @@ -7274,6 +7458,28 @@ impl Simd for Avx2 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_u8x32(self, a: u8x32, indices: u8x32) -> u8x32 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx2, a: u8x32, indices: u8x32) -> u8x32 { + let bytes = Bytes::to_bytes(a).val.0; + let indices = indices.into(); + let swapped = _mm256_permute2x128_si256::<0x01>(bytes, bytes); + let local = _mm256_shuffle_epi8(bytes, indices); + let remote = _mm256_shuffle_epi8(swapped, indices); + let select_remote = _mm256_slli_epi16::<3>(indices); + let flip_high_lane = _mm256_set_m128i(_mm_set1_epi8(i8::MIN), _mm_setzero_si128()); + let select_remote = _mm256_xor_si256(select_remote, flip_high_lane); + let result = _mm256_blendv_epi8(local, remote, select_remote); + Bytes::from_bytes(u8x32 { + val: crate::support::Aligned256(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u8x32(self, a: u8x32, indices: u8x32) -> u8x32 { crate::kernel!( #[inline(always)] @@ -8065,6 +8271,28 @@ impl Simd for Avx2 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_i16x16(self, a: i16x16, indices: u8x32) -> i16x16 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx2, a: i16x16, indices: u8x32) -> i16x16 { + let bytes = Bytes::to_bytes(a).val.0; + let indices = indices.into(); + let swapped = _mm256_permute2x128_si256::<0x01>(bytes, bytes); + let local = _mm256_shuffle_epi8(bytes, indices); + let remote = _mm256_shuffle_epi8(swapped, indices); + let select_remote = _mm256_slli_epi16::<3>(indices); + let flip_high_lane = _mm256_set_m128i(_mm_set1_epi8(i8::MIN), _mm_setzero_si128()); + let select_remote = _mm256_xor_si256(select_remote, flip_high_lane); + let result = _mm256_blendv_epi8(local, remote, select_remote); + Bytes::from_bytes(u8x32 { + val: crate::support::Aligned256(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i16x16(self, a: i16x16, indices: u8x32) -> i16x16 { crate::kernel!( #[inline(always)] @@ -8617,6 +8845,28 @@ impl Simd for Avx2 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_u16x16(self, a: u16x16, indices: u8x32) -> u16x16 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx2, a: u16x16, indices: u8x32) -> u16x16 { + let bytes = Bytes::to_bytes(a).val.0; + let indices = indices.into(); + let swapped = _mm256_permute2x128_si256::<0x01>(bytes, bytes); + let local = _mm256_shuffle_epi8(bytes, indices); + let remote = _mm256_shuffle_epi8(swapped, indices); + let select_remote = _mm256_slli_epi16::<3>(indices); + let flip_high_lane = _mm256_set_m128i(_mm_set1_epi8(i8::MIN), _mm_setzero_si128()); + let select_remote = _mm256_xor_si256(select_remote, flip_high_lane); + let result = _mm256_blendv_epi8(local, remote, select_remote); + Bytes::from_bytes(u8x32 { + val: crate::support::Aligned256(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u16x16(self, a: u16x16, indices: u8x32) -> u16x16 { crate::kernel!( #[inline(always)] @@ -9330,6 +9580,28 @@ impl Simd for Avx2 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_i32x8(self, a: i32x8, indices: u8x32) -> i32x8 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx2, a: i32x8, indices: u8x32) -> i32x8 { + let bytes = Bytes::to_bytes(a).val.0; + let indices = indices.into(); + let swapped = _mm256_permute2x128_si256::<0x01>(bytes, bytes); + let local = _mm256_shuffle_epi8(bytes, indices); + let remote = _mm256_shuffle_epi8(swapped, indices); + let select_remote = _mm256_slli_epi16::<3>(indices); + let flip_high_lane = _mm256_set_m128i(_mm_set1_epi8(i8::MIN), _mm_setzero_si128()); + let select_remote = _mm256_xor_si256(select_remote, flip_high_lane); + let result = _mm256_blendv_epi8(local, remote, select_remote); + Bytes::from_bytes(u8x32 { + val: crate::support::Aligned256(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i32x8(self, a: i32x8, indices: u8x32) -> i32x8 { crate::kernel!( #[inline(always)] @@ -9806,6 +10078,28 @@ impl Simd for Avx2 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_u32x8(self, a: u32x8, indices: u8x32) -> u32x8 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx2, a: u32x8, indices: u8x32) -> u32x8 { + let bytes = Bytes::to_bytes(a).val.0; + let indices = indices.into(); + let swapped = _mm256_permute2x128_si256::<0x01>(bytes, bytes); + let local = _mm256_shuffle_epi8(bytes, indices); + let remote = _mm256_shuffle_epi8(swapped, indices); + let select_remote = _mm256_slli_epi16::<3>(indices); + let flip_high_lane = _mm256_set_m128i(_mm_set1_epi8(i8::MIN), _mm_setzero_si128()); + let select_remote = _mm256_xor_si256(select_remote, flip_high_lane); + let result = _mm256_blendv_epi8(local, remote, select_remote); + Bytes::from_bytes(u8x32 { + val: crate::support::Aligned256(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u32x8(self, a: u32x8, indices: u8x32) -> u32x8 { crate::kernel!( #[inline(always)] @@ -10450,6 +10744,28 @@ impl Simd for Avx2 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_f64x4(self, a: f64x4, indices: u8x32) -> f64x4 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx2, a: f64x4, indices: u8x32) -> f64x4 { + let bytes = Bytes::to_bytes(a).val.0; + let indices = indices.into(); + let swapped = _mm256_permute2x128_si256::<0x01>(bytes, bytes); + let local = _mm256_shuffle_epi8(bytes, indices); + let remote = _mm256_shuffle_epi8(swapped, indices); + let select_remote = _mm256_slli_epi16::<3>(indices); + let flip_high_lane = _mm256_set_m128i(_mm_set1_epi8(i8::MIN), _mm_setzero_si128()); + let select_remote = _mm256_xor_si256(select_remote, flip_high_lane); + let result = _mm256_blendv_epi8(local, remote, select_remote); + Bytes::from_bytes(u8x32 { + val: crate::support::Aligned256(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_f64x4(self, a: f64x4, indices: u8x32) -> f64x4 { crate::kernel!( #[inline(always)] @@ -10949,6 +11265,28 @@ impl Simd for Avx2 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_i64x4(self, a: i64x4, indices: u8x32) -> i64x4 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx2, a: i64x4, indices: u8x32) -> i64x4 { + let bytes = Bytes::to_bytes(a).val.0; + let indices = indices.into(); + let swapped = _mm256_permute2x128_si256::<0x01>(bytes, bytes); + let local = _mm256_shuffle_epi8(bytes, indices); + let remote = _mm256_shuffle_epi8(swapped, indices); + let select_remote = _mm256_slli_epi16::<3>(indices); + let flip_high_lane = _mm256_set_m128i(_mm_set1_epi8(i8::MIN), _mm_setzero_si128()); + let select_remote = _mm256_xor_si256(select_remote, flip_high_lane); + let result = _mm256_blendv_epi8(local, remote, select_remote); + Bytes::from_bytes(u8x32 { + val: crate::support::Aligned256(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i64x4(self, a: i64x4, indices: u8x32) -> i64x4 { crate::kernel!( #[inline(always)] @@ -11387,6 +11725,28 @@ impl Simd for Avx2 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_u64x4(self, a: u64x4, indices: u8x32) -> u64x4 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx2, a: u64x4, indices: u8x32) -> u64x4 { + let bytes = Bytes::to_bytes(a).val.0; + let indices = indices.into(); + let swapped = _mm256_permute2x128_si256::<0x01>(bytes, bytes); + let local = _mm256_shuffle_epi8(bytes, indices); + let remote = _mm256_shuffle_epi8(swapped, indices); + let select_remote = _mm256_slli_epi16::<3>(indices); + let flip_high_lane = _mm256_set_m128i(_mm_set1_epi8(i8::MIN), _mm_setzero_si128()); + let select_remote = _mm256_xor_si256(select_remote, flip_high_lane); + let result = _mm256_blendv_epi8(local, remote, select_remote); + Bytes::from_bytes(u8x32 { + val: crate::support::Aligned256(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u64x4(self, a: u64x4, indices: u8x32) -> u64x4 { crate::kernel!( #[inline(always)] @@ -12015,6 +12375,10 @@ impl Simd for Avx2 { ) } #[inline(always)] + fn swizzle_dyn_f32x16(self, a: f32x16, indices: u8x64) -> f32x16 { + self.swizzle_dyn_precise_f32x16(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_f32x16(self, a: f32x16, indices: u8x64) -> f32x16 { crate::kernel!( #[inline(always)] @@ -12634,6 +12998,10 @@ impl Simd for Avx2 { ) } #[inline(always)] + fn swizzle_dyn_i8x64(self, a: i8x64, indices: u8x64) -> i8x64 { + self.swizzle_dyn_precise_i8x64(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i8x64(self, a: i8x64, indices: u8x64) -> i8x64 { crate::kernel!( #[inline(always)] @@ -13176,6 +13544,10 @@ impl Simd for Avx2 { ) } #[inline(always)] + fn swizzle_dyn_u8x64(self, a: u8x64, indices: u8x64) -> u8x64 { + self.swizzle_dyn_precise_u8x64(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u8x64(self, a: u8x64, indices: u8x64) -> u8x64 { crate::kernel!( #[inline(always)] @@ -13730,6 +14102,10 @@ impl Simd for Avx2 { ) } #[inline(always)] + fn swizzle_dyn_i16x32(self, a: i16x32, indices: u8x64) -> i16x32 { + self.swizzle_dyn_precise_i16x32(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i16x32(self, a: i16x32, indices: u8x64) -> i16x32 { crate::kernel!( #[inline(always)] @@ -14154,6 +14530,10 @@ impl Simd for Avx2 { ) } #[inline(always)] + fn swizzle_dyn_u16x32(self, a: u16x32, indices: u8x64) -> u16x32 { + self.swizzle_dyn_precise_u16x32(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u16x32(self, a: u16x32, indices: u8x64) -> u16x32 { crate::kernel!( #[inline(always)] @@ -14644,6 +15024,10 @@ impl Simd for Avx2 { ) } #[inline(always)] + fn swizzle_dyn_i32x16(self, a: i32x16, indices: u8x64) -> i32x16 { + self.swizzle_dyn_precise_i32x16(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i32x16(self, a: i32x16, indices: u8x64) -> i32x16 { crate::kernel!( #[inline(always)] @@ -15003,6 +15387,10 @@ impl Simd for Avx2 { ) } #[inline(always)] + fn swizzle_dyn_u32x16(self, a: u32x16, indices: u8x64) -> u32x16 { + self.swizzle_dyn_precise_u32x16(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u32x16(self, a: u32x16, indices: u8x64) -> u32x16 { crate::kernel!( #[inline(always)] @@ -15448,6 +15836,10 @@ impl Simd for Avx2 { ) } #[inline(always)] + fn swizzle_dyn_f64x8(self, a: f64x8, indices: u8x64) -> f64x8 { + self.swizzle_dyn_precise_f64x8(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_f64x8(self, a: f64x8, indices: u8x64) -> f64x8 { crate::kernel!( #[inline(always)] @@ -15817,6 +16209,10 @@ impl Simd for Avx2 { ) } #[inline(always)] + fn swizzle_dyn_i64x8(self, a: i64x8, indices: u8x64) -> i64x8 { + self.swizzle_dyn_precise_i64x8(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i64x8(self, a: i64x8, indices: u8x64) -> i64x8 { crate::kernel!( #[inline(always)] @@ -16135,6 +16531,10 @@ impl Simd for Avx2 { ) } #[inline(always)] + fn swizzle_dyn_u64x8(self, a: u64x8, indices: u8x64) -> u64x8 { + self.swizzle_dyn_precise_u64x8(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u64x8(self, a: u64x8, indices: u8x64) -> u64x8 { crate::kernel!( #[inline(always)] diff --git a/fearless_simd/src/generated/avx512.rs b/fearless_simd/src/generated/avx512.rs index a391c70d..322d616f 100644 --- a/fearless_simd/src/generated/avx512.rs +++ b/fearless_simd/src/generated/avx512.rs @@ -487,6 +487,20 @@ impl Simd for Avx512 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_f32x4(self, a: f32x4, indices: u8x16) -> f32x4 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: f32x4, indices: u8x16) -> f32x4 { + let result = _mm_permutexvar_epi8(indices.into(), Bytes::to_bytes(a).val.0); + Bytes::from_bytes(u8x16 { + val: crate::support::Aligned128(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_f32x4(self, a: f32x4, indices: u8x16) -> f32x4 { crate::kernel!( #[inline(always)] @@ -1107,6 +1121,20 @@ impl Simd for Avx512 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_i8x16(self, a: i8x16, indices: u8x16) -> i8x16 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: i8x16, indices: u8x16) -> i8x16 { + let result = _mm_permutexvar_epi8(indices.into(), Bytes::to_bytes(a).val.0); + Bytes::from_bytes(u8x16 { + val: crate::support::Aligned128(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i8x16(self, a: i8x16, indices: u8x16) -> i8x16 { crate::kernel!( #[inline(always)] @@ -1685,6 +1713,20 @@ impl Simd for Avx512 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_u8x16(self, a: u8x16, indices: u8x16) -> u8x16 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: u8x16, indices: u8x16) -> u8x16 { + let result = _mm_permutexvar_epi8(indices.into(), Bytes::to_bytes(a).val.0); + Bytes::from_bytes(u8x16 { + val: crate::support::Aligned128(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u8x16(self, a: u8x16, indices: u8x16) -> u8x16 { crate::kernel!( #[inline(always)] @@ -2338,6 +2380,20 @@ impl Simd for Avx512 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_i16x8(self, a: i16x8, indices: u8x16) -> i16x8 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: i16x8, indices: u8x16) -> i16x8 { + let result = _mm_permutexvar_epi8(indices.into(), Bytes::to_bytes(a).val.0); + Bytes::from_bytes(u8x16 { + val: crate::support::Aligned128(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i16x8(self, a: i16x8, indices: u8x16) -> i16x8 { crate::kernel!( #[inline(always)] @@ -2830,6 +2886,20 @@ impl Simd for Avx512 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_u16x8(self, a: u16x8, indices: u8x16) -> u16x8 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: u16x8, indices: u8x16) -> u16x8 { + let result = _mm_permutexvar_epi8(indices.into(), Bytes::to_bytes(a).val.0); + Bytes::from_bytes(u8x16 { + val: crate::support::Aligned128(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u16x8(self, a: u16x8, indices: u8x16) -> u16x8 { crate::kernel!( #[inline(always)] @@ -3406,6 +3476,20 @@ impl Simd for Avx512 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_i32x4(self, a: i32x4, indices: u8x16) -> i32x4 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: i32x4, indices: u8x16) -> i32x4 { + let result = _mm_permutexvar_epi8(indices.into(), Bytes::to_bytes(a).val.0); + Bytes::from_bytes(u8x16 { + val: crate::support::Aligned128(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i32x4(self, a: i32x4, indices: u8x16) -> i32x4 { crate::kernel!( #[inline(always)] @@ -3876,6 +3960,20 @@ impl Simd for Avx512 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_u32x4(self, a: u32x4, indices: u8x16) -> u32x4 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: u32x4, indices: u8x16) -> u32x4 { + let result = _mm_permutexvar_epi8(indices.into(), Bytes::to_bytes(a).val.0); + Bytes::from_bytes(u8x16 { + val: crate::support::Aligned128(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u32x4(self, a: u32x4, indices: u8x16) -> u32x4 { crate::kernel!( #[inline(always)] @@ -4439,6 +4537,20 @@ impl Simd for Avx512 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_f64x2(self, a: f64x2, indices: u8x16) -> f64x2 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: f64x2, indices: u8x16) -> f64x2 { + let result = _mm_permutexvar_epi8(indices.into(), Bytes::to_bytes(a).val.0); + Bytes::from_bytes(u8x16 { + val: crate::support::Aligned128(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_f64x2(self, a: f64x2, indices: u8x16) -> f64x2 { crate::kernel!( #[inline(always)] @@ -4944,6 +5056,20 @@ impl Simd for Avx512 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_i64x2(self, a: i64x2, indices: u8x16) -> i64x2 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: i64x2, indices: u8x16) -> i64x2 { + let result = _mm_permutexvar_epi8(indices.into(), Bytes::to_bytes(a).val.0); + Bytes::from_bytes(u8x16 { + val: crate::support::Aligned128(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i64x2(self, a: i64x2, indices: u8x16) -> i64x2 { crate::kernel!( #[inline(always)] @@ -5390,6 +5516,20 @@ impl Simd for Avx512 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_u64x2(self, a: u64x2, indices: u8x16) -> u64x2 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: u64x2, indices: u8x16) -> u64x2 { + let result = _mm_permutexvar_epi8(indices.into(), Bytes::to_bytes(a).val.0); + Bytes::from_bytes(u8x16 { + val: crate::support::Aligned128(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u64x2(self, a: u64x2, indices: u8x16) -> u64x2 { crate::kernel!( #[inline(always)] @@ -5989,6 +6129,20 @@ impl Simd for Avx512 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_f32x8(self, a: f32x8, indices: u8x32) -> f32x8 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: f32x8, indices: u8x32) -> f32x8 { + let result = _mm256_permutexvar_epi8(indices.into(), Bytes::to_bytes(a).val.0); + Bytes::from_bytes(u8x32 { + val: crate::support::Aligned256(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_f32x8(self, a: f32x8, indices: u8x32) -> f32x8 { crate::kernel!( #[inline(always)] @@ -6722,6 +6876,20 @@ impl Simd for Avx512 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_i8x32(self, a: i8x32, indices: u8x32) -> i8x32 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: i8x32, indices: u8x32) -> i8x32 { + let result = _mm256_permutexvar_epi8(indices.into(), Bytes::to_bytes(a).val.0); + Bytes::from_bytes(u8x32 { + val: crate::support::Aligned256(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i8x32(self, a: i8x32, indices: u8x32) -> i8x32 { crate::kernel!( #[inline(always)] @@ -7409,6 +7577,20 @@ impl Simd for Avx512 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_u8x32(self, a: u8x32, indices: u8x32) -> u8x32 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: u8x32, indices: u8x32) -> u8x32 { + let result = _mm256_permutexvar_epi8(indices.into(), Bytes::to_bytes(a).val.0); + Bytes::from_bytes(u8x32 { + val: crate::support::Aligned256(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u8x32(self, a: u8x32, indices: u8x32) -> u8x32 { crate::kernel!( #[inline(always)] @@ -8157,6 +8339,20 @@ impl Simd for Avx512 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_i16x16(self, a: i16x16, indices: u8x32) -> i16x16 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: i16x16, indices: u8x32) -> i16x16 { + let result = _mm256_permutexvar_epi8(indices.into(), Bytes::to_bytes(a).val.0); + Bytes::from_bytes(u8x32 { + val: crate::support::Aligned256(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i16x16(self, a: i16x16, indices: u8x32) -> i16x16 { crate::kernel!( #[inline(always)] @@ -8718,6 +8914,20 @@ impl Simd for Avx512 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_u16x16(self, a: u16x16, indices: u8x32) -> u16x16 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: u16x16, indices: u8x32) -> u16x16 { + let result = _mm256_permutexvar_epi8(indices.into(), Bytes::to_bytes(a).val.0); + Bytes::from_bytes(u8x32 { + val: crate::support::Aligned256(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u16x16(self, a: u16x16, indices: u8x32) -> u16x16 { crate::kernel!( #[inline(always)] @@ -9367,6 +9577,20 @@ impl Simd for Avx512 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_i32x8(self, a: i32x8, indices: u8x32) -> i32x8 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: i32x8, indices: u8x32) -> i32x8 { + let result = _mm256_permutexvar_epi8(indices.into(), Bytes::to_bytes(a).val.0); + Bytes::from_bytes(u8x32 { + val: crate::support::Aligned256(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i32x8(self, a: i32x8, indices: u8x32) -> i32x8 { crate::kernel!( #[inline(always)] @@ -9880,6 +10104,20 @@ impl Simd for Avx512 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_u32x8(self, a: u32x8, indices: u8x32) -> u32x8 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: u32x8, indices: u8x32) -> u32x8 { + let result = _mm256_permutexvar_epi8(indices.into(), Bytes::to_bytes(a).val.0); + Bytes::from_bytes(u8x32 { + val: crate::support::Aligned256(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u32x8(self, a: u32x8, indices: u8x32) -> u32x8 { crate::kernel!( #[inline(always)] @@ -10492,6 +10730,20 @@ impl Simd for Avx512 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_f64x4(self, a: f64x4, indices: u8x32) -> f64x4 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: f64x4, indices: u8x32) -> f64x4 { + let result = _mm256_permutexvar_epi8(indices.into(), Bytes::to_bytes(a).val.0); + Bytes::from_bytes(u8x32 { + val: crate::support::Aligned256(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_f64x4(self, a: f64x4, indices: u8x32) -> f64x4 { crate::kernel!( #[inline(always)] @@ -11038,6 +11290,20 @@ impl Simd for Avx512 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_i64x4(self, a: i64x4, indices: u8x32) -> i64x4 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: i64x4, indices: u8x32) -> i64x4 { + let result = _mm256_permutexvar_epi8(indices.into(), Bytes::to_bytes(a).val.0); + Bytes::from_bytes(u8x32 { + val: crate::support::Aligned256(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i64x4(self, a: i64x4, indices: u8x32) -> i64x4 { crate::kernel!( #[inline(always)] @@ -11509,6 +11775,20 @@ impl Simd for Avx512 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_u64x4(self, a: u64x4, indices: u8x32) -> u64x4 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: u64x4, indices: u8x32) -> u64x4 { + let result = _mm256_permutexvar_epi8(indices.into(), Bytes::to_bytes(a).val.0); + Bytes::from_bytes(u8x32 { + val: crate::support::Aligned256(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u64x4(self, a: u64x4, indices: u8x32) -> u64x4 { crate::kernel!( #[inline(always)] @@ -12147,6 +12427,20 @@ impl Simd for Avx512 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_f32x16(self, a: f32x16, indices: u8x64) -> f32x16 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: f32x16, indices: u8x64) -> f32x16 { + let result = _mm512_permutexvar_epi8(indices.into(), Bytes::to_bytes(a).val.0); + Bytes::from_bytes(u8x64 { + val: crate::support::Aligned512(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_f32x16(self, a: f32x16, indices: u8x64) -> f32x16 { crate::kernel!( #[inline(always)] @@ -13021,6 +13315,20 @@ impl Simd for Avx512 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_i8x64(self, a: i8x64, indices: u8x64) -> i8x64 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: i8x64, indices: u8x64) -> i8x64 { + let result = _mm512_permutexvar_epi8(indices.into(), Bytes::to_bytes(a).val.0); + Bytes::from_bytes(u8x64 { + val: crate::support::Aligned512(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i8x64(self, a: i8x64, indices: u8x64) -> i8x64 { crate::kernel!( #[inline(always)] @@ -13844,6 +14152,20 @@ impl Simd for Avx512 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_u8x64(self, a: u8x64, indices: u8x64) -> u8x64 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: u8x64, indices: u8x64) -> u8x64 { + let result = _mm512_permutexvar_epi8(indices.into(), Bytes::to_bytes(a).val.0); + Bytes::from_bytes(u8x64 { + val: crate::support::Aligned512(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u8x64(self, a: u8x64, indices: u8x64) -> u8x64 { crate::kernel!( #[inline(always)] @@ -14645,6 +14967,20 @@ impl Simd for Avx512 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_i16x32(self, a: i16x32, indices: u8x64) -> i16x32 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: i16x32, indices: u8x64) -> i16x32 { + let result = _mm512_permutexvar_epi8(indices.into(), Bytes::to_bytes(a).val.0); + Bytes::from_bytes(u8x64 { + val: crate::support::Aligned512(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i16x32(self, a: i16x32, indices: u8x64) -> i16x32 { crate::kernel!( #[inline(always)] @@ -15279,6 +15615,20 @@ impl Simd for Avx512 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_u16x32(self, a: u16x32, indices: u8x64) -> u16x32 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: u16x32, indices: u8x64) -> u16x32 { + let result = _mm512_permutexvar_epi8(indices.into(), Bytes::to_bytes(a).val.0); + Bytes::from_bytes(u8x64 { + val: crate::support::Aligned512(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u16x32(self, a: u16x32, indices: u8x64) -> u16x32 { crate::kernel!( #[inline(always)] @@ -15965,6 +16315,20 @@ impl Simd for Avx512 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_i32x16(self, a: i32x16, indices: u8x64) -> i32x16 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: i32x16, indices: u8x64) -> i32x16 { + let result = _mm512_permutexvar_epi8(indices.into(), Bytes::to_bytes(a).val.0); + Bytes::from_bytes(u8x64 { + val: crate::support::Aligned512(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i32x16(self, a: i32x16, indices: u8x64) -> i32x16 { crate::kernel!( #[inline(always)] @@ -16527,6 +16891,20 @@ impl Simd for Avx512 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_u32x16(self, a: u32x16, indices: u8x64) -> u32x16 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: u32x16, indices: u8x64) -> u32x16 { + let result = _mm512_permutexvar_epi8(indices.into(), Bytes::to_bytes(a).val.0); + Bytes::from_bytes(u8x64 { + val: crate::support::Aligned512(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u32x16(self, a: u32x16, indices: u8x64) -> u32x16 { crate::kernel!( #[inline(always)] @@ -17159,6 +17537,20 @@ impl Simd for Avx512 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_f64x8(self, a: f64x8, indices: u8x64) -> f64x8 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: f64x8, indices: u8x64) -> f64x8 { + let result = _mm512_permutexvar_epi8(indices.into(), Bytes::to_bytes(a).val.0); + Bytes::from_bytes(u8x64 { + val: crate::support::Aligned512(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_f64x8(self, a: f64x8, indices: u8x64) -> f64x8 { crate::kernel!( #[inline(always)] @@ -17732,6 +18124,20 @@ impl Simd for Avx512 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_i64x8(self, a: i64x8, indices: u8x64) -> i64x8 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: i64x8, indices: u8x64) -> i64x8 { + let result = _mm512_permutexvar_epi8(indices.into(), Bytes::to_bytes(a).val.0); + Bytes::from_bytes(u8x64 { + val: crate::support::Aligned512(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i64x8(self, a: i64x8, indices: u8x64) -> i64x8 { crate::kernel!( #[inline(always)] @@ -18226,6 +18632,20 @@ impl Simd for Avx512 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_u64x8(self, a: u64x8, indices: u8x64) -> u64x8 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Avx512, a: u64x8, indices: u8x64) -> u64x8 { + let result = _mm512_permutexvar_epi8(indices.into(), Bytes::to_bytes(a).val.0); + Bytes::from_bytes(u8x64 { + val: crate::support::Aligned512(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u64x8(self, a: u64x8, indices: u8x64) -> u64x8 { crate::kernel!( #[inline(always)] diff --git a/fearless_simd/src/generated/fallback.rs b/fearless_simd/src/generated/fallback.rs index a8fcaba6..04814141 100644 --- a/fearless_simd/src/generated/fallback.rs +++ b/fearless_simd/src/generated/fallback.rs @@ -308,6 +308,17 @@ impl Simd for Fallback { Bytes::from_bytes(result) } #[inline(always)] + fn swizzle_dyn_f32x4(self, a: f32x4, indices: u8x16) -> f32x4 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 16usize]; + for lane in 0..16usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 16usize]; + } + let result: u8x16 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_f32x4(self, a: f32x4, indices: u8x16) -> f32x4 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 16usize]; @@ -874,6 +885,17 @@ impl Simd for Fallback { Bytes::from_bytes(result) } #[inline(always)] + fn swizzle_dyn_i8x16(self, a: i8x16, indices: u8x16) -> i8x16 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 16usize]; + for lane in 0..16usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 16usize]; + } + let result: u8x16 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_i8x16(self, a: i8x16, indices: u8x16) -> i8x16 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 16usize]; @@ -1785,6 +1807,17 @@ impl Simd for Fallback { Bytes::from_bytes(result) } #[inline(always)] + fn swizzle_dyn_u8x16(self, a: u8x16, indices: u8x16) -> u8x16 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 16usize]; + for lane in 0..16usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 16usize]; + } + let result: u8x16 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_u8x16(self, a: u8x16, indices: u8x16) -> u8x16 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 16usize]; @@ -2999,6 +3032,17 @@ impl Simd for Fallback { Bytes::from_bytes(result) } #[inline(always)] + fn swizzle_dyn_i16x8(self, a: i16x8, indices: u8x16) -> i16x8 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 16usize]; + for lane in 0..16usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 16usize]; + } + let result: u8x16 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_i16x8(self, a: i16x8, indices: u8x16) -> i16x8 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 16usize]; @@ -3615,6 +3659,17 @@ impl Simd for Fallback { Bytes::from_bytes(result) } #[inline(always)] + fn swizzle_dyn_u16x8(self, a: u16x8, indices: u8x16) -> u16x8 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 16usize]; + for lane in 0..16usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 16usize]; + } + let result: u8x16 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_u16x8(self, a: u16x8, indices: u8x16) -> u16x8 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 16usize]; @@ -4416,6 +4471,17 @@ impl Simd for Fallback { Bytes::from_bytes(result) } #[inline(always)] + fn swizzle_dyn_i32x4(self, a: i32x4, indices: u8x16) -> i32x4 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 16usize]; + for lane in 0..16usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 16usize]; + } + let result: u8x16 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_i32x4(self, a: i32x4, indices: u8x16) -> i32x4 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 16usize]; @@ -4862,6 +4928,17 @@ impl Simd for Fallback { Bytes::from_bytes(result) } #[inline(always)] + fn swizzle_dyn_u32x4(self, a: u32x4, indices: u8x16) -> u32x4 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 16usize]; + for lane in 0..16usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 16usize]; + } + let result: u8x16 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_u32x4(self, a: u32x4, indices: u8x16) -> u32x4 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 16usize]; @@ -5433,6 +5510,17 @@ impl Simd for Fallback { Bytes::from_bytes(result) } #[inline(always)] + fn swizzle_dyn_f64x2(self, a: f64x2, indices: u8x16) -> f64x2 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 16usize]; + for lane in 0..16usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 16usize]; + } + let result: u8x16 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_f64x2(self, a: f64x2, indices: u8x16) -> f64x2 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 16usize]; @@ -5813,6 +5901,17 @@ impl Simd for Fallback { Bytes::from_bytes(result) } #[inline(always)] + fn swizzle_dyn_i64x2(self, a: i64x2, indices: u8x16) -> i64x2 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 16usize]; + for lane in 0..16usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 16usize]; + } + let result: u8x16 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_i64x2(self, a: i64x2, indices: u8x16) -> i64x2 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 16usize]; @@ -6177,6 +6276,17 @@ impl Simd for Fallback { Bytes::from_bytes(result) } #[inline(always)] + fn swizzle_dyn_u64x2(self, a: u64x2, indices: u8x16) -> u64x2 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 16usize]; + for lane in 0..16usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 16usize]; + } + let result: u8x16 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_u64x2(self, a: u64x2, indices: u8x16) -> u64x2 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 16usize]; @@ -6621,6 +6731,17 @@ impl Simd for Fallback { ) } #[inline(always)] + fn swizzle_dyn_f32x8(self, a: f32x8, indices: u8x32) -> f32x8 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 32usize]; + for lane in 0..32usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 32usize]; + } + let result: u8x32 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_f32x8(self, a: f32x8, indices: u8x32) -> f32x8 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 32usize]; @@ -7090,6 +7211,17 @@ impl Simd for Fallback { ) } #[inline(always)] + fn swizzle_dyn_i8x32(self, a: i8x32, indices: u8x32) -> i8x32 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 32usize]; + for lane in 0..32usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 32usize]; + } + let result: u8x32 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_i8x32(self, a: i8x32, indices: u8x32) -> i8x32 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 32usize]; @@ -7482,6 +7614,17 @@ impl Simd for Fallback { ) } #[inline(always)] + fn swizzle_dyn_u8x32(self, a: u8x32, indices: u8x32) -> u8x32 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 32usize]; + for lane in 0..32usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 32usize]; + } + let result: u8x32 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_u8x32(self, a: u8x32, indices: u8x32) -> u8x32 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 32usize]; @@ -7922,6 +8065,17 @@ impl Simd for Fallback { ) } #[inline(always)] + fn swizzle_dyn_i16x16(self, a: i16x16, indices: u8x32) -> i16x16 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 32usize]; + for lane in 0..32usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 32usize]; + } + let result: u8x32 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_i16x16(self, a: i16x16, indices: u8x32) -> i16x16 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 32usize]; @@ -8254,6 +8408,17 @@ impl Simd for Fallback { ) } #[inline(always)] + fn swizzle_dyn_u16x16(self, a: u16x16, indices: u8x32) -> u16x16 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 32usize]; + for lane in 0..32usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 32usize]; + } + let result: u8x32 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_u16x16(self, a: u16x16, indices: u8x32) -> u16x16 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 32usize]; @@ -8675,6 +8840,17 @@ impl Simd for Fallback { ) } #[inline(always)] + fn swizzle_dyn_i32x8(self, a: i32x8, indices: u8x32) -> i32x8 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 32usize]; + for lane in 0..32usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 32usize]; + } + let result: u8x32 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_i32x8(self, a: i32x8, indices: u8x32) -> i32x8 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 32usize]; @@ -8976,6 +9152,17 @@ impl Simd for Fallback { ) } #[inline(always)] + fn swizzle_dyn_u32x8(self, a: u32x8, indices: u8x32) -> u32x8 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 32usize]; + for lane in 0..32usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 32usize]; + } + let result: u8x32 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_u32x8(self, a: u32x8, indices: u8x32) -> u32x8 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 32usize]; @@ -9364,6 +9551,17 @@ impl Simd for Fallback { ) } #[inline(always)] + fn swizzle_dyn_f64x4(self, a: f64x4, indices: u8x32) -> f64x4 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 32usize]; + for lane in 0..32usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 32usize]; + } + let result: u8x32 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_f64x4(self, a: f64x4, indices: u8x32) -> f64x4 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 32usize]; @@ -9695,6 +9893,17 @@ impl Simd for Fallback { ) } #[inline(always)] + fn swizzle_dyn_i64x4(self, a: i64x4, indices: u8x32) -> i64x4 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 32usize]; + for lane in 0..32usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 32usize]; + } + let result: u8x32 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_i64x4(self, a: i64x4, indices: u8x32) -> i64x4 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 32usize]; @@ -9975,6 +10184,17 @@ impl Simd for Fallback { ) } #[inline(always)] + fn swizzle_dyn_u64x4(self, a: u64x4, indices: u8x32) -> u64x4 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 32usize]; + for lane in 0..32usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 32usize]; + } + let result: u8x32 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_u64x4(self, a: u64x4, indices: u8x32) -> u64x4 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 32usize]; @@ -10410,6 +10630,17 @@ impl Simd for Fallback { ) } #[inline(always)] + fn swizzle_dyn_f32x16(self, a: f32x16, indices: u8x64) -> f32x16 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 64usize]; + for lane in 0..64usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 64usize]; + } + let result: u8x64 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_f32x16(self, a: f32x16, indices: u8x64) -> f32x16 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -11000,6 +11231,17 @@ impl Simd for Fallback { ) } #[inline(always)] + fn swizzle_dyn_i8x64(self, a: i8x64, indices: u8x64) -> i8x64 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 64usize]; + for lane in 0..64usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 64usize]; + } + let result: u8x64 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_i8x64(self, a: i8x64, indices: u8x64) -> i8x64 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -11513,6 +11755,17 @@ impl Simd for Fallback { ) } #[inline(always)] + fn swizzle_dyn_u8x64(self, a: u8x64, indices: u8x64) -> u8x64 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 64usize]; + for lane in 0..64usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 64usize]; + } + let result: u8x64 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_u8x64(self, a: u8x64, indices: u8x64) -> u8x64 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -11998,6 +12251,17 @@ impl Simd for Fallback { ) } #[inline(always)] + fn swizzle_dyn_i16x32(self, a: i16x32, indices: u8x64) -> i16x32 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 64usize]; + for lane in 0..64usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 64usize]; + } + let result: u8x64 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_i16x32(self, a: i16x32, indices: u8x64) -> i16x32 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -12393,6 +12657,17 @@ impl Simd for Fallback { ) } #[inline(always)] + fn swizzle_dyn_u16x32(self, a: u16x32, indices: u8x64) -> u16x32 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 64usize]; + for lane in 0..64usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 64usize]; + } + let result: u8x64 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_u16x32(self, a: u16x32, indices: u8x64) -> u16x32 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -12828,6 +13103,17 @@ impl Simd for Fallback { ) } #[inline(always)] + fn swizzle_dyn_i32x16(self, a: i32x16, indices: u8x64) -> i32x16 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 64usize]; + for lane in 0..64usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 64usize]; + } + let result: u8x64 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_i32x16(self, a: i32x16, indices: u8x64) -> i32x16 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -13158,6 +13444,17 @@ impl Simd for Fallback { ) } #[inline(always)] + fn swizzle_dyn_u32x16(self, a: u32x16, indices: u8x64) -> u32x16 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 64usize]; + for lane in 0..64usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 64usize]; + } + let result: u8x64 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_u32x16(self, a: u32x16, indices: u8x64) -> u32x16 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -13548,6 +13845,17 @@ impl Simd for Fallback { ) } #[inline(always)] + fn swizzle_dyn_f64x8(self, a: f64x8, indices: u8x64) -> f64x8 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 64usize]; + for lane in 0..64usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 64usize]; + } + let result: u8x64 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_f64x8(self, a: f64x8, indices: u8x64) -> f64x8 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -13888,6 +14196,17 @@ impl Simd for Fallback { ) } #[inline(always)] + fn swizzle_dyn_i64x8(self, a: i64x8, indices: u8x64) -> i64x8 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 64usize]; + for lane in 0..64usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 64usize]; + } + let result: u8x64 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_i64x8(self, a: i64x8, indices: u8x64) -> i64x8 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -14177,6 +14496,17 @@ impl Simd for Fallback { ) } #[inline(always)] + fn swizzle_dyn_u64x8(self, a: u64x8, indices: u8x64) -> u64x8 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 64usize]; + for lane in 0..64usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 64usize]; + } + let result: u8x64 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_u64x8(self, a: u64x8, indices: u8x64) -> u64x8 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; diff --git a/fearless_simd/src/generated/neon.rs b/fearless_simd/src/generated/neon.rs index 54207fdc..d0fac457 100644 --- a/fearless_simd/src/generated/neon.rs +++ b/fearless_simd/src/generated/neon.rs @@ -205,6 +205,10 @@ impl Simd for Neon { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_f32x4(self, a: f32x4, indices: u8x16) -> f32x4 { + self.swizzle_dyn_precise_f32x4(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_f32x4(self, a: f32x4, indices: u8x16) -> f32x4 { crate::kernel!( #[inline(always)] @@ -750,6 +754,10 @@ impl Simd for Neon { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_i8x16(self, a: i8x16, indices: u8x16) -> i8x16 { + self.swizzle_dyn_precise_i8x16(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i8x16(self, a: i8x16, indices: u8x16) -> i8x16 { crate::kernel!( #[inline(always)] @@ -1204,6 +1212,10 @@ impl Simd for Neon { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_u8x16(self, a: u8x16, indices: u8x16) -> u8x16 { + self.swizzle_dyn_precise_u8x16(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u8x16(self, a: u8x16, indices: u8x16) -> u8x16 { crate::kernel!( #[inline(always)] @@ -1804,6 +1816,10 @@ impl Simd for Neon { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_i16x8(self, a: i16x8, indices: u8x16) -> i16x8 { + self.swizzle_dyn_precise_i16x8(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i16x8(self, a: i16x8, indices: u8x16) -> i16x8 { crate::kernel!( #[inline(always)] @@ -2226,6 +2242,10 @@ impl Simd for Neon { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_u16x8(self, a: u16x8, indices: u8x16) -> u16x8 { + self.swizzle_dyn_precise_u16x8(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u16x8(self, a: u16x8, indices: u8x16) -> u16x8 { crate::kernel!( #[inline(always)] @@ -2790,6 +2810,10 @@ impl Simd for Neon { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_i32x4(self, a: i32x4, indices: u8x16) -> i32x4 { + self.swizzle_dyn_precise_i32x4(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i32x4(self, a: i32x4, indices: u8x16) -> i32x4 { crate::kernel!( #[inline(always)] @@ -3206,6 +3230,10 @@ impl Simd for Neon { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_u32x4(self, a: u32x4, indices: u8x16) -> u32x4 { + self.swizzle_dyn_precise_u32x4(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u32x4(self, a: u32x4, indices: u8x16) -> u32x4 { crate::kernel!( #[inline(always)] @@ -3771,6 +3799,10 @@ impl Simd for Neon { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_f64x2(self, a: f64x2, indices: u8x16) -> f64x2 { + self.swizzle_dyn_precise_f64x2(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_f64x2(self, a: f64x2, indices: u8x16) -> f64x2 { crate::kernel!( #[inline(always)] @@ -4232,6 +4264,10 @@ impl Simd for Neon { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_i64x2(self, a: i64x2, indices: u8x16) -> i64x2 { + self.swizzle_dyn_precise_i64x2(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i64x2(self, a: i64x2, indices: u8x16) -> i64x2 { crate::kernel!( #[inline(always)] @@ -4624,6 +4660,10 @@ impl Simd for Neon { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_u64x2(self, a: u64x2, indices: u8x16) -> u64x2 { + self.swizzle_dyn_precise_u64x2(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u64x2(self, a: u64x2, indices: u8x16) -> u64x2 { crate::kernel!( #[inline(always)] @@ -5212,6 +5252,10 @@ impl Simd for Neon { ) } #[inline(always)] + fn swizzle_dyn_f32x8(self, a: f32x8, indices: u8x32) -> f32x8 { + self.swizzle_dyn_precise_f32x8(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_f32x8(self, a: f32x8, indices: u8x32) -> f32x8 { crate::kernel!( #[inline(always)] @@ -5723,6 +5767,10 @@ impl Simd for Neon { ) } #[inline(always)] + fn swizzle_dyn_i8x32(self, a: i8x32, indices: u8x32) -> i8x32 { + self.swizzle_dyn_precise_i8x32(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i8x32(self, a: i8x32, indices: u8x32) -> i8x32 { crate::kernel!( #[inline(always)] @@ -6157,6 +6205,10 @@ impl Simd for Neon { ) } #[inline(always)] + fn swizzle_dyn_u8x32(self, a: u8x32, indices: u8x32) -> u8x32 { + self.swizzle_dyn_precise_u8x32(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u8x32(self, a: u8x32, indices: u8x32) -> u8x32 { crate::kernel!( #[inline(always)] @@ -6646,6 +6698,10 @@ impl Simd for Neon { ) } #[inline(always)] + fn swizzle_dyn_i16x16(self, a: i16x16, indices: u8x32) -> i16x16 { + self.swizzle_dyn_precise_i16x16(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i16x16(self, a: i16x16, indices: u8x32) -> i16x16 { crate::kernel!( #[inline(always)] @@ -7020,6 +7076,10 @@ impl Simd for Neon { ) } #[inline(always)] + fn swizzle_dyn_u16x16(self, a: u16x16, indices: u8x32) -> u16x16 { + self.swizzle_dyn_precise_u16x16(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u16x16(self, a: u16x16, indices: u8x32) -> u16x16 { crate::kernel!( #[inline(always)] @@ -7481,6 +7541,10 @@ impl Simd for Neon { ) } #[inline(always)] + fn swizzle_dyn_i32x8(self, a: i32x8, indices: u8x32) -> i32x8 { + self.swizzle_dyn_precise_i32x8(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i32x8(self, a: i32x8, indices: u8x32) -> i32x8 { crate::kernel!( #[inline(always)] @@ -7824,6 +7888,10 @@ impl Simd for Neon { ) } #[inline(always)] + fn swizzle_dyn_u32x8(self, a: u32x8, indices: u8x32) -> u32x8 { + self.swizzle_dyn_precise_u32x8(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u32x8(self, a: u32x8, indices: u8x32) -> u32x8 { crate::kernel!( #[inline(always)] @@ -8261,6 +8329,10 @@ impl Simd for Neon { ) } #[inline(always)] + fn swizzle_dyn_f64x4(self, a: f64x4, indices: u8x32) -> f64x4 { + self.swizzle_dyn_precise_f64x4(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_f64x4(self, a: f64x4, indices: u8x32) -> f64x4 { crate::kernel!( #[inline(always)] @@ -8634,6 +8706,10 @@ impl Simd for Neon { ) } #[inline(always)] + fn swizzle_dyn_i64x4(self, a: i64x4, indices: u8x32) -> i64x4 { + self.swizzle_dyn_precise_i64x4(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i64x4(self, a: i64x4, indices: u8x32) -> i64x4 { crate::kernel!( #[inline(always)] @@ -8956,6 +9032,10 @@ impl Simd for Neon { ) } #[inline(always)] + fn swizzle_dyn_u64x4(self, a: u64x4, indices: u8x32) -> u64x4 { + self.swizzle_dyn_precise_u64x4(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u64x4(self, a: u64x4, indices: u8x32) -> u64x4 { crate::kernel!( #[inline(always)] @@ -9458,6 +9538,10 @@ impl Simd for Neon { ) } #[inline(always)] + fn swizzle_dyn_f32x16(self, a: f32x16, indices: u8x64) -> f32x16 { + self.swizzle_dyn_precise_f32x16(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_f32x16(self, a: f32x16, indices: u8x64) -> f32x16 { crate::kernel!( #[inline(always)] @@ -10110,6 +10194,10 @@ impl Simd for Neon { ) } #[inline(always)] + fn swizzle_dyn_i8x64(self, a: i8x64, indices: u8x64) -> i8x64 { + self.swizzle_dyn_precise_i8x64(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i8x64(self, a: i8x64, indices: u8x64) -> i8x64 { crate::kernel!( #[inline(always)] @@ -10685,6 +10773,10 @@ impl Simd for Neon { ) } #[inline(always)] + fn swizzle_dyn_u8x64(self, a: u8x64, indices: u8x64) -> u8x64 { + self.swizzle_dyn_precise_u8x64(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u8x64(self, a: u8x64, indices: u8x64) -> u8x64 { crate::kernel!( #[inline(always)] @@ -11237,6 +11329,10 @@ impl Simd for Neon { ) } #[inline(always)] + fn swizzle_dyn_i16x32(self, a: i16x32, indices: u8x64) -> i16x32 { + self.swizzle_dyn_precise_i16x32(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i16x32(self, a: i16x32, indices: u8x64) -> i16x32 { crate::kernel!( #[inline(always)] @@ -11694,6 +11790,10 @@ impl Simd for Neon { ) } #[inline(always)] + fn swizzle_dyn_u16x32(self, a: u16x32, indices: u8x64) -> u16x32 { + self.swizzle_dyn_precise_u16x32(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u16x32(self, a: u16x32, indices: u8x64) -> u16x32 { crate::kernel!( #[inline(always)] @@ -12196,6 +12296,10 @@ impl Simd for Neon { ) } #[inline(always)] + fn swizzle_dyn_i32x16(self, a: i32x16, indices: u8x64) -> i32x16 { + self.swizzle_dyn_precise_i32x16(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i32x16(self, a: i32x16, indices: u8x64) -> i32x16 { crate::kernel!( #[inline(always)] @@ -12588,6 +12692,10 @@ impl Simd for Neon { ) } #[inline(always)] + fn swizzle_dyn_u32x16(self, a: u32x16, indices: u8x64) -> u32x16 { + self.swizzle_dyn_precise_u32x16(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u32x16(self, a: u32x16, indices: u8x64) -> u32x16 { crate::kernel!( #[inline(always)] @@ -13045,6 +13153,10 @@ impl Simd for Neon { ) } #[inline(always)] + fn swizzle_dyn_f64x8(self, a: f64x8, indices: u8x64) -> f64x8 { + self.swizzle_dyn_precise_f64x8(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_f64x8(self, a: f64x8, indices: u8x64) -> f64x8 { crate::kernel!( #[inline(always)] @@ -13447,6 +13559,10 @@ impl Simd for Neon { ) } #[inline(always)] + fn swizzle_dyn_i64x8(self, a: i64x8, indices: u8x64) -> i64x8 { + self.swizzle_dyn_precise_i64x8(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i64x8(self, a: i64x8, indices: u8x64) -> i64x8 { crate::kernel!( #[inline(always)] @@ -13798,6 +13914,10 @@ impl Simd for Neon { ) } #[inline(always)] + fn swizzle_dyn_u64x8(self, a: u64x8, indices: u8x64) -> u64x8 { + self.swizzle_dyn_precise_u64x8(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u64x8(self, a: u64x8, indices: u8x64) -> u64x8 { crate::kernel!( #[inline(always)] diff --git a/fearless_simd/src/generated/simd_trait.rs b/fearless_simd/src/generated/simd_trait.rs index 78d08131..f8670185 100644 --- a/fearless_simd/src/generated/simd_trait.rs +++ b/fearless_simd/src/generated/simd_trait.rs @@ -190,7 +190,9 @@ pub trait Simd: ) -> f32x4; #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."] fn swizzle_dyn_within_blocks_f32x4(self, a: f32x4, indices: u8x16) -> f32x4; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn_f32x4(self, a: f32x4, indices: u8x16) -> f32x4; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise_f32x4(self, a: f32x4, indices: u8x16) -> f32x4; #[doc = "Compute the absolute value of each element."] fn abs_f32x4(self, a: f32x4) -> f32x4; @@ -304,7 +306,9 @@ pub trait Simd: ) -> i8x16; #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."] fn swizzle_dyn_within_blocks_i8x16(self, a: i8x16, indices: u8x16) -> i8x16; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn_i8x16(self, a: i8x16, indices: u8x16) -> i8x16; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise_i8x16(self, a: i8x16, indices: u8x16) -> i8x16; #[doc = "Add two vectors element-wise, wrapping on overflow."] fn add_i8x16(self, a: i8x16, b: i8x16) -> i8x16; @@ -398,7 +402,9 @@ pub trait Simd: ) -> u8x16; #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."] fn swizzle_dyn_within_blocks_u8x16(self, a: u8x16, indices: u8x16) -> u8x16; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn_u8x16(self, a: u8x16, indices: u8x16) -> u8x16; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise_u8x16(self, a: u8x16, indices: u8x16) -> u8x16; #[doc = "Add two vectors element-wise, wrapping on overflow."] fn add_u8x16(self, a: u8x16, b: u8x16) -> u8x16; @@ -527,7 +533,9 @@ pub trait Simd: ) -> i16x8; #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."] fn swizzle_dyn_within_blocks_i16x8(self, a: i16x8, indices: u8x16) -> i16x8; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn_i16x8(self, a: i16x8, indices: u8x16) -> i16x8; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise_i16x8(self, a: i16x8, indices: u8x16) -> i16x8; #[doc = "Add two vectors element-wise, wrapping on overflow."] fn add_i16x8(self, a: i16x8, b: i16x8) -> i16x8; @@ -621,7 +629,9 @@ pub trait Simd: ) -> u16x8; #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."] fn swizzle_dyn_within_blocks_u16x8(self, a: u16x8, indices: u8x16) -> u16x8; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn_u16x8(self, a: u16x8, indices: u8x16) -> u16x8; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise_u16x8(self, a: u16x8, indices: u8x16) -> u16x8; #[doc = "Add two vectors element-wise, wrapping on overflow."] fn add_u16x8(self, a: u16x8, b: u16x8) -> u16x8; @@ -748,7 +758,9 @@ pub trait Simd: ) -> i32x4; #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."] fn swizzle_dyn_within_blocks_i32x4(self, a: i32x4, indices: u8x16) -> i32x4; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn_i32x4(self, a: i32x4, indices: u8x16) -> i32x4; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise_i32x4(self, a: i32x4, indices: u8x16) -> i32x4; #[doc = "Add two vectors element-wise, wrapping on overflow."] fn add_i32x4(self, a: i32x4, b: i32x4) -> i32x4; @@ -844,7 +856,9 @@ pub trait Simd: ) -> u32x4; #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."] fn swizzle_dyn_within_blocks_u32x4(self, a: u32x4, indices: u8x16) -> u32x4; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn_u32x4(self, a: u32x4, indices: u8x16) -> u32x4; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise_u32x4(self, a: u32x4, indices: u8x16) -> u32x4; #[doc = "Add two vectors element-wise, wrapping on overflow."] fn add_u32x4(self, a: u32x4, b: u32x4) -> u32x4; @@ -973,7 +987,9 @@ pub trait Simd: ) -> f64x2; #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."] fn swizzle_dyn_within_blocks_f64x2(self, a: f64x2, indices: u8x16) -> f64x2; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn_f64x2(self, a: f64x2, indices: u8x16) -> f64x2; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise_f64x2(self, a: f64x2, indices: u8x16) -> f64x2; #[doc = "Compute the absolute value of each element."] fn abs_f64x2(self, a: f64x2) -> f64x2; @@ -1079,7 +1095,9 @@ pub trait Simd: ) -> i64x2; #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."] fn swizzle_dyn_within_blocks_i64x2(self, a: i64x2, indices: u8x16) -> i64x2; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn_i64x2(self, a: i64x2, indices: u8x16) -> i64x2; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise_i64x2(self, a: i64x2, indices: u8x16) -> i64x2; #[doc = "Add two vectors element-wise, wrapping on overflow."] fn add_i64x2(self, a: i64x2, b: i64x2) -> i64x2; @@ -1173,7 +1191,9 @@ pub trait Simd: ) -> u64x2; #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."] fn swizzle_dyn_within_blocks_u64x2(self, a: u64x2, indices: u8x16) -> u64x2; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn_u64x2(self, a: u64x2, indices: u8x16) -> u64x2; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise_u64x2(self, a: u64x2, indices: u8x16) -> u64x2; #[doc = "Add two vectors element-wise, wrapping on overflow."] fn add_u64x2(self, a: u64x2, b: u64x2) -> u64x2; @@ -1300,7 +1320,9 @@ pub trait Simd: ) -> f32x8; #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."] fn swizzle_dyn_within_blocks_f32x8(self, a: f32x8, indices: u8x32) -> f32x8; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn_f32x8(self, a: f32x8, indices: u8x32) -> f32x8; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise_f32x8(self, a: f32x8, indices: u8x32) -> f32x8; #[doc = "Compute the absolute value of each element."] fn abs_f32x8(self, a: f32x8) -> f32x8; @@ -1406,7 +1428,9 @@ pub trait Simd: ) -> i8x32; #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."] fn swizzle_dyn_within_blocks_i8x32(self, a: i8x32, indices: u8x32) -> i8x32; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn_i8x32(self, a: i8x32, indices: u8x32) -> i8x32; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise_i8x32(self, a: i8x32, indices: u8x32) -> i8x32; #[doc = "Add two vectors element-wise, wrapping on overflow."] fn add_i8x32(self, a: i8x32, b: i8x32) -> i8x32; @@ -1492,7 +1516,9 @@ pub trait Simd: ) -> u8x32; #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."] fn swizzle_dyn_within_blocks_u8x32(self, a: u8x32, indices: u8x32) -> u8x32; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn_u8x32(self, a: u8x32, indices: u8x32) -> u8x32; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise_u8x32(self, a: u8x32, indices: u8x32) -> u8x32; #[doc = "Add two vectors element-wise, wrapping on overflow."] fn add_u8x32(self, a: u8x32, b: u8x32) -> u8x32; @@ -1619,7 +1645,9 @@ pub trait Simd: a: i16x16, indices: u8x32, ) -> i16x16; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn_i16x16(self, a: i16x16, indices: u8x32) -> i16x16; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise_i16x16(self, a: i16x16, indices: u8x32) -> i16x16; #[doc = "Add two vectors element-wise, wrapping on overflow."] fn add_i16x16(self, a: i16x16, b: i16x16) -> i16x16; @@ -1709,7 +1737,9 @@ pub trait Simd: a: u16x16, indices: u8x32, ) -> u16x16; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn_u16x16(self, a: u16x16, indices: u8x32) -> u16x16; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise_u16x16(self, a: u16x16, indices: u8x32) -> u16x16; #[doc = "Add two vectors element-wise, wrapping on overflow."] fn add_u16x16(self, a: u16x16, b: u16x16) -> u16x16; @@ -1832,7 +1862,9 @@ pub trait Simd: ) -> i32x8; #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."] fn swizzle_dyn_within_blocks_i32x8(self, a: i32x8, indices: u8x32) -> i32x8; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn_i32x8(self, a: i32x8, indices: u8x32) -> i32x8; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise_i32x8(self, a: i32x8, indices: u8x32) -> i32x8; #[doc = "Add two vectors element-wise, wrapping on overflow."] fn add_i32x8(self, a: i32x8, b: i32x8) -> i32x8; @@ -1920,7 +1952,9 @@ pub trait Simd: ) -> u32x8; #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."] fn swizzle_dyn_within_blocks_u32x8(self, a: u32x8, indices: u8x32) -> u32x8; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn_u32x8(self, a: u32x8, indices: u8x32) -> u32x8; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise_u32x8(self, a: u32x8, indices: u8x32) -> u32x8; #[doc = "Add two vectors element-wise, wrapping on overflow."] fn add_u32x8(self, a: u32x8, b: u32x8) -> u32x8; @@ -2043,7 +2077,9 @@ pub trait Simd: ) -> f64x4; #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."] fn swizzle_dyn_within_blocks_f64x4(self, a: f64x4, indices: u8x32) -> f64x4; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn_f64x4(self, a: f64x4, indices: u8x32) -> f64x4; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise_f64x4(self, a: f64x4, indices: u8x32) -> f64x4; #[doc = "Compute the absolute value of each element."] fn abs_f64x4(self, a: f64x4) -> f64x4; @@ -2141,7 +2177,9 @@ pub trait Simd: ) -> i64x4; #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."] fn swizzle_dyn_within_blocks_i64x4(self, a: i64x4, indices: u8x32) -> i64x4; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn_i64x4(self, a: i64x4, indices: u8x32) -> i64x4; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise_i64x4(self, a: i64x4, indices: u8x32) -> i64x4; #[doc = "Add two vectors element-wise, wrapping on overflow."] fn add_i64x4(self, a: i64x4, b: i64x4) -> i64x4; @@ -2227,7 +2265,9 @@ pub trait Simd: ) -> u64x4; #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."] fn swizzle_dyn_within_blocks_u64x4(self, a: u64x4, indices: u8x32) -> u64x4; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn_u64x4(self, a: u64x4, indices: u8x32) -> u64x4; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise_u64x4(self, a: u64x4, indices: u8x32) -> u64x4; #[doc = "Add two vectors element-wise, wrapping on overflow."] fn add_u64x4(self, a: u64x4, b: u64x4) -> u64x4; @@ -2352,7 +2392,9 @@ pub trait Simd: a: f32x16, indices: u8x64, ) -> f32x16; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn_f32x16(self, a: f32x16, indices: u8x64) -> f32x16; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise_f32x16(self, a: f32x16, indices: u8x64) -> f32x16; #[doc = "Compute the absolute value of each element."] fn abs_f32x16(self, a: f32x16) -> f32x16; @@ -2456,7 +2498,9 @@ pub trait Simd: ) -> i8x64; #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."] fn swizzle_dyn_within_blocks_i8x64(self, a: i8x64, indices: u8x64) -> i8x64; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn_i8x64(self, a: i8x64, indices: u8x64) -> i8x64; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise_i8x64(self, a: i8x64, indices: u8x64) -> i8x64; #[doc = "Add two vectors element-wise, wrapping on overflow."] fn add_i8x64(self, a: i8x64, b: i8x64) -> i8x64; @@ -2540,7 +2584,9 @@ pub trait Simd: ) -> u8x64; #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."] fn swizzle_dyn_within_blocks_u8x64(self, a: u8x64, indices: u8x64) -> u8x64; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn_u8x64(self, a: u8x64, indices: u8x64) -> u8x64; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise_u8x64(self, a: u8x64, indices: u8x64) -> u8x64; #[doc = "Add two vectors element-wise, wrapping on overflow."] fn add_u8x64(self, a: u8x64, b: u8x64) -> u8x64; @@ -2661,7 +2707,9 @@ pub trait Simd: a: i16x32, indices: u8x64, ) -> i16x32; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn_i16x32(self, a: i16x32, indices: u8x64) -> i16x32; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise_i16x32(self, a: i16x32, indices: u8x64) -> i16x32; #[doc = "Add two vectors element-wise, wrapping on overflow."] fn add_i16x32(self, a: i16x32, b: i16x32) -> i16x32; @@ -2749,7 +2797,9 @@ pub trait Simd: a: u16x32, indices: u8x64, ) -> u16x32; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn_u16x32(self, a: u16x32, indices: u8x64) -> u16x32; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise_u16x32(self, a: u16x32, indices: u8x64) -> u16x32; #[doc = "Add two vectors element-wise, wrapping on overflow."] fn add_u16x32(self, a: u16x32, b: u16x32) -> u16x32; @@ -2872,7 +2922,9 @@ pub trait Simd: a: i32x16, indices: u8x64, ) -> i32x16; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn_i32x16(self, a: i32x16, indices: u8x64) -> i32x16; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise_i32x16(self, a: i32x16, indices: u8x64) -> i32x16; #[doc = "Add two vectors element-wise, wrapping on overflow."] fn add_i32x16(self, a: i32x16, b: i32x16) -> i32x16; @@ -2962,7 +3014,9 @@ pub trait Simd: a: u32x16, indices: u8x64, ) -> u32x16; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn_u32x16(self, a: u32x16, indices: u8x64) -> u32x16; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise_u32x16(self, a: u32x16, indices: u8x64) -> u32x16; #[doc = "Add two vectors element-wise, wrapping on overflow."] fn add_u32x16(self, a: u32x16, b: u32x16) -> u32x16; @@ -3081,7 +3135,9 @@ pub trait Simd: ) -> f64x8; #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."] fn swizzle_dyn_within_blocks_f64x8(self, a: f64x8, indices: u8x64) -> f64x8; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn_f64x8(self, a: f64x8, indices: u8x64) -> f64x8; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise_f64x8(self, a: f64x8, indices: u8x64) -> f64x8; #[doc = "Compute the absolute value of each element."] fn abs_f64x8(self, a: f64x8) -> f64x8; @@ -3177,7 +3233,9 @@ pub trait Simd: ) -> i64x8; #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."] fn swizzle_dyn_within_blocks_i64x8(self, a: i64x8, indices: u8x64) -> i64x8; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn_i64x8(self, a: i64x8, indices: u8x64) -> i64x8; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise_i64x8(self, a: i64x8, indices: u8x64) -> i64x8; #[doc = "Add two vectors element-wise, wrapping on overflow."] fn add_i64x8(self, a: i64x8, b: i64x8) -> i64x8; @@ -3261,7 +3319,9 @@ pub trait Simd: ) -> u64x8; #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."] fn swizzle_dyn_within_blocks_u64x8(self, a: u64x8, indices: u8x64) -> u64x8; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn_u64x8(self, a: u64x8, indices: u8x64) -> u64x8; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise_u64x8(self, a: u64x8, indices: u8x64) -> u64x8; #[doc = "Add two vectors element-wise, wrapping on overflow."] fn add_u64x8(self, a: u64x8, b: u64x8) -> u64x8; @@ -3611,7 +3671,9 @@ pub trait SimdBase: fn shift_elements_right(self, padding: Self::Element) -> Self; #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."] fn swizzle_dyn_within_blocks(self, indices: impl SimdInto) -> Self; - #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes."] + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self; + #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self; } #[doc = r" Functionality implemented by floating-point SIMD vectors."] diff --git a/fearless_simd/src/generated/simd_types.rs b/fearless_simd/src/generated/simd_types.rs index 5782c2f7..d7bec2c2 100644 --- a/fearless_simd/src/generated/simd_types.rs +++ b/fearless_simd/src/generated/simd_types.rs @@ -162,6 +162,11 @@ impl SimdBase for f32x4 { .swizzle_dyn_within_blocks_f32x4(self, indices.simd_into(self.simd)) } #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd + .swizzle_dyn_f32x4(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd .swizzle_dyn_precise_f32x4(self, indices.simd_into(self.simd)) @@ -471,6 +476,11 @@ impl SimdBase for i8x16 { .swizzle_dyn_within_blocks_i8x16(self, indices.simd_into(self.simd)) } #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd + .swizzle_dyn_i8x16(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd .swizzle_dyn_precise_i8x16(self, indices.simd_into(self.simd)) @@ -712,6 +722,11 @@ impl SimdBase for u8x16 { .swizzle_dyn_within_blocks_u8x16(self, indices.simd_into(self.simd)) } #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd + .swizzle_dyn_u8x16(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd .swizzle_dyn_precise_u8x16(self, indices.simd_into(self.simd)) @@ -1039,6 +1054,11 @@ impl SimdBase for i16x8 { .swizzle_dyn_within_blocks_i16x8(self, indices.simd_into(self.simd)) } #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd + .swizzle_dyn_i16x8(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd .swizzle_dyn_precise_i16x8(self, indices.simd_into(self.simd)) @@ -1272,6 +1292,11 @@ impl SimdBase for u16x8 { .swizzle_dyn_within_blocks_u16x8(self, indices.simd_into(self.simd)) } #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd + .swizzle_dyn_u16x8(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd .swizzle_dyn_precise_u16x8(self, indices.simd_into(self.simd)) @@ -1587,6 +1612,11 @@ impl SimdBase for i32x4 { .swizzle_dyn_within_blocks_i32x4(self, indices.simd_into(self.simd)) } #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd + .swizzle_dyn_i32x4(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd .swizzle_dyn_precise_i32x4(self, indices.simd_into(self.simd)) @@ -1820,6 +1850,11 @@ impl SimdBase for u32x4 { .swizzle_dyn_within_blocks_u32x4(self, indices.simd_into(self.simd)) } #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd + .swizzle_dyn_u32x4(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd .swizzle_dyn_precise_u32x4(self, indices.simd_into(self.simd)) @@ -2147,6 +2182,11 @@ impl SimdBase for f64x2 { .swizzle_dyn_within_blocks_f64x2(self, indices.simd_into(self.simd)) } #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd + .swizzle_dyn_f64x2(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd .swizzle_dyn_precise_f64x2(self, indices.simd_into(self.simd)) @@ -2422,6 +2462,11 @@ impl SimdBase for i64x2 { .swizzle_dyn_within_blocks_i64x2(self, indices.simd_into(self.simd)) } #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd + .swizzle_dyn_i64x2(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd .swizzle_dyn_precise_i64x2(self, indices.simd_into(self.simd)) @@ -2643,6 +2688,11 @@ impl SimdBase for u64x2 { .swizzle_dyn_within_blocks_u64x2(self, indices.simd_into(self.simd)) } #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd + .swizzle_dyn_u64x2(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd .swizzle_dyn_precise_u64x2(self, indices.simd_into(self.simd)) @@ -2970,6 +3020,11 @@ impl SimdBase for f32x8 { .swizzle_dyn_within_blocks_f32x8(self, indices.simd_into(self.simd)) } #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd + .swizzle_dyn_f32x8(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd .swizzle_dyn_precise_f32x8(self, indices.simd_into(self.simd)) @@ -3302,6 +3357,11 @@ impl SimdBase for i8x32 { .swizzle_dyn_within_blocks_i8x32(self, indices.simd_into(self.simd)) } #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd + .swizzle_dyn_i8x32(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd .swizzle_dyn_precise_i8x32(self, indices.simd_into(self.simd)) @@ -3566,6 +3626,11 @@ impl SimdBase for u8x32 { .swizzle_dyn_within_blocks_u8x32(self, indices.simd_into(self.simd)) } #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd + .swizzle_dyn_u8x32(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd .swizzle_dyn_precise_u8x32(self, indices.simd_into(self.simd)) @@ -3909,6 +3974,11 @@ impl SimdBase for i16x16 { .swizzle_dyn_within_blocks_i16x16(self, indices.simd_into(self.simd)) } #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd + .swizzle_dyn_i16x16(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd .swizzle_dyn_precise_i16x16(self, indices.simd_into(self.simd)) @@ -4159,6 +4229,11 @@ impl SimdBase for u16x16 { .swizzle_dyn_within_blocks_u16x16(self, indices.simd_into(self.simd)) } #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd + .swizzle_dyn_u16x16(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd .swizzle_dyn_precise_u16x16(self, indices.simd_into(self.simd)) @@ -4494,6 +4569,11 @@ impl SimdBase for i32x8 { .swizzle_dyn_within_blocks_i32x8(self, indices.simd_into(self.simd)) } #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd + .swizzle_dyn_i32x8(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd .swizzle_dyn_precise_i32x8(self, indices.simd_into(self.simd)) @@ -4746,6 +4826,11 @@ impl SimdBase for u32x8 { .swizzle_dyn_within_blocks_u32x8(self, indices.simd_into(self.simd)) } #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd + .swizzle_dyn_u32x8(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd .swizzle_dyn_precise_u32x8(self, indices.simd_into(self.simd)) @@ -5080,6 +5165,11 @@ impl SimdBase for f64x4 { .swizzle_dyn_within_blocks_f64x4(self, indices.simd_into(self.simd)) } #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd + .swizzle_dyn_f64x4(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd .swizzle_dyn_precise_f64x4(self, indices.simd_into(self.simd)) @@ -5362,6 +5452,11 @@ impl SimdBase for i64x4 { .swizzle_dyn_within_blocks_i64x4(self, indices.simd_into(self.simd)) } #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd + .swizzle_dyn_i64x4(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd .swizzle_dyn_precise_i64x4(self, indices.simd_into(self.simd)) @@ -5590,6 +5685,11 @@ impl SimdBase for u64x4 { .swizzle_dyn_within_blocks_u64x4(self, indices.simd_into(self.simd)) } #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd + .swizzle_dyn_u64x4(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd .swizzle_dyn_precise_u64x4(self, indices.simd_into(self.simd)) @@ -5934,6 +6034,11 @@ impl SimdBase for f32x16 { .swizzle_dyn_within_blocks_f32x16(self, indices.simd_into(self.simd)) } #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd + .swizzle_dyn_f32x16(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd .swizzle_dyn_precise_f32x16(self, indices.simd_into(self.simd)) @@ -6293,6 +6398,11 @@ impl SimdBase for i8x64 { .swizzle_dyn_within_blocks_i8x64(self, indices.simd_into(self.simd)) } #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd + .swizzle_dyn_i8x64(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd .swizzle_dyn_precise_i8x64(self, indices.simd_into(self.simd)) @@ -6583,6 +6693,11 @@ impl SimdBase for u8x64 { .swizzle_dyn_within_blocks_u8x64(self, indices.simd_into(self.simd)) } #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd + .swizzle_dyn_u8x64(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd .swizzle_dyn_precise_u8x64(self, indices.simd_into(self.simd)) @@ -6936,6 +7051,11 @@ impl SimdBase for i16x32 { .swizzle_dyn_within_blocks_i16x32(self, indices.simd_into(self.simd)) } #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd + .swizzle_dyn_i16x32(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd .swizzle_dyn_precise_i16x32(self, indices.simd_into(self.simd)) @@ -7196,6 +7316,11 @@ impl SimdBase for u16x32 { .swizzle_dyn_within_blocks_u16x32(self, indices.simd_into(self.simd)) } #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd + .swizzle_dyn_u16x32(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd .swizzle_dyn_precise_u16x32(self, indices.simd_into(self.simd)) @@ -7534,6 +7659,11 @@ impl SimdBase for i32x16 { .swizzle_dyn_within_blocks_i32x16(self, indices.simd_into(self.simd)) } #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd + .swizzle_dyn_i32x16(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd .swizzle_dyn_precise_i32x16(self, indices.simd_into(self.simd)) @@ -7790,6 +7920,11 @@ impl SimdBase for u32x16 { .swizzle_dyn_within_blocks_u32x16(self, indices.simd_into(self.simd)) } #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd + .swizzle_dyn_u32x16(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd .swizzle_dyn_precise_u32x16(self, indices.simd_into(self.simd)) @@ -8131,6 +8266,11 @@ impl SimdBase for f64x8 { .swizzle_dyn_within_blocks_f64x8(self, indices.simd_into(self.simd)) } #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd + .swizzle_dyn_f64x8(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd .swizzle_dyn_precise_f64x8(self, indices.simd_into(self.simd)) @@ -8419,6 +8559,11 @@ impl SimdBase for i64x8 { .swizzle_dyn_within_blocks_i64x8(self, indices.simd_into(self.simd)) } #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd + .swizzle_dyn_i64x8(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd .swizzle_dyn_precise_i64x8(self, indices.simd_into(self.simd)) @@ -8653,6 +8798,11 @@ impl SimdBase for u64x8 { .swizzle_dyn_within_blocks_u64x8(self, indices.simd_into(self.simd)) } #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd + .swizzle_dyn_u64x8(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd .swizzle_dyn_precise_u64x8(self, indices.simd_into(self.simd)) diff --git a/fearless_simd/src/generated/sse2.rs b/fearless_simd/src/generated/sse2.rs index 860b9741..a35ae9c4 100644 --- a/fearless_simd/src/generated/sse2.rs +++ b/fearless_simd/src/generated/sse2.rs @@ -335,6 +335,17 @@ impl Simd for Sse2 { Bytes::from_bytes(result) } #[inline(always)] + fn swizzle_dyn_f32x4(self, a: f32x4, indices: u8x16) -> f32x4 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 16usize]; + for lane in 0..16usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 16usize]; + } + let result: u8x16 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_f32x4(self, a: f32x4, indices: u8x16) -> f32x4 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 16usize]; @@ -1000,6 +1011,17 @@ impl Simd for Sse2 { Bytes::from_bytes(result) } #[inline(always)] + fn swizzle_dyn_i8x16(self, a: i8x16, indices: u8x16) -> i8x16 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 16usize]; + for lane in 0..16usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 16usize]; + } + let result: u8x16 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_i8x16(self, a: i8x16, indices: u8x16) -> i8x16 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 16usize]; @@ -1695,6 +1717,17 @@ impl Simd for Sse2 { Bytes::from_bytes(result) } #[inline(always)] + fn swizzle_dyn_u8x16(self, a: u8x16, indices: u8x16) -> u8x16 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 16usize]; + for lane in 0..16usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 16usize]; + } + let result: u8x16 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_u8x16(self, a: u8x16, indices: u8x16) -> u8x16 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 16usize]; @@ -2541,6 +2574,17 @@ impl Simd for Sse2 { Bytes::from_bytes(result) } #[inline(always)] + fn swizzle_dyn_i16x8(self, a: i16x8, indices: u8x16) -> i16x8 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 16usize]; + for lane in 0..16usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 16usize]; + } + let result: u8x16 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_i16x8(self, a: i16x8, indices: u8x16) -> i16x8 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 16usize]; @@ -3085,6 +3129,17 @@ impl Simd for Sse2 { Bytes::from_bytes(result) } #[inline(always)] + fn swizzle_dyn_u16x8(self, a: u16x8, indices: u8x16) -> u16x8 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 16usize]; + for lane in 0..16usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 16usize]; + } + let result: u8x16 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_u16x8(self, a: u16x8, indices: u8x16) -> u16x8 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 16usize]; @@ -3818,6 +3873,17 @@ impl Simd for Sse2 { Bytes::from_bytes(result) } #[inline(always)] + fn swizzle_dyn_i32x4(self, a: i32x4, indices: u8x16) -> i32x4 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 16usize]; + for lane in 0..16usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 16usize]; + } + let result: u8x16 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_i32x4(self, a: i32x4, indices: u8x16) -> i32x4 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 16usize]; @@ -4363,6 +4429,17 @@ impl Simd for Sse2 { Bytes::from_bytes(result) } #[inline(always)] + fn swizzle_dyn_u32x4(self, a: u32x4, indices: u8x16) -> u32x4 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 16usize]; + for lane in 0..16usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 16usize]; + } + let result: u8x16 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_u32x4(self, a: u32x4, indices: u8x16) -> u32x4 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 16usize]; @@ -5090,6 +5167,17 @@ impl Simd for Sse2 { Bytes::from_bytes(result) } #[inline(always)] + fn swizzle_dyn_f64x2(self, a: f64x2, indices: u8x16) -> f64x2 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 16usize]; + for lane in 0..16usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 16usize]; + } + let result: u8x16 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_f64x2(self, a: f64x2, indices: u8x16) -> f64x2 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 16usize]; @@ -5621,6 +5709,17 @@ impl Simd for Sse2 { Bytes::from_bytes(result) } #[inline(always)] + fn swizzle_dyn_i64x2(self, a: i64x2, indices: u8x16) -> i64x2 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 16usize]; + for lane in 0..16usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 16usize]; + } + let result: u8x16 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_i64x2(self, a: i64x2, indices: u8x16) -> i64x2 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 16usize]; @@ -6097,6 +6196,17 @@ impl Simd for Sse2 { Bytes::from_bytes(result) } #[inline(always)] + fn swizzle_dyn_u64x2(self, a: u64x2, indices: u8x16) -> u64x2 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 16usize]; + for lane in 0..16usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 16usize]; + } + let result: u8x16 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_u64x2(self, a: u64x2, indices: u8x16) -> u64x2 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 16usize]; @@ -6686,6 +6796,17 @@ impl Simd for Sse2 { ) } #[inline(always)] + fn swizzle_dyn_f32x8(self, a: f32x8, indices: u8x32) -> f32x8 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 32usize]; + for lane in 0..32usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 32usize]; + } + let result: u8x32 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_f32x8(self, a: f32x8, indices: u8x32) -> f32x8 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 32usize]; @@ -7169,6 +7290,17 @@ impl Simd for Sse2 { ) } #[inline(always)] + fn swizzle_dyn_i8x32(self, a: i8x32, indices: u8x32) -> i8x32 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 32usize]; + for lane in 0..32usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 32usize]; + } + let result: u8x32 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_i8x32(self, a: i8x32, indices: u8x32) -> i8x32 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 32usize]; @@ -7575,6 +7707,17 @@ impl Simd for Sse2 { ) } #[inline(always)] + fn swizzle_dyn_u8x32(self, a: u8x32, indices: u8x32) -> u8x32 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 32usize]; + for lane in 0..32usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 32usize]; + } + let result: u8x32 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_u8x32(self, a: u8x32, indices: u8x32) -> u8x32 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 32usize]; @@ -8034,6 +8177,17 @@ impl Simd for Sse2 { ) } #[inline(always)] + fn swizzle_dyn_i16x16(self, a: i16x16, indices: u8x32) -> i16x16 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 32usize]; + for lane in 0..32usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 32usize]; + } + let result: u8x32 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_i16x16(self, a: i16x16, indices: u8x32) -> i16x16 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 32usize]; @@ -8380,6 +8534,17 @@ impl Simd for Sse2 { ) } #[inline(always)] + fn swizzle_dyn_u16x16(self, a: u16x16, indices: u8x32) -> u16x16 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 32usize]; + for lane in 0..32usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 32usize]; + } + let result: u8x32 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_u16x16(self, a: u16x16, indices: u8x32) -> u16x16 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 32usize]; @@ -8819,6 +8984,17 @@ impl Simd for Sse2 { ) } #[inline(always)] + fn swizzle_dyn_i32x8(self, a: i32x8, indices: u8x32) -> i32x8 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 32usize]; + for lane in 0..32usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 32usize]; + } + let result: u8x32 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_i32x8(self, a: i32x8, indices: u8x32) -> i32x8 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 32usize]; @@ -9134,6 +9310,17 @@ impl Simd for Sse2 { ) } #[inline(always)] + fn swizzle_dyn_u32x8(self, a: u32x8, indices: u8x32) -> u32x8 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 32usize]; + for lane in 0..32usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 32usize]; + } + let result: u8x32 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_u32x8(self, a: u32x8, indices: u8x32) -> u32x8 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 32usize]; @@ -9541,6 +9728,17 @@ impl Simd for Sse2 { ) } #[inline(always)] + fn swizzle_dyn_f64x4(self, a: f64x4, indices: u8x32) -> f64x4 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 32usize]; + for lane in 0..32usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 32usize]; + } + let result: u8x32 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_f64x4(self, a: f64x4, indices: u8x32) -> f64x4 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 32usize]; @@ -9886,6 +10084,17 @@ impl Simd for Sse2 { ) } #[inline(always)] + fn swizzle_dyn_i64x4(self, a: i64x4, indices: u8x32) -> i64x4 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 32usize]; + for lane in 0..32usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 32usize]; + } + let result: u8x32 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_i64x4(self, a: i64x4, indices: u8x32) -> i64x4 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 32usize]; @@ -10180,6 +10389,17 @@ impl Simd for Sse2 { ) } #[inline(always)] + fn swizzle_dyn_u64x4(self, a: u64x4, indices: u8x32) -> u64x4 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 32usize]; + for lane in 0..32usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 32usize]; + } + let result: u8x32 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_u64x4(self, a: u64x4, indices: u8x32) -> u64x4 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 32usize]; @@ -10634,6 +10854,17 @@ impl Simd for Sse2 { ) } #[inline(always)] + fn swizzle_dyn_f32x16(self, a: f32x16, indices: u8x64) -> f32x16 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 64usize]; + for lane in 0..64usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 64usize]; + } + let result: u8x64 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_f32x16(self, a: f32x16, indices: u8x64) -> f32x16 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -11238,6 +11469,17 @@ impl Simd for Sse2 { ) } #[inline(always)] + fn swizzle_dyn_i8x64(self, a: i8x64, indices: u8x64) -> i8x64 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 64usize]; + for lane in 0..64usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 64usize]; + } + let result: u8x64 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_i8x64(self, a: i8x64, indices: u8x64) -> i8x64 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -11765,6 +12007,17 @@ impl Simd for Sse2 { ) } #[inline(always)] + fn swizzle_dyn_u8x64(self, a: u8x64, indices: u8x64) -> u8x64 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 64usize]; + for lane in 0..64usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 64usize]; + } + let result: u8x64 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_u8x64(self, a: u8x64, indices: u8x64) -> u8x64 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -12269,6 +12522,17 @@ impl Simd for Sse2 { ) } #[inline(always)] + fn swizzle_dyn_i16x32(self, a: i16x32, indices: u8x64) -> i16x32 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 64usize]; + for lane in 0..64usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 64usize]; + } + let result: u8x64 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_i16x32(self, a: i16x32, indices: u8x64) -> i16x32 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -12678,6 +12942,17 @@ impl Simd for Sse2 { ) } #[inline(always)] + fn swizzle_dyn_u16x32(self, a: u16x32, indices: u8x64) -> u16x32 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 64usize]; + for lane in 0..64usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 64usize]; + } + let result: u8x64 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_u16x32(self, a: u16x32, indices: u8x64) -> u16x32 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -13141,6 +13416,17 @@ impl Simd for Sse2 { ) } #[inline(always)] + fn swizzle_dyn_i32x16(self, a: i32x16, indices: u8x64) -> i32x16 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 64usize]; + for lane in 0..64usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 64usize]; + } + let result: u8x64 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_i32x16(self, a: i32x16, indices: u8x64) -> i32x16 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -13485,6 +13771,17 @@ impl Simd for Sse2 { ) } #[inline(always)] + fn swizzle_dyn_u32x16(self, a: u32x16, indices: u8x64) -> u32x16 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 64usize]; + for lane in 0..64usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 64usize]; + } + let result: u8x64 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_u32x16(self, a: u32x16, indices: u8x64) -> u32x16 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -13894,6 +14191,17 @@ impl Simd for Sse2 { ) } #[inline(always)] + fn swizzle_dyn_f64x8(self, a: f64x8, indices: u8x64) -> f64x8 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 64usize]; + for lane in 0..64usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 64usize]; + } + let result: u8x64 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_f64x8(self, a: f64x8, indices: u8x64) -> f64x8 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -14248,6 +14556,17 @@ impl Simd for Sse2 { ) } #[inline(always)] + fn swizzle_dyn_i64x8(self, a: i64x8, indices: u8x64) -> i64x8 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 64usize]; + for lane in 0..64usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 64usize]; + } + let result: u8x64 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_i64x8(self, a: i64x8, indices: u8x64) -> i64x8 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -14551,6 +14870,17 @@ impl Simd for Sse2 { ) } #[inline(always)] + fn swizzle_dyn_u64x8(self, a: u64x8, indices: u8x64) -> u64x8 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 64usize]; + for lane in 0..64usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 64usize]; + } + let result: u8x64 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_u64x8(self, a: u64x8, indices: u8x64) -> u64x8 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; diff --git a/fearless_simd/src/generated/sse4_2.rs b/fearless_simd/src/generated/sse4_2.rs index 5b0b6195..4c64887b 100644 --- a/fearless_simd/src/generated/sse4_2.rs +++ b/fearless_simd/src/generated/sse4_2.rs @@ -210,6 +210,20 @@ impl Simd for Sse4_2 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_f32x4(self, a: f32x4, indices: u8x16) -> f32x4 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Sse4_2, a: f32x4, indices: u8x16) -> f32x4 { + let result = _mm_shuffle_epi8(Bytes::to_bytes(a).val.0, indices.into()); + Bytes::from_bytes(u8x16 { + val: crate::support::Aligned128(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_f32x4(self, a: f32x4, indices: u8x16) -> f32x4 { crate::kernel!( #[inline(always)] @@ -848,6 +862,20 @@ impl Simd for Sse4_2 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_i8x16(self, a: i8x16, indices: u8x16) -> i8x16 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Sse4_2, a: i8x16, indices: u8x16) -> i8x16 { + let result = _mm_shuffle_epi8(Bytes::to_bytes(a).val.0, indices.into()); + Bytes::from_bytes(u8x16 { + val: crate::support::Aligned128(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i8x16(self, a: i8x16, indices: u8x16) -> i8x16 { crate::kernel!( #[inline(always)] @@ -1414,6 +1442,20 @@ impl Simd for Sse4_2 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_u8x16(self, a: u8x16, indices: u8x16) -> u8x16 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Sse4_2, a: u8x16, indices: u8x16) -> u8x16 { + let result = _mm_shuffle_epi8(Bytes::to_bytes(a).val.0, indices.into()); + Bytes::from_bytes(u8x16 { + val: crate::support::Aligned128(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u8x16(self, a: u8x16, indices: u8x16) -> u8x16 { crate::kernel!( #[inline(always)] @@ -2120,6 +2162,20 @@ impl Simd for Sse4_2 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_i16x8(self, a: i16x8, indices: u8x16) -> i16x8 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Sse4_2, a: i16x8, indices: u8x16) -> i16x8 { + let result = _mm_shuffle_epi8(Bytes::to_bytes(a).val.0, indices.into()); + Bytes::from_bytes(u8x16 { + val: crate::support::Aligned128(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i16x8(self, a: i16x8, indices: u8x16) -> i16x8 { crate::kernel!( #[inline(always)] @@ -2615,6 +2671,20 @@ impl Simd for Sse4_2 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_u16x8(self, a: u16x8, indices: u8x16) -> u16x8 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Sse4_2, a: u16x8, indices: u8x16) -> u16x8 { + let result = _mm_shuffle_epi8(Bytes::to_bytes(a).val.0, indices.into()); + Bytes::from_bytes(u8x16 { + val: crate::support::Aligned128(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u16x8(self, a: u16x8, indices: u8x16) -> u16x8 { crate::kernel!( #[inline(always)] @@ -3257,6 +3327,20 @@ impl Simd for Sse4_2 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_i32x4(self, a: i32x4, indices: u8x16) -> i32x4 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Sse4_2, a: i32x4, indices: u8x16) -> i32x4 { + let result = _mm_shuffle_epi8(Bytes::to_bytes(a).val.0, indices.into()); + Bytes::from_bytes(u8x16 { + val: crate::support::Aligned128(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i32x4(self, a: i32x4, indices: u8x16) -> i32x4 { crate::kernel!( #[inline(always)] @@ -3726,6 +3810,20 @@ impl Simd for Sse4_2 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_u32x4(self, a: u32x4, indices: u8x16) -> u32x4 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Sse4_2, a: u32x4, indices: u8x16) -> u32x4 { + let result = _mm_shuffle_epi8(Bytes::to_bytes(a).val.0, indices.into()); + Bytes::from_bytes(u8x16 { + val: crate::support::Aligned128(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u32x4(self, a: u32x4, indices: u8x16) -> u32x4 { crate::kernel!( #[inline(always)] @@ -4356,6 +4454,20 @@ impl Simd for Sse4_2 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_f64x2(self, a: f64x2, indices: u8x16) -> f64x2 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Sse4_2, a: f64x2, indices: u8x16) -> f64x2 { + let result = _mm_shuffle_epi8(Bytes::to_bytes(a).val.0, indices.into()); + Bytes::from_bytes(u8x16 { + val: crate::support::Aligned128(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_f64x2(self, a: f64x2, indices: u8x16) -> f64x2 { crate::kernel!( #[inline(always)] @@ -4847,6 +4959,20 @@ impl Simd for Sse4_2 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_i64x2(self, a: i64x2, indices: u8x16) -> i64x2 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Sse4_2, a: i64x2, indices: u8x16) -> i64x2 { + let result = _mm_shuffle_epi8(Bytes::to_bytes(a).val.0, indices.into()); + Bytes::from_bytes(u8x16 { + val: crate::support::Aligned128(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i64x2(self, a: i64x2, indices: u8x16) -> i64x2 { crate::kernel!( #[inline(always)] @@ -5266,6 +5392,20 @@ impl Simd for Sse4_2 { kernel(self, a, indices) } #[inline(always)] + fn swizzle_dyn_u64x2(self, a: u64x2, indices: u8x16) -> u64x2 { + crate::kernel!( + #[inline(always)] + fn kernel(token: Sse4_2, a: u64x2, indices: u8x16) -> u64x2 { + let result = _mm_shuffle_epi8(Bytes::to_bytes(a).val.0, indices.into()); + Bytes::from_bytes(u8x16 { + val: crate::support::Aligned128(result), + simd: token, + }) + } + ); + kernel(self, a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u64x2(self, a: u64x2, indices: u8x16) -> u64x2 { crate::kernel!( #[inline(always)] @@ -5854,6 +5994,10 @@ impl Simd for Sse4_2 { ) } #[inline(always)] + fn swizzle_dyn_f32x8(self, a: f32x8, indices: u8x32) -> f32x8 { + self.swizzle_dyn_precise_f32x8(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_f32x8(self, a: f32x8, indices: u8x32) -> f32x8 { crate::kernel!( #[inline(always)] @@ -6352,6 +6496,10 @@ impl Simd for Sse4_2 { ) } #[inline(always)] + fn swizzle_dyn_i8x32(self, a: i8x32, indices: u8x32) -> i8x32 { + self.swizzle_dyn_precise_i8x32(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i8x32(self, a: i8x32, indices: u8x32) -> i8x32 { crate::kernel!( #[inline(always)] @@ -6773,6 +6921,10 @@ impl Simd for Sse4_2 { ) } #[inline(always)] + fn swizzle_dyn_u8x32(self, a: u8x32, indices: u8x32) -> u8x32 { + self.swizzle_dyn_precise_u8x32(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u8x32(self, a: u8x32, indices: u8x32) -> u8x32 { crate::kernel!( #[inline(always)] @@ -7247,6 +7399,10 @@ impl Simd for Sse4_2 { ) } #[inline(always)] + fn swizzle_dyn_i16x16(self, a: i16x16, indices: u8x32) -> i16x16 { + self.swizzle_dyn_precise_i16x16(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i16x16(self, a: i16x16, indices: u8x32) -> i16x16 { crate::kernel!( #[inline(always)] @@ -7608,6 +7764,10 @@ impl Simd for Sse4_2 { ) } #[inline(always)] + fn swizzle_dyn_u16x16(self, a: u16x16, indices: u8x32) -> u16x16 { + self.swizzle_dyn_precise_u16x16(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u16x16(self, a: u16x16, indices: u8x32) -> u16x16 { crate::kernel!( #[inline(always)] @@ -8062,6 +8222,10 @@ impl Simd for Sse4_2 { ) } #[inline(always)] + fn swizzle_dyn_i32x8(self, a: i32x8, indices: u8x32) -> i32x8 { + self.swizzle_dyn_precise_i32x8(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i32x8(self, a: i32x8, indices: u8x32) -> i32x8 { crate::kernel!( #[inline(always)] @@ -8392,6 +8556,10 @@ impl Simd for Sse4_2 { ) } #[inline(always)] + fn swizzle_dyn_u32x8(self, a: u32x8, indices: u8x32) -> u32x8 { + self.swizzle_dyn_precise_u32x8(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u32x8(self, a: u32x8, indices: u8x32) -> u32x8 { crate::kernel!( #[inline(always)] @@ -8814,6 +8982,10 @@ impl Simd for Sse4_2 { ) } #[inline(always)] + fn swizzle_dyn_f64x4(self, a: f64x4, indices: u8x32) -> f64x4 { + self.swizzle_dyn_precise_f64x4(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_f64x4(self, a: f64x4, indices: u8x32) -> f64x4 { crate::kernel!( #[inline(always)] @@ -9174,6 +9346,10 @@ impl Simd for Sse4_2 { ) } #[inline(always)] + fn swizzle_dyn_i64x4(self, a: i64x4, indices: u8x32) -> i64x4 { + self.swizzle_dyn_precise_i64x4(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i64x4(self, a: i64x4, indices: u8x32) -> i64x4 { crate::kernel!( #[inline(always)] @@ -9483,6 +9659,10 @@ impl Simd for Sse4_2 { ) } #[inline(always)] + fn swizzle_dyn_u64x4(self, a: u64x4, indices: u8x32) -> u64x4 { + self.swizzle_dyn_precise_u64x4(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u64x4(self, a: u64x4, indices: u8x32) -> u64x4 { crate::kernel!( #[inline(always)] @@ -9952,6 +10132,17 @@ impl Simd for Sse4_2 { ) } #[inline(always)] + fn swizzle_dyn_f32x16(self, a: f32x16, indices: u8x64) -> f32x16 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 64usize]; + for lane in 0..64usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 64usize]; + } + let result: u8x64 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_f32x16(self, a: f32x16, indices: u8x64) -> f32x16 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -10556,6 +10747,17 @@ impl Simd for Sse4_2 { ) } #[inline(always)] + fn swizzle_dyn_i8x64(self, a: i8x64, indices: u8x64) -> i8x64 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 64usize]; + for lane in 0..64usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 64usize]; + } + let result: u8x64 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_i8x64(self, a: i8x64, indices: u8x64) -> i8x64 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -11083,6 +11285,17 @@ impl Simd for Sse4_2 { ) } #[inline(always)] + fn swizzle_dyn_u8x64(self, a: u8x64, indices: u8x64) -> u8x64 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 64usize]; + for lane in 0..64usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 64usize]; + } + let result: u8x64 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_u8x64(self, a: u8x64, indices: u8x64) -> u8x64 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -11628,6 +11841,17 @@ impl Simd for Sse4_2 { ) } #[inline(always)] + fn swizzle_dyn_i16x32(self, a: i16x32, indices: u8x64) -> i16x32 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 64usize]; + for lane in 0..64usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 64usize]; + } + let result: u8x64 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_i16x32(self, a: i16x32, indices: u8x64) -> i16x32 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -12037,6 +12261,17 @@ impl Simd for Sse4_2 { ) } #[inline(always)] + fn swizzle_dyn_u16x32(self, a: u16x32, indices: u8x64) -> u16x32 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 64usize]; + for lane in 0..64usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 64usize]; + } + let result: u8x64 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_u16x32(self, a: u16x32, indices: u8x64) -> u16x32 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -12500,6 +12735,17 @@ impl Simd for Sse4_2 { ) } #[inline(always)] + fn swizzle_dyn_i32x16(self, a: i32x16, indices: u8x64) -> i32x16 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 64usize]; + for lane in 0..64usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 64usize]; + } + let result: u8x64 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_i32x16(self, a: i32x16, indices: u8x64) -> i32x16 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -12844,6 +13090,17 @@ impl Simd for Sse4_2 { ) } #[inline(always)] + fn swizzle_dyn_u32x16(self, a: u32x16, indices: u8x64) -> u32x16 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 64usize]; + for lane in 0..64usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 64usize]; + } + let result: u8x64 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_u32x16(self, a: u32x16, indices: u8x64) -> u32x16 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -13253,6 +13510,17 @@ impl Simd for Sse4_2 { ) } #[inline(always)] + fn swizzle_dyn_f64x8(self, a: f64x8, indices: u8x64) -> f64x8 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 64usize]; + for lane in 0..64usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 64usize]; + } + let result: u8x64 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_f64x8(self, a: f64x8, indices: u8x64) -> f64x8 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -13607,6 +13875,17 @@ impl Simd for Sse4_2 { ) } #[inline(always)] + fn swizzle_dyn_i64x8(self, a: i64x8, indices: u8x64) -> i64x8 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 64usize]; + for lane in 0..64usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 64usize]; + } + let result: u8x64 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_i64x8(self, a: i64x8, indices: u8x64) -> i64x8 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -13910,6 +14189,17 @@ impl Simd for Sse4_2 { ) } #[inline(always)] + fn swizzle_dyn_u64x8(self, a: u64x8, indices: u8x64) -> u64x8 { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; 64usize]; + for lane in 0..64usize { + let index = indices[lane] as usize; + output[lane] = bytes[index % 64usize]; + } + let result: u8x64 = output.simd_into(self); + Bytes::from_bytes(result) + } + #[inline(always)] fn swizzle_dyn_precise_u64x8(self, a: u64x8, indices: u8x64) -> u64x8 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; diff --git a/fearless_simd/src/generated/wasm.rs b/fearless_simd/src/generated/wasm.rs index 037a4f16..5b2eb385 100644 --- a/fearless_simd/src/generated/wasm.rs +++ b/fearless_simd/src/generated/wasm.rs @@ -187,6 +187,10 @@ impl Simd for WasmSimd128 { }) } #[inline(always)] + fn swizzle_dyn_f32x4(self, a: f32x4, indices: u8x16) -> f32x4 { + self.swizzle_dyn_precise_f32x4(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_f32x4(self, a: f32x4, indices: u8x16) -> f32x4 { let result = u8x16_swizzle(Bytes::to_bytes(a).val.0, indices.into()); Bytes::from_bytes(u8x16 { @@ -583,6 +587,10 @@ impl Simd for WasmSimd128 { }) } #[inline(always)] + fn swizzle_dyn_i8x16(self, a: i8x16, indices: u8x16) -> i8x16 { + self.swizzle_dyn_precise_i8x16(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i8x16(self, a: i8x16, indices: u8x16) -> i8x16 { let result = u8x16_swizzle(Bytes::to_bytes(a).val.0, indices.into()); Bytes::from_bytes(u8x16 { @@ -966,6 +974,10 @@ impl Simd for WasmSimd128 { }) } #[inline(always)] + fn swizzle_dyn_u8x16(self, a: u8x16, indices: u8x16) -> u8x16 { + self.swizzle_dyn_precise_u8x16(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u8x16(self, a: u8x16, indices: u8x16) -> u8x16 { let result = u8x16_swizzle(Bytes::to_bytes(a).val.0, indices.into()); Bytes::from_bytes(u8x16 { @@ -1411,6 +1423,10 @@ impl Simd for WasmSimd128 { }) } #[inline(always)] + fn swizzle_dyn_i16x8(self, a: i16x8, indices: u8x16) -> i16x8 { + self.swizzle_dyn_precise_i16x8(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i16x8(self, a: i16x8, indices: u8x16) -> i16x8 { let result = u8x16_swizzle(Bytes::to_bytes(a).val.0, indices.into()); Bytes::from_bytes(u8x16 { @@ -1710,6 +1726,10 @@ impl Simd for WasmSimd128 { }) } #[inline(always)] + fn swizzle_dyn_u16x8(self, a: u16x8, indices: u8x16) -> u16x8 { + self.swizzle_dyn_precise_u16x8(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u16x8(self, a: u16x8, indices: u8x16) -> u16x8 { let result = u8x16_swizzle(Bytes::to_bytes(a).val.0, indices.into()); Bytes::from_bytes(u8x16 { @@ -2075,6 +2095,10 @@ impl Simd for WasmSimd128 { }) } #[inline(always)] + fn swizzle_dyn_i32x4(self, a: i32x4, indices: u8x16) -> i32x4 { + self.swizzle_dyn_precise_i32x4(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i32x4(self, a: i32x4, indices: u8x16) -> i32x4 { let result = u8x16_swizzle(Bytes::to_bytes(a).val.0, indices.into()); Bytes::from_bytes(u8x16 { @@ -2354,6 +2378,10 @@ impl Simd for WasmSimd128 { }) } #[inline(always)] + fn swizzle_dyn_u32x4(self, a: u32x4, indices: u8x16) -> u32x4 { + self.swizzle_dyn_precise_u32x4(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u32x4(self, a: u32x4, indices: u8x16) -> u32x4 { let result = u8x16_swizzle(Bytes::to_bytes(a).val.0, indices.into()); Bytes::from_bytes(u8x16 { @@ -2707,6 +2735,10 @@ impl Simd for WasmSimd128 { }) } #[inline(always)] + fn swizzle_dyn_f64x2(self, a: f64x2, indices: u8x16) -> f64x2 { + self.swizzle_dyn_precise_f64x2(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_f64x2(self, a: f64x2, indices: u8x16) -> f64x2 { let result = u8x16_swizzle(Bytes::to_bytes(a).val.0, indices.into()); Bytes::from_bytes(u8x16 { @@ -3013,6 +3045,10 @@ impl Simd for WasmSimd128 { }) } #[inline(always)] + fn swizzle_dyn_i64x2(self, a: i64x2, indices: u8x16) -> i64x2 { + self.swizzle_dyn_precise_i64x2(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i64x2(self, a: i64x2, indices: u8x16) -> i64x2 { let result = u8x16_swizzle(Bytes::to_bytes(a).val.0, indices.into()); Bytes::from_bytes(u8x16 { @@ -3276,6 +3312,10 @@ impl Simd for WasmSimd128 { }) } #[inline(always)] + fn swizzle_dyn_u64x2(self, a: u64x2, indices: u8x16) -> u64x2 { + self.swizzle_dyn_precise_u64x2(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u64x2(self, a: u64x2, indices: u8x16) -> u64x2 { let result = u8x16_swizzle(Bytes::to_bytes(a).val.0, indices.into()); Bytes::from_bytes(u8x16 { @@ -3672,6 +3712,10 @@ impl Simd for WasmSimd128 { ) } #[inline(always)] + fn swizzle_dyn_f32x8(self, a: f32x8, indices: u8x32) -> f32x8 { + self.swizzle_dyn_precise_f32x8(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_f32x8(self, a: f32x8, indices: u8x32) -> f32x8 { let bytes = Bytes::to_bytes(a); let (table_low, table_high) = self.split_u8x32(bytes); @@ -4156,6 +4200,10 @@ impl Simd for WasmSimd128 { ) } #[inline(always)] + fn swizzle_dyn_i8x32(self, a: i8x32, indices: u8x32) -> i8x32 { + self.swizzle_dyn_precise_i8x32(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i8x32(self, a: i8x32, indices: u8x32) -> i8x32 { let bytes = Bytes::to_bytes(a); let (table_low, table_high) = self.split_u8x32(bytes); @@ -4563,6 +4611,10 @@ impl Simd for WasmSimd128 { ) } #[inline(always)] + fn swizzle_dyn_u8x32(self, a: u8x32, indices: u8x32) -> u8x32 { + self.swizzle_dyn_precise_u8x32(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u8x32(self, a: u8x32, indices: u8x32) -> u8x32 { let bytes = Bytes::to_bytes(a); let (table_low, table_high) = self.split_u8x32(bytes); @@ -5026,6 +5078,10 @@ impl Simd for WasmSimd128 { ) } #[inline(always)] + fn swizzle_dyn_i16x16(self, a: i16x16, indices: u8x32) -> i16x16 { + self.swizzle_dyn_precise_i16x16(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i16x16(self, a: i16x16, indices: u8x32) -> i16x16 { let bytes = Bytes::to_bytes(a); let (table_low, table_high) = self.split_u8x32(bytes); @@ -5376,6 +5432,10 @@ impl Simd for WasmSimd128 { ) } #[inline(always)] + fn swizzle_dyn_u16x16(self, a: u16x16, indices: u8x32) -> u16x16 { + self.swizzle_dyn_precise_u16x16(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u16x16(self, a: u16x16, indices: u8x32) -> u16x16 { let bytes = Bytes::to_bytes(a); let (table_low, table_high) = self.split_u8x32(bytes); @@ -5807,6 +5867,10 @@ impl Simd for WasmSimd128 { ) } #[inline(always)] + fn swizzle_dyn_i32x8(self, a: i32x8, indices: u8x32) -> i32x8 { + self.swizzle_dyn_precise_i32x8(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i32x8(self, a: i32x8, indices: u8x32) -> i32x8 { let bytes = Bytes::to_bytes(a); let (table_low, table_high) = self.split_u8x32(bytes); @@ -6126,6 +6190,10 @@ impl Simd for WasmSimd128 { ) } #[inline(always)] + fn swizzle_dyn_u32x8(self, a: u32x8, indices: u8x32) -> u32x8 { + self.swizzle_dyn_precise_u32x8(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u32x8(self, a: u32x8, indices: u8x32) -> u32x8 { let bytes = Bytes::to_bytes(a); let (table_low, table_high) = self.split_u8x32(bytes); @@ -6537,6 +6605,10 @@ impl Simd for WasmSimd128 { ) } #[inline(always)] + fn swizzle_dyn_f64x4(self, a: f64x4, indices: u8x32) -> f64x4 { + self.swizzle_dyn_precise_f64x4(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_f64x4(self, a: f64x4, indices: u8x32) -> f64x4 { let bytes = Bytes::to_bytes(a); let (table_low, table_high) = self.split_u8x32(bytes); @@ -6886,6 +6958,10 @@ impl Simd for WasmSimd128 { ) } #[inline(always)] + fn swizzle_dyn_i64x4(self, a: i64x4, indices: u8x32) -> i64x4 { + self.swizzle_dyn_precise_i64x4(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i64x4(self, a: i64x4, indices: u8x32) -> i64x4 { let bytes = Bytes::to_bytes(a); let (table_low, table_high) = self.split_u8x32(bytes); @@ -7184,6 +7260,10 @@ impl Simd for WasmSimd128 { ) } #[inline(always)] + fn swizzle_dyn_u64x4(self, a: u64x4, indices: u8x32) -> u64x4 { + self.swizzle_dyn_precise_u64x4(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u64x4(self, a: u64x4, indices: u8x32) -> u64x4 { let bytes = Bytes::to_bytes(a); let (table_low, table_high) = self.split_u8x32(bytes); @@ -7642,6 +7722,10 @@ impl Simd for WasmSimd128 { ) } #[inline(always)] + fn swizzle_dyn_f32x16(self, a: f32x16, indices: u8x64) -> f32x16 { + self.swizzle_dyn_precise_f32x16(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_f32x16(self, a: f32x16, indices: u8x64) -> f32x16 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -8242,6 +8326,10 @@ impl Simd for WasmSimd128 { ) } #[inline(always)] + fn swizzle_dyn_i8x64(self, a: i8x64, indices: u8x64) -> i8x64 { + self.swizzle_dyn_precise_i8x64(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i8x64(self, a: i8x64, indices: u8x64) -> i8x64 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -8765,6 +8853,10 @@ impl Simd for WasmSimd128 { ) } #[inline(always)] + fn swizzle_dyn_u8x64(self, a: u8x64, indices: u8x64) -> u8x64 { + self.swizzle_dyn_precise_u8x64(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u8x64(self, a: u8x64, indices: u8x64) -> u8x64 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -9268,6 +9360,10 @@ impl Simd for WasmSimd128 { ) } #[inline(always)] + fn swizzle_dyn_i16x32(self, a: i16x32, indices: u8x64) -> i16x32 { + self.swizzle_dyn_precise_i16x32(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i16x32(self, a: i16x32, indices: u8x64) -> i16x32 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -9676,6 +9772,10 @@ impl Simd for WasmSimd128 { ) } #[inline(always)] + fn swizzle_dyn_u16x32(self, a: u16x32, indices: u8x64) -> u16x32 { + self.swizzle_dyn_precise_u16x32(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u16x32(self, a: u16x32, indices: u8x64) -> u16x32 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -10129,6 +10229,10 @@ impl Simd for WasmSimd128 { ) } #[inline(always)] + fn swizzle_dyn_i32x16(self, a: i32x16, indices: u8x64) -> i32x16 { + self.swizzle_dyn_precise_i32x16(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i32x16(self, a: i32x16, indices: u8x64) -> i32x16 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -10472,6 +10576,10 @@ impl Simd for WasmSimd128 { ) } #[inline(always)] + fn swizzle_dyn_u32x16(self, a: u32x16, indices: u8x64) -> u32x16 { + self.swizzle_dyn_precise_u32x16(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u32x16(self, a: u32x16, indices: u8x64) -> u32x16 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -10880,6 +10988,10 @@ impl Simd for WasmSimd128 { ) } #[inline(always)] + fn swizzle_dyn_f64x8(self, a: f64x8, indices: u8x64) -> f64x8 { + self.swizzle_dyn_precise_f64x8(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_f64x8(self, a: f64x8, indices: u8x64) -> f64x8 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -11233,6 +11345,10 @@ impl Simd for WasmSimd128 { ) } #[inline(always)] + fn swizzle_dyn_i64x8(self, a: i64x8, indices: u8x64) -> i64x8 { + self.swizzle_dyn_precise_i64x8(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_i64x8(self, a: i64x8, indices: u8x64) -> i64x8 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; @@ -11535,6 +11651,10 @@ impl Simd for WasmSimd128 { ) } #[inline(always)] + fn swizzle_dyn_u64x8(self, a: u64x8, indices: u8x64) -> u64x8 { + self.swizzle_dyn_precise_u64x8(a, indices) + } + #[inline(always)] fn swizzle_dyn_precise_u64x8(self, a: u64x8, indices: u8x64) -> u64x8 { let bytes = Bytes::to_bytes(a); let mut output = [0u8; 64usize]; diff --git a/fearless_simd_gen/src/generic.rs b/fearless_simd_gen/src/generic.rs index 25faf879..e5827ce4 100644 --- a/fearless_simd_gen/src/generic.rs +++ b/fearless_simd_gen/src/generic.rs @@ -79,9 +79,10 @@ pub(crate) fn integer_lane_mask_splat_arg(vec_ty: &VecType) -> TokenStream { } } -/// Implementation based on split/combine +/// Generic operation implementations. /// -/// Only suitable for lane-wise and block-wise operations +/// Most operations are implemented using split/combine, while some forward to +/// another operation with compatible semantics. pub(crate) fn generic_op(op: &Op, ty: &VecType) -> TokenStream { let split = generic_op_name("split", ty); let half = VecType::new(ty.scalar, ty.scalar_bits, ty.len / 2); @@ -136,7 +137,7 @@ pub(crate) fn generic_op(op: &Op, ty: &VecType) -> TokenStream { } } } - OpSig::SwizzleDynPrecise => { + OpSig::SwizzleDyn | OpSig::SwizzleDynPrecise => { panic!("whole-vector swizzles cannot be done via split/combine"); } OpSig::Ternary => { diff --git a/fearless_simd_gen/src/mk_fallback.rs b/fearless_simd_gen/src/mk_fallback.rs index 975e1671..619677ad 100644 --- a/fearless_simd_gen/src/mk_fallback.rs +++ b/fearless_simd_gen/src/mk_fallback.rs @@ -440,6 +440,24 @@ impl Level for Fallback { } } } + OpSig::SwizzleDyn => { + let bytes_ty = vec_ty.bytes_ty(); + let bytes_rust = bytes_ty.rust(); + let byte_count = bytes_ty.len; + + quote! { + #method_sig { + let bytes = Bytes::to_bytes(a); + let mut output = [0u8; #byte_count]; + for lane in 0..#byte_count { + let index = indices[lane] as usize; + output[lane] = bytes[index % #byte_count]; + } + let result: #bytes_rust = output.simd_into(self); + Bytes::from_bytes(result) + } + } + } OpSig::SwizzleDynPrecise => { let bytes_ty = vec_ty.bytes_ty(); let bytes_rust = bytes_ty.rust(); diff --git a/fearless_simd_gen/src/mk_neon.rs b/fearless_simd_gen/src/mk_neon.rs index 0412f74d..ac165390 100644 --- a/fearless_simd_gen/src/mk_neon.rs +++ b/fearless_simd_gen/src/mk_neon.rs @@ -490,6 +490,14 @@ impl Level for Neon { } }) } + OpSig::SwizzleDyn => { + let precise = generic_op_name("swizzle_dyn_precise", vec_ty); + quote! { + #method_sig { + self.#precise(a, indices) + } + } + } OpSig::SwizzleDynPrecise => { let bytes_ty = vec_ty.bytes_ty(); let bytes = bytes_ty.rust(); diff --git a/fearless_simd_gen/src/mk_simd_types.rs b/fearless_simd_gen/src/mk_simd_types.rs index ea915255..1f764b13 100644 --- a/fearless_simd_gen/src/mk_simd_types.rs +++ b/fearless_simd_gen/src/mk_simd_types.rs @@ -443,6 +443,7 @@ fn simd_vec_impl(ty: &VecType) -> TokenStream { let shift_elements_left_op = generic_op_name("shift_elements_left", ty); let shift_elements_right_op = generic_op_name("shift_elements_right", ty); let swizzle_dyn_within_blocks_op = generic_op_name("swizzle_dyn_within_blocks", ty); + let swizzle_dyn_op = generic_op_name("swizzle_dyn", ty); let swizzle_dyn_precise_op = generic_op_name("swizzle_dyn_precise", ty); quote! { impl SimdBase for #name { @@ -528,6 +529,11 @@ fn simd_vec_impl(ty: &VecType) -> TokenStream { self.simd.#swizzle_dyn_within_blocks_op(self, indices.simd_into(self.simd)) } + #[inline(always)] + fn swizzle_dyn(self, indices: impl SimdInto) -> Self { + self.simd.#swizzle_dyn_op(self, indices.simd_into(self.simd)) + } + #[inline(always)] fn swizzle_dyn_precise(self, indices: impl SimdInto) -> Self { self.simd.#swizzle_dyn_precise_op(self, indices.simd_into(self.simd)) diff --git a/fearless_simd_gen/src/mk_wasm.rs b/fearless_simd_gen/src/mk_wasm.rs index a6251648..313fcb3e 100644 --- a/fearless_simd_gen/src/mk_wasm.rs +++ b/fearless_simd_gen/src/mk_wasm.rs @@ -517,6 +517,14 @@ impl Level for WasmSimd128 { } } } + OpSig::SwizzleDyn => { + let precise = generic_op_name("swizzle_dyn_precise", vec_ty); + quote! { + #method_sig { + self.#precise(a, indices) + } + } + } OpSig::SwizzleDynPrecise => match vec_ty.n_bits() { 128 => { let bytes_ty = vec_ty.bytes_ty(); diff --git a/fearless_simd_gen/src/mk_x86.rs b/fearless_simd_gen/src/mk_x86.rs index 19e05a18..83b53ac3 100644 --- a/fearless_simd_gen/src/mk_x86.rs +++ b/fearless_simd_gen/src/mk_x86.rs @@ -310,6 +310,7 @@ impl Level for X86 { unreachable!("element moves use generic lowering") } OpSig::SwizzleDynWithinBlocks => self.handle_swizzle_dyn_within_blocks(op, vec_ty), + OpSig::SwizzleDyn => self.handle_swizzle_dyn(op, vec_ty), OpSig::SwizzleDynPrecise => self.handle_swizzle_dyn_precise(op, vec_ty), OpSig::Cvt { target_ty, @@ -2804,6 +2805,76 @@ impl X86 { }) } + pub(crate) fn handle_swizzle_dyn(&self, op: Op, vec_ty: &VecType) -> TokenStream { + let bytes_ty = vec_ty.bytes_ty(); + let bytes = bytes_ty.rust(); + let wrapper = bytes_ty.aligned_wrapper(); + + if *self == Self::Sse2 || (*self == Self::Sse4_2 && vec_ty.n_bits() == 512) { + return fallback_method(op, vec_ty); + } + + // Emulated double-native-width variants delegate to swizzle_dyn_precise + // because zeroes let us cheaply join the two halves, and on AVX2 zeroing is already very cheap + // through a clever trick: https://shnatsel.github.io/improving-std-simd-swizzle-dyn/#optimizing-avx2 + if matches!( + (*self, vec_ty.n_bits()), + (Self::Sse4_2, 256) | (Self::Avx2, 512) + ) { + let method_sig = op.simd_trait_method_sig(vec_ty); + let precise = generic_op_name("swizzle_dyn_precise", vec_ty); + return quote! { + #method_sig { + self.#precise(a, indices) + } + }; + } + + // lower into native ops for native-width vectors + self.kernel_method(op, vec_ty, |token| { + let body = match (*self, vec_ty.n_bits()) { + (Self::Sse4_2 | Self::Avx2, 128) => quote! { + let result = + _mm_shuffle_epi8(Bytes::to_bytes(a).val.0, indices.into()); + }, + (Self::Avx2, 256) => quote! { + let bytes = Bytes::to_bytes(a).val.0; + let indices = indices.into(); + let swapped = _mm256_permute2x128_si256::<0x01>(bytes, bytes); + let local = _mm256_shuffle_epi8(bytes, indices); + let remote = _mm256_shuffle_epi8(swapped, indices); + + // Move index bit 4 into each byte's sign bit for VPBLENDVB. + // The high output lane has the opposite local/remote mapping, + // so invert its blend controls. + let select_remote = _mm256_slli_epi16::<3>(indices); + let flip_high_lane = _mm256_set_m128i( + _mm_set1_epi8(i8::MIN), + _mm_setzero_si128(), + ); + let select_remote = _mm256_xor_si256(select_remote, flip_high_lane); + let result = _mm256_blendv_epi8(local, remote, select_remote); + }, + (Self::Avx512, 128 | 256 | 512) => { + let permute = intrinsic_ident("permutexvar", "epi8", vec_ty.n_bits()); + quote! { + let result = + #permute(indices.into(), Bytes::to_bytes(a).val.0); + } + } + _ => unreachable!(), + }; + + quote! { + #body + Bytes::from_bytes(#bytes { + val: #wrapper(result), + simd: #token, + }) + } + }) + } + pub(crate) fn handle_swizzle_dyn_precise(&self, op: Op, vec_ty: &VecType) -> TokenStream { let bytes_ty = vec_ty.bytes_ty(); let bytes = bytes_ty.rust(); diff --git a/fearless_simd_gen/src/ops.rs b/fearless_simd_gen/src/ops.rs index e401c55b..35ae2b8d 100644 --- a/fearless_simd_gen/src/ops.rs +++ b/fearless_simd_gen/src/ops.rs @@ -80,7 +80,10 @@ pub(crate) enum OpSig { /// dynamically swizzled within each 128-bit block. SwizzleDynWithinBlocks, /// Takes a vector and a same-width byte-index vector, and returns the original vector type with its bytes - /// dynamically swizzled across the whole vector. Out-of-range indices produce zero bytes. + /// dynamically swizzled across the whole vector. Out-of-range indices produce implementation-defined bytes. + SwizzleDyn, + /// Takes a vector and a same-width byte-index vector, and returns the original vector type with its bytes + /// dynamically swizzled across the whole vector. Out-of-range indices produce zero. SwizzleDynPrecise, /// Takes a single argument of the source vector type, and returns a vector type of the target scalar type and the /// same length. @@ -299,7 +302,7 @@ impl Op { OpSig::ElementRotate { .. } => (vec![vec.clone()], vec), OpSig::ElementShift { .. } => (vec![vec.clone(), splat_arg_ty(vec_ty)], vec), OpSig::Slide { .. } => (vec![vec.clone(), vec.clone()], vec), - OpSig::SwizzleDynWithinBlocks | OpSig::SwizzleDynPrecise => { + OpSig::SwizzleDynWithinBlocks | OpSig::SwizzleDyn | OpSig::SwizzleDynPrecise => { let bytes_ty = vec_ty.bytes_ty().rust(); (vec![vec.clone(), quote! { #bytes_ty<#simd_ty> }], vec) } @@ -391,7 +394,7 @@ impl Op { let arg1 = &arg_names[1]; quote! { (#arg0, #arg1: impl SimdInto) -> Self } } - OpSig::SwizzleDynWithinBlocks | OpSig::SwizzleDynPrecise => { + OpSig::SwizzleDynWithinBlocks | OpSig::SwizzleDyn | OpSig::SwizzleDynPrecise => { let arg0 = &arg_names[0]; let arg1 = &arg_names[1]; quote! { (#arg0, #arg1: impl SimdInto) -> Self } @@ -549,12 +552,20 @@ const BASE_OPS: &[Op] = &[ The `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\n\ Out-of-range index behavior varies by platform.", ), + Op::new( + "swizzle_dyn", + OpKind::BaseTraitMethod, + OpSig::SwizzleDyn, + "Dynamically swizzle this vector's bytes across the whole vector.\n\n\ + The `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\n\ + Use [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero.", + ), Op::new( "swizzle_dyn_precise", OpKind::BaseTraitMethod, OpSig::SwizzleDynPrecise, "Dynamically swizzle this vector's bytes across the whole vector.\n\n\ - The `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero bytes.", + The `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero.", ), ]; @@ -1453,8 +1464,8 @@ impl CoreOpTrait { } impl OpSig { - /// Determine whether a given operation should defer to the generic split/combine implementation, for a given vector - /// type and the maximum native vector width. + /// Determine whether a given operation should defer to its generic implementation, for a given vector type and the + /// maximum native vector width. pub(crate) fn should_use_generic_op(&self, vec_ty: &VecType, native_width: usize) -> bool { // For widen/narrow operations, we care about the *target* type's width. if let Self::WidenNarrow { target_ty } = self @@ -1475,6 +1486,7 @@ impl OpSig { | Self::LoadInterleaved { .. } | Self::StoreInterleaved { .. } | Self::MaskSet + | Self::SwizzleDyn | Self::SwizzleDynPrecise | Self::Slide { granularity: SlideGranularity::AcrossBlocks, @@ -1512,7 +1524,9 @@ impl OpSig { | Self::WidenNarrow { .. } | Self::MaskReduce { .. } | Self::MaskToBitmask => &["a"], - Self::SwizzleDynWithinBlocks | Self::SwizzleDynPrecise => &["a", "indices"], + Self::SwizzleDynWithinBlocks | Self::SwizzleDyn | Self::SwizzleDynPrecise => { + &["a", "indices"] + } Self::Binary | Self::Compare | Self::Combine { .. } @@ -1540,7 +1554,9 @@ impl OpSig { Self::Unary | Self::Cvt { .. } | Self::WidenNarrow { .. } | Self::MaskReduce { .. } => { &["self"] } - Self::SwizzleDynWithinBlocks | Self::SwizzleDynPrecise => &["self", "indices"], + Self::SwizzleDynWithinBlocks | Self::SwizzleDyn | Self::SwizzleDynPrecise => { + &["self", "indices"] + } Self::Binary | Self::Compare | Self::Zip { .. } @@ -1601,6 +1617,7 @@ impl OpSig { | Self::LoadInterleaved { .. } | Self::StoreInterleaved { .. } | Self::SwizzleDynWithinBlocks + | Self::SwizzleDyn | Self::SwizzleDynPrecise | Self::Slide { .. } => return None, }; diff --git a/fearless_simd_tests/tests/harness/ops/mod.rs b/fearless_simd_tests/tests/harness/ops/mod.rs index 0e6f6adf..ec845fdd 100644 --- a/fearless_simd_tests/tests/harness/ops/mod.rs +++ b/fearless_simd_tests/tests/harness/ops/mod.rs @@ -75,6 +75,7 @@ mod store_array; mod store_four_interleaved; mod store_slice; mod sub; +mod swizzle_dyn; mod swizzle_dyn_precise; mod swizzle_dyn_within_blocks; mod to_bitmask; diff --git a/fearless_simd_tests/tests/harness/ops/swizzle_dyn.rs b/fearless_simd_tests/tests/harness/ops/swizzle_dyn.rs new file mode 100644 index 00000000..5234152f --- /dev/null +++ b/fearless_simd_tests/tests/harness/ops/swizzle_dyn.rs @@ -0,0 +1,149 @@ +// Copyright 2026 the Fearless_SIMD Authors +// SPDX-License-Identifier: Apache-2.0 OR MIT + +use fearless_simd::*; +use fearless_simd_dev_macros::simd_test; + +fn assert_swizzle_dyn(bytes: [u8; N], indices: [u8; N], result: [u8; N]) { + for i in 0..N { + let index = indices[i] as usize; + if index < N { + assert_eq!(result[i], bytes[index], "output lane {i}, index {index}"); + } + } +} + +#[simd_test] +fn swizzle_dyn_u8x16(simd: S) { + let bytes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; + let indices = [15, 14, 0, 1, 16, 17, 31, 127, 128, 255, 8, 7, 6, 5, 4, 3]; + + let value = u8x16::simd_from(simd, bytes); + let index_vec = u8x16::simd_from(simd, indices); + let result = value.swizzle_dyn(index_vec); + + assert_swizzle_dyn(bytes, indices, *result); +} + +#[simd_test] +fn swizzle_dyn_u8x32_crosses_blocks(simd: S) { + let bytes: [u8; 32] = core::array::from_fn(|i| u8::try_from(i + 1).unwrap()); + let indices = [ + 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 0, 1, 2, 3, 4, 5, 6, 7, 32, + 33, 127, 128, 255, 15, 16, 31, + ]; + + let value = u8x32::simd_from(simd, bytes); + let index_vec = u8x32::simd_from(simd, indices); + let result = value.swizzle_dyn(index_vec); + + assert_swizzle_dyn(bytes, indices, *result); +} + +#[simd_test] +fn swizzle_dyn_u8x64_crosses_blocks(simd: S) { + let bytes: [u8; 64] = core::array::from_fn(|i| u8::try_from(i + 1).unwrap()); + let indices: [u8; 64] = core::array::from_fn(|i| { + if i % 7 == 0 { + u8::try_from(64 + i).unwrap() + } else { + u8::try_from((i * 17) % 64).unwrap() + } + }); + + let value = u8x64::simd_from(simd, bytes); + let index_vec = u8x64::simd_from(simd, indices); + let result = value.swizzle_dyn(index_vec); + + assert_swizzle_dyn(bytes, indices, *result); +} + +#[simd_test] +fn swizzle_dyn_bitcast_f32x8(simd: S) { + let bytes: [u8; 32] = core::array::from_fn(|i| u8::try_from(i * 3 + 1).unwrap()); + let indices = [ + 16, 17, 18, 19, 0, 1, 2, 3, 31, 30, 29, 28, 32, 33, 128, 255, 4, 5, 6, 7, 20, 21, 22, 23, + 27, 26, 25, 24, 15, 14, 13, 12, + ]; + + let byte_vec = u8x32::simd_from(simd, bytes); + let value: f32x8 = byte_vec.bitcast(); + let index_vec = u8x32::simd_from(simd, indices); + let result_bytes: u8x32 = value.swizzle_dyn(index_vec).bitcast(); + + assert_swizzle_dyn(bytes, indices, *result_bytes); +} + +#[simd_test] +fn swizzle_dyn_generic_indices(simd: S) { + #[inline(always)] + fn do_swizzle>(value: V, indices: V::Bytes) -> V { + value.swizzle_dyn(indices) + } + + let bytes: [u8; 32] = core::array::from_fn(|i| u8::try_from(i + 1).unwrap()); + let indices = [ + 16, 17, 18, 19, 20, 21, 22, 23, 31, 30, 29, 28, 27, 26, 25, 24, 0, 1, 2, 3, 4, 5, 6, 7, 32, + 64, 127, 128, 255, 8, 9, 10, + ]; + + let value = u8x32::simd_from(simd, bytes); + let index_vec = u8x32::simd_from(simd, indices); + let result = do_swizzle::>(value, index_vec); + + assert_swizzle_dyn(bytes, indices, *result); +} + +#[simd_test] +#[ignore = "this test is slow"] +// run with: cargo test --release swizzle_dyn_random_u8_all_widths -- --ignored +fn swizzle_dyn_random_u8_all_widths(simd: S) { + let mut rng = fastrand::Rng::with_seed(0x5eed_5eed_cafe_f00d); + + for iteration in 0..100_000 { + let mut bytes: [u8; 64] = [0; 64]; + let mut indices: [u8; 64] = [0; 64]; + rng.fill(&mut bytes); + rng.fill(&mut indices); + + let bytes16 = &bytes[..16]; + let indices16 = &indices[..16]; + let value16 = u8x16::from_slice(simd, bytes16); + let index_vec16 = u8x16::from_slice(simd, indices16); + let result16 = value16.swizzle_dyn(index_vec16); + assert_random_swizzle_dyn_from_slice(bytes16, indices16, *result16, iteration); + + let bytes32 = &bytes[..32]; + let indices32 = &indices[..32]; + let value32 = u8x32::from_slice(simd, bytes32); + let index_vec32 = u8x32::from_slice(simd, indices32); + let result32 = value32.swizzle_dyn(index_vec32); + assert_random_swizzle_dyn_from_slice(bytes32, indices32, *result32, iteration); + + let bytes64 = &bytes[..64]; + let indices64 = &indices[..64]; + let value64 = u8x64::from_slice(simd, bytes64); + let index_vec64 = u8x64::from_slice(simd, indices64); + let result64 = value64.swizzle_dyn(index_vec64); + assert_random_swizzle_dyn_from_slice(bytes64, indices64, *result64, iteration); + } +} + +fn assert_random_swizzle_dyn_from_slice( + bytes: &[u8], + indices: &[u8], + result: [u8; N], + iteration: usize, +) { + assert_eq!(bytes.len(), N); + assert_eq!(indices.len(), N); + for i in 0..N { + let index = indices[i] as usize; + if index < N { + assert_eq!( + result[i], bytes[index], + "iteration {iteration}, width {N}, output lane {i}, index {index}" + ); + } + } +}