Home | History | Annotate | Download | only in single
      1 /*
      2  * math_private.h
      3  *
      4  * Copyright (c) 2015-2018, Arm Limited.
      5  * SPDX-License-Identifier: MIT
      6  */
      7 
      8 /*
      9  * Header file containing some definitions and other small reusable pieces of
     10  * code that we need in the libraries.
     11  */
     12 
     13 #ifndef __MATH_PRIVATE_H
     14 #define __MATH_PRIVATE_H
     15 
     16 #include <errno.h>
     17 #include <stdint.h>
     18 
     19 extern int    __ieee754_rem_pio2(double, double *);
     20 extern double __kernel_poly(const double *, int, double);
     21 
     22 #define __FP_IEEE
     23 #define __FP_FENV_EXCEPTIONS
     24 #define __FP_FENV_ROUNDING
     25 #define __FP_INEXACT_EXCEPTION
     26 
     27 #define __set_errno(val) (errno = (val))
     28 
     29 static __inline uint32_t __LO(double x)
     30 {
     31   union {double f; uint64_t i;} u = {x};
     32   return (uint32_t)u.i;
     33 }
     34 
     35 static __inline uint32_t __HI(double x)
     36 {
     37   union {double f; uint64_t i;} u = {x};
     38   return u.i >> 32;
     39 }
     40 
     41 static __inline double __SET_LO(double x, uint32_t lo)
     42 {
     43   union {double f; uint64_t i;} u = {x};
     44   u.i = (u.i >> 32) << 32 | lo;
     45   return u.f;
     46 }
     47 
     48 static __inline unsigned int fai(float f)
     49 {
     50   union {float f; uint32_t i;} u = {f};
     51   return u.i;
     52 }
     53 
     54 static __inline float fhex(unsigned int n)
     55 {
     56   union {uint32_t i; float f;} u = {n};
     57   return u.f;
     58 }
     59 
     60 #define CLEARBOTTOMHALF(x) fhex((fai(x) + 0x00000800) & 0xFFFFF000)
     61 
     62 #define FE_IEEE_OVERFLOW           (0x00000004)
     63 #define FE_IEEE_UNDERFLOW          (0x00000008)
     64 #define FE_IEEE_FLUSHZERO          (0x01000000)
     65 #define FE_IEEE_ROUND_TONEAREST    (0x00000000)
     66 #define FE_IEEE_ROUND_UPWARD       (0x00400000)
     67 #define FE_IEEE_ROUND_DOWNWARD     (0x00800000)
     68 #define FE_IEEE_ROUND_TOWARDZERO   (0x00C00000)
     69 #define FE_IEEE_ROUND_MASK         (0x00C00000)
     70 #define FE_IEEE_MASK_INVALID       (0x00000100)
     71 #define FE_IEEE_MASK_DIVBYZERO     (0x00000200)
     72 #define FE_IEEE_MASK_OVERFLOW      (0x00000400)
     73 #define FE_IEEE_MASK_UNDERFLOW     (0x00000800)
     74 #define FE_IEEE_MASK_INEXACT       (0x00001000)
     75 #define FE_IEEE_MASK_INPUTDENORMAL (0x00008000)
     76 #define FE_IEEE_MASK_ALL_EXCEPT    (0x00009F00)
     77 #define FE_IEEE_INVALID            (0x00000001)
     78 #define FE_IEEE_DIVBYZERO          (0x00000002)
     79 #define FE_IEEE_INEXACT            (0x00000010)
     80 #define FE_IEEE_INPUTDENORMAL      (0x00000080)
     81 #define FE_IEEE_ALL_EXCEPT         (0x0000009F)
     82 
     83 extern double __mathlib_dbl_overflow(void);
     84 extern float __mathlib_flt_overflow(void);
     85 extern double __mathlib_dbl_underflow(void);
     86 extern float __mathlib_flt_underflow(void);
     87 extern double __mathlib_dbl_invalid(void);
     88 extern float __mathlib_flt_invalid(void);
     89 extern double __mathlib_dbl_divzero(void);
     90 extern float __mathlib_flt_divzero(void);
     91 #define DOUBLE_OVERFLOW ( __mathlib_dbl_overflow() )
     92 #define FLOAT_OVERFLOW ( __mathlib_flt_overflow() )
     93 #define DOUBLE_UNDERFLOW ( __mathlib_dbl_underflow() )
     94 #define FLOAT_UNDERFLOW ( __mathlib_flt_underflow() )
     95 #define DOUBLE_INVALID ( __mathlib_dbl_invalid() )
     96 #define FLOAT_INVALID  ( __mathlib_flt_invalid() )
     97 #define DOUBLE_DIVZERO ( __mathlib_dbl_divzero() )
     98 #define FLOAT_DIVZERO  ( __mathlib_flt_divzero() )
     99 
    100 extern float  __mathlib_flt_infnan(float);
    101 extern float  __mathlib_flt_infnan2(float, float);
    102 extern double __mathlib_dbl_infnan(double);
    103 extern double __mathlib_dbl_infnan2(double, double);
    104 extern unsigned __ieee_status(unsigned, unsigned);
    105 
    106 #define FLOAT_INFNAN(x) __mathlib_flt_infnan(x)
    107 #define FLOAT_INFNAN2(x,y) __mathlib_flt_infnan2(x,y)
    108 #define DOUBLE_INFNAN(x) __mathlib_dbl_infnan(x)
    109 #define DOUBLE_INFNAN2(x,y) __mathlib_dbl_infnan2(x,y)
    110 
    111 #define MATHERR_POWF_00(x,y) (__set_errno(EDOM), 1.0f)
    112 #define MATHERR_POWF_INF0(x,y) (__set_errno(EDOM), 1.0f)
    113 #define MATHERR_POWF_0NEG(x,y) (__set_errno(ERANGE), FLOAT_DIVZERO)
    114 #define MATHERR_POWF_NEG0FRAC(x,y) (0.0f)
    115 #define MATHERR_POWF_0NEGODD(x,y) (__set_errno(ERANGE), -FLOAT_DIVZERO)
    116 #define MATHERR_POWF_0NEGEVEN(x,y) (__set_errno(ERANGE), FLOAT_DIVZERO)
    117 #define MATHERR_POWF_NEGFRAC(x,y) (__set_errno(EDOM), FLOAT_INVALID)
    118 #define MATHERR_POWF_ONEINF(x,y) (1.0f)
    119 #define MATHERR_POWF_OFL(x,y,z) (__set_errno(ERANGE), copysignf(FLOAT_OVERFLOW,z))
    120 #define MATHERR_POWF_UFL(x,y,z) (__set_errno(ERANGE), copysignf(FLOAT_UNDERFLOW,z))
    121 
    122 #define MATHERR_LOGF_0(x) (__set_errno(ERANGE), -FLOAT_DIVZERO)
    123 #define MATHERR_LOGF_NEG(x) (__set_errno(EDOM), FLOAT_INVALID)
    124 
    125 #define MATHERR_SIN_INF(x) (__set_errno(EDOM), DOUBLE_INVALID)
    126 #define MATHERR_SINF_INF(x) (__set_errno(EDOM), FLOAT_INVALID)
    127 #define MATHERR_COS_INF(x) (__set_errno(EDOM), DOUBLE_INVALID)
    128 #define MATHERR_COSF_INF(x) (__set_errno(EDOM), FLOAT_INVALID)
    129 #define MATHERR_TAN_INF(x) (__set_errno(EDOM), DOUBLE_INVALID)
    130 #define MATHERR_TANF_INF(x) (__set_errno(EDOM), FLOAT_INVALID)
    131 
    132 #define MATHERR_EXPF_UFL(x) (__set_errno(ERANGE), FLOAT_UNDERFLOW)
    133 #define MATHERR_EXPF_OFL(x) (__set_errno(ERANGE), FLOAT_OVERFLOW)
    134 
    135 #define FLOAT_CHECKDENORM(x) ( (fpclassify(x) == FP_SUBNORMAL ? FLOAT_UNDERFLOW : 0), x )
    136 #define DOUBLE_CHECKDENORM(x) ( (fpclassify(x) == FP_SUBNORMAL ? DOUBLE_UNDERFLOW : 0), x )
    137 
    138 #endif /* __MATH_PRIVATE_H */
    139