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