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