1- #![ cfg_attr( feature = "as_crate" , no_std) ] // We are std!
21#![ cfg_attr(
32 feature = "as_crate" ,
43 feature( core_intrinsics) ,
@@ -67,43 +66,28 @@ pub trait StdFloat: Sealed + Sized {
6766
6867 /// Produces a vector where every element has the sine of the value
6968 /// in the equivalently-indexed element in `self`.
70- #[ inline]
7169 #[ 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 ;
7571
7672 /// Produces a vector where every element has the cosine of the value
7773 /// in the equivalently-indexed element in `self`.
78- #[ inline]
7974 #[ 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 ;
8376
8477 /// Produces a vector where every element has the exponential (base e) of the value
8578 /// in the equivalently-indexed element in `self`.
86- #[ inline]
8779 #[ 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 ;
9181
9282 /// Produces a vector where every element has the exponential (base 2) of the value
9383 /// in the equivalently-indexed element in `self`.
94- #[ inline]
9584 #[ 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 ;
9986
10087 /// Produces a vector where every element has the natural logarithm of the value
10188 /// in the equivalently-indexed element in `self`.
102- #[ inline]
10389 #[ 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 ;
10791
10892 /// Produces a vector where every element has the logarithm with respect to an arbitrary
10993 /// in the equivalently-indexed elements in `self` and `base`.
@@ -115,19 +99,13 @@ pub trait StdFloat: Sealed + Sized {
11599
116100 /// Produces a vector where every element has the base-2 logarithm of the value
117101 /// in the equivalently-indexed element in `self`.
118- #[ inline]
119102 #[ 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 ;
123104
124105 /// Produces a vector where every element has the base-10 logarithm of the value
125106 /// in the equivalently-indexed element in `self`.
126- #[ inline]
127107 #[ 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 ;
131109
132110 /// Returns the smallest integer greater than or equal to each element.
133111 #[ must_use = "method returns a new vector and does not mutate the original value" ]
@@ -165,27 +143,65 @@ pub trait StdFloat: Sealed + Sized {
165143impl < const N : usize > Sealed for Simd < f32 , N > where LaneCount < N > : SupportedLaneCount { }
166144impl < const N : usize > Sealed for Simd < f64 , N > where LaneCount < N > : SupportedLaneCount { }
167145
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+ }
178196 }
179197}
180198
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,
191207}
0 commit comments