4
4
/// `$lanes` of float `$type`, which uses `$bits_ty` as its binary
5
5
/// representation. Called from `define_float_vector!`.
6
6
macro_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 } => {
8
8
impl_vector! { $name, $type }
9
9
10
10
impl <const LANES : usize > $name<LANES >
@@ -36,6 +36,60 @@ macro_rules! impl_float_vector {
36
36
Self :: from_bits( self . to_bits( ) & no_sign)
37
37
}
38
38
}
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
+ }
39
93
} ;
40
94
}
41
95
@@ -46,7 +100,7 @@ pub struct SimdF32<const LANES: usize>([f32; LANES])
46
100
where
47
101
Self : crate :: LanesAtMost64 ;
48
102
49
- impl_float_vector ! { SimdF32 , f32 , SimdU32 }
103
+ impl_float_vector ! { SimdF32 , f32 , SimdU32 , Mask32 , SimdI32 }
50
104
51
105
from_transmute_x86 ! { unsafe f32x4 => __m128 }
52
106
from_transmute_x86 ! { unsafe f32x8 => __m256 }
@@ -58,7 +112,7 @@ pub struct SimdF64<const LANES: usize>([f64; LANES])
58
112
where
59
113
Self : crate :: LanesAtMost64 ;
60
114
61
- impl_float_vector ! { SimdF64 , f64 , SimdU64 }
115
+ impl_float_vector ! { SimdF64 , f64 , SimdU64 , Mask64 , SimdI64 }
62
116
63
117
from_transmute_x86 ! { unsafe f64x2 => __m128d }
64
118
from_transmute_x86 ! { unsafe f64x4 => __m256d }
0 commit comments