@@ -11,6 +11,22 @@ use core::f64;
11
11
12
12
use crate :: { Num , NumCast , ToPrimitive } ;
13
13
14
+ #[ cfg( all( not( feature = "std" ) , feature = "libm" ) ) ]
15
+ mod compiler_builtins {
16
+ extern "C" {
17
+ pub fn floorf16 ( x : f16 ) -> f16 ;
18
+ pub fn floorf128 ( x : f128 ) -> f128 ;
19
+ pub fn ceilf16 ( x : f16 ) -> f16 ;
20
+ pub fn ceilf128 ( x : f128 ) -> f128 ;
21
+ pub fn roundf16 ( x : f16 ) -> f16 ;
22
+ pub fn roundf128 ( x : f128 ) -> f128 ;
23
+ pub fn truncf16 ( x : f16 ) -> f16 ;
24
+ pub fn truncf128 ( x : f128 ) -> f128 ;
25
+ pub fn fdimf16 ( x : f16 , y : f16 ) -> f16 ;
26
+ pub fn fdimf128 ( x : f128 , y : f128 ) -> f128 ;
27
+ }
28
+ }
29
+
14
30
/// Generic trait for floating point numbers that works with `no_std`.
15
31
///
16
32
/// This trait implements a subset of the `Float` trait.
@@ -852,8 +868,24 @@ impl FloatCore for f16 {
852
868
Self :: powi( self , n: i32 ) -> Self ;
853
869
}
854
870
855
- // TODO:
856
- // use floor, ceil, round, trunc, abs and fract provided by libm
871
+ #[ cfg( all( not( feature = "std" ) , feature = "libm" ) ) ]
872
+ forward ! {
873
+ unsafe compiler_builtins:: floorf16 as floor( self ) -> Self ;
874
+ unsafe compiler_builtins:: ceilf16 as ceil( self ) -> Self ;
875
+ unsafe compiler_builtins:: roundf16 as round( self ) -> Self ;
876
+ unsafe compiler_builtins:: truncf16 as trunc( self ) -> Self ;
877
+ }
878
+
879
+ #[ cfg( all( not( feature = "std" ) , feature = "libm" ) ) ]
880
+ forward ! {
881
+ f16:: abs as abs( self ) -> Self ;
882
+ }
883
+
884
+ #[ cfg( all( not( feature = "std" ) , feature = "libm" ) ) ]
885
+ #[ inline]
886
+ fn fract ( self ) -> Self {
887
+ self - unsafe { compiler_builtins:: truncf16 ( self ) as Self }
888
+ }
857
889
}
858
890
859
891
impl FloatCore for f32 {
@@ -1026,8 +1058,24 @@ impl FloatCore for f128 {
1026
1058
Self :: powi( self , n: i32 ) -> Self ;
1027
1059
}
1028
1060
1029
- // TODO:
1030
- // use floor, ceil, round, trunc, abs and fract provided by libm
1061
+ #[ cfg( all( not( feature = "std" ) , feature = "libm" ) ) ]
1062
+ forward ! {
1063
+ unsafe compiler_builtins:: floorf128 as floor( self ) -> Self ;
1064
+ unsafe compiler_builtins:: ceilf128 as ceil( self ) -> Self ;
1065
+ unsafe compiler_builtins:: roundf128 as round( self ) -> Self ;
1066
+ unsafe compiler_builtins:: truncf128 as trunc( self ) -> Self ;
1067
+ }
1068
+
1069
+ #[ cfg( all( not( feature = "std" ) , feature = "libm" ) ) ]
1070
+ forward ! {
1071
+ f128:: abs as abs( self ) -> Self ;
1072
+ }
1073
+
1074
+ #[ cfg( all( not( feature = "std" ) , feature = "libm" ) ) ]
1075
+ #[ inline]
1076
+ fn fract ( self ) -> Self {
1077
+ self - unsafe { compiler_builtins:: truncf128 ( self ) as Self }
1078
+ }
1031
1079
}
1032
1080
1033
1081
// FIXME: these doctests aren't actually helpful, because they're using and
@@ -2232,6 +2280,63 @@ float_impl_std!(f64 integer_decode_f64);
2232
2280
#[ cfg( feature = "std" ) ]
2233
2281
float_impl_std ! ( f128 integer_decode_f128_truncated) ;
2234
2282
2283
+ #[ cfg( all( not( feature = "std" ) , feature = "libm" ) ) ]
2284
+ impl Float for f16 {
2285
+ float_impl_libm ! ( f16 integer_decode_f16) ;
2286
+
2287
+ #[ inline]
2288
+ #[ allow( deprecated) ]
2289
+ fn abs_sub ( self , other : Self ) -> Self {
2290
+ unsafe { compiler_builtins:: fdimf16 ( self , other) as Self }
2291
+ }
2292
+
2293
+ forward ! {
2294
+ unsafe compiler_builtins:: floorf16 as floor( self ) -> Self ;
2295
+ unsafe compiler_builtins:: ceilf16 as ceil( self ) -> Self ;
2296
+ unsafe compiler_builtins:: roundf16 as round( self ) -> Self ;
2297
+ unsafe compiler_builtins:: truncf16 as trunc( self ) -> Self ;
2298
+ }
2299
+
2300
+ cast_forward_cast ! {
2301
+ [ f32 ] libm:: fmaf as mul_add( self , a: Self , b: Self ) -> Self ;
2302
+ [ f32 ] libm:: powf as powf( self , n: Self ) -> Self ;
2303
+ [ f32 ] libm:: sqrtf as sqrt( self ) -> Self ;
2304
+ [ f32 ] libm:: expf as exp( self ) -> Self ;
2305
+ [ f32 ] libm:: exp2f as exp2( self ) -> Self ;
2306
+ [ f32 ] libm:: logf as ln( self ) -> Self ;
2307
+ [ f32 ] libm:: log2f as log2( self ) -> Self ;
2308
+ [ f32 ] libm:: log10f as log10( self ) -> Self ;
2309
+ [ f32 ] libm:: cbrtf as cbrt( self ) -> Self ;
2310
+ [ f32 ] libm:: hypotf as hypot( self , other: Self ) -> Self ;
2311
+ [ f32 ] libm:: sinf as sin( self ) -> Self ;
2312
+ [ f32 ] libm:: cosf as cos( self ) -> Self ;
2313
+ [ f32 ] libm:: tanf as tan( self ) -> Self ;
2314
+ [ f32 ] libm:: asinf as asin( self ) -> Self ;
2315
+ [ f32 ] libm:: acosf as acos( self ) -> Self ;
2316
+ [ f32 ] libm:: atanf as atan( self ) -> Self ;
2317
+ [ f32 ] libm:: atan2f as atan2( self , other: Self ) -> Self ;
2318
+ [ f32 ] libm:: expm1f as exp_m1( self ) -> Self ;
2319
+ [ f32 ] libm:: log1pf as ln_1p( self ) -> Self ;
2320
+ [ f32 ] libm:: sinhf as sinh( self ) -> Self ;
2321
+ [ f32 ] libm:: coshf as cosh( self ) -> Self ;
2322
+ [ f32 ] libm:: tanhf as tanh( self ) -> Self ;
2323
+ [ f32 ] libm:: asinhf as asinh( self ) -> Self ;
2324
+ [ f32 ] libm:: acoshf as acosh( self ) -> Self ;
2325
+ [ f32 ] libm:: atanhf as atanh( self ) -> Self ;
2326
+ }
2327
+
2328
+ forward ! {
2329
+ f16:: abs as abs( self ) -> Self ;
2330
+ f16:: copysign as copysign( self , other: Self ) -> Self ;
2331
+ }
2332
+
2333
+ #[ inline]
2334
+ fn sin_cos ( self ) -> ( Self , Self ) {
2335
+ let ( x, y) = libm:: sincosf ( self as f32 ) ;
2336
+ ( x as Self , y as Self )
2337
+ }
2338
+ }
2339
+
2235
2340
#[ cfg( all( not( feature = "std" ) , feature = "libm" ) ) ]
2236
2341
impl Float for f32 {
2237
2342
float_impl_libm ! ( f32 integer_decode_f32) ;
@@ -2324,6 +2429,63 @@ impl Float for f64 {
2324
2429
}
2325
2430
}
2326
2431
2432
+ #[ cfg( all( not( feature = "std" ) , feature = "libm" ) ) ]
2433
+ impl Float for f128 {
2434
+ float_impl_libm ! ( f128 integer_decode_f128_truncated) ;
2435
+
2436
+ #[ inline]
2437
+ #[ allow( deprecated) ]
2438
+ fn abs_sub ( self , other : Self ) -> Self {
2439
+ unsafe { compiler_builtins:: fdimf128 ( self , other) as Self }
2440
+ }
2441
+
2442
+ forward ! {
2443
+ unsafe compiler_builtins:: floorf128 as floor( self ) -> Self ;
2444
+ unsafe compiler_builtins:: ceilf128 as ceil( self ) -> Self ;
2445
+ unsafe compiler_builtins:: roundf128 as round( self ) -> Self ;
2446
+ unsafe compiler_builtins:: truncf128 as trunc( self ) -> Self ;
2447
+ }
2448
+
2449
+ cast_forward_cast ! {
2450
+ [ f64 ] libm:: fma as mul_add( self , a: Self , b: Self ) -> Self ;
2451
+ [ f64 ] libm:: pow as powf( self , n: Self ) -> Self ;
2452
+ [ f64 ] libm:: sqrt as sqrt( self ) -> Self ;
2453
+ [ f64 ] libm:: exp as exp( self ) -> Self ;
2454
+ [ f64 ] libm:: exp2 as exp2( self ) -> Self ;
2455
+ [ f64 ] libm:: log as ln( self ) -> Self ;
2456
+ [ f64 ] libm:: log2 as log2( self ) -> Self ;
2457
+ [ f64 ] libm:: log10 as log10( self ) -> Self ;
2458
+ [ f64 ] libm:: cbrt as cbrt( self ) -> Self ;
2459
+ [ f64 ] libm:: hypot as hypot( self , other: Self ) -> Self ;
2460
+ [ f64 ] libm:: sin as sin( self ) -> Self ;
2461
+ [ f64 ] libm:: cos as cos( self ) -> Self ;
2462
+ [ f64 ] libm:: tan as tan( self ) -> Self ;
2463
+ [ f64 ] libm:: asin as asin( self ) -> Self ;
2464
+ [ f64 ] libm:: acos as acos( self ) -> Self ;
2465
+ [ f64 ] libm:: atan as atan( self ) -> Self ;
2466
+ [ f64 ] libm:: atan2 as atan2( self , other: Self ) -> Self ;
2467
+ [ f64 ] libm:: expm1 as exp_m1( self ) -> Self ;
2468
+ [ f64 ] libm:: log1p as ln_1p( self ) -> Self ;
2469
+ [ f64 ] libm:: sinh as sinh( self ) -> Self ;
2470
+ [ f64 ] libm:: cosh as cosh( self ) -> Self ;
2471
+ [ f64 ] libm:: tanh as tanh( self ) -> Self ;
2472
+ [ f64 ] libm:: asinh as asinh( self ) -> Self ;
2473
+ [ f64 ] libm:: acosh as acosh( self ) -> Self ;
2474
+ [ f64 ] libm:: atanh as atanh( self ) -> Self ;
2475
+ }
2476
+
2477
+ forward ! {
2478
+ f128:: abs as abs( self ) -> Self ;
2479
+ f128:: copysign as copysign( self , other: Self ) -> Self ;
2480
+ }
2481
+
2482
+ #[ inline]
2483
+ fn sin_cos ( self ) -> ( Self , Self ) {
2484
+ let ( x, y) = libm:: sincos ( self as f64 ) ;
2485
+ ( x as Self , y as Self )
2486
+ }
2487
+ }
2488
+
2327
2489
macro_rules! float_const_impl {
2328
2490
( $( #[ $doc: meta] $constant: ident, ) +) => (
2329
2491
#[ allow( non_snake_case) ]
0 commit comments