Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
6429 | siemargl | 1 | #ifndef _TCC_LIBM_H_ |
2 | #define _TCC_LIBM_H_ |
||
3 | |||
4 | #include "../include/math.h" |
||
5 | |||
6 | /* TCC uses 8 bytes for double and long double, so effectively the l variants |
||
7 | * are never used. For now, they just run the normal (double) variant. |
||
8 | */ |
||
9 | |||
10 | /* |
||
11 | * most of the code in this file is taken from MUSL rs-1.0 (MIT license) |
||
12 | * - musl-libc: http://git.musl-libc.org/cgit/musl/tree/src/math?h=rs-1.0 |
||
13 | * - License: http://git.musl-libc.org/cgit/musl/tree/COPYRIGHT?h=rs-1.0 |
||
14 | */ |
||
15 | |||
16 | /******************************************************************************* |
||
17 | Start of code based on MUSL |
||
18 | *******************************************************************************/ |
||
19 | /* |
||
20 | musl as a whole is licensed under the following standard MIT license: |
||
21 | |||
22 | ---------------------------------------------------------------------- |
||
23 | Copyright © 2005-2014 Rich Felker, et al. |
||
24 | |||
25 | Permission is hereby granted, free of charge, to any person obtaining |
||
26 | a copy of this software and associated documentation files (the |
||
27 | "Software"), to deal in the Software without restriction, including |
||
28 | without limitation the rights to use, copy, modify, merge, publish, |
||
29 | distribute, sublicense, and/or sell copies of the Software, and to |
||
30 | permit persons to whom the Software is furnished to do so, subject to |
||
31 | the following conditions: |
||
32 | |||
33 | The above copyright notice and this permission notice shall be |
||
34 | included in all copies or substantial portions of the Software. |
||
35 | |||
36 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
||
37 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
||
38 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
||
39 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
||
40 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
||
41 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
||
42 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||
43 | ---------------------------------------------------------------------- |
||
44 | */ |
||
45 | |||
46 | /* fpclassify */ |
||
47 | |||
48 | __CRT_INLINE int __cdecl __fpclassify (double x) { |
||
49 | union {double f; uint64_t i;} u = {x}; |
||
50 | int e = u.i>>52 & 0x7ff; |
||
51 | if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO; |
||
52 | if (e==0x7ff) return u.i<<12 ? FP_NAN : FP_INFINITE; |
||
53 | return FP_NORMAL; |
||
54 | } |
||
55 | |||
56 | __CRT_INLINE int __cdecl __fpclassifyf (float x) { |
||
57 | union {float f; uint32_t i;} u = {x}; |
||
58 | int e = u.i>>23 & 0xff; |
||
59 | if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO; |
||
60 | if (e==0xff) return u.i<<9 ? FP_NAN : FP_INFINITE; |
||
61 | return FP_NORMAL; |
||
62 | } |
||
63 | |||
64 | __CRT_INLINE int __cdecl __fpclassifyl (long double x) { |
||
65 | return __fpclassify(x); |
||
66 | } |
||
67 | |||
68 | |||
69 | /* signbit */ |
||
70 | |||
71 | __CRT_INLINE int __cdecl __signbit (double x) { |
||
72 | union {double d; uint64_t i;} y = { x }; |
||
73 | return y.i>>63; |
||
74 | } |
||
75 | |||
76 | __CRT_INLINE int __cdecl __signbitf (float x) { |
||
77 | union {float f; uint32_t i; } y = { x }; |
||
78 | return y.i>>31; |
||
79 | } |
||
80 | |||
81 | __CRT_INLINE int __cdecl __signbitl (long double x) { |
||
82 | return __signbit(x); |
||
83 | } |
||
84 | |||
85 | |||
86 | /* fmin*, fmax* */ |
||
87 | |||
88 | #define TCCFP_FMIN_EVAL (isnan(x) ? y : \ |
||
89 | isnan(y) ? x : \ |
||
90 | (signbit(x) != signbit(y)) ? (signbit(x) ? x : y) : \ |
||
91 | x < y ? x : y) |
||
92 | |||
93 | __CRT_INLINE double __cdecl fmin (double x, double y) { |
||
94 | return TCCFP_FMIN_EVAL; |
||
95 | } |
||
96 | |||
97 | __CRT_INLINE float __cdecl fminf (float x, float y) { |
||
98 | return TCCFP_FMIN_EVAL; |
||
99 | } |
||
100 | |||
101 | __CRT_INLINE long double __cdecl fminl (long double x, long double y) { |
||
102 | return TCCFP_FMIN_EVAL; |
||
103 | } |
||
104 | |||
105 | #define TCCFP_FMAX_EVAL (isnan(x) ? y : \ |
||
106 | isnan(y) ? x : \ |
||
107 | (signbit(x) != signbit(y)) ? (signbit(x) ? y : x) : \ |
||
108 | x < y ? y : x) |
||
109 | |||
110 | __CRT_INLINE double __cdecl fmax (double x, double y) { |
||
111 | return TCCFP_FMAX_EVAL; |
||
112 | } |
||
113 | |||
114 | __CRT_INLINE float __cdecl fmaxf (float x, float y) { |
||
115 | return TCCFP_FMAX_EVAL; |
||
116 | } |
||
117 | |||
118 | __CRT_INLINE long double __cdecl fmaxl (long double x, long double y) { |
||
119 | return TCCFP_FMAX_EVAL; |
||
120 | } |
||
121 | |||
122 | |||
123 | /* *round* */ |
||
124 | |||
125 | #define TCCFP_FORCE_EVAL(x) do { \ |
||
126 | if (sizeof(x) == sizeof(float)) { \ |
||
127 | volatile float __x; \ |
||
128 | __x = (x); \ |
||
129 | } else if (sizeof(x) == sizeof(double)) { \ |
||
130 | volatile double __x; \ |
||
131 | __x = (x); \ |
||
132 | } else { \ |
||
133 | volatile long double __x; \ |
||
134 | __x = (x); \ |
||
135 | } \ |
||
136 | } while(0) |
||
137 | |||
138 | __CRT_INLINE double __cdecl round (double x) { |
||
139 | union {double f; uint64_t i;} u = {x}; |
||
140 | int e = u.i >> 52 & 0x7ff; |
||
141 | double y; |
||
142 | |||
143 | if (e >= 0x3ff+52) |
||
144 | return x; |
||
145 | if (u.i >> 63) |
||
146 | x = -x; |
||
147 | if (e < 0x3ff-1) { |
||
148 | /* raise inexact if x!=0 */ |
||
149 | TCCFP_FORCE_EVAL(x + 0x1p52); |
||
150 | return 0*u.f; |
||
151 | } |
||
152 | y = (double)(x + 0x1p52) - 0x1p52 - x; |
||
153 | if (y > 0.5) |
||
154 | y = y + x - 1; |
||
155 | else if (y <= -0.5) |
||
156 | y = y + x + 1; |
||
157 | else |
||
158 | y = y + x; |
||
159 | if (u.i >> 63) |
||
160 | y = -y; |
||
161 | return y; |
||
162 | } |
||
163 | |||
164 | __CRT_INLINE long __cdecl lround (double x) { |
||
165 | return round(x); |
||
166 | } |
||
167 | |||
168 | __CRT_INLINE long long __cdecl llround (double x) { |
||
169 | return round(x); |
||
170 | } |
||
171 | |||
172 | __CRT_INLINE float __cdecl roundf (float x) { |
||
173 | return round(x); |
||
174 | } |
||
175 | |||
176 | __CRT_INLINE long __cdecl lroundf (float x) { |
||
177 | return round(x); |
||
178 | } |
||
179 | |||
180 | __CRT_INLINE long long __cdecl llroundf (float x) { |
||
181 | return round(x); |
||
182 | } |
||
183 | |||
184 | __CRT_INLINE long double __cdecl roundl (long double x) { |
||
185 | return round(x); |
||
186 | } |
||
187 | |||
188 | __CRT_INLINE long __cdecl lroundl (long double x) { |
||
189 | return round(x); |
||
190 | } |
||
191 | |||
192 | __CRT_INLINE long long __cdecl llroundl (long double x) { |
||
193 | return round(x); |
||
194 | } |
||
195 | |||
196 | |||
197 | /******************************************************************************* |
||
198 | End of code based on MUSL |
||
199 | *******************************************************************************/ |
||
200 | |||
201 | #endif /* _TCC_LIBM_H_ */=>>>>9><9>1><1>12><12>1><1> |