44/// `$lanes` of float `$type`, which uses `$bits_ty` as its binary
55/// representation. Called from `define_float_vector!`.
66macro_rules! impl_float_vector {
7- { $name: ident, $type: ty, $bits_ty: ident } => {
7+ { $name: ident, $type: ty, $bits_ty: ident, $mask_ty : ident , $mask_impl_ty : ident } => {
88 impl_vector! { $name, $type }
99
1010 impl <const LANES : usize > $name<LANES >
@@ -36,6 +36,60 @@ macro_rules! impl_float_vector {
3636 Self :: from_bits( self . to_bits( ) & no_sign)
3737 }
3838 }
39+
40+ impl <const LANES : usize > $name<LANES >
41+ where
42+ Self : crate :: LanesAtMost64 ,
43+ crate :: $bits_ty<LANES >: crate :: LanesAtMost64 ,
44+ crate :: $mask_impl_ty<LANES >: crate :: LanesAtMost64 ,
45+ {
46+ /// Returns true for each lane if it has a positive sign, including
47+ /// `+0.0`, `NaN`s with positive sign bit and positive infinity.
48+ #[ inline]
49+ pub fn is_sign_positive( self ) -> crate :: $mask_ty<LANES > {
50+ let sign_bits = self . to_bits( ) & crate :: $bits_ty:: splat( ( !0 >> 1 ) + 1 ) ;
51+ sign_bits. lanes_gt( crate :: $bits_ty:: splat( 0 ) )
52+ }
53+
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.
56+ #[ inline]
57+ pub fn is_sign_negative( self ) -> crate :: $mask_ty<LANES > {
58+ !self . is_sign_positive( )
59+ }
60+
61+ /// Returns true for each lane if its value is `NaN`.
62+ #[ inline]
63+ pub fn is_nan( self ) -> crate :: $mask_ty<LANES > {
64+ self . lanes_eq( self )
65+ }
66+
67+ /// Returns true for each lane if its value is positive infinity or negative infinity.
68+ #[ inline]
69+ pub fn is_infinite( self ) -> crate :: $mask_ty<LANES > {
70+ self . abs( ) . lanes_eq( Self :: splat( <$type>:: INFINITY ) )
71+ }
72+
73+ /// Returns true for each lane if its value is neither infinite nor `NaN`.
74+ #[ inline]
75+ pub fn is_finite( self ) -> crate :: $mask_ty<LANES > {
76+ self . abs( ) . lanes_lt( Self :: splat( <$type>:: INFINITY ) )
77+ }
78+
79+ /// Returns true for each lane if its value is subnormal.
80+ #[ inline]
81+ pub fn is_subnormal( self ) -> crate :: $mask_ty<LANES > {
82+ let mantissa_mask = crate :: $bits_ty:: splat( ( 1 << ( <$type>:: MANTISSA_DIGITS - 1 ) ) - 1 ) ;
83+ self . abs( ) . lanes_ne( Self :: splat( 0.0 ) ) & ( self . to_bits( ) & mantissa_mask) . lanes_eq( crate :: $bits_ty:: splat( 0 ) )
84+ }
85+
86+ /// Returns true for each lane if its value is neither neither zero, infinite,
87+ /// subnormal, or `NaN`.
88+ #[ inline]
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( ) )
91+ }
92+ }
3993 } ;
4094}
4195
@@ -46,7 +100,7 @@ pub struct SimdF32<const LANES: usize>([f32; LANES])
46100where
47101 Self : crate :: LanesAtMost64 ;
48102
49- impl_float_vector ! { SimdF32 , f32 , SimdU32 }
103+ impl_float_vector ! { SimdF32 , f32 , SimdU32 , Mask32 , SimdI32 }
50104
51105from_transmute_x86 ! { unsafe f32x4 => __m128 }
52106from_transmute_x86 ! { unsafe f32x8 => __m256 }
@@ -58,7 +112,7 @@ pub struct SimdF64<const LANES: usize>([f64; LANES])
58112where
59113 Self : crate :: LanesAtMost64 ;
60114
61- impl_float_vector ! { SimdF64 , f64 , SimdU64 }
115+ impl_float_vector ! { SimdF64 , f64 , SimdU64 , Mask64 , SimdI64 }
62116
63117from_transmute_x86 ! { unsafe f64x2 => __m128d }
64118from_transmute_x86 ! { unsafe f64x4 => __m256d }
0 commit comments