libroot/posix/stdio: Remove unused portions.
[haiku.git] / src / system / libroot / posix / glibc / include / arch / m68k / bits / mathinline.h
blob1cadb9ebb658057c93badc3384b88ba64236fce2
1 /* Definitions of inline math functions implemented by the m68881/2.
2 Copyright (C) 1991,92,93,94,96,97,98,99,2000,2002, 2003, 2004
3 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA. */
21 #ifdef __GNUC__
23 #ifdef __USE_ISOC99
24 /* GCC 3.1 and up have builtins that actually can be used. */
25 # if !__GNUC_PREREQ (3,1)
26 /* ISO C99 defines some macros to perform unordered comparisons. The
27 m68k FPU supports this with special opcodes and we should use them.
28 These must not be inline functions since we have to be able to handle
29 all floating-point types. */
30 # undef isgreater
31 # undef isgreaterequal
32 # undef isless
33 # undef islessequal
34 # undef islessgreater
35 # undef isunordered
36 # define isgreater(x, y) \
37 __extension__ \
38 ({ char __result; \
39 __asm__ ("fcmp%.x %2,%1; fsogt %0" \
40 : "=dm" (__result) : "f" (x), "f" (y)); \
41 __result != 0; })
43 # define isgreaterequal(x, y) \
44 __extension__ \
45 ({ char __result; \
46 __asm__ ("fcmp%.x %2,%1; fsoge %0" \
47 : "=dm" (__result) : "f" (x), "f" (y)); \
48 __result != 0; })
50 # define isless(x, y) \
51 __extension__ \
52 ({ char __result; \
53 __asm__ ("fcmp%.x %2,%1; fsolt %0" \
54 : "=dm" (__result) : "f" (x), "f" (y)); \
55 __result != 0; })
57 # define islessequal(x, y) \
58 __extension__ \
59 ({ char __result; \
60 __asm__ ("fcmp%.x %2,%1; fsole %0" \
61 : "=dm" (__result) : "f" (x), "f" (y)); \
62 __result != 0; })
64 # define islessgreater(x, y) \
65 __extension__ \
66 ({ char __result; \
67 __asm__ ("fcmp%.x %2,%1; fsogl %0" \
68 : "=dm" (__result) : "f" (x), "f" (y)); \
69 __result != 0; })
71 # define isunordered(x, y) \
72 __extension__ \
73 ({ char __result; \
74 __asm__ ("fcmp%.x %2,%1; fsun %0" \
75 : "=dm" (__result) : "f" (x), "f" (y)); \
76 __result != 0; })
77 # endif /* GCC 3.1 */
78 #endif
81 #if (!defined __NO_MATH_INLINES && defined __OPTIMIZE__) \
82 || defined __LIBC_INTERNAL_MATH_INLINES
84 #ifdef __LIBC_INTERNAL_MATH_INLINES
85 /* This is used when defining the functions themselves. Define them with
86 __ names, and with `static inline' instead of `extern inline' so the
87 bodies will always be used, never an external function call. */
88 # define __m81_u(x) __CONCAT(__,x)
89 # define __m81_inline static __inline
90 #else
91 # define __m81_u(x) x
92 # ifdef __cplusplus
93 # define __m81_inline __inline
94 # else
95 # define __m81_inline extern __inline
96 # endif
97 # define __M81_MATH_INLINES 1
98 #endif
100 /* Define a const math function. */
101 #define __m81_defun(rettype, func, args) \
102 __m81_inline rettype __attribute__((__const__)) \
103 __m81_u(func) args
105 /* Define the three variants of a math function that has a direct
106 implementation in the m68k fpu. FUNC is the name for C (which will be
107 suffixed with f and l for the float and long double version, resp). OP
108 is the name of the fpu operation (without leading f). */
110 #if defined __USE_MISC || defined __USE_ISOC99
111 #ifndef NO_LONG_DOUBLE
112 # define __inline_mathop(func, op) \
113 __inline_mathop1(double, func, op) \
114 __inline_mathop1(float, __CONCAT(func,f), op) \
115 __inline_mathop1(long double, __CONCAT(func,l), op)
116 #else
117 # define __inline_mathop(func, op) \
118 __inline_mathop1(double, func, op) \
119 __inline_mathop1(float, __CONCAT(func,f), op)
120 #endif
121 #else
122 # define __inline_mathop(func, op) \
123 __inline_mathop1(double, func, op)
124 #endif
126 #define __inline_mathop1(float_type,func, op) \
127 __m81_defun (float_type, func, (float_type __mathop_x)) \
129 float_type __result; \
130 __asm("f" __STRING(op) "%.x %1, %0" : "=f" (__result) : "f" (__mathop_x));\
131 return __result; \
134 __inline_mathop(__atan, atan)
135 __inline_mathop(__cos, cos)
136 __inline_mathop(__sin, sin)
137 __inline_mathop(__tan, tan)
138 __inline_mathop(__tanh, tanh)
139 __inline_mathop(__fabs, abs)
141 #if defined __USE_MISC || defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99
142 __inline_mathop(__rint, int)
143 __inline_mathop(__expm1, etoxm1)
144 __inline_mathop(__log1p, lognp1)
145 #endif
147 #ifdef __USE_MISC
148 __inline_mathop(__significand, getman)
149 #endif
151 #ifdef __USE_ISOC99
152 __inline_mathop(__trunc, intrz)
153 #endif
155 #if !defined __NO_MATH_INLINES && defined __OPTIMIZE__
157 __inline_mathop(atan, atan)
158 __inline_mathop(cos, cos)
159 __inline_mathop(sin, sin)
160 __inline_mathop(tan, tan)
161 __inline_mathop(tanh, tanh)
163 # if defined __USE_MISC || defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99
164 __inline_mathop(rint, int)
165 __inline_mathop(expm1, etoxm1)
166 __inline_mathop(log1p, lognp1)
167 # endif
169 # ifdef __USE_MISC
170 __inline_mathop(significand, getman)
171 # endif
173 # ifdef __USE_ISOC99
174 __inline_mathop(trunc, intrz)
175 # endif
177 #endif /* !__NO_MATH_INLINES && __OPTIMIZE__ */
179 /* This macro contains the definition for the rest of the inline
180 functions, using FLOAT_TYPE as the domain type and S as the suffix
181 for the function names. */
183 #define __inline_functions(float_type, s) \
184 __m81_defun (float_type, __CONCAT(__floor,s), (float_type __x)) \
186 float_type __result; \
187 unsigned long int __ctrl_reg; \
188 __asm __volatile__ ("fmove%.l %!, %0" : "=dm" (__ctrl_reg)); \
189 /* Set rounding towards negative infinity. */ \
190 __asm __volatile__ ("fmove%.l %0, %!" : /* No outputs. */ \
191 : "dmi" ((__ctrl_reg & ~0x10) | 0x20)); \
192 /* Convert X to an integer, using -Inf rounding. */ \
193 __asm __volatile__ ("fint%.x %1, %0" : "=f" (__result) : "f" (__x)); \
194 /* Restore the previous rounding mode. */ \
195 __asm __volatile__ ("fmove%.l %0, %!" : /* No outputs. */ \
196 : "dmi" (__ctrl_reg)); \
197 return __result; \
200 __m81_defun (float_type, __CONCAT(__ceil,s), (float_type __x)) \
202 float_type __result; \
203 unsigned long int __ctrl_reg; \
204 __asm __volatile__ ("fmove%.l %!, %0" : "=dm" (__ctrl_reg)); \
205 /* Set rounding towards positive infinity. */ \
206 __asm __volatile__ ("fmove%.l %0, %!" : /* No outputs. */ \
207 : "dmi" (__ctrl_reg | 0x30)); \
208 /* Convert X to an integer, using +Inf rounding. */ \
209 __asm __volatile__ ("fint%.x %1, %0" : "=f" (__result) : "f" (__x)); \
210 /* Restore the previous rounding mode. */ \
211 __asm __volatile__ ("fmove%.l %0, %!" : /* No outputs. */ \
212 : "dmi" (__ctrl_reg)); \
213 return __result; \
216 __inline_functions(double,)
217 #if defined __USE_MISC || defined __USE_ISOC99
218 __inline_functions(float,f)
219 #ifndef NO_LONG_DOUBLE
220 __inline_functions(long double,l)
221 #endif
222 #endif
223 #undef __inline_functions
225 #ifdef __USE_MISC
227 # define __inline_functions(float_type, s) \
228 __m81_defun (int, __CONCAT(__isinf,s), (float_type __value)) \
230 /* There is no branch-condition for infinity, \
231 so we must extract and examine the condition codes manually. */ \
232 unsigned long int __fpsr; \
233 __asm("ftst%.x %1\n" \
234 "fmove%.l %/fpsr, %0" : "=dm" (__fpsr) : "f" (__value)); \
235 return (__fpsr & (2 << 24)) ? (__fpsr & (8 << 24) ? -1 : 1) : 0; \
238 __m81_defun (int, __CONCAT(__finite,s), (float_type __value)) \
240 /* There is no branch-condition for infinity, so we must extract and \
241 examine the condition codes manually. */ \
242 unsigned long int __fpsr; \
243 __asm ("ftst%.x %1\n" \
244 "fmove%.l %/fpsr, %0" : "=dm" (__fpsr) : "f" (__value)); \
245 return (__fpsr & (3 << 24)) == 0; \
248 __m81_defun (float_type, __CONCAT(__scalbn,s), \
249 (float_type __x, int __n)) \
251 float_type __result; \
252 __asm ("fscale%.l %1, %0" : "=f" (__result) : "dmi" (__n), "0" (__x)); \
253 return __result; \
256 __inline_functions(double,)
257 __inline_functions(float,f)
258 #ifndef NO_LONG_DOUBLE
259 __inline_functions(long double,l)
260 #endif
261 # undef __inline_functions
263 #endif /* Use misc. */
265 #if defined __USE_MISC || defined __USE_XOPEN
267 # define __inline_functions(float_type, s) \
268 __m81_defun (int, __CONCAT(__isnan,s), (float_type __value)) \
270 char __result; \
271 __asm("ftst%.x %1\n" \
272 "fsun %0" : "=dm" (__result) : "f" (__value)); \
273 return __result; \
276 __inline_functions(double,)
277 # ifdef __USE_MISC
278 __inline_functions(float,f)
279 #ifndef NO_LONG_DOUBLE
280 __inline_functions(long double,l)
281 #endif
282 # endif
283 # undef __inline_functions
285 #endif
287 #ifdef __USE_ISOC99
289 # define __inline_functions(float_type, s) \
290 __m81_defun (int, __CONCAT(__signbit,s), (float_type __value)) \
292 /* There is no branch-condition for the sign bit, so we must extract \
293 and examine the condition codes manually. */ \
294 unsigned long int __fpsr; \
295 __asm ("ftst%.x %1\n" \
296 "fmove%.l %/fpsr, %0" : "=dm" (__fpsr) : "f" (__value)); \
297 return (__fpsr >> 27) & 1; \
300 __m81_defun (float_type, __CONCAT(__scalbln,s), \
301 (float_type __x, long int __n)) \
303 return __CONCAT(__scalbn,s) (__x, __n); \
306 __m81_defun (float_type, __CONCAT(__nearbyint,s), (float_type __x)) \
308 float_type __result; \
309 unsigned long int __ctrl_reg; \
310 __asm __volatile__ ("fmove%.l %!, %0" : "=dm" (__ctrl_reg)); \
311 /* Temporarily disable the inexact exception. */ \
312 __asm __volatile__ ("fmove%.l %0, %!" : /* No outputs. */ \
313 : "dmi" (__ctrl_reg & ~0x200)); \
314 __asm __volatile__ ("fint%.x %1, %0" : "=f" (__result) : "f" (__x)); \
315 __asm __volatile__ ("fmove%.l %0, %!" : /* No outputs. */ \
316 : "dmi" (__ctrl_reg)); \
317 return __result; \
320 __m81_defun (long int, __CONCAT(__lrint,s), (float_type __x)) \
322 long int __result; \
323 __asm ("fmove%.l %1, %0" : "=dm" (__result) : "f" (__x)); \
324 return __result; \
327 __m81_inline float_type \
328 __m81_u(__CONCAT(__fma,s))(float_type __x, float_type __y, \
329 float_type __z) \
331 return (__x * __y) + __z; \
334 __inline_functions (double,)
335 __inline_functions (float,f)
336 #ifndef NO_LONG_DOUBLE
337 __inline_functions (long double,l)
338 #endif
339 # undef __inline_functions
341 #endif /* Use ISO C9x */
343 #ifdef __USE_GNU
345 # define __inline_functions(float_type, s) \
346 __m81_inline void \
347 __m81_u(__CONCAT(__sincos,s))(float_type __x, float_type *__sinx, \
348 float_type *__cosx) \
350 __asm ("fsincos%.x %2,%1:%0" \
351 : "=f" (*__sinx), "=f" (*__cosx) : "f" (__x)); \
354 __inline_functions (double,)
355 __inline_functions (float,f)
356 #ifndef NO_LONG_DOUBLE
357 __inline_functions (long double,l)
358 #endif
359 # undef __inline_functions
361 #endif
363 #if !defined __NO_MATH_INLINES && defined __OPTIMIZE__
365 /* Define inline versions of the user visible functions. */
367 /* Note that there must be no whitespace before the argument passed for
368 NAME, to make token pasting work correctly with -traditional. */
369 # define __inline_forward_c(rettype, name, args1, args2) \
370 extern __inline rettype __attribute__((__const__)) \
371 name args1 \
373 return __CONCAT(__,name) args2; \
376 # define __inline_forward(rettype, name, args1, args2) \
377 extern __inline rettype name args1 \
379 return __CONCAT(__,name) args2; \
382 __inline_forward_c(double,floor, (double __x), (__x))
383 __inline_forward_c(double,ceil, (double __x), (__x))
384 # ifdef __USE_MISC
385 # ifndef __USE_ISOC99 /* Conflict with macro of same name. */
386 __inline_forward_c(int,isinf, (double __value), (__value))
387 # endif
388 __inline_forward_c(int,finite, (double __value), (__value))
389 __inline_forward_c(double,scalbn, (double __x, int __n), (__x, __n))
390 # endif
391 # if defined __USE_MISC || defined __USE_XOPEN
392 # ifndef __USE_ISOC99 /* Conflict with macro of same name. */
393 __inline_forward_c(int,isnan, (double __value), (__value))
394 # endif
395 # endif
396 # ifdef __USE_ISOC99
397 __inline_forward_c(double,scalbln, (double __x, long int __n), (__x, __n))
398 __inline_forward_c(double,nearbyint, (double __value), (__value))
399 __inline_forward_c(long int,lrint, (double __value), (__value))
400 __inline_forward_c(double,fma, (double __x, double __y, double __z),
401 (__x, __y, __z))
402 # endif
403 # ifdef __USE_GNU
404 __inline_forward(void,sincos, (double __x, double *__sinx, double *__cosx),
405 (__x, __sinx, __cosx))
406 # endif
408 # if defined __USE_MISC || defined __USE_ISOC99
410 __inline_forward_c(float,floorf, (float __x), (__x))
411 __inline_forward_c(float,ceilf, (float __x), (__x))
412 # ifdef __USE_MISC
413 __inline_forward_c(int,isinff, (float __value), (__value))
414 __inline_forward_c(int,finitef, (float __value), (__value))
415 __inline_forward_c(float,scalbnf, (float __x, int __n), (__x, __n))
416 __inline_forward_c(int,isnanf, (float __value), (__value))
417 # endif
418 # ifdef __USE_ISOC99
419 __inline_forward_c(float,scalblnf, (float __x, long int __n), (__x, __n))
420 __inline_forward_c(float,nearbyintf, (float __value), (__value))
421 __inline_forward_c(long int,lrintf, (float __value), (__value))
422 __inline_forward_c(float,fmaf, (float __x, float __y, float __z),
423 (__x, __y, __z))
424 # endif
425 # ifdef __USE_GNU
426 __inline_forward(void,sincosf, (float __x, float *__sinx, float *__cosx),
427 (__x, __sinx, __cosx))
428 # endif
430 # ifndef NO_LONG_DOUBLE
431 __inline_forward_c(long double,floorl, (long double __x), (__x))
432 __inline_forward_c(long double,ceill, (long double __x), (__x))
433 # ifdef __USE_MISC
434 __inline_forward_c(int,isinfl, (long double __value), (__value))
435 __inline_forward_c(int,finitel, (long double __value), (__value))
436 __inline_forward_c(long double,scalbnl, (long double __x, int __n), (__x, __n))
437 __inline_forward_c(int,isnanl, (long double __value), (__value))
438 # endif
439 # ifdef __USE_ISOC99
440 __inline_forward_c(long double,scalblnl, (long double __x, long int __n),
441 (__x, __n))
442 __inline_forward_c(long double,nearbyintl, (long double __value), (__value))
443 __inline_forward_c(long int,lrintl, (long double __value), (__value))
444 __inline_forward_c(long double,fmal,
445 (long double __x, long double __y, long double __z),
446 (__x, __y, __z))
447 # endif
448 # ifdef __USE_GNU
449 __inline_forward(void,sincosl,
450 (long double __x, long double *__sinx, long double *__cosx),
451 (__x, __sinx, __cosx))
452 # endif
453 # endif
455 #endif /* Use misc or ISO C99 */
457 #undef __inline_forward
458 #undef __inline_forward_c
460 #endif /* !__NO_MATH_INLINES && __OPTIMIZE__ */
462 #endif
463 #endif /* GCC. */