@@ -3599,3 +3599,141 @@ long double powl(long double x, long double y)
3599
3599
return result_u .l ;
3600
3600
#endif
3601
3601
}
3602
+
3603
+ /* FUNCTION: fma */
3604
+
3605
+ #ifndef __CPROVER_MATH_H_INCLUDED
3606
+ # include <math.h>
3607
+ # define __CPROVER_MATH_H_INCLUDED
3608
+ #endif
3609
+
3610
+ #ifndef __CPROVER_FENV_H_INCLUDED
3611
+ # include <fenv.h>
3612
+ # define __CPROVER_FENV_H_INCLUDED
3613
+ #endif
3614
+
3615
+ double __builtin_inf (void );
3616
+
3617
+ double fma (double x , double y , double z )
3618
+ {
3619
+ // see man fma (https://linux.die.net/man/3/fma)
3620
+ if (isnan (x ) || isnan (y ))
3621
+ return 0.0 / 0.0 ;
3622
+ else if (
3623
+ (isinf (x ) || isinf (y )) &&
3624
+ (fpclassify (x ) == FP_ZERO || fpclassify (y ) == FP_ZERO ))
3625
+ {
3626
+ feraiseexcept (FE_INVALID );
3627
+ return 0.0 / 0.0 ;
3628
+ }
3629
+ else if (isnan (z ))
3630
+ return 0.0 / 0.0 ;
3631
+
3632
+ double x_times_y = x * y ;
3633
+ if (
3634
+ isinf (x_times_y ) && isinf (z ) &&
3635
+ __CPROVER_signd (x_times_y ) != __CPROVER_signd (z ))
3636
+ {
3637
+ feraiseexcept (FE_INVALID );
3638
+ return 0.0 / 0.0 ;
3639
+ }
3640
+
3641
+ // TODO: detect overflow (FE_OVERFLOW), return +/- __builtin_inf()
3642
+ // TODO: detect underflow (FE_UNDERFLOW), return +/- 0
3643
+ return x_times_y + z ;
3644
+ }
3645
+
3646
+ /* FUNCTION: fmaf */
3647
+
3648
+ #ifndef __CPROVER_MATH_H_INCLUDED
3649
+ # include <math.h>
3650
+ # define __CPROVER_MATH_H_INCLUDED
3651
+ #endif
3652
+
3653
+ #ifndef __CPROVER_FENV_H_INCLUDED
3654
+ # include <fenv.h>
3655
+ # define __CPROVER_FENV_H_INCLUDED
3656
+ #endif
3657
+
3658
+ float __builtin_inff (void );
3659
+
3660
+ float fmaf (float x , float y , float z )
3661
+ {
3662
+ // see man fma (https://linux.die.net/man/3/fma)
3663
+ if (isnanf (x ) || isnanf (y ))
3664
+ return 0.0f / 0.0f ;
3665
+ else if (
3666
+ (isinff (x ) || isinff (y )) &&
3667
+ (fpclassify (x ) == FP_ZERO || fpclassify (y ) == FP_ZERO ))
3668
+ {
3669
+ feraiseexcept (FE_INVALID );
3670
+ return 0.0f / 0.0f ;
3671
+ }
3672
+ else if (isnanf (z ))
3673
+ return 0.0f / 0.0f ;
3674
+
3675
+ float x_times_y = x * y ;
3676
+ if (
3677
+ isinff (x_times_y ) && isinff (z ) &&
3678
+ __CPROVER_signf (x_times_y ) != __CPROVER_signf (z ))
3679
+ {
3680
+ feraiseexcept (FE_INVALID );
3681
+ return 0.0f / 0.0f ;
3682
+ }
3683
+
3684
+ // TODO: detect overflow (FE_OVERFLOW), return +/- __builtin_inff()
3685
+ // TODO: detect underflow (FE_UNDERFLOW), return +/- 0
3686
+ return x_times_y + z ;
3687
+ }
3688
+
3689
+ /* FUNCTION: fmal */
3690
+
3691
+ #ifndef __CPROVER_MATH_H_INCLUDED
3692
+ # include <math.h>
3693
+ # define __CPROVER_MATH_H_INCLUDED
3694
+ #endif
3695
+
3696
+ #ifndef __CPROVER_FENV_H_INCLUDED
3697
+ # include <fenv.h>
3698
+ # define __CPROVER_FENV_H_INCLUDED
3699
+ #endif
3700
+
3701
+ #ifndef __CPROVER_FLOAT_H_INCLUDED
3702
+ # include <float.h>
3703
+ # define __CPROVER_FLOAT_H_INCLUDED
3704
+ #endif
3705
+
3706
+ long double __builtin_infl (void );
3707
+
3708
+ long double fmal (long double x , long double y , long double z )
3709
+ {
3710
+ // see man fma (https://linux.die.net/man/3/fma)
3711
+ if (isnanl (x ) || isnanl (y ))
3712
+ return 0.0l / 0.0l ;
3713
+ else if (
3714
+ (isinfl (x ) || isinfl (y )) &&
3715
+ (fpclassify (x ) == FP_ZERO || fpclassify (y ) == FP_ZERO ))
3716
+ {
3717
+ feraiseexcept (FE_INVALID );
3718
+ return 0.0l / 0.0l ;
3719
+ }
3720
+ else if (isnanl (z ))
3721
+ return 0.0l / 0.0l ;
3722
+
3723
+ long double x_times_y = x * y ;
3724
+ if (
3725
+ isinfl (x_times_y ) && isinfl (z ) &&
3726
+ __CPROVER_signld (x_times_y ) != __CPROVER_signld (z ))
3727
+ {
3728
+ feraiseexcept (FE_INVALID );
3729
+ return 0.0l / 0.0l ;
3730
+ }
3731
+
3732
+ #if LDBL_MAX_EXP == DBL_MAX_EXP
3733
+ return fma (x , y , z );
3734
+ #else
3735
+ // TODO: detect overflow (FE_OVERFLOW), return +/- __builtin_infl()
3736
+ // TODO: detect underflow (FE_UNDERFLOW), return +/- 0
3737
+ return x_times_y + z ;
3738
+ #endif
3739
+ }
0 commit comments