3 #error This file should be included only with GCC compiler
7 #if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) \
8 || !defined __STRICT_ANSI__ || defined __cplusplus
10 #if __MINGW_GNUC_PREREQ(3, 3)
11 #define HUGE_VALF __builtin_huge_valf()
12 #define HUGE_VALL __builtin_huge_vall()
13 #define INFINITY __builtin_inf()
14 #define NAN __builtin_nan("")
16 extern const float __INFF
;
17 #define HUGE_VALF __INFF
18 extern const long double __INFL
;
19 #define HUGE_VALL __INFL
20 #define INFINITY HUGE_VALF
21 extern const double __QNAN
;
23 #endif /* __MINGW_GNUC_PREREQ(3, 3) */
25 /* Use the compiler's builtin define for FLT_EVAL_METHOD to
26 set float_t and double_t. */
27 #if defined(__FLT_EVAL_METHOD__)
28 # if ( __FLT_EVAL_METHOD__== 0)
29 typedef float float_t
;
30 typedef double double_t
;
31 # elif (__FLT_EVAL_METHOD__ == 1)
32 typedef double float_t
;
33 typedef double double_t
;
34 # elif (__FLT_EVAL_METHOD__ == 2)
35 typedef long double float_t
;
36 typedef long double double_t
;
38 #else /* ix87 FPU default */
39 typedef long double float_t
;
40 typedef long double double_t
;
45 Return values for fpclassify.
46 These are based on Intel x87 fpu condition codes
47 in the high byte of status word and differ from
48 the return values for MS IEEE 754 extension _fpclass()
51 #define FP_NORMAL 0x0400
52 #define FP_INFINITE (FP_NAN | FP_NORMAL)
53 #define FP_ZERO 0x4000
54 #define FP_SUBNORMAL (FP_NORMAL | FP_ZERO)
55 /* 0x0200 is signbit mask */
58 We can't inline float or double, because we want to ensure truncation
59 to semantic type before classification.
60 (A normal long double value might become subnormal when
61 converted to double, and zero when converted to float.)
64 extern int __cdecl
__fpclassifyl (long double);
65 extern int __cdecl
__fpclassifyf (float);
66 extern int __cdecl
__fpclassify (double);
68 #ifndef __CRT__NO_INLINE
69 __CRT_INLINE
int __cdecl
__fpclassifyl (long double x
) {
71 __asm__
__volatile__ ("fxam; fstsw %%ax;" : "=a" (sw
): "t" (x
));
72 return sw
& (FP_NAN
| FP_NORMAL
| FP_ZERO
);
74 __CRT_INLINE
int __cdecl
__fpclassify (double x
) {
76 __asm__
__volatile__ ("fxam; fstsw %%ax;" : "=a" (sw
): "t" (x
));
77 return sw
& (FP_NAN
| FP_NORMAL
| FP_ZERO
);
79 __CRT_INLINE
int __cdecl
__fpclassifyf (float x
) {
81 __asm__
__volatile__ ("fxam; fstsw %%ax;" : "=a" (sw
): "t" (x
));
82 return sw
& (FP_NAN
| FP_NORMAL
| FP_ZERO
);
86 #define fpclassify(x) (sizeof (x) == sizeof (float) ? __fpclassifyf (x) \
87 : sizeof (x) == sizeof (double) ? __fpclassify (x) \
91 #define isfinite(x) ((fpclassify(x) & FP_NAN) == 0)
94 #define isinf(x) (fpclassify(x) == FP_INFINITE)
97 /* We don't need to worry about truncation here:
100 extern int __cdecl
__isnan (double);
101 extern int __cdecl
__isnanf (float);
102 extern int __cdecl
__isnanl (long double);
104 #ifndef __CRT__NO_INLINE
105 __CRT_INLINE
int __cdecl
__isnan (double _x
)
108 __asm__
__volatile__ ("fxam;"
109 "fstsw %%ax": "=a" (sw
) : "t" (_x
));
110 return (sw
& (FP_NAN
| FP_NORMAL
| FP_INFINITE
| FP_ZERO
| FP_SUBNORMAL
))
114 __CRT_INLINE
int __cdecl
__isnanf (float _x
)
117 __asm__
__volatile__ ("fxam;"
118 "fstsw %%ax": "=a" (sw
) : "t" (_x
));
119 return (sw
& (FP_NAN
| FP_NORMAL
| FP_INFINITE
| FP_ZERO
| FP_SUBNORMAL
))
123 __CRT_INLINE
int __cdecl
__isnanl (long double _x
)
126 __asm__
__volatile__ ("fxam;"
127 "fstsw %%ax": "=a" (sw
) : "t" (_x
));
128 return (sw
& (FP_NAN
| FP_NORMAL
| FP_INFINITE
| FP_ZERO
| FP_SUBNORMAL
))
133 #define isnan(x) (sizeof (x) == sizeof (float) ? __isnanf (x) \
134 : sizeof (x) == sizeof (double) ? __isnan (x) \
138 #define isnormal(x) (fpclassify(x) == FP_NORMAL)
140 /* 7.12.3.6 The signbit macro */
141 extern int __cdecl
__signbit (double);
142 extern int __cdecl
__signbitf (float);
143 extern int __cdecl
__signbitl (long double);
144 #ifndef __CRT__NO_INLINE
145 __CRT_INLINE
int __cdecl
__signbit (double x
) {
147 __asm__
__volatile__ ( "fxam; fstsw %%ax;": "=a" (stw
) : "t" (x
));
151 __CRT_INLINE
int __cdecl
__signbitf (float x
) {
153 __asm__
__volatile__ ("fxam; fstsw %%ax;": "=a" (stw
) : "t" (x
));
157 __CRT_INLINE
int __cdecl
__signbitl (long double x
) {
159 __asm__
__volatile__ ("fxam; fstsw %%ax;": "=a" (stw
) : "t" (x
));
164 #define signbit(x) (sizeof (x) == sizeof (float) ? __signbitf (x) \
165 : sizeof (x) == sizeof (double) ? __signbit (x) \
168 /* 7.12.4 Trigonometric functions: Double in C89 */
171 /* 7.12.5 Hyperbolic functions: Double in C89 */
174 /* Inverse hyperbolic trig functions */
176 extern double __cdecl
acosh (double);
177 extern float __cdecl
acoshf (float);
178 extern long double __cdecl
acoshl (long double);
181 extern double __cdecl
asinh (double);
182 extern float __cdecl
asinhf (float);
183 extern long double __cdecl
asinhl (long double);
186 extern double __cdecl
atanh (double);
187 extern float __cdecl
atanhf (float);
188 extern long double __cdecl
atanhl (long double);
190 /* Exponentials and logarithms */
191 /* 7.12.6.1 Double in C89 */
192 // exp functions. Already in math.h
195 extern double __cdecl
exp2(double);
196 extern float __cdecl
exp2f(float);
197 extern long double __cdecl
exp2l(long double);
199 /* 7.12.6.3 The expm1 functions */
200 /* TODO: These could be inlined */
201 extern double __cdecl
expm1(double);
202 extern float __cdecl
expm1f(float);
203 extern long double __cdecl
expm1l(long double);
205 /* 7.12.6.4 Double in C89 */
206 // frexp functions. Already in math.h
209 #define FP_ILOGB0 ((int)0x80000000)
210 #define FP_ILOGBNAN ((int)0x80000000)
211 extern int __cdecl
ilogb (double);
212 extern int __cdecl
ilogbf (float);
213 extern int __cdecl
ilogbl (long double);
215 /* 7.12.6.6 Double in C89 */
216 // ldexp functions. Already in math.h
218 /* 7.12.6.7 Double in C89 */
219 // log functions. Already in math.h
221 /* 7.12.6.8 Double in C89 */
222 // log10 functions. Already in math.h
225 extern double __cdecl
log1p(double);
226 extern float __cdecl
log1pf(float);
227 extern long double __cdecl
log1pl(long double);
230 extern double __cdecl
log2 (double);
231 extern float __cdecl
log2f (float);
232 extern long double __cdecl
log2l (long double);
235 extern double __cdecl
logb (double);
236 extern float __cdecl
logbf (float);
237 extern long double __cdecl
logbl (long double);
239 /* Inline versions. GCC-4.0+ can do a better fast-math optimization
241 #ifndef __CRT__NO_INLINE
242 #if !(__MINGW_GNUC_PREREQ (4, 0) && defined (__FAST_MATH__))
243 __CRT_INLINE
double __cdecl
logb (double x
)
246 __asm__
__volatile__ ("fxtract\n\t"
247 "fstp %%st" : "=t" (res
) : "0" (x
));
251 __CRT_INLINE
float __cdecl
logbf (float x
)
254 __asm__
__volatile__ ("fxtract\n\t"
255 "fstp %%st" : "=t" (res
) : "0" (x
));
259 __CRT_INLINE
long double __cdecl
logbl (long double x
)
261 long double res
= 0.0l;
262 __asm__
__volatile__ ("fxtract\n\t"
263 "fstp %%st" : "=t" (res
) : "0" (x
));
266 #endif /* !defined __FAST_MATH__ || !__MINGW_GNUC_PREREQ (4, 0) */
267 #endif /* __CRT__NO_INLINE */
269 /* 7.12.6.12 Double in C89 */
270 // modf functions. Already in math.h
273 extern double __cdecl
scalbn (double, int);
274 extern float __cdecl
scalbnf (float, int);
275 extern long double __cdecl
scalbnl (long double, int);
277 extern double __cdecl
scalbln (double, long);
278 extern float __cdecl
scalblnf (float, long);
279 extern long double __cdecl
scalblnl (long double, long);
282 /* Implementations adapted from Cephes versions */
283 extern double __cdecl
cbrt (double);
284 extern float __cdecl
cbrtf (float);
285 extern long double __cdecl
cbrtl (long double);
287 /* 7.12.7.2 The fabs functions: Double in C89 */
291 // hypot functions. Already in math.h
293 /* 7.12.7.4 The pow functions. Double in C89 */
296 /* 7.12.7.5 The sqrt functions. Double in C89. */
299 /* 7.12.8.1 The erf functions */
300 extern double __cdecl
erf (double);
301 extern float __cdecl
erff (float);
302 extern long double __cdecl
erfl (long double);
304 /* 7.12.8.2 The erfc functions */
305 extern double __cdecl
erfc (double);
306 extern float __cdecl
erfcf (float);
307 extern long double __cdecl
erfcl (long double);
309 /* 7.12.8.3 The lgamma functions */
310 extern double __cdecl
lgamma (double);
311 extern float __cdecl
lgammaf (float);
312 extern long double __cdecl
lgammal (long double);
314 /* 7.12.8.4 The tgamma functions */
315 extern double __cdecl
tgamma (double);
316 extern float __cdecl
tgammaf (float);
317 extern long double __cdecl
tgammal (long double);
319 /* 7.12.9.1 Double in C89 */
320 // ceil functions. Already in math.h
322 /* 7.12.9.2 Double in C89 */
323 // floor functions. Already in math.h
326 extern double __cdecl
nearbyint ( double);
327 extern float __cdecl
nearbyintf (float);
328 extern long double __cdecl
nearbyintl (long double);
331 /* round, using fpu control word settings */
332 extern double __cdecl
rint (double);
333 extern float __cdecl
rintf (float);
334 extern long double __cdecl
rintl (long double);
337 extern long __cdecl
lrint (double);
338 extern long __cdecl
lrintf (float);
339 extern long __cdecl
lrintl (long double);
341 __MINGW_EXTENSION
long long __cdecl
llrint (double);
342 __MINGW_EXTENSION
long long __cdecl
llrintf (float);
343 __MINGW_EXTENSION
long long __cdecl
llrintl (long double);
345 /* Inline versions of above.
346 GCC 4.0+ can do a better fast-math job with __builtins. */
348 #ifndef __CRT__NO_INLINE
349 #if !(__MINGW_GNUC_PREREQ (4, 0) && defined __FAST_MATH__ )
350 __CRT_INLINE
double __cdecl
rint (double x
)
353 __asm__
__volatile__ ("frndint;": "=t" (retval
) : "0" (x
));
357 __CRT_INLINE
float __cdecl
rintf (float x
)
360 __asm__
__volatile__ ("frndint;" : "=t" (retval
) : "0" (x
) );
364 __CRT_INLINE
long double __cdecl
rintl (long double x
)
366 long double retval
= 0.0l;
367 __asm__
__volatile__ ("frndint;" : "=t" (retval
) : "0" (x
) );
371 __CRT_INLINE
long __cdecl
lrint (double x
)
374 __asm__ __volatile__ \
375 ("fistpl %0" : "=m" (retval
) : "t" (x
) : "st"); \
379 __CRT_INLINE
long __cdecl
lrintf (float x
)
382 __asm__ __volatile__ \
383 ("fistpl %0" : "=m" (retval
) : "t" (x
) : "st"); \
387 __CRT_INLINE
long __cdecl
lrintl (long double x
)
390 __asm__ __volatile__ \
391 ("fistpl %0" : "=m" (retval
) : "t" (x
) : "st"); \
395 __MINGW_EXTENSION __CRT_INLINE
long long __cdecl
llrint (double x
)
397 __MINGW_EXTENSION
long long retval
= 0ll;
398 __asm__ __volatile__ \
399 ("fistpll %0" : "=m" (retval
) : "t" (x
) : "st"); \
403 __MINGW_EXTENSION __CRT_INLINE
long long __cdecl
llrintf (float x
)
405 __MINGW_EXTENSION
long long retval
= 0ll;
406 __asm__ __volatile__ \
407 ("fistpll %0" : "=m" (retval
) : "t" (x
) : "st"); \
411 __MINGW_EXTENSION __CRT_INLINE
long long __cdecl
llrintl (long double x
)
413 __MINGW_EXTENSION
long long retval
= 0ll;
414 __asm__ __volatile__ \
415 ("fistpll %0" : "=m" (retval
) : "t" (x
) : "st"); \
418 #endif /* !__FAST_MATH__ || !__MINGW_GNUC_PREREQ (4,0) */
419 #endif /* !__CRT__NO_INLINE */
422 /* round away from zero, regardless of fpu control word settings */
423 extern double __cdecl
round (double);
424 extern float __cdecl
roundf (float);
425 extern long double __cdecl
roundl (long double);
428 extern long __cdecl
lround (double);
429 extern long __cdecl
lroundf (float);
430 extern long __cdecl
lroundl (long double);
431 __MINGW_EXTENSION
long long __cdecl
llround (double);
432 __MINGW_EXTENSION
long long __cdecl
llroundf (float);
433 __MINGW_EXTENSION
long long __cdecl
llroundl (long double);
436 /* round towards zero, regardless of fpu control word settings */
437 extern double __cdecl
trunc (double);
438 extern float __cdecl
truncf (float);
439 extern long double __cdecl
truncl (long double);
441 /* 7.12.10.1 Double in C89 */
442 // fmod functions. Already in math.h
445 extern double __cdecl
remainder (double, double);
446 extern float __cdecl
remainderf (float, float);
447 extern long double __cdecl
remainderl (long double, long double);
450 extern double __cdecl
remquo(double, double, int *);
451 extern float __cdecl
remquof(float, float, int *);
452 extern long double __cdecl
remquol(long double, long double, int *);
455 extern double __cdecl
copysign (double, double); /* in libmoldname.a */
456 extern float __cdecl
copysignf (float, float);
457 extern long double __cdecl
copysignl (long double, long double);
459 /* 7.12.11.2 Return a NaN */
460 extern double __cdecl
nan(const char *tagp
);
461 extern float __cdecl
nanf(const char *tagp
);
462 extern long double __cdecl
nanl(const char *tagp
);
464 #ifndef __STRICT_ANSI__
465 #define _nan() nan("")
466 #define _nanf() nanf("")
467 #define _nanl() nanl("")
471 extern double __cdecl
nextafter (double, double); /* in libmoldname.a */
472 extern float __cdecl
nextafterf (float, float);
473 extern long double __cdecl
nextafterl (long double, long double);
475 /* 7.12.11.4 The nexttoward functions */
476 extern double __cdecl
nexttoward (double, long double);
477 extern float __cdecl
nexttowardf (float, long double);
478 extern long double __cdecl
nexttowardl (long double, long double);
481 /* x > y ? (x - y) : 0.0 */
482 extern double __cdecl
fdim (double x
, double y
);
483 extern float __cdecl
fdimf (float x
, float y
);
484 extern long double __cdecl
fdiml (long double x
, long double y
);
487 NaN arguments are treated as missing data: if one argument is a NaN
488 and the other numeric, then these functions choose the numeric
492 extern double __cdecl
fmax (double, double);
493 extern float __cdecl
fmaxf (float, float);
494 extern long double __cdecl
fmaxl (long double, long double);
497 extern double __cdecl
fmin (double, double);
498 extern float __cdecl
fminf (float, float);
499 extern long double __cdecl
fminl (long double, long double);
502 /* return x * y + z as a ternary op */
503 extern double __cdecl
fma (double, double, double);
504 extern float __cdecl
fmaf (float, float, float);
505 extern long double __cdecl
fmal (long double, long double, long double);
509 * With these functions, comparisons involving quiet NaNs set the FP
510 * condition code to "unordered". The IEEE floating-point spec
511 * dictates that the result of floating-point comparisons should be
512 * false whenever a NaN is involved, with the exception of the != op,
513 * which always returns true: yes, (NaN != NaN) is true).
518 #define isgreater(x, y) __builtin_isgreater(x, y)
519 #define isgreaterequal(x, y) __builtin_isgreaterequal(x, y)
520 #define isless(x, y) __builtin_isless(x, y)
521 #define islessequal(x, y) __builtin_islessequal(x, y)
522 #define islessgreater(x, y) __builtin_islessgreater(x, y)
523 #define isunordered(x, y) __builtin_isunordered(x, y)
527 #ifndef __CRT__NO_INLINE
528 __CRT_INLINE
int __cdecl
529 __fp_unordered_compare (long double x
, long double y
){
530 unsigned short retval
;
531 __asm__
__volatile__ ("fucom %%st(1);"
532 "fnstsw;": "=a" (retval
) : "t" (x
), "u" (y
));
537 #define isgreater(x, y) ((__fp_unordered_compare(x, y) & 0x4500) == 0)
538 #define isless(x, y) ((__fp_unordered_compare (y, x) & 0x4500) == 0)
539 #define isgreaterequal(x, y) ((__fp_unordered_compare (x, y) & FP_INFINITE) == 0)
540 #define islessequal(x, y) ((__fp_unordered_compare(y, x) & FP_INFINITE) == 0)
541 #define islessgreater(x, y) ((__fp_unordered_compare(x, y) & FP_SUBNORMAL) == 0)
542 #define isunordered(x, y) ((__fp_unordered_compare(x, y) & 0x4500) == 0x4500)
546 #endif /* C99 or non strict ANSI or C++ */
547 #endif /* __NO_ISOCEXT */