1
- #![ cfg_attr( feature = "as_crate" , no_std) ] // We are std!
2
1
#![ cfg_attr(
3
2
feature = "as_crate" ,
4
3
feature( core_intrinsics) ,
@@ -67,43 +66,28 @@ pub trait StdFloat: Sealed + Sized {
67
66
68
67
/// Produces a vector where every element has the sine of the value
69
68
/// in the equivalently-indexed element in `self`.
70
- #[ inline]
71
69
#[ must_use = "method returns a new vector and does not mutate the original value" ]
72
- fn sin ( self ) -> Self {
73
- unsafe { intrinsics:: simd_fsin ( self ) }
74
- }
70
+ fn sin ( self ) -> Self ;
75
71
76
72
/// Produces a vector where every element has the cosine of the value
77
73
/// in the equivalently-indexed element in `self`.
78
- #[ inline]
79
74
#[ must_use = "method returns a new vector and does not mutate the original value" ]
80
- fn cos ( self ) -> Self {
81
- unsafe { intrinsics:: simd_fcos ( self ) }
82
- }
75
+ fn cos ( self ) -> Self ;
83
76
84
77
/// Produces a vector where every element has the exponential (base e) of the value
85
78
/// in the equivalently-indexed element in `self`.
86
- #[ inline]
87
79
#[ must_use = "method returns a new vector and does not mutate the original value" ]
88
- fn exp ( self ) -> Self {
89
- unsafe { intrinsics:: simd_fexp ( self ) }
90
- }
80
+ fn exp ( self ) -> Self ;
91
81
92
82
/// Produces a vector where every element has the exponential (base 2) of the value
93
83
/// in the equivalently-indexed element in `self`.
94
- #[ inline]
95
84
#[ must_use = "method returns a new vector and does not mutate the original value" ]
96
- fn exp2 ( self ) -> Self {
97
- unsafe { intrinsics:: simd_fexp2 ( self ) }
98
- }
85
+ fn exp2 ( self ) -> Self ;
99
86
100
87
/// Produces a vector where every element has the natural logarithm of the value
101
88
/// in the equivalently-indexed element in `self`.
102
- #[ inline]
103
89
#[ must_use = "method returns a new vector and does not mutate the original value" ]
104
- fn ln ( self ) -> Self {
105
- unsafe { intrinsics:: simd_flog ( self ) }
106
- }
90
+ fn ln ( self ) -> Self ;
107
91
108
92
/// Produces a vector where every element has the logarithm with respect to an arbitrary
109
93
/// in the equivalently-indexed elements in `self` and `base`.
@@ -115,19 +99,13 @@ pub trait StdFloat: Sealed + Sized {
115
99
116
100
/// Produces a vector where every element has the base-2 logarithm of the value
117
101
/// in the equivalently-indexed element in `self`.
118
- #[ inline]
119
102
#[ must_use = "method returns a new vector and does not mutate the original value" ]
120
- fn log2 ( self ) -> Self {
121
- unsafe { intrinsics:: simd_flog2 ( self ) }
122
- }
103
+ fn log2 ( self ) -> Self ;
123
104
124
105
/// Produces a vector where every element has the base-10 logarithm of the value
125
106
/// in the equivalently-indexed element in `self`.
126
- #[ inline]
127
107
#[ must_use = "method returns a new vector and does not mutate the original value" ]
128
- fn log10 ( self ) -> Self {
129
- unsafe { intrinsics:: simd_flog10 ( self ) }
130
- }
108
+ fn log10 ( self ) -> Self ;
131
109
132
110
/// Returns the smallest integer greater than or equal to each element.
133
111
#[ must_use = "method returns a new vector and does not mutate the original value" ]
@@ -165,27 +143,65 @@ pub trait StdFloat: Sealed + Sized {
165
143
impl < const N : usize > Sealed for Simd < f32 , N > where LaneCount < N > : SupportedLaneCount { }
166
144
impl < const N : usize > Sealed for Simd < f64 , N > where LaneCount < N > : SupportedLaneCount { }
167
145
168
- // We can safely just use all the defaults.
169
- impl < const N : usize > StdFloat for Simd < f32 , N >
170
- where
171
- LaneCount < N > : SupportedLaneCount ,
172
- {
173
- /// Returns the floating point's fractional value, with its integer part removed.
174
- #[ must_use = "method returns a new vector and does not mutate the original value" ]
175
- #[ inline]
176
- fn fract ( self ) -> Self {
177
- self - self . trunc ( )
146
+ macro_rules! impl_float {
147
+ {
148
+ $( $fn: ident: $intrinsic: ident, ) *
149
+ } => {
150
+ impl <const N : usize > StdFloat for Simd <f32 , N >
151
+ where
152
+ LaneCount <N >: SupportedLaneCount ,
153
+ {
154
+ #[ inline]
155
+ fn fract( self ) -> Self {
156
+ self - self . trunc( )
157
+ }
158
+
159
+ $(
160
+ #[ inline]
161
+ fn $fn( self ) -> Self {
162
+ unsafe { intrinsics:: $intrinsic( self ) }
163
+ }
164
+ ) *
165
+ }
166
+
167
+ impl <const N : usize > StdFloat for Simd <f64 , N >
168
+ where
169
+ LaneCount <N >: SupportedLaneCount ,
170
+ {
171
+ #[ inline]
172
+ fn fract( self ) -> Self {
173
+ self - self . trunc( )
174
+ }
175
+
176
+ $(
177
+ #[ inline]
178
+ fn $fn( self ) -> Self {
179
+ // https://github.com/llvm/llvm-project/issues/83729
180
+ #[ cfg( target_arch = "aarch64" ) ]
181
+ {
182
+ let mut ln = Self :: splat( 0f64 ) ;
183
+ for i in 0 ..N {
184
+ ln[ i] = self [ i] . $fn( )
185
+ }
186
+ ln
187
+ }
188
+
189
+ #[ cfg( not( target_arch = "aarch64" ) ) ]
190
+ {
191
+ unsafe { intrinsics:: $intrinsic( self ) }
192
+ }
193
+ }
194
+ ) *
195
+ }
178
196
}
179
197
}
180
198
181
- impl < const N : usize > StdFloat for Simd < f64 , N >
182
- where
183
- LaneCount < N > : SupportedLaneCount ,
184
- {
185
- /// Returns the floating point's fractional value, with its integer part removed.
186
- #[ must_use = "method returns a new vector and does not mutate the original value" ]
187
- #[ inline]
188
- fn fract ( self ) -> Self {
189
- self - self . trunc ( )
190
- }
199
+ impl_float ! {
200
+ sin: simd_fsin,
201
+ cos: simd_fcos,
202
+ exp: simd_fexp,
203
+ exp2: simd_fexp2,
204
+ ln: simd_flog,
205
+ log2: simd_flog2,
206
+ log10: simd_flog10,
191
207
}
0 commit comments