* sysdeps/m68k/fpu/bits/mathinline.h (isinf): Avoid conflict with
[glibc.git] / sysdeps / m68k / fpu / bits / mathinline.h
blobb1e2a75f1b354eb0a6a348b7bbd7c87d5024565e
1 /* Definitions of inline math functions implemented by the m68881/2.
2 Copyright (C) 1991, 92, 93, 94, 96, 97, 98 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
20 #ifdef __GNUC__
22 #ifdef __USE_ISOC9X
24 /* ISO C 9X defines some macros to perform unordered comparisons. The
25 m68k FPU supports this with special opcodes and we should use them.
26 These must not be inline functions since we have to be able to handle
27 all floating-point types. */
28 # define isgreater(x, y) \
29 __extension__ \
30 ({ char __result; \
31 __asm__ ("fcmp%.x %2,%1; fsogt %0" \
32 : "=dm" (__result) : "f" (x), "f" (y)); \
33 __result != 0; })
35 # define isgreaterequal(x, y) \
36 __extension__ \
37 ({ char __result; \
38 __asm__ ("fcmp%.x %2,%1; fsoge %0" \
39 : "=dm" (__result) : "f" (x), "f" (y)); \
40 __result != 0; })
42 # define isless(x, y) \
43 __extension__ \
44 ({ char __result; \
45 __asm__ ("fcmp%.x %2,%1; fsolt %0" \
46 : "=dm" (__result) : "f" (x), "f" (y)); \
47 __result != 0; })
49 # define islessequal(x, y) \
50 __extension__ \
51 ({ char __result; \
52 __asm__ ("fcmp%.x %2,%1; fsole %0" \
53 : "=dm" (__result) : "f" (x), "f" (y)); \
54 __result != 0; })
56 # define islessgreater(x, y) \
57 __extension__ \
58 ({ char __result; \
59 __asm__ ("fcmp%.x %2,%1; fsogl %0" \
60 : "=dm" (__result) : "f" (x), "f" (y)); \
61 __result != 0; })
63 # define isunordered(x, y) \
64 __extension__ \
65 ({ char __result; \
66 __asm__ ("fcmp%.x %2,%1; fsun %0" \
67 : "=dm" (__result) : "f" (x), "f" (y)); \
68 __result != 0; })
69 #endif
72 #if (!defined __NO_MATH_INLINES && defined __OPTIMIZE__) \
73 || defined __LIBC_INTERNAL_MATH_INLINES
75 #ifdef __LIBC_INTERNAL_MATH_INLINES
76 /* This is used when defining the functions themselves. Define them with
77 __ names, and with `static inline' instead of `extern inline' so the
78 bodies will always be used, never an external function call. */
79 # define __m81_u(x) __CONCAT(__,x)
80 # define __m81_inline static __inline
81 #else
82 # define __m81_u(x) x
83 # ifdef __cplusplus
84 # define __m81_inline __inline
85 # else
86 # define __m81_inline extern __inline
87 # endif
88 # define __M81_MATH_INLINES 1
89 #endif
91 /* Define a const math function. */
92 #define __m81_defun(rettype, func, args) \
93 __m81_inline rettype __attribute__((__const__)) \
94 __m81_u(func) args
96 /* Define the three variants of a math function that has a direct
97 implementation in the m68k fpu. FUNC is the name for C (which will be
98 suffixed with f and l for the float and long double version, resp). OP
99 is the name of the fpu operation (without leading f). */
101 #if defined __USE_MISC || defined __USE_ISOC9X
102 # define __inline_mathop(func, op) \
103 __inline_mathop1(double, func, op) \
104 __inline_mathop1(float, __CONCAT(func,f), op) \
105 __inline_mathop1(long double, __CONCAT(func,l), op)
106 #else
107 # define __inline_mathop(func, op) \
108 __inline_mathop1(double, func, op)
109 #endif
111 #define __inline_mathop1(float_type,func, op) \
112 __m81_defun (float_type, func, (float_type __mathop_x)) \
114 float_type __result; \
115 __asm("f" __STRING(op) "%.x %1, %0" : "=f" (__result) : "f" (__mathop_x));\
116 return __result; \
119 #ifdef __LIBC_INTERNAL_MATH_INLINES
120 /* ieee style elementary functions */
121 /* These are internal to the implementation of libm. */
122 __inline_mathop(__ieee754_acos, acos)
123 __inline_mathop(__ieee754_asin, asin)
124 __inline_mathop(__ieee754_cosh, cosh)
125 __inline_mathop(__ieee754_sinh, sinh)
126 __inline_mathop(__ieee754_exp, etox)
127 __inline_mathop(__ieee754_exp2, twotox)
128 __inline_mathop(__ieee754_exp10, tentox)
129 __inline_mathop(__ieee754_log10, log10)
130 __inline_mathop(__ieee754_log, logn)
131 __inline_mathop(__ieee754_sqrt, sqrt)
132 __inline_mathop(__ieee754_atanh, atanh)
133 #endif
135 __inline_mathop(__atan, atan)
136 __inline_mathop(__cos, cos)
137 __inline_mathop(__sin, sin)
138 __inline_mathop(__tan, tan)
139 __inline_mathop(__tanh, tanh)
140 __inline_mathop(__fabs, abs)
142 #if defined __USE_MISC || defined __USE_XOPEN_EXTENDED || defined __USE_ISOC9X
143 __inline_mathop(__rint, int)
144 __inline_mathop(__expm1, etoxm1)
145 __inline_mathop(__log1p, lognp1)
146 #endif
148 #ifdef __USE_MISC
149 __inline_mathop(__significand, getman)
150 #endif
152 #ifdef __USE_ISOC9X
153 __inline_mathop(__log2, log2)
154 __inline_mathop(__trunc, intrz)
155 #endif
157 #if !defined __NO_MATH_INLINES && defined __OPTIMIZE__
159 __inline_mathop(atan, atan)
160 __inline_mathop(cos, cos)
161 __inline_mathop(sin, sin)
162 __inline_mathop(tan, tan)
163 __inline_mathop(tanh, tanh)
165 # if defined __USE_MISC || defined __USE_XOPEN_EXTENDED || defined __USE_ISOC9X
166 __inline_mathop(rint, int)
167 __inline_mathop(expm1, etoxm1)
168 __inline_mathop(log1p, lognp1)
169 # endif
171 # ifdef __USE_MISC
172 __inline_mathop(significand, getman)
173 # endif
175 # ifdef __USE_ISOC9X
176 __inline_mathop(log2, log2)
177 __inline_mathop(trunc, intrz)
178 # endif
180 #endif /* !__NO_MATH_INLINES && __OPTIMIZE__ */
182 /* This macro contains the definition for the rest of the inline
183 functions, using __FLOAT_TYPE as the domain type and __S as the suffix
184 for the function names. */
186 #ifdef __LIBC_INTERNAL_MATH_INLINES
187 /* Internally used functions. */
188 # define __internal_inline_functions(float_type, s) \
189 __m81_defun (float_type, __CONCAT(__ieee754_remainder,s), \
190 (float_type __x, float_type __y)) \
192 float_type __result; \
193 __asm("frem%.x %1, %0" : "=f" (__result) : "f" (__y), "0" (__x)); \
194 return __result; \
197 __m81_defun (float_type, __CONCAT(__ieee754_fmod,s), \
198 (float_type __x, float_type __y)) \
200 float_type __result; \
201 __asm("fmod%.x %1, %0" : "=f" (__result) : "f" (__y), "0" (__x)); \
202 return __result; \
205 __internal_inline_functions (double,)
206 __internal_inline_functions (float,f)
207 __internal_inline_functions (long double,l)
208 # undef __internal_inline_functions
210 /* Get the m68881 condition codes, to quickly check multiple conditions. */
211 static __inline__ unsigned long
212 __m81_test (long double __val)
214 unsigned long __fpsr;
215 __asm ("ftst%.x %1; fmove%.l %/fpsr,%0" : "=dm" (__fpsr) : "f" (__val));
216 return __fpsr;
219 /* Bit values returned by __m81_test. */
220 # define __M81_COND_NAN (1 << 24)
221 # define __M81_COND_INF (2 << 24)
222 # define __M81_COND_ZERO (4 << 24)
223 # define __M81_COND_NEG (8 << 24)
225 #endif /* __LIBC_INTENRAL_MATH_INLINES */
227 /* The rest of the functions are available to the user. */
229 #define __inline_functions(float_type, s) \
230 __m81_inline float_type \
231 __m81_u(__CONCAT(__frexp,s))(float_type __value, int *__expptr) \
233 float_type __mantissa, __exponent; \
234 int __iexponent; \
235 unsigned long __fpsr; \
236 __asm("ftst%.x %1\n" \
237 "fmove%.l %/fpsr, %0" : "=dm" (__fpsr) : "f" (__value)); \
238 if (__fpsr & (7 << 24)) \
240 /* Not finite or zero. */ \
241 *__expptr = 0; \
242 return __value; \
244 __asm("fgetexp%.x %1, %0" : "=f" (__exponent) : "f" (__value)); \
245 __iexponent = (int) __exponent + 1; \
246 *__expptr = __iexponent; \
247 __asm("fscale%.l %2, %0" : "=f" (__mantissa) \
248 : "0" (__value), "dmi" (-__iexponent)); \
249 return __mantissa; \
252 __m81_defun (float_type, __CONCAT(__floor,s), (float_type __x)) \
254 float_type __result; \
255 unsigned long int __ctrl_reg; \
256 __asm __volatile__ ("fmove%.l %!, %0" : "=dm" (__ctrl_reg)); \
257 /* Set rounding towards negative infinity. */ \
258 __asm __volatile__ ("fmove%.l %0, %!" : /* No outputs. */ \
259 : "dmi" ((__ctrl_reg & ~0x10) | 0x20)); \
260 /* Convert X to an integer, using -Inf rounding. */ \
261 __asm __volatile__ ("fint%.x %1, %0" : "=f" (__result) : "f" (__x)); \
262 /* Restore the previous rounding mode. */ \
263 __asm __volatile__ ("fmove%.l %0, %!" : /* No outputs. */ \
264 : "dmi" (__ctrl_reg)); \
265 return __result; \
268 __m81_defun (float_type, __CONCAT(__ceil,s), (float_type __x)) \
270 float_type __result; \
271 unsigned long int __ctrl_reg; \
272 __asm __volatile__ ("fmove%.l %!, %0" : "=dm" (__ctrl_reg)); \
273 /* Set rounding towards positive infinity. */ \
274 __asm __volatile__ ("fmove%.l %0, %!" : /* No outputs. */ \
275 : "dmi" (__ctrl_reg | 0x30)); \
276 /* Convert X to an integer, using +Inf rounding. */ \
277 __asm __volatile__ ("fint%.x %1, %0" : "=f" (__result) : "f" (__x)); \
278 /* Restore the previous rounding mode. */ \
279 __asm __volatile__ ("fmove%.l %0, %!" : /* No outputs. */ \
280 : "dmi" (__ctrl_reg)); \
281 return __result; \
284 __inline_functions(double,)
285 #if defined __USE_MISC || defined __USE_ISOC9X
286 __inline_functions(float,f)
287 __inline_functions(long double,l)
288 #endif
289 #undef __inline_functions
291 #ifdef __USE_MISC
293 # define __inline_functions(float_type, s) \
294 __m81_defun (int, __CONCAT(__isinf,s), (float_type __value)) \
296 /* There is no branch-condition for infinity, \
297 so we must extract and examine the condition codes manually. */ \
298 unsigned long int __fpsr; \
299 __asm("ftst%.x %1\n" \
300 "fmove%.l %/fpsr, %0" : "=dm" (__fpsr) : "f" (__value)); \
301 return (__fpsr & (2 << 24)) ? (__fpsr & (8 << 24) ? -1 : 1) : 0; \
304 __m81_defun (int, __CONCAT(__finite,s), (float_type __value)) \
306 /* There is no branch-condition for infinity, so we must extract and \
307 examine the condition codes manually. */ \
308 unsigned long int __fpsr; \
309 __asm ("ftst%.x %1\n" \
310 "fmove%.l %/fpsr, %0" : "=dm" (__fpsr) : "f" (__value)); \
311 return (__fpsr & (3 << 24)) == 0; \
314 __m81_defun (float_type, __CONCAT(__scalbn,s), \
315 (float_type __x, int __n)) \
317 float_type __result; \
318 __asm ("fscale%.l %1, %0" : "=f" (__result) : "dmi" (__n), "0" (__x)); \
319 return __result; \
322 __inline_functions(double,)
323 __inline_functions(float,f)
324 __inline_functions(long double,l)
325 # undef __inline_functions
327 #endif /* Use misc. */
329 #if defined __USE_MISC || defined __USE_XOPEN
331 # define __inline_functions(float_type, s) \
332 __m81_defun (int, __CONCAT(__isnan,s), (float_type __value)) \
334 char __result; \
335 __asm("ftst%.x %1\n" \
336 "fsun %0" : "=dm" (__result) : "f" (__value)); \
337 return __result; \
340 __inline_functions(double,)
341 # ifdef __USE_MISC
342 __inline_functions(float,f)
343 __inline_functions(long double,l)
344 # endif
345 # undef __inline_functions
347 #endif
349 #ifdef __USE_ISOC9X
351 # define __inline_functions(float_type, s) \
352 __m81_defun (int, __CONCAT(__signbit,s), (float_type __value)) \
354 /* There is no branch-condition for the sign bit, so we must extract \
355 and examine the condition codes manually. */ \
356 unsigned long int __fpsr; \
357 __asm ("ftst%.x %1\n" \
358 "fmove%.l %/fpsr, %0" : "=dm" (__fpsr) : "f" (__value)); \
359 return (__fpsr >> 27) & 1; \
362 __m81_defun (float_type, __CONCAT(__scalbln,s), \
363 (float_type __x, long int __n)) \
365 return __CONCAT(__scalbn,s) (__x, __n); \
368 __m81_defun (float_type, __CONCAT(__nearbyint,s), (float_type __x)) \
370 float_type __result; \
371 unsigned long int __ctrl_reg; \
372 __asm __volatile__ ("fmove%.l %!, %0" : "=dm" (__ctrl_reg)); \
373 /* Temporarily disable the inexact exception. */ \
374 __asm __volatile__ ("fmove%.l %0, %!" : /* No outputs. */ \
375 : "dmi" (__ctrl_reg & ~0x200)); \
376 __asm __volatile__ ("fint%.x %1, %0" : "=f" (__result) : "f" (__x)); \
377 __asm __volatile__ ("fmove%.l %0, %!" : /* No outputs. */ \
378 : "dmi" (__ctrl_reg)); \
379 return __result; \
382 __m81_defun (long int, __CONCAT(__lrint,s), (float_type __x)) \
384 long int __result; \
385 __asm ("fmove%.l %1, %0" : "=dm" (__result) : "f" (__x)); \
386 return __result; \
389 __m81_inline float_type \
390 __m81_u(__CONCAT(__fma,s))(float_type __x, float_type __y, \
391 float_type __z) \
393 return (__x * __y) + __z; \
396 __inline_functions (double,)
397 __inline_functions (float,f)
398 __inline_functions (long double,l)
399 # undef __inline_functions
401 #endif /* Use ISO C9x */
403 #ifdef __USE_GNU
405 # define __inline_functions(float_type, s) \
406 __m81_inline void \
407 __m81_u(__CONCAT(__sincos,s))(float_type __x, float_type *__sinx, \
408 float_type *__cosx) \
410 __asm ("fsincos%.x %2,%1:%0" \
411 : "=f" (*__sinx), "=f" (*__cosx) : "f" (__x)); \
414 __inline_functions (double,)
415 __inline_functions (float,f)
416 __inline_functions (long double,l)
417 # undef __inline_functions
419 #endif
421 #if !defined __NO_MATH_INLINES && defined __OPTIMIZE__
423 /* Define inline versions of the user visible functions. */
425 /* Note that there must be no whitespace before the argument passed for
426 NAME, to make token pasting work correctly with -traditional. */
427 # define __inline_forward_c(rettype, name, args1, args2) \
428 extern __inline rettype __attribute__((__const__)) \
429 name args1 \
431 return __CONCAT(__,name) args2; \
434 # define __inline_forward(rettype, name, args1, args2) \
435 extern __inline rettype name args1 \
437 return __CONCAT(__,name) args2; \
440 __inline_forward(double,frexp, (double __value, int *__expptr),
441 (__value, __expptr))
442 __inline_forward_c(double,floor, (double __x), (__x))
443 __inline_forward_c(double,ceil, (double __x), (__x))
444 # ifdef __USE_MISC
445 # ifndef __USE_ISOC9X /* Conflict with macro of same name. */
446 __inline_forward_c(int,isinf, (double __value), (__value))
447 # endif
448 __inline_forward_c(int,finite, (double __value), (__value))
449 __inline_forward_c(double,scalbn, (double __x, int __n), (__x, __n))
450 # endif
451 # if defined __USE_MISC || defined __USE_XOPEN
452 # ifndef __USE_ISOC9X /* Conflict with macro of same name. */
453 __inline_forward_c(int,isnan, (double __value), (__value))
454 # endif
455 # endif
456 # ifdef __USE_ISOC9X
457 __inline_forward_c(double,scalbln, (double __x, long int __n), (__x, __n))
458 __inline_forward_c(double,nearbyint, (double __value), (__value))
459 __inline_forward_c(long int,lrint, (double __value), (__value))
460 __inline_forward_c(double,fma, (double __x, double __y, double __z),
461 (__x, __y, __z))
462 # endif
463 # ifdef __USE_GNU
464 __inline_forward(void,sincos, (double __x, double *__sinx, double *__cosx),
465 (__x, __sinx, __cosx))
466 # endif
468 # if defined __USE_MISC || defined __USE_ISOC9X
470 __inline_forward(float,frexpf, (float __value, int *__expptr),
471 (__value, __expptr))
472 __inline_forward_c(float,floorf, (float __x), (__x))
473 __inline_forward_c(float,ceilf, (float __x), (__x))
474 # ifdef __USE_MISC
475 __inline_forward_c(int,isinff, (float __value), (__value))
476 __inline_forward_c(int,finitef, (float __value), (__value))
477 __inline_forward_c(float,scalbnf, (float __x, int __n), (__x, __n))
478 __inline_forward_c(int,isnanf, (float __value), (__value))
479 # endif
480 # ifdef __USE_ISOC9X
481 __inline_forward_c(float,scalblnf, (float __x, long int __n), (__x, __n))
482 __inline_forward_c(float,nearbyintf, (float __value), (__value))
483 __inline_forward_c(long int,lrintf, (float __value), (__value))
484 __inline_forward_c(float,fmaf, (float __x, float __y, float __z),
485 (__x, __y, __z))
486 # endif
487 # ifdef __USE_GNU
488 __inline_forward(void,sincosf, (float __x, float *__sinx, float *__cosx),
489 (__x, __sinx, __cosx))
490 # endif
492 __inline_forward(long double,frexpl, (long double __value, int *__expptr),
493 (__value, __expptr))
494 __inline_forward_c(long double,floorl, (long double __x), (__x))
495 __inline_forward_c(long double,ceill, (long double __x), (__x))
496 # ifdef __USE_MISC
497 __inline_forward_c(int,isinfl, (long double __value), (__value))
498 __inline_forward_c(int,finitel, (long double __value), (__value))
499 __inline_forward_c(long double,scalbnl, (long double __x, int __n), (__x, __n))
500 __inline_forward_c(int,isnanl, (long double __value), (__value))
501 # endif
502 # ifdef __USE_ISOC9X
503 __inline_forward_c(long double,scalblnl, (long double __x, long int __n),
504 (__x, __n))
505 __inline_forward_c(long double,nearbyintl, (long double __value), (__value))
506 __inline_forward_c(long int,lrintl, (long double __value), (__value))
507 __inline_forward_c(long double,fmal,
508 (long double __x, long double __y, long double __z),
509 (__x, __y, __z))
510 # endif
511 # ifdef __USE_GNU
512 __inline_forward(void,sincosl,
513 (long double __x, long double *__sinx, long double *__cosx),
514 (__x, __sinx, __cosx))
515 # endif
517 #endif /* Use misc or ISO C9X */
519 #undef __inline_forward
520 #undef __inline_forward_c
522 #endif /* !__NO_MATH_INLINES && __OPTIMIZE__ */
524 #endif
525 #endif /* GCC. */