@@ -160,9 +160,11 @@ pub trait Float:
160160 fn abs ( self ) -> Self ;
161161
162162 /// Returns a number composed of the magnitude of self and the sign of sign.
163- #[ allow( dead_code) ]
164163 fn copysign ( self , other : Self ) -> Self ;
165164
165+ /// Fused multiply add, rounding once.
166+ fn fma ( self , y : Self , z : Self ) -> Self ;
167+
166168 /// Returns (normalized exponent, normalized significand)
167169 #[ allow( dead_code) ]
168170 fn normalize ( significand : Self :: Int ) -> ( i32 , Self :: Int ) ;
@@ -184,7 +186,9 @@ macro_rules! float_impl {
184186 $sity: ident,
185187 $bits: expr,
186188 $significand_bits: expr,
187- $from_bits: path
189+ $from_bits: path,
190+ $fma_fn: ident,
191+ $fma_intrinsic: ident
188192 ) => {
189193 impl Float for $ty {
190194 type Int = $ity;
@@ -252,6 +256,16 @@ macro_rules! float_impl {
252256 }
253257 }
254258 }
259+ fn fma( self , y: Self , z: Self ) -> Self {
260+ cfg_if! {
261+ // fma is not yet available in `core`
262+ if #[ cfg( intrinsics_enabled) ] {
263+ unsafe { core:: intrinsics:: $fma_intrinsic( self , y, z) }
264+ } else {
265+ super :: super :: $fma_fn( self , y, z)
266+ }
267+ }
268+ }
255269 fn normalize( significand: Self :: Int ) -> ( i32 , Self :: Int ) {
256270 let shift = significand. leading_zeros( ) . wrapping_sub( Self :: EXP_BITS ) ;
257271 ( 1i32 . wrapping_sub( shift as i32 ) , significand << shift as Self :: Int )
@@ -261,11 +275,11 @@ macro_rules! float_impl {
261275}
262276
263277#[ cfg( f16_enabled) ]
264- float_impl ! ( f16, u16 , i16 , 16 , 10 , f16:: from_bits) ;
265- float_impl ! ( f32 , u32 , i32 , 32 , 23 , f32_from_bits) ;
266- float_impl ! ( f64 , u64 , i64 , 64 , 52 , f64_from_bits) ;
278+ float_impl ! ( f16, u16 , i16 , 16 , 10 , f16:: from_bits, fmaf16 , fmaf16 ) ;
279+ float_impl ! ( f32 , u32 , i32 , 32 , 23 , f32_from_bits, fmaf , fmaf32 ) ;
280+ float_impl ! ( f64 , u64 , i64 , 64 , 52 , f64_from_bits, fma , fmaf64 ) ;
267281#[ cfg( f128_enabled) ]
268- float_impl ! ( f128, u128 , i128 , 128 , 112 , f128:: from_bits) ;
282+ float_impl ! ( f128, u128 , i128 , 128 , 112 , f128:: from_bits, fmaf128 , fmaf128 ) ;
269283
270284/* FIXME(msrv): vendor some things that are not const stable at our MSRV */
271285
0 commit comments