1 #![allow(non_camel_case_types)]
3 /// Implements inherent methods for a float vector `$name` containing multiple
4 /// `$lanes` of float `$type`, which uses `$bits_ty` as its binary
5 /// representation. Called from `define_float_vector!`.
6 macro_rules! impl_float_vector {
7 { $name:ident, $type:ty, $bits_ty:ident, $mask_ty:ident, $mask_impl_ty:ident } => {
8 impl_vector! { $name, $type }
9 impl_float_reductions! { $name, $type }
11 impl<const LANES: usize> $name<LANES>
13 Self: crate::LanesAtMost32,
14 crate::$bits_ty<LANES>: crate::LanesAtMost32,
16 /// Raw transmutation to an unsigned integer vector type with the
17 /// same size and number of lanes.
19 pub fn to_bits(self) -> crate::$bits_ty<LANES> {
20 assert_eq!(core::mem::size_of::<Self>(), core::mem::size_of::<crate::$bits_ty<LANES>>());
21 unsafe { core::mem::transmute_copy(&self) }
24 /// Raw transmutation from an unsigned integer vector type with the
25 /// same size and number of lanes.
27 pub fn from_bits(bits: crate::$bits_ty<LANES>) -> Self {
28 assert_eq!(core::mem::size_of::<Self>(), core::mem::size_of::<crate::$bits_ty<LANES>>());
29 unsafe { core::mem::transmute_copy(&bits) }
32 /// Produces a vector where every lane has the absolute value of the
33 /// equivalently-indexed lane in `self`.
35 pub fn abs(self) -> Self {
36 unsafe { crate::intrinsics::simd_fabs(self) }
40 impl<const LANES: usize> $name<LANES>
42 Self: crate::LanesAtMost32,
43 crate::$bits_ty<LANES>: crate::LanesAtMost32,
44 crate::$mask_impl_ty<LANES>: crate::LanesAtMost32,
45 crate::$mask_ty<LANES>: crate::Mask,
47 /// Returns true for each lane if it has a positive sign, including
48 /// `+0.0`, `NaN`s with positive sign bit and positive infinity.
50 pub fn is_sign_positive(self) -> crate::$mask_ty<LANES> {
51 !self.is_sign_negative()
54 /// Returns true for each lane if it has a negative sign, including
55 /// `-0.0`, `NaN`s with negative sign bit and negative infinity.
57 pub fn is_sign_negative(self) -> crate::$mask_ty<LANES> {
58 let sign_bits = self.to_bits() & crate::$bits_ty::splat((!0 >> 1) + 1);
59 sign_bits.lanes_gt(crate::$bits_ty::splat(0))
62 /// Returns true for each lane if its value is `NaN`.
64 pub fn is_nan(self) -> crate::$mask_ty<LANES> {
68 /// Returns true for each lane if its value is positive infinity or negative infinity.
70 pub fn is_infinite(self) -> crate::$mask_ty<LANES> {
71 self.abs().lanes_eq(Self::splat(<$type>::INFINITY))
74 /// Returns true for each lane if its value is neither infinite nor `NaN`.
76 pub fn is_finite(self) -> crate::$mask_ty<LANES> {
77 self.abs().lanes_lt(Self::splat(<$type>::INFINITY))
80 /// Returns true for each lane if its value is subnormal.
82 pub fn is_subnormal(self) -> crate::$mask_ty<LANES> {
83 self.abs().lanes_ne(Self::splat(0.0)) & (self.to_bits() & Self::splat(<$type>::INFINITY).to_bits()).lanes_eq(crate::$bits_ty::splat(0))
86 /// Returns true for each lane if its value is neither neither zero, infinite,
87 /// subnormal, or `NaN`.
89 pub fn is_normal(self) -> crate::$mask_ty<LANES> {
90 !(self.abs().lanes_eq(Self::splat(0.0)) | self.is_nan() | self.is_subnormal() | self.is_infinite())
96 /// A SIMD vector of containing `LANES` `f32` values.
98 pub struct SimdF32<const LANES: usize>([f32; LANES])
100 Self: crate::LanesAtMost32;
102 impl_float_vector! { SimdF32, f32, SimdU32, Mask32, SimdI32 }
104 from_transmute_x86! { unsafe f32x4 => __m128 }
105 from_transmute_x86! { unsafe f32x8 => __m256 }
106 //from_transmute_x86! { unsafe f32x16 => __m512 }
108 /// A SIMD vector of containing `LANES` `f64` values.
110 pub struct SimdF64<const LANES: usize>([f64; LANES])
112 Self: crate::LanesAtMost32;
114 impl_float_vector! { SimdF64, f64, SimdU64, Mask64, SimdI64 }
116 from_transmute_x86! { unsafe f64x2 => __m128d }
117 from_transmute_x86! { unsafe f64x4 => __m256d }
118 //from_transmute_x86! { unsafe f64x8 => __m512d }
120 /// Vector of two `f32` values
121 pub type f32x2 = SimdF32<2>;
123 /// Vector of four `f32` values
124 pub type f32x4 = SimdF32<4>;
126 /// Vector of eight `f32` values
127 pub type f32x8 = SimdF32<8>;
129 /// Vector of 16 `f32` values
130 pub type f32x16 = SimdF32<16>;
132 /// Vector of two `f64` values
133 pub type f64x2 = SimdF64<2>;
135 /// Vector of four `f64` values
136 pub type f64x4 = SimdF64<4>;
138 /// Vector of eight `f64` values
139 pub type f64x8 = SimdF64<8>;