1#![no_std]
2#![allow(non_camel_case_types)]
3#![warn(clippy::doc_markdown)]
4#![warn(clippy::missing_inline_in_public_items)]
5#![allow(clippy::eq_op)]
6#![allow(clippy::excessive_precision)]
7#![allow(clippy::let_and_return)]
8#![allow(clippy::unusual_byte_groupings)]
9#![allow(clippy::misrefactored_assign_op)]
10#![allow(clippy::approx_constant)]
11
12#[cfg(feature = "std")]
31extern crate std;
32
33use core::{
38 fmt::{
39 Binary, Debug, Display, LowerExp, LowerHex, Octal, UpperExp, UpperHex,
40 },
41 ops::*,
42};
43
44#[allow(unused_imports)]
45#[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
46use safe_arch::*;
47
48use bytemuck::*;
49
50#[cfg(feature = "serde")]
51use serde::{ser::SerializeTuple, Deserialize, Serialize};
52
53#[macro_use]
54mod macros;
55
56macro_rules! pick {
57 ($(if #[cfg($($test:meta),*)] {
58 $($if_tokens:tt)*
59 })else+ else {
60 $($else_tokens:tt)*
61 }) => {
62 pick!{
63 @__forests [ ] ;
64 $( [ {$($test),*} {$($if_tokens)*} ], )*
65 [ { } {$($else_tokens)*} ],
66 }
67 };
68 (if #[cfg($($if_meta:meta),*)] {
69 $($if_tokens:tt)*
70 } $(else if #[cfg($($else_meta:meta),*)] {
71 $($else_tokens:tt)*
72 })*) => {
73 pick!{
74 @__forests [ ] ;
75 [ {$($if_meta),*} {$($if_tokens)*} ],
76 $( [ {$($else_meta),*} {$($else_tokens)*} ], )*
77 }
78 };
79 (@__forests [$($not:meta,)*];) => {
80 };
82 (@__forests [$($not:meta,)*]; [{$($m:meta),*} {$($tokens:tt)*}], $($rest:tt)*) => {
83 #[cfg(all( $($m,)* not(any($($not),*)) ))]
84 pick!{ @__identity $($tokens)* }
85 pick!{ @__forests [ $($not,)* $($m,)* ] ; $($rest)* }
86 };
87 (@__identity $($tokens:tt)*) => {
88 $($tokens)*
89 };
90}
91
92macro_rules! polynomial_2 {
95 ($x:expr, $c0:expr, $c1:expr, $c2:expr $(,)?) => {{
96 let x = $x;
97 let x2 = x * x;
98 x2.mul_add($c2, x.mul_add($c1, $c0))
99 }};
100}
101
102macro_rules! polynomial_3 {
103 ($x:expr, $c0:expr, $c1:expr, $c2:expr, $c3:expr $(,)?) => {{
104 let x = $x;
105 let x2 = x * x;
106 $c3.mul_add(x, $c2).mul_add(x2, $c1.mul_add(x, $c0))
107 }};
108}
109
110macro_rules! polynomial_4 {
111 ($x:expr, $c0:expr, $c1:expr, $c2:expr ,$c3:expr, $c4:expr $(,)?) => {{
112 let x = $x;
113 let x2 = x * x;
114 let x4 = x2 * x2;
115 $c3.mul_add(x, $c2).mul_add(x2, $c1.mul_add(x, $c0)) + $c4 * x4
116 }};
117}
118
119macro_rules! polynomial_5 {
120 ($x:expr, $c0:expr, $c1:expr, $c2:expr, $c3:expr, $c4:expr, $c5:expr $(,)?) => {{
121 let x = $x;
122 let x2 = x * x;
123 let x4 = x2 * x2;
124 $c3
125 .mul_add(x, $c2)
126 .mul_add(x2, $c5.mul_add(x, $c4).mul_add(x4, $c1.mul_add(x, $c0)))
127 }};
128}
129
130macro_rules! polynomial_5n {
131 ($x:expr, $c0:expr, $c1:expr, $c2:expr, $c3:expr, $c4:expr $(,)?) => {{
132 let x = $x;
133 let x2 = x * x;
134 let x4 = x2 * x2;
135 x2.mul_add(x.mul_add($c3, $c2), (x4.mul_add($c4 + x, x.mul_add($c1, $c0))))
136 }};
137}
138
139macro_rules! polynomial_6 {
140 ($x:expr, $c0:expr, $c1:expr, $c2:expr, $c3:expr, $c4:expr, $c5:expr ,$c6:expr $(,)?) => {{
141 let x = $x;
142 let x2 = x * x;
143 let x4 = x2 * x2;
144 x4.mul_add(
145 x2.mul_add($c6, x.mul_add($c5, $c4)),
146 x2.mul_add(x.mul_add($c3, $c2), x.mul_add($c1, $c0)),
147 )
148 }};
149}
150
151macro_rules! polynomial_6n {
152 ($x:expr, $c0:expr, $c1:expr, $c2:expr, $c3:expr, $c4:expr, $c5:expr $(,)?) => {{
153 let x = $x;
154 let x2 = x * x;
155 let x4 = x2 * x2;
156 x4.mul_add(
157 x.mul_add($c5, x2 + $c4),
158 x2.mul_add(x.mul_add($c3, $c2), x.mul_add($c1, $c0)),
159 )
160 }};
161}
162
163macro_rules! polynomial_8 {
164 ($x:expr, $c0:expr, $c1:expr, $c2:expr, $c3:expr, $c4:expr, $c5:expr, $c6:expr, $c7:expr, $c8:expr $(,)?) => {{
165 let x = $x;
166 let x2 = x * x;
167 let x4 = x2 * x2;
168 let x8 = x4 * x4;
169 x4.mul_add(
170 x2.mul_add($c7.mul_add(x, $c6), x.mul_add($c5, $c4)),
171 x8.mul_add($c8, x2.mul_add(x.mul_add($c3, $c2), x.mul_add($c1, $c0))),
172 )
173 }};
174}
175
176macro_rules! polynomial_13 {
177 ($x:expr, $c2:expr, $c3:expr, $c4:expr, $c5:expr,$c6:expr, $c7:expr, $c8:expr,$c9:expr, $c10:expr, $c11:expr, $c12:expr, $c13:expr $(,)?) => {{
179 let x = $x;
180 let x2 = x * x;
181 let x4 = x2 * x2;
182 let x8 = x4 * x4;
183 x8.mul_add(
184 x4.mul_add(
185 x.mul_add($c13, $c12),
186 x2.mul_add(x.mul_add($c11, $c10), x.mul_add($c9, $c8)),
187 ),
188 x4.mul_add(
189 x2.mul_add(x.mul_add($c7, $c6), x.mul_add($c5, $c4)),
190 x2.mul_add(x.mul_add($c3, $c2), x),
191 ),
192 )
193 }};
194}
195
196macro_rules! polynomial_13m {
197 ($x:expr, $c2:expr, $c3:expr, $c4:expr, $c5:expr,$c6:expr, $c7:expr, $c8:expr,$c9:expr, $c10:expr, $c11:expr, $c12:expr, $c13:expr $(,)?) => {{
200 let x = $x;
201 let x2 = x * x;
202 let x4 = x2 * x2;
203 let x8 = x4 * x4;
204
205 x8.mul_add(
206 x4.mul_add(
207 x.mul_add($c13, $c12),
208 x2.mul_add(x.mul_add($c11, $c10), x.mul_add($c9, $c8)),
209 ),
210 x4.mul_add(
211 x2.mul_add(x.mul_add($c7, $c6), x.mul_add($c5, $c4)),
212 x2.mul_add(x.mul_add($c3, $c2), x),
213 ),
214 )
215 }};
216}
217
218mod f32x16_;
219pub use f32x16_::*;
220
221mod f32x8_;
222pub use f32x8_::*;
223
224mod f32x4_;
225pub use f32x4_::*;
226
227mod f64x8_;
228pub use f64x8_::*;
229
230mod f64x4_;
231pub use f64x4_::*;
232
233mod f64x2_;
234pub use f64x2_::*;
235
236mod i8x16_;
237pub use i8x16_::*;
238
239mod i16x16_;
240pub use i16x16_::*;
241
242mod i16x32_;
243pub use i16x32_::*;
244
245mod i8x32_;
246pub use i8x32_::*;
247
248mod i16x8_;
249pub use i16x8_::*;
250
251mod i32x4_;
252pub use i32x4_::*;
253
254mod i32x8_;
255pub use i32x8_::*;
256
257mod i32x16_;
258pub use i32x16_::*;
259
260mod i64x2_;
261pub use i64x2_::*;
262
263mod i64x4_;
264pub use i64x4_::*;
265
266mod i64x8_;
267pub use i64x8_::*;
268
269mod u8x16_;
270pub use u8x16_::*;
271
272mod u8x32_;
273pub use u8x32_::*;
274
275mod u16x8_;
276pub use u16x8_::*;
277
278mod u16x16_;
279pub use u16x16_::*;
280
281mod u16x32_;
282pub use u16x32_::*;
283
284mod u32x4_;
285pub use u32x4_::*;
286
287mod u32x8_;
288pub use u32x8_::*;
289
290mod u32x16_;
291pub use u32x16_::*;
292
293mod u64x2_;
294pub use u64x2_::*;
295
296mod u64x4_;
297pub use u64x4_::*;
298
299mod u64x8_;
300pub use u64x8_::*;
301
302#[allow(dead_code)]
303fn generic_bit_blend<T>(mask: T, y: T, n: T) -> T
304where
305 T: Copy + BitXor<Output = T> + BitAnd<Output = T>,
306{
307 n ^ ((n ^ y) & mask)
308}
309
310macro_rules! bulk_impl_op_ref_self_for {
312 ($(($op:ident, $method:ident) => [$($t:ty),+]),+ $(,)?) => {
313 $( $( impl $op<&Self> for $t {
316 type Output = Self;
317 #[inline]
318 fn $method(self, rhs: &Self) -> Self::Output {
319 self.$method(*rhs)
320 }
321 }
322 )+
323 )+
324 };
325}
326
327bulk_impl_op_ref_self_for! {
328 (Add, add) => [f32x16, f32x8, f32x4, f64x8, f64x4, f64x2, i8x32, i8x16, i16x8, i16x16, i16x32, i32x8, i32x4, i32x16, i64x2, i64x4, i64x8, u8x32, u8x16, u16x8, u16x16, u16x32, u32x8, u32x4, u32x16, u64x4, u64x2, u64x8],
329 (Sub, sub) => [f32x16, f32x8, f32x4, f64x8, f64x4, f64x2, i8x32, i8x16, i16x8, i16x16, i16x32, i32x8, i32x4, i32x16, i64x2, i64x4, i64x8, u8x32, u8x16, u16x8, u16x16, u16x32, u32x8, u32x4, u32x16, u64x4, u64x2, u64x8],
330 (Mul, mul) => [f32x16, f32x8, f32x4, f64x8, f64x4, f64x2, i16x8, i16x16, i16x32, i32x8, i32x4, i32x16, u16x8, u16x16, u16x32],
331 (Div, div) => [f32x16, f32x8, f32x4, f64x8, f64x4, f64x2],
332 (BitAnd, bitand) => [f32x16, f32x8, f32x4, f64x8, f64x4, f64x2, i8x32, i8x16, i16x8, i16x16, i16x32, i32x8, i32x4, i32x16, i64x2, i64x4, i64x8, u8x32, u8x16, u16x8, u16x16, u16x32, u32x8, u32x4, u32x16, u64x4, u64x2, u64x8],
333 (BitOr, bitor) => [f32x16, f32x8, f32x4, f64x8, f64x4, f64x2, i8x32, i8x16, i16x8, i16x16, i16x32, i32x8, i32x4, i32x16, i64x2, i64x4, i64x8, u8x32, u8x16, u16x8, u16x16, u16x32, u32x8, u32x4, u32x16, u64x4, u64x2, u64x8],
334 (BitXor, bitxor) => [f32x16, f32x8, f32x4, f64x8, f64x4, f64x2, i8x32, i8x16, i16x8, i16x16, i16x32, i32x8, i32x4, i32x16, i64x2, i64x4, i64x8, u8x32, u8x16, u16x8, u16x16, u16x32, u32x8, u32x4, u32x16, u64x4, u64x2, u64x8],
335}
336
337macro_rules! bulk_impl_op_assign_for {
339 ($(($op:ident<$rhs:ty>, $method:ident, $method_assign:ident) => [$($t:ty),+]),+ $(,)?) => {
340 $( $( impl $op<$rhs> for $t {
343 #[inline]
344 fn $method_assign(&mut self, rhs: $rhs) {
345 *self = self.$method(rhs);
346 }
347 }
348 )+
349 )+
350 };
351}
352
353bulk_impl_op_assign_for! {
356 (AddAssign<Self>, add, add_assign) => [f32x16, f32x8, f32x4, f64x8, f64x4, f64x2, i8x32, i8x16, i16x8, i16x16, i16x32, i32x8, i32x4, i32x16, i64x2, i64x4, i64x8, u8x32, u8x16, u16x8, u16x16, u16x32, u32x8, u32x4, u32x16, u64x4, u64x2, u64x8],
357 (AddAssign<&Self>, add, add_assign) => [f32x16, f32x8, f32x4, f64x8, f64x4, f64x2, i8x32, i8x16, i16x8, i16x16, i16x32, i32x8, i32x4, i32x16, i64x2, i64x4, i64x8, u8x32, u8x16, u16x8, u16x16, u16x32, u32x8, u32x4, u32x16, u64x4, u64x2, u64x8],
358 (SubAssign<Self>, sub, sub_assign) => [f32x16, f32x8, f32x4, f64x8, f64x4, f64x2, i8x32, i8x16, i16x8, i16x16, i16x32, i32x8, i32x4, i32x16, i64x2, i64x4, i64x8, u8x32, u8x16, u16x8, u16x16, u16x32, u32x8, u32x4, u32x16, u64x4, u64x2, u64x8],
359 (SubAssign<&Self>, sub, sub_assign) => [f32x16, f32x8, f32x4, f64x8, f64x4, f64x2, i8x32, i8x16, i16x8, i16x16, i16x32, i32x8, i32x4, i32x16, i64x2, i64x4, i64x8, u8x32, u8x16, u16x8, u16x16, u16x32, u32x8, u32x4, u32x16, u64x4, u64x2, u64x8],
360 (MulAssign<Self>, mul, mul_assign) => [f32x16, f32x8, f32x4, f64x8, f64x4, f64x2, i16x8, i16x16, i16x32, i32x8, i32x4, i32x16, u16x8, u16x16, u16x32],
361 (MulAssign<&Self>, mul, mul_assign) => [f32x16, f32x8, f32x4, f64x8, f64x4, f64x2, i16x8, i16x16, i16x32, i32x8, i32x4, i32x16, u16x8, u16x16, u16x32],
362 (DivAssign<Self>, div, div_assign) => [f32x16, f32x8, f32x4, f64x8, f64x4, f64x2],
363 (DivAssign<&Self>, div, div_assign) => [f32x16, f32x8, f32x4, f64x8, f64x4, f64x2],
364 (BitAndAssign<Self>, bitand, bitand_assign) => [f32x16, f32x8, f32x4, f64x8, f64x4, f64x2, i8x32, i8x16, i16x8, i16x16, i16x32, u16x16, u16x32, i32x8, i32x4, i32x16, i64x2, i64x4, i64x8, u8x32, u8x16, u16x8, u32x8, u32x4, u32x16, u64x4, u64x2, u64x8],
365 (BitAndAssign<&Self>, bitand, bitand_assign) => [f32x16, f32x8, f32x4, f64x8, f64x4, f64x2, i8x32, i8x16, i16x8, i16x16, i16x32, u16x16, u16x32, i32x8, i32x4, i32x16, i64x2, i64x4, i64x8, u8x32, u8x16, u16x8, u32x8, u32x4, u32x16, u64x4, u64x2, u64x8],
366 (BitOrAssign<Self>, bitor, bitor_assign) => [f32x16, f32x8, f32x4, f64x8, f64x4, f64x2, i8x32, i8x16, i16x8, i16x16, i16x32, u16x16, u16x32, i32x8, i32x4, i32x16, i64x2, i64x4, i64x8, u8x32, u8x16, u16x8, u32x8, u32x4, u32x16, u64x4, u64x2, u64x8],
367 (BitOrAssign<&Self>, bitor, bitor_assign) => [f32x16, f32x8, f32x4, f64x8, f64x4, f64x2, i8x32, i8x16, i16x8, i16x16, i16x32, u16x16, u16x32, i32x8, i32x4, i32x16, i64x2, i64x4, i64x8, u8x32, u8x16, u16x8, u32x8, u32x4, u32x16, u64x4, u64x2, u64x8],
368 (BitXorAssign<Self>, bitxor, bitxor_assign) => [f32x16, f32x8, f32x4, f64x8, f64x4, f64x2, i8x32, i8x16, i16x8, i16x16, i16x32, u16x16, u16x32, i32x8, i32x4, i32x16, i64x2, i64x4, i64x8, u8x32, u8x16, u16x8, u32x8, u32x4, u32x16, u64x4, u64x2, u64x8],
369 (BitXorAssign<&Self>, bitxor, bitxor_assign) => [f32x16, f32x8, f32x4, f64x8, f64x4, f64x2, i8x32, i8x16, i16x8, i16x16, i16x32, u16x16, u16x32, i32x8, i32x4, i32x16, i64x2, i64x4, i64x8, u8x32, u8x16, u16x8, u32x8, u32x4, u32x16, u64x4, u64x2, u64x8],
370}
371
372macro_rules! impl_integer_neg {
373 ($($t:ty),+ $(,)?) => {
374 $(
375 impl Neg for $t {
376 type Output = Self;
377 #[inline(always)]
378 fn neg(self) -> Self::Output {
379 Self::default() - self
380 }
381 }
382 impl Neg for &'_ $t {
383 type Output = $t;
384 #[inline(always)]
385 fn neg(self) -> Self::Output {
386 <$t>::default() - *self
387 }
388 }
389 )+
390 };
391}
392
393impl_integer_neg! {
394 i8x32, i8x16, i16x8, i16x16, i16x32, i32x8, i32x4, i32x16, i64x4, i64x2, i64x8, u8x32, u8x16, u16x8, u16x16, u16x32, u32x8, u32x4, u32x16, u64x2, u64x4, u64x8
395}
396
397macro_rules! impl_simple_not {
399 ($($t:ty),+ $(,)?) => {
400 $(
401 impl Not for $t {
402 type Output = Self;
403 #[inline]
404 fn not(self) -> Self::Output {
405 self ^ cast::<u128, $t>(u128::MAX)
406 }
407 }
408 impl Not for &'_ $t {
409 type Output = $t;
410 #[inline]
411 fn not(self) -> Self::Output {
412 *self ^ cast::<u128, $t>(u128::MAX)
413 }
414 }
415 )+
416 };
417}
418
419impl_simple_not! {
420 f32x4, i8x16, i16x8, i32x4, i64x2, u8x16, u16x8, u32x4, u64x2,
421}
422
423macro_rules! impl_simple_sum {
424 ($($t:ty),+ $(,)?) => {
425 $(
426 impl<RHS> core::iter::Sum<RHS> for $t where $t: AddAssign<RHS> {
427 #[inline]
428 fn sum<I: Iterator<Item = RHS>>(iter: I) -> Self {
429 let mut total = Self::zeroed();
430 for val in iter {
431 total += val;
432 }
433 total
434 }
435 }
436 )+
437 };
438}
439
440impl_simple_sum! {
441 f32x16, f32x4, f64x8, f64x4, f64x2, i8x32, i8x16, i16x8, i16x16, i16x32, i32x8, i32x4, i32x16, i64x4, i64x2, i64x8, u8x32, u8x16, u16x8, u16x16, u16x32, u32x8, u32x4, u32x16, u64x2, u64x4, u64x8
442}
443
444macro_rules! impl_floating_product {
445 ($($t:ty),+ $(,)?) => {
446 $(
447 impl<RHS> core::iter::Product<RHS> for $t where $t: MulAssign<RHS> {
448 #[inline]
449 fn product<I: Iterator<Item = RHS>>(iter: I) -> Self {
450 let mut total = Self::from(1.0);
451 for val in iter {
452 total *= val;
453 }
454 total
455 }
456 }
457 )+
458 };
459}
460
461impl_floating_product! {
462 f32x16, f32x8, f32x4, f64x8, f64x4, f64x2
463}
464
465macro_rules! impl_integer_product {
466 ($($t:ty),+ $(,)?) => {
467 $(
468 impl<RHS> core::iter::Product<RHS> for $t where $t: MulAssign<RHS> {
469 #[inline]
470 fn product<I: Iterator<Item = RHS>>(iter: I) -> Self {
471 let mut total = Self::from(1);
472 for val in iter {
473 total *= val;
474 }
475 total
476 }
477 }
478 )+
479 };
480}
481
482impl_integer_product! {
483 i16x8, i16x32, i32x4, i32x8, i32x16,
484}
485
486macro_rules! impl_from_a_for_b_with_cast {
488 ($(($arr:ty, $simd:ty)),+ $(,)?) => {
489 $(impl From<$arr> for $simd {
490 #[inline]
491 fn from(arr: $arr) -> Self {
492 cast(arr)
493 }
494 }
495 impl From<$simd> for $arr {
496 #[inline]
497 fn from(simd: $simd) -> Self {
498 cast(simd)
499 }
500 })+
501 };
502}
503
504impl_from_a_for_b_with_cast! {
505 ([f32;16], f32x16), ([f32;8], f32x8),
506 ([f32;4], f32x4), ([f64;8], f64x8), ([f64;4], f64x4), ([f64;2], f64x2),
507 ([i8;32], i8x32), ([i8;16], i8x16), ([i16;8], i16x8), ([i16;16], i16x16), ([i16;32], i16x32), ([i32;8], i32x8), ([i32;4], i32x4), ([i32;16], i32x16), ([i64;2], i64x2), ([i64;4], i64x4), ([i64;8], i64x8),
508 ([u8;32], u8x32), ([u8;16], u8x16), ([u16;8], u16x8), ([u16;16], u16x16), ([u16;32], u16x32), ([u32;8], u32x8), ([u32;4], u32x4), ([u32;16], u32x16), ([u64;2], u64x2), ([u64;4], u64x4), ([u64;8], u64x8),
509}
510
511macro_rules! impl_from_single_value {
512 ($(([$elem:ty;$len:expr], $simd:ty)),+ $(,)?) => {
513 $(impl From<$elem> for $simd {
514 #[inline]
516 fn from(elem: $elem) -> Self {
517 cast([elem; $len])
518 }
519 }
520 impl $simd {
521 #[inline]
522 #[must_use]
523 pub const fn splat(elem: $elem) -> $simd {
524 unsafe { core::mem::transmute([elem; $len]) }
525 }
526 })+
527 };
528}
529
530impl_from_single_value! {
531 ([f32;16], f32x16), ([f32;8], f32x8),
532 ([f32;4], f32x4), ([f64;8], f64x8), ([f64;4], f64x4), ([f64;2], f64x2),
533 ([i8;32], i8x32), ([i8;16], i8x16), ([i16;8], i16x8), ([i16;16], i16x16), ([i16;32], i16x32), ([i32;8], i32x8), ([i32;4], i32x4), ([i32;16], i32x16), ([i64;2], i64x2), ([i64;4], i64x4), ([i64;8], i64x8),
534 ([u8;32], u8x32), ([u8;16], u8x16), ([u16;8], u16x8), ([u16;16], u16x16), ([u16;32], u16x32), ([u32;8], u32x8), ([u32;4], u32x4), ([u32;16], u32x16), ([u64;2], u64x2), ([u64;4], u64x4), ([u64;8], u64x8),
535}
536
537macro_rules! impl_formatter_for {
539 ($($trait:ident => [$(($arr:ty, $simd:ty)),+]),+ $(,)?) => {
540 $( $( impl $trait for $simd {
543 #[allow(clippy::missing_inline_in_public_items)]
544 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
545 let a: $arr = cast(*self);
546 write!(f, "(")?;
547 for (x, a_ref) in a.iter().enumerate() {
548 if x > 0 {
549 write!(f, ", ")?;
550 }
551 $trait::fmt(a_ref, f)?;
552 }
553 write!(f, ")")
554 }
555 }
556 )+
557 )+
558 }
559}
560
561impl_formatter_for! {
562 Binary => [([u32;16], f32x16), ([u32;8], f32x8), ([u32;4], f32x4), ([u64;8], f64x8), ([u64;4], f64x4), ([u64;2], f64x2),
563 ([i8;32], i8x32), ([i8;16], i8x16), ([i16;8], i16x8), ([i16;16], i16x16), ([i16;32], i16x32), ([i32;8], i32x8), ([i32;4], i32x4), ([i32;16], i32x16), ([i64;2], i64x2),([i64;4], i64x4),([i64;8], i64x8),
564 ([u8;32], u8x32), ([u8;16], u8x16), ([u16;8], u16x8), ([u16;16], u16x16), ([u16;32], u16x32), ([u32;8], u32x8), ([u32;4], u32x4), ([u32;16], u32x16), ([u64;2], u64x2),([u64;4], u64x4),([u64;8], u64x8)],
565 Debug => [([f32;16], f32x16), ([f32;8], f32x8), ([f32;4], f32x4), ([f64;8], f64x8), ([f64;4], f64x4), ([f64;2], f64x2),
566 ([i8;32], i8x32), ([i8;16], i8x16), ([i16;8], i16x8), ([i16;16], i16x16), ([i16;32], i16x32), ([i32;8], i32x8), ([i32;4], i32x4), ([i32;16], i32x16), ([i64;2], i64x2),([i64;4], i64x4),([i64;8], i64x8),
567 ([u8;32], u8x32), ([u8;16], u8x16), ([u16;8], u16x8), ([u16;16], u16x16), ([u16;32], u16x32), ([u32;8], u32x8), ([u32;4], u32x4), ([u32;16], u32x16), ([u64;2], u64x2),([u64;4], u64x4),([u64;8], u64x8)],
568 Display => [([f32;16], f32x16), ([f32;8], f32x8), ([f32;4], f32x4), ([f64;8], f64x8), ([f64;4], f64x4), ([f64;2], f64x2),
569 ([i8;32], i8x32), ([i8;16], i8x16), ([i16;8], i16x8), ([i16;16], i16x16), ([i16;32], i16x32), ([i32;8], i32x8), ([i32;4], i32x4), ([i32;16], i32x16), ([i64;2], i64x2),([i64;4], i64x4),([i64;8], i64x8),
570 ([u8;32], u8x32), ([u8;16], u8x16), ([u16;8], u16x8), ([u16;16], u16x16), ([u16;32], u16x32), ([u32;8], u32x8), ([u32;4], u32x4), ([u32;16], u32x16), ([u64;2], u64x2),([u64;4], u64x4),([u64;8], u64x8)],
571 LowerExp => [([f32;16], f32x16), ([f32;8], f32x8), ([f32;4], f32x4), ([f64;8], f64x8), ([f64;4], f64x4), ([f64;2], f64x2),
572 ([i8;32], i8x32), ([i8;16], i8x16), ([i16;8], i16x8), ([i16;16], i16x16), ([i16;32], i16x32), ([i32;8], i32x8), ([i32;4], i32x4), ([i32;16], i32x16), ([i64;2], i64x2),([i64;4], i64x4),([i64;8], i64x8),
573 ([u8;32], u8x32), ([u8;16], u8x16), ([u16;8], u16x8), ([u16;16], u16x16), ([u16;32], u16x32), ([u32;8], u32x8), ([u32;4], u32x4), ([u32;16], u32x16), ([u64;2], u64x2),([u64;4], u64x4),([u64;8], u64x8)],
574 LowerHex => [([u32;16], f32x16), ([u32;8], f32x8), ([u32;4], f32x4), ([u64;8], f64x8), ([u64;4], f64x4), ([u64;2], f64x2),
575 ([i8;32], i8x32), ([i8;16], i8x16), ([i16;8], i16x8), ([i16;16], i16x16), ([i16;32], i16x32), ([i32;8], i32x8), ([i32;4], i32x4), ([i32;16], i32x16), ([i64;2], i64x2),([i64;4], i64x4),([i64;8], i64x8),
576 ([u8;32], u8x32), ([u8;16], u8x16), ([u16;8], u16x8), ([u16;16], u16x16), ([u16;32], u16x32), ([u32;8], u32x8), ([u32;4], u32x4), ([u32;16], u32x16), ([u64;2], u64x2),([u64;4], u64x4),([u64;8], u64x8)],
577 Octal => [([u32;16], f32x16), ([u32;8], f32x8), ([u32;4], f32x4), ([u64;8], f64x8), ([u64;4], f64x4), ([u64;2], f64x2),
578 ([i8;32], i8x32), ([i8;16], i8x16), ([i16;8], i16x8), ([i16;16], i16x16), ([i16;32], i16x32), ([i32;8], i32x8), ([i32;4], i32x4), ([i32;16], i32x16), ([i64;2], i64x2),([i64;4], i64x4),([i64;8], i64x8),
579 ([u8;32], u8x32), ([u8;16], u8x16), ([u16;8], u16x8), ([u16;16], u16x16), ([u16;32], u16x32), ([u32;8], u32x8), ([u32;4], u32x4), ([u32;16], u32x16), ([u64;2], u64x2),([u64;4], u64x4),([u64;8], u64x8)],
580 UpperExp => [([u32;16], f32x16), ([u32;8], f32x8), ([u32;4], f32x4), ([u64;8], f64x8), ([u64;4], f64x4), ([u64;2], f64x2),
581 ([i8;32], i8x32), ([i8;16], i8x16), ([i16;8], i16x8), ([i16;16], i16x16), ([i16;32], i16x32), ([i32;8], i32x8), ([i32;4], i32x4), ([i32;16], i32x16), ([i64;2], i64x2),([i64;4], i64x4),([i64;8], i64x8),
582 ([u8;32], u8x32), ([u8;16], u8x16), ([u16;8], u16x8), ([u16;16], u16x16), ([u16;32], u16x32), ([u32;8], u32x8), ([u32;4], u32x4), ([u32;16], u32x16), ([u64;2], u64x2),([u64;4], u64x4),([u64;8], u64x8)],
583 UpperHex => [([u32;16], f32x16), ([u32;8], f32x8), ([u32;4], f32x4), ([u64;8], f64x8), ([u64;4], f64x4), ([u64;2], f64x2),
584 ([i8;32], i8x32), ([i8;16], i8x16), ([i16;8], i16x8), ([i16;16], i16x16), ([i16;32], i16x32), ([i32;8], i32x8), ([i32;4], i32x4), ([i32;16], i32x16), ([i64;2], i64x2),([i64;4], i64x4),([i64;8], i64x8),
585 ([u8;32], u8x32), ([u8;16], u8x16), ([u16;8], u16x8), ([u16;16], u16x16), ([u16;32], u16x32), ([u32;8], u32x8), ([u32;4], u32x4), ([u32;16], u32x16), ([u64;2], u64x2),([u64;4], u64x4),([u64;8], u64x8)],
586}
587
588macro_rules! from_array {
590 ($ty:ty,$dst:ty,$dst_wide:ident,32) => {
591 impl From<&[$ty]> for $dst_wide {
592 #[inline]
593 fn from(src: &[$ty]) -> $dst_wide {
594 match src.len() {
595 32 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst, src[9] as $dst, src[10] as $dst, src[11] as $dst, src[12] as $dst, src[13] as $dst, src[14] as $dst, src[15] as $dst, src[16] as $dst, src[17] as $dst, src[18] as $dst, src[19] as $dst, src[20] as $dst, src[21] as $dst, src[22] as $dst, src[23] as $dst, src[24] as $dst, src[25] as $dst, src[26] as $dst, src[27] as $dst, src[28] as $dst, src[29] as $dst, src[30] as $dst, src[31] as $dst,]),
596 31 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst, src[9] as $dst, src[10] as $dst, src[11] as $dst, src[12] as $dst, src[13] as $dst, src[14] as $dst, src[15] as $dst, src[16] as $dst, src[17] as $dst, src[18] as $dst, src[19] as $dst, src[20] as $dst, src[21] as $dst, src[22] as $dst, src[23] as $dst, src[24] as $dst, src[25] as $dst, src[26] as $dst, src[27] as $dst, src[28] as $dst, src[29] as $dst, src[30] as $dst,0 as $dst,]),
597 30 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst, src[9] as $dst, src[10] as $dst, src[11] as $dst, src[12] as $dst, src[13] as $dst, src[14] as $dst, src[15] as $dst, src[16] as $dst, src[17] as $dst, src[18] as $dst, src[19] as $dst, src[20] as $dst, src[21] as $dst, src[22] as $dst, src[23] as $dst, src[24] as $dst, src[25] as $dst, src[26] as $dst, src[27] as $dst, src[28] as $dst, src[29] as $dst,0 as $dst,0 as $dst,]),
598 29 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst, src[9] as $dst, src[10] as $dst, src[11] as $dst, src[12] as $dst, src[13] as $dst, src[14] as $dst, src[15] as $dst, src[16] as $dst, src[17] as $dst, src[18] as $dst, src[19] as $dst, src[20] as $dst, src[21] as $dst, src[22] as $dst, src[23] as $dst, src[24] as $dst, src[25] as $dst, src[26] as $dst, src[27] as $dst, src[28] as $dst,0 as $dst,0 as $dst,0 as $dst,]),
599 28 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst, src[9] as $dst, src[10] as $dst, src[11] as $dst, src[12] as $dst, src[13] as $dst, src[14] as $dst, src[15] as $dst, src[16] as $dst, src[17] as $dst, src[18] as $dst, src[19] as $dst, src[20] as $dst, src[21] as $dst, src[22] as $dst, src[23] as $dst, src[24] as $dst, src[25] as $dst, src[26] as $dst, src[27] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
600 27 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst, src[9] as $dst, src[10] as $dst, src[11] as $dst, src[12] as $dst, src[13] as $dst, src[14] as $dst, src[15] as $dst, src[16] as $dst, src[17] as $dst, src[18] as $dst, src[19] as $dst, src[20] as $dst, src[21] as $dst, src[22] as $dst, src[23] as $dst, src[24] as $dst, src[25] as $dst, src[26] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
601 26 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst, src[9] as $dst, src[10] as $dst, src[11] as $dst, src[12] as $dst, src[13] as $dst, src[14] as $dst, src[15] as $dst, src[16] as $dst, src[17] as $dst, src[18] as $dst, src[19] as $dst, src[20] as $dst, src[21] as $dst, src[22] as $dst, src[23] as $dst, src[24] as $dst, src[25] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
602 25 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst, src[9] as $dst, src[10] as $dst, src[11] as $dst, src[12] as $dst, src[13] as $dst, src[14] as $dst, src[15] as $dst, src[16] as $dst, src[17] as $dst, src[18] as $dst, src[19] as $dst, src[20] as $dst, src[21] as $dst, src[22] as $dst, src[23] as $dst, src[24] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
603 24 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst, src[9] as $dst, src[10] as $dst, src[11] as $dst, src[12] as $dst, src[13] as $dst, src[14] as $dst, src[15] as $dst, src[16] as $dst, src[17] as $dst, src[18] as $dst, src[19] as $dst, src[20] as $dst, src[21] as $dst, src[22] as $dst, src[23] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
604 23 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst, src[9] as $dst, src[10] as $dst, src[11] as $dst, src[12] as $dst, src[13] as $dst, src[14] as $dst, src[15] as $dst, src[16] as $dst, src[17] as $dst, src[18] as $dst, src[19] as $dst, src[20] as $dst, src[21] as $dst, src[22] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
605 22 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst, src[9] as $dst, src[10] as $dst, src[11] as $dst, src[12] as $dst, src[13] as $dst, src[14] as $dst, src[15] as $dst, src[16] as $dst, src[17] as $dst, src[18] as $dst, src[19] as $dst, src[20] as $dst, src[21] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
606 21 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst, src[9] as $dst, src[10] as $dst, src[11] as $dst, src[12] as $dst, src[13] as $dst, src[14] as $dst, src[15] as $dst, src[16] as $dst, src[17] as $dst, src[18] as $dst, src[19] as $dst, src[20] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
607 20 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst, src[9] as $dst, src[10] as $dst, src[11] as $dst, src[12] as $dst, src[13] as $dst, src[14] as $dst, src[15] as $dst, src[16] as $dst, src[17] as $dst, src[18] as $dst, src[19] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
608 19 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst, src[9] as $dst, src[10] as $dst, src[11] as $dst, src[12] as $dst, src[13] as $dst, src[14] as $dst, src[15] as $dst, src[16] as $dst, src[17] as $dst, src[18] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
609 18 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst, src[9] as $dst, src[10] as $dst, src[11] as $dst, src[12] as $dst, src[13] as $dst, src[14] as $dst, src[15] as $dst, src[16] as $dst, src[17] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
610 17 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst, src[9] as $dst, src[10] as $dst, src[11] as $dst, src[12] as $dst, src[13] as $dst, src[14] as $dst, src[15] as $dst, src[16] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
611 16 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst, src[9] as $dst, src[10] as $dst, src[11] as $dst, src[12] as $dst, src[13] as $dst, src[14] as $dst, src[15] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
612 15 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst, src[9] as $dst, src[10] as $dst, src[11] as $dst, src[12] as $dst, src[13] as $dst, src[14] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
613 14 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst, src[9] as $dst, src[10] as $dst, src[11] as $dst, src[12] as $dst, src[13] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
614 13 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst, src[9] as $dst, src[10] as $dst, src[11] as $dst, src[12] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
615 12 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst, src[9] as $dst, src[10] as $dst, src[11] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
616 11 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst, src[9] as $dst, src[10] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
617 10 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst, src[9] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
618 9 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
619 8 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
620 7 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
621 6 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
622 5 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
623 4 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
624 3 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
625 2 => $dst_wide::from([src[0] as $dst, src[1] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
626 1 => $dst_wide::from([src[0] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
627 _ => panic!(
628 "Converting from an array larger than what can be stored in $dst_wide"
629 ),
630 }
631 }
632 }
633 };
634 ($ty:ty,$dst:ty,$dst_wide:ident,16) => {
635 impl From<&[$ty]> for $dst_wide {
636 #[inline]
637 fn from(src: &[$ty]) -> $dst_wide {
638 match src.len() {
639 16 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst, src[9] as $dst, src[10] as $dst, src[11] as $dst, src[12] as $dst, src[13] as $dst, src[14] as $dst, src[15] as $dst,]),
640 15 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst, src[9] as $dst, src[10] as $dst, src[11] as $dst, src[12] as $dst, src[13] as $dst, src[14] as $dst,0 as $dst,]),
641 14 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst, src[9] as $dst, src[10] as $dst, src[11] as $dst, src[12] as $dst, src[13] as $dst,0 as $dst,0 as $dst,]),
642 13 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst, src[9] as $dst, src[10] as $dst, src[11] as $dst, src[12] as $dst,0 as $dst,0 as $dst,0 as $dst,]),
643 12 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst, src[9] as $dst, src[10] as $dst, src[11] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
644 11 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst, src[9] as $dst, src[10] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
645 10 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst, src[9] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
646 9 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst, src[8] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
647 8 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
648 7 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
649 6 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
650 5 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
651 4 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
652 3 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
653 2 => $dst_wide::from([src[0] as $dst, src[1] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
654 1 => $dst_wide::from([src[0] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
655 _ => panic!(
656 "Converting from an array larger than what can be stored in $dst_wide"
657 ),
658 }
659 }
660 }
661 };
662 ($ty:ty,$dst:ty,$dst_wide:ident,8) => {
663 impl From<&[$ty]> for $dst_wide {
664 #[inline]
665 fn from(src: &[$ty]) -> $dst_wide {
666 match src.len() {
667 8 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst, src[7] as $dst,]),
668 7 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst, src[6] as $dst,0 as $dst,]),
669 6 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst, src[5] as $dst,0 as $dst,0 as $dst,]),
670 5 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst, src[4] as $dst,0 as $dst,0 as $dst,0 as $dst,]),
671 4 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
672 3 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
673 2 => $dst_wide::from([src[0] as $dst, src[1] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
674 1 => $dst_wide::from([src[0] as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
675 0 => $dst_wide::from([0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,0 as $dst,]),
676 _ => panic!(
677 "Converting from an array larger than what can be stored in $dst_wide"
678 ),
679 }
680 }
681 }
682 };
683 ($ty:ty,$dst:ty,$dst_wide:ident,4) => {
684 impl From<&[$ty]> for $dst_wide {
685 #[inline]
686 fn from(src: &[$ty]) -> $dst_wide {
687 match src.len() {
688 4 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst, src[3] as $dst,]),
689 3 => $dst_wide::from([src[0] as $dst, src[1] as $dst, src[2] as $dst,0 as $dst,]),
690 2 => $dst_wide::from([src[0] as $dst, src[1] as $dst,0 as $dst,0 as $dst,]),
691 1 => $dst_wide::from([src[0] as $dst,0 as $dst,0 as $dst,0 as $dst,]),
692 _ => panic!(
693 "Converting from an array larger than what can be stored in $dst_wide"
694 ),
695 }
696 }
697 }
698 };
699}
700
701from_array!(i8, i8, i8x32, 32);
702from_array!(i8, i8, i8x16, 16);
703from_array!(i8, i32, i32x8, 8);
704from_array!(u8, u8, u8x16, 16);
705from_array!(u8, u8, u8x32, 32);
706from_array!(i16, i16, i16x16, 16);
707from_array!(u16, u16, u16x16, 16);
708from_array!(i32, i32, i32x8, 8);
709from_array!(f32, f32, f32x8, 8);
710from_array!(f32, f32, f32x4, 4);
711from_array!(f64, f64, f64x4, 4);
712from_array!(u64, u64, u64x4, 4);
713from_array!(i64, i64, i64x4, 4);
714from_array!(u64, u64, u64x8, 8);
715from_array!(i64, i64, i64x8, 8);
716from_array!(i16, i16, i16x32, 32);
717from_array!(u16, u16, u16x32, 32);
718from_array!(i32, i32, i32x16, 16);
719from_array!(u32, u32, u32x16, 16);
720from_array!(f32, f32, f32x16, 16);
721from_array!(f64, f64, f64x8, 8);
722
723#[allow(unused)]
724fn software_sqrt(x: f64) -> f64 {
725 use core::num::Wrapping;
726 type wu32 = Wrapping<u32>;
727 const fn w(u: u32) -> wu32 {
728 Wrapping(u)
729 }
730 let mut z: f64;
731 let sign: wu32 = w(0x80000000);
732 let mut ix0: i32;
733 let mut s0: i32;
734 let mut q: i32;
735 let mut m: i32;
736 let mut t: i32;
737 let mut i: i32;
738 let mut r: wu32;
739 let mut t1: wu32;
740 let mut s1: wu32;
741 let mut ix1: wu32;
742 let mut q1: wu32;
743 pick! {
746 if #[cfg(target_endian = "little")]
747 {
748 let [low, high]: [u32; 2] = cast(x);
749 ix0 = high as i32;
750 ix1 = w(low);
751 }
752 else
753 {
754 let [high, low]: [u32; 2] = cast(x);
755 ix0 = high as i32;
756 ix1 = w(low);
757 }
758 }
759
760 {
762 if x.is_nan() {
763 return f64::NAN;
764 }
765 if ix0 & 0x7ff00000 == 0x7ff00000 {
766 return x * x + x;
767 }
768 }
769 {
771 if ix0 <= 0 {
772 if ((ix0 & (!sign).0 as i32) | (ix1.0 as i32)) == 0 {
773 return x;
774 } else if ix0 < 0 {
775 return (x - x) / (x - x);
776 }
777 }
778 }
779 {
781 m = ix0 >> 20;
782 if m == 0 {
783 while ix0 == 0 {
785 m -= 21;
786 ix0 |= (ix1 >> 11).0 as i32;
787 ix1 <<= 21;
788 }
789 i = 0;
790 while ix0 & 0x00100000 == 0 {
791 ix0 <<= 1;
792 i += 1;
793 }
794 m -= i - 1;
795 ix0 |= (ix1.0 >> (31 - i)) as i32;
796 ix1 <<= i as usize;
797 }
798 m -= 1023;
800 ix0 = (ix0 & 0x000fffff) | 0x00100000;
801 if (m & 1) != 0 {
802 ix0 += ix0 + ((ix1 & sign) >> 31).0 as i32;
804 ix1 += ix1;
805 }
806 m >>= 1;
807 }
808 {
810 ix0 += ix0 + ((ix1 & sign) >> 31).0 as i32;
811 ix1 += ix1;
812 q = 0;
814 q1 = w(0);
815 s0 = 0;
816 s1 = w(0);
817 r = w(0x00200000);
819 while r != w(0) {
820 t = s0 + (r.0 as i32);
821 if t <= ix0 {
822 s0 = t + (r.0 as i32);
823 ix0 -= t;
824 q += (r.0 as i32);
825 }
826 ix0 += ix0 + ((ix1 & sign) >> 31).0 as i32;
827 ix1 += ix1;
828 r >>= 1;
829 }
830 r = sign;
831 while r != w(0) {
832 t1 = s1 + r;
833 t = s0;
834 if (t < ix0) || ((t == ix0) && (t1 <= ix1)) {
835 s1 = t1 + r;
836 if t1 & sign == sign && (s1 & sign) == w(0) {
837 s0 += 1;
838 }
839 ix0 -= t;
840 if ix1 < t1 {
841 ix0 -= 1;
842 }
843 ix1 -= t1;
844 q1 += r;
845 }
846 ix0 += ix0 + ((ix1 & sign) >> 31).0 as i32;
847 ix1 += ix1;
848 r >>= 1;
849 }
850 }
851 {
853 if ix0 | (ix1.0 as i32) != 0 {
854 z = 1.0 - 1.0e-300;
855 if z >= 1.0 {
856 z = 1.0 + 1.0e-300;
857 if q1 == w(0xffffffff) {
858 q1 = w(0);
859 q += 1;
860 } else if z > 1.0 {
861 if q1 == w(0xfffffffe) {
862 q += 1;
863 }
864 q1 += w(2);
865 } else {
866 q1 += q1 & w(1);
867 }
868 }
869 }
870 }
871 ix0 = (q >> 1) + 0x3fe00000;
873 ix1 = q1 >> 1;
874 if q & 1 == 1 {
875 ix1 |= sign;
876 }
877 ix0 += m << 20;
878
879 pick! {
880 if #[cfg(target_endian = "little")]
881 {
882 cast::<[u32; 2], f64>([ix1.0, ix0 as u32])
883 }
884 else
885 {
886 cast::<[u32; 2], f64>([ix0 as u32, ix1.0])
887 }
888 }
889}
890
891#[test]
892fn test_software_sqrt() {
893 assert!(software_sqrt(f64::NAN).is_nan());
894 assert_eq!(software_sqrt(f64::INFINITY), f64::INFINITY);
895 assert_eq!(software_sqrt(0.0), 0.0);
896 assert_eq!(software_sqrt(-0.0), -0.0);
897 assert!(software_sqrt(-1.0).is_nan());
898 assert!(software_sqrt(f64::NEG_INFINITY).is_nan());
899 assert_eq!(software_sqrt(4.0), 2.0);
900 assert_eq!(software_sqrt(9.0), 3.0);
901 assert_eq!(software_sqrt(16.0), 4.0);
902 assert_eq!(software_sqrt(25.0), 5.0);
903 assert_eq!(software_sqrt(5000.0 * 5000.0), 5000.0);
904}
905
906pub trait CmpEq<Rhs = Self> {
907 type Output;
908 fn simd_eq(self, rhs: Rhs) -> Self::Output;
909}
910
911pub trait CmpGt<Rhs = Self> {
912 type Output;
913 fn simd_gt(self, rhs: Rhs) -> Self::Output;
914}
915
916pub trait CmpGe<Rhs = Self> {
917 type Output;
918 fn simd_ge(self, rhs: Rhs) -> Self::Output;
919}
920
921pub trait CmpNe<Rhs = Self> {
922 type Output;
923 fn simd_ne(self, rhs: Rhs) -> Self::Output;
924}
925
926pub trait CmpLt<Rhs = Self> {
927 type Output;
928 fn simd_lt(self, rhs: Rhs) -> Self::Output;
929}
930
931pub trait CmpLe<Rhs = Self> {
932 type Output;
933 fn simd_le(self, rhs: Rhs) -> Self::Output;
934}
935pub trait AlignTo
936where
937 Self: Pod + Default + PartialEq + From<Self::Elem>,
938 Self::Elem: Pod + Default + PartialEq,
939{
940 type Elem;
941
942 #[inline]
943 fn simd_align_to(
944 slice: &[Self::Elem],
945 ) -> (&[Self::Elem], &[Self], &[Self::Elem]) {
946 pod_align_to(slice)
947 }
948
949 #[inline]
950 fn simd_align_to_mut(
951 slice: &mut [Self::Elem],
952 ) -> (&mut [Self::Elem], &mut [Self], &mut [Self::Elem]) {
953 pod_align_to_mut(slice)
954 }
955}
956
957macro_rules! bulk_impl_const_rhs_op {
958 (($op:ident,$method:ident) => [$(($lhs:ty,$rhs:ty),)+]) => {
959 $(
960 impl $op<$rhs> for $lhs {
961 type Output = Self;
962 #[inline]
963 fn $method(self, rhs: $rhs) -> Self::Output {
964 self.$method(<$lhs>::splat(rhs))
965 }
966 }
967 )+
968 };
969}
970
971bulk_impl_const_rhs_op!((CmpEq, simd_eq) => [(f64x8, f64), (f64x4, f64), (f64x2, f64), (f32x4,f32), (f32x8,f32), (f32x16,f32),]);
972bulk_impl_const_rhs_op!((CmpLt, simd_lt) => [(f64x8, f64), (f64x4, f64), (f64x2, f64), (f32x4,f32), (f32x8,f32), (f32x16,f32),]);
973bulk_impl_const_rhs_op!((CmpGt, simd_gt) => [(f64x8, f64), (f64x4, f64), (f64x2, f64), (f32x4,f32), (f32x8,f32), (f32x16,f32),]);
974bulk_impl_const_rhs_op!((CmpNe, simd_ne) => [(f64x8, f64), (f64x4, f64), (f64x2, f64), (f32x4,f32), (f32x8,f32), (f32x16,f32),]);
975bulk_impl_const_rhs_op!((CmpLe, simd_le) => [(f64x8, f64), (f64x4, f64), (f64x2, f64), (f32x4,f32), (f32x8,f32), (f32x16,f32),]);
976bulk_impl_const_rhs_op!((CmpGe, simd_ge) => [(f64x8, f64), (f64x4, f64), (f64x2, f64), (f32x4,f32), (f32x8,f32), (f32x16,f32),]);
977
978macro_rules! impl_serde {
979 ($i:ident, [$t:ty; $len:expr]) => {
980 #[cfg(feature = "serde")]
981 impl Serialize for $i {
982 #[inline]
983 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
984 where
985 S: serde::Serializer,
986 {
987 let array = self.as_array();
988 let mut seq = serializer.serialize_tuple($len)?;
989 for e in array {
990 seq.serialize_element(e)?;
991 }
992 seq.end()
993 }
994 }
995
996 #[cfg(feature = "serde")]
997 impl<'de> Deserialize<'de> for $i {
998 #[inline]
999 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1000 where
1001 D: serde::Deserializer<'de>,
1002 {
1003 Ok(<[$t; $len]>::deserialize(deserializer)?.into())
1004 }
1005 }
1006 };
1007}
1008
1009impl_serde!(f32x8, [f32; 8]);
1010impl_serde!(f32x4, [f32; 4]);
1011impl_serde!(f64x4, [f64; 4]);
1012impl_serde!(f64x2, [f64; 2]);
1013impl_serde!(i8x16, [i8; 16]);
1014impl_serde!(i16x16, [i16; 16]);
1015impl_serde!(i8x32, [i8; 32]);
1016impl_serde!(i16x8, [i16; 8]);
1017impl_serde!(i32x4, [i32; 4]);
1018impl_serde!(i32x8, [i32; 8]);
1019impl_serde!(i64x2, [i64; 2]);
1020impl_serde!(i64x4, [i64; 4]);
1021impl_serde!(u8x16, [u8; 16]);
1022impl_serde!(u8x32, [u8; 32]);
1023impl_serde!(u16x8, [u16; 8]);
1024impl_serde!(u16x16, [u16; 16]);
1025impl_serde!(u32x4, [u32; 4]);
1026impl_serde!(u32x8, [u32; 8]);
1027impl_serde!(u64x2, [u64; 2]);
1028impl_serde!(u64x4, [u64; 4]);
1029impl_serde!(u64x8, [u64; 8]);
1030impl_serde!(i64x8, [i64; 8]);
1031impl_serde!(i16x32, [i16; 32]);
1032impl_serde!(u16x32, [u16; 32]);
1033impl_serde!(i32x16, [i32; 16]);
1034impl_serde!(u32x16, [u32; 16]);
1035impl_serde!(f32x16, [f32; 16]);
1036impl_serde!(f64x8, [f64; 8]);