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