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
__LO(double x)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
__HI(double x)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
__SET_LO(double x,uint32_t lo)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
fai(float f)48 static __inline unsigned int fai(float f)
49 {
50 union {float f; uint32_t i;} u = {f};
51 return u.i;
52 }
53
fhex(unsigned int n)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