Annotation of /usr/include/bits/mathinline.h for ./mpqc.vmon.0018
1 /* Inline math functions for i387.
2 Copyright (C) 1995,96,97,98,99,2000,2001 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by John C. Bowman <bowman@math.ualberta.ca>, 1995.
5
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 License, or (at your option) any later version.
10
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 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public
17 License along with the GNU C Library; see the file COPYING.LIB. If not,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21 #ifndef _MATH_H
22 # error "Never use <bits/mathinline.h> directly; include <math.h> instead."
23 #endif
24
25 #ifdef __cplusplus
26 # define __MATH_INLINE __inline
27 #else
28 # define __MATH_INLINE extern __inline
29 #endif
30
31
32 #if defined __USE_ISOC99 && defined __GNUC__ && __GNUC__ >= 2
33 # if __GNUC_PREREQ (2,97)
34 /* GCC 2.97 and up have builtins that actually can be used. */
35 # define isgreater(x, y) __builtin_isgreater (x, y)
36 # define isgreaterequal(x, y) __builtin_isgreaterequal (x, y)
37 # define isless(x, y) __builtin_isless (x, y)
38 # define islessequal(x, y) __builtin_islessequal (x, y)
39 # define islessgreater(x, y) __builtin_islessgreater (x, y)
40 # define isunordered(x, y) __builtin_isunordered (x, y)
41 # else
42 /* ISO C99 defines some macros to perform unordered comparisons. The
43 ix87 FPU supports this with special opcodes and we should use them.
44 These must not be inline functions since we have to be able to handle
45 all floating-point types. */
46 # ifdef __i686__
47 /* For the PentiumPro and more recent processors we can provide
48 better code. */
49 # define isgreater(x, y) \
50 ({ register char __result; \
51 __asm__ ("fucomip %%st(1), %%st; seta %%al" \
52 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \
53 __result; })
54 # define isgreaterequal(x, y) \
55 ({ register char __result; \
56 __asm__ ("fucomip %%st(1), %%st; setae %%al" \
57 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \
58 __result; })
59
60 # define isless(x, y) \
61 ({ register char __result; \
62 __asm__ ("fucomip %%st(1), %%st; seta %%al" \
63 : "=a" (__result) : "u" (x), "t" (y) : "cc", "st"); \
64 __result; })
65
66 # define islessequal(x, y) \
67 ({ register char __result; \
68 __asm__ ("fucomip %%st(1), %%st; setae %%al" \
69 : "=a" (__result) : "u" (x), "t" (y) : "cc", "st"); \
70 __result; })
71
72 # define islessgreater(x, y) \
73 ({ register char __result; \
74 __asm__ ("fucomip %%st(1), %%st; setne %%al" \
75 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \
76 __result; })
77
78 # define isunordered(x, y) \
79 ({ register char __result; \
80 __asm__ ("fucomip %%st(1), %%st; setp %%al" \
81 1 0 1 0 1 0 0 0 0 0 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \
82 __result; })
83 # else
84 /* This is the dumb, portable code for i386 and above. */
85 # define isgreater(x, y) \
86 ({ register char __result; \
87 __asm__ ("fucompp; fnstsw; testb $0x45, %%ah; setz %%al" \
88 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
89 __result; })
90
91 # define isgreaterequal(x, y) \
92 ({ register char __result; \
93 __asm__ ("fucompp; fnstsw; testb $0x05, %%ah; setz %%al" \
94 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
95 __result; })
96
97 # define isless(x, y) \
98 ({ register char __result; \
99 __asm__ ("fucompp; fnstsw; testb $0x45, %%ah; setz %%al" \
100 : "=a" (__result) : "u" (x), "t" (y) : "cc", "st", "st(1)"); \
101 __result; })
102
103 # define islessequal(x, y) \
104 ({ register char __result; \
105 __asm__ ("fucompp; fnstsw; testb $0x05, %%ah; setz %%al" \
106 : "=a" (__result) : "u" (x), "t" (y) : "cc", "st", "st(1)"); \
107 __result; })
108
109 # define islessgreater(x, y) \
110 ({ register char __result; \
111 __asm__ ("fucompp; fnstsw; testb $0x44, %%ah; setz %%al" \
112 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
113 __result; })
114
115 # define isunordered(x, y) \
116 ({ register char __result; \
117 __asm__ ("fucompp; fnstsw; sahf; setp %%al" \
118 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
119 __result; })
120 # endif /* __i686__ */
121 # endif /* GCC 2.97 */
122
123 /* The gcc, version 2.7 or below, has problems with all this inlining
124 code. So disable it for this version of the compiler. */
125 # if __GNUC_PREREQ (2, 8)
126 /* Test for negative number. Used in the signbit() macro. */
127 __MATH_INLINE int
128 __signbitf (float __x) __THROW
129 {
130 __extension__ union { float __f; int __i; } __u = { __f: __x };
131 return __u.__i < 0;
132 }
133 __MATH_INLINE int
134 __signbit (double __x) __THROW
135 {
136 __extension__ union { double __d; int __i[2]; } __u = { __d: __x };
137 return __u.__i[1] < 0;
138 }
139 __MATH_INLINE int
140 __signbitl (long double __x) __THROW
141 {
142 __extension__ union { long double __l; int __i[3]; } __u = { __l: __x };
143 return (__u.__i[2] & 0x8000) != 0;
144 }
145 # endif
146 #endif
147
148
149 /* The gcc, version 2.7 or below, has problems with all this inlining
150 code. So disable it for this version of the compiler. */
151 #if __GNUC_PREREQ (2, 8)
152
153 #if ((!defined __NO_MATH_INLINES || defined __LIBC_INTERNAL_MATH_INLINES) \
154 && defined __OPTIMIZE__)
155
156 /* A macro to define float, double, and long double versions of various
157 math functions for the ix87 FPU. FUNC is the function name (which will
158 be suffixed with f and l for the float and long double version,
159 respectively). OP is the name of the FPU operation.
160 We define two sets of macros. The set with the additional NP
161 doesn't add a prototype declaration. */
162
163 #if defined __USE_MISC || defined __USE_ISOC99
164 # define __inline_mathop(func, op) \
165 __inline_mathop_ (double, func, op) \
166 __inline_mathop_ (float, __CONCAT(func,f), op) \
167 __inline_mathop_ (long double, __CONCAT(func,l), op)
168 # define __inline_mathopNP(func, op) \
169 __inline_mathopNP_ (double, func, op) \
170 __inline_mathopNP_ (float, __CONCAT(func,f), op) \
171 __inline_mathopNP_ (long double, __CONCAT(func,l), op)
172 #else
173 # define __inline_mathop(func, op) \
174 __inline_mathop_ (double, func, op)
175 # define __inline_mathopNP(func, op) \
176 __inline_mathopNP_ (double, func, op)
177 #endif
178
179 #define __inline_mathop_(float_type, func, op) \
180 __inline_mathop_decl_ (float_type, func, op, "0" (__x))
181 #define __inline_mathopNP_(float_type, func, op) \
182 __inline_mathop_declNP_ (float_type, func, op, "0" (__x))
183
184
185 #if defined __USE_MISC || defined __USE_ISOC99
186 # define __inline_mathop_decl(func, op, params...) \
187 __inline_mathop_decl_ (double, func, op, params) \
188 __inline_mathop_decl_ (float, __CONCAT(func,f), op, params) \
189 __inline_mathop_decl_ (long double, __CONCAT(func,l), op, params)
190 # define __inline_mathop_declNP(func, op, params...) \
191 __inline_mathop_declNP_ (double, func, op, params) \
192 __inline_mathop_declNP_ (float, __CONCAT(func,f), op, params) \
193 __inline_mathop_declNP_ (long double, __CONCAT(func,l), op, params)
194 #else
195 # define __inline_mathop_decl(func, op, params...) \
196 __inline_mathop_decl_ (double, func, op, params)
197 # define __inline_mathop_declNP(func, op, params...) \
198 __inline_mathop_declNP_ (double, func, op, params)
199 #endif
200
201 #define __inline_mathop_decl_(float_type, func, op, params...) \
202 __MATH_INLINE float_type func (float_type) __THROW; \
203 __inline_mathop_declNP_ (float_type, func, op, params)
204
205 #define __inline_mathop_declNP_(float_type, func, op, params...) \
206 __MATH_INLINE float_type func (float_type __x) __THROW \
207 { \
208 register float_type __result; \
209 __asm __volatile__ (op : "=t" (__result) : params); \
210 return __result; \
211 }
212
213
214 #if defined __USE_MISC || defined __USE_ISOC99
215 # define __inline_mathcode(func, arg, code) \
216 __inline_mathcode_ (double, func, arg, code) \
217 __inline_mathcode_ (float, __CONCAT(func,f), arg, code) \
218 __inline_mathcode_ (long double, __CONCAT(func,l), arg, code)
219 # define __inline_mathcodeNP(func, arg, code) \
220 __inline_mathcodeNP_ (double, func, arg, code) \
221 __inline_mathcodeNP_ (float, __CONCAT(func,f), arg, code) \
222 __inline_mathcodeNP_ (long double, __CONCAT(func,l), arg, code)
223 # define __inline_mathcode2(func, arg1, arg2, code) \
224 __inline_mathcode2_ (double, func, arg1, arg2, code) \
225 __inline_mathcode2_ (float, __CONCAT(func,f), arg1, arg2, code) \
226 __inline_mathcode2_ (long double, __CONCAT(func,l), arg1, arg2, code)
227 # define __inline_mathcodeNP2(func, arg1, arg2, code) \
228 __inline_mathcodeNP2_ (double, func, arg1, arg2, code) \
229 __inline_mathcodeNP2_ (float, __CONCAT(func,f), arg1, arg2, code) \
230 __inline_mathcodeNP2_ (long double, __CONCAT(func,l), arg1, arg2, code)
231 # define __inline_mathcode3(func, arg1, arg2, arg3, code) \
232 __inline_mathcode3_ (double, func, arg1, arg2, arg3, code) \
233 __inline_mathcode3_ (float, __CONCAT(func,f), arg1, arg2, arg3, code) \
234 __inline_mathcode3_ (long double, __CONCAT(func,l), arg1, arg2, arg3, code)
235 # define __inline_mathcodeNP3(func, arg1, arg2, arg3, code) \
236 __inline_mathcodeNP3_ (double, func, arg1, arg2, arg3, code) \
237 __inline_mathcodeNP3_ (float, __CONCAT(func,f), arg1, arg2, arg3, code) \
238 __inline_mathcodeNP3_ (long double, __CONCAT(func,l), arg1, arg2, arg3, code)
239 #else
240 # define __inline_mathcode(func, arg, code) \
241 __inline_mathcode_ (double, func, (arg), code)
242 # define __inline_mathcodeNP(func, arg, code) \
243 __inline_mathcodeNP_ (double, func, (arg), code)
244 # define __inline_mathcode2(func, arg1, arg2, code) \
245 __inline_mathcode2_ (double, func, arg1, arg2, code)
246 # define __inline_mathcodeNP2(func, arg1, arg2, code) \
247 __inline_mathcodeNP2_ (double, func, arg1, arg2, code)
248 # define __inline_mathcode3(func, arg1, arg2, arg3, code) \
249 __inline_mathcode3_ (double, func, arg1, arg2, arg3, code)
250 # define __inline_mathcodeNP3(func, arg1, arg2, arg3, code) \
251 __inline_mathcodeNP3_ (double, func, arg1, arg2, arg3, code)
252 #endif
253
254 #define __inline_mathcode_(float_type, func, arg, code) \
255 __MATH_INLINE float_type func (float_type) __THROW; \
256 __inline_mathcodeNP_(float_type, func, arg, code)
257
258 #define __inline_mathcodeNP_(float_type, func, arg, code) \
259 __MATH_INLINE float_type func (float_type arg) __THROW \
260 { \
261 code; \
262 }
263
264
265 #define __inline_mathcode2_(float_type, func, arg1, arg2, code) \
266 __MATH_INLINE float_type func (float_type, float_type) __THROW; \
267 __inline_mathcodeNP2_ (float_type, func, arg1, arg2, code)
268
269 #define __inline_mathcodeNP2_(float_type, func, arg1, arg2, code) \
270 __MATH_INLINE float_type func (float_type arg1, float_type arg2) __THROW \
271 { \
272 code; \
273 }
274
275 #define __inline_mathcode3_(float_type, func, arg1, arg2, arg3, code) \
276 __MATH_INLINE float_type func (float_type, float_type, float_type) __THROW; \
277 __inline_mathcodeNP3_(float_type, func, arg1, arg2, arg3, code)
278
279 #define __inline_mathcodeNP3_(float_type, func, arg1, arg2, arg3, code) \
280 __MATH_INLINE float_type func (float_type arg1, float_type arg2, \
281 float_type arg3) __THROW \
282 { \
283 code; \
284 }
285 #endif
286
287
288 #if !defined __NO_MATH_INLINES && defined __OPTIMIZE__
289 /* Miscellaneous functions */
290
291 __inline_mathcode (__sgn, __x, \
292 return __x == 0.0 ? 0.0 : (__x > 0.0 ? 1.0 : -1.0))
293
294 /* __FAST_MATH__ is defined by gcc -ffast-math. */
295 #ifdef __FAST_MATH__
296 __inline_mathcode (__pow2, __x, \
297 register long double __value; \
298 register long double __exponent; \
299 __extension__ long long int __p = (long long int) __x; \
300 if (__x == (long double) __p) \
301 { \
302 __asm __volatile__ \
303 ("fscale" \
304 : "=t" (__value) : "0" (1.0), "u" (__x)); \
305 return __value; \
306 } \
307 __asm __volatile__ \
308 ("fld %%st(0)\n\t" \
309 "frndint # int(x)\n\t" \
310 "fxch\n\t" \
311 "fsub %%st(1) # fract(x)\n\t" \
312 "f2xm1 # 2^(fract(x)) - 1\n\t" \
313 : "=t" (__value), "=u" (__exponent) : "0" (__x)); \
314 __value += 1.0; \
315 __asm __volatile__ \
316 ("fscale" \
317 : "=t" (__value) : "0" (__value), "u" (__exponent)); \
318 return __value)
319
320 # ifdef __USE_GNU
321 # define __sincos_code \
322 register long double __cosr; \
323 register long double __sinr; \
324 __asm __volatile__ \
325 ("fsincos\n\t" \
326 "fnstsw %%ax\n\t" \
327 "testl $0x400, %%eax\n\t" \
328 "jz 1f\n\t" \
329 "fldpi\n\t" \
330 "fadd %%st(0)\n\t" \
331 "fxch %%st(1)\n\t" \
332 "2: fprem1\n\t" \
333 "fnstsw %%ax\n\t" \
334 "testl $0x400, %%eax\n\t" \
335 "jnz 2b\n\t" \
336 "fstp %%st(1)\n\t" \
337 "fsincos\n\t" \
338 "1:" \
339 : "=t" (__cosr), "=u" (__sinr) : "0" (__x)); \
340 *__sinx = __sinr; \
341 *__cosx = __cosr
342
343 __MATH_INLINE void
344 __sincos (double __x, double *__sinx, double *__cosx) __THROW
345 {
346 __sincos_code;
347 }
348
349 __MATH_INLINE void
350 __sincosf (float __x, float *__sinx, float *__cosx) __THROW
351 {
352 __sincos_code;
353 }
354
355 __MATH_INLINE void
356 __sincosl (long double __x, long double *__sinx, long double *__cosx) __THROW
357 {
358 __sincos_code;
359 }
360 # endif
361
362
363 /* Optimized inline implementation, sometimes with reduced precision
364 and/or argument range. */
365
366 # define __expm1_code \
367 register long double __value; \
368 register long double __exponent; \
369 register long double __temp; \
370 __asm __volatile__ \
371 ("fldl2e # e^x - 1 = 2^(x * log2(e)) - 1\n\t" \
372 "fmul %%st(1) # x * log2(e)\n\t" \
373 "fst %%st(1)\n\t" \
374 "frndint # int(x * log2(e))\n\t" \
375 "fxch\n\t" \
376 "fsub %%st(1) # fract(x * log2(e))\n\t" \
377 "f2xm1 # 2^(fract(x * log2(e))) - 1\n\t" \
378 "fscale # 2^(x * log2(e)) - 2^(int(x * log2(e)))\n\t" \
379 : "=t" (__value), "=u" (__exponent) : "0" (__x)); \
380 __asm __volatile__ \
381 ("fscale # 2^int(x * log2(e))\n\t" \
382 : "=t" (__temp) : "0" (1.0), "u" (__exponent)); \
383 __temp -= 1.0; \
384 __temp += __value; \
385 return __temp ? __temp : __x
386 __inline_mathcodeNP_ (long double, __expm1l, __x, __expm1_code)
387
388
389 # define __exp_code \
390 register long double __value; \
391 register long double __exponent; \
392 __asm __volatile__ \
393 ("fldl2e # e^x = 2^(x * log2(e))\n\t" \
394 "fmul %%st(1) # x * log2(e)\n\t" \
395 "fst %%st(1)\n\t" \
396 "frndint # int(x * log2(e))\n\t" \
397 "fxch\n\t" \
398 "fsub %%st(1) # fract(x * log2(e))\n\t" \
399 "f2xm1 # 2^(fract(x * log2(e))) - 1\n\t" \
400 : "=t" (__value), "=u" (__exponent) : "0" (__x)); \
401 __value += 1.0; \
402 __asm __volatile__ \
403 ("fscale" \
404 : "=t" (__value) : "0" (__value), "u" (__exponent)); \
405 return __value
406 __inline_mathcodeNP (exp, __x, __exp_code)
407 __inline_mathcodeNP_ (long double, __expl, __x, __exp_code)
408
409
410 __inline_mathcodeNP (tan, __x, \
411 register long double __value; \
412 register long double __value2 __attribute__ ((__unused__)); \
413 __asm __volatile__ \
414 ("fptan" \
415 : "=t" (__value2), "=u" (__value) : "0" (__x)); \
416 return __value)
417 #endif /* __FAST_MATH__ */
418
419
420 #define __atan2_code \
421 register long double __value; \
422 __asm __volatile__ \
423 ("fpatan" \
424 : "=t" (__value) : "0" (__x), "u" (__y) : "st(1)"); \
425 return __value
426 __inline_mathcodeNP2 (atan2, __y, __x, __atan2_code)
427 __inline_mathcodeNP2_ (long double, __atan2l, __y, __x, __atan2_code)
428
429
430 __inline_mathcodeNP2 (fmod, __x, __y, \
431 register long double __value; \
432 __asm __volatile__ \
433 ("1: fprem\n\t" \
434 "fnstsw %%ax\n\t" \
435 "sahf\n\t" \
436 "jp 1b" \
437 : "=t" (__value) : "0" (__x), "u" (__y) : "ax", "cc"); \
438 return __value)
439
440
441 1853 108 1176 932 665 115 6 3 0 0 __inline_mathopNP (sqrt, "fsqrt")
442 __inline_mathopNP_ (long double, __sqrtl, "fsqrt")
443
444 #if __GNUC_PREREQ (2, 8)
445 44 3 45 10 12 9 1 0 0 0 __inline_mathcodeNP_ (double, fabs, __x, return __builtin_fabs (__x))
446 __inline_mathcodeNP_ (float, fabsf, __x, return __builtin_fabsf (__x))
447 __inline_mathcodeNP_ (long double, fabsl, __x, return __builtin_fabsl (__x))
448 __inline_mathcodeNP_ (long double, __fabsl, __x, return __builtin_fabsl (__x))
449 #else
450 __inline_mathop (fabs, "fabs")
451 __inline_mathop_ (long double, __fabsl, "fabs")
452 #endif
453
454 #ifdef __FAST_MATH__
455 /* The argument range of this inline version is reduced. */
456 __inline_mathopNP (sin, "fsin")
457 /* The argument range of this inline version is reduced. */
458 __inline_mathopNP (cos, "fcos")
459
460 __inline_mathop_declNP (log, "fldln2; fxch; fyl2x", "0" (__x) : "st(1)")
461 __inline_mathop_declNP (log10, "fldlg2; fxch; fyl2x", "0" (__x) : "st(1)")
462
463 __inline_mathcodeNP (asin, __x, return __atan2l (__x, __sqrtl (1.0 - __x * __x)))
464 __inline_mathcodeNP (acos, __x, return __atan2l (__sqrtl (1.0 - __x * __x), __x))
465 #endif /* __FAST_MATH__ */
466
467 __inline_mathop_declNP (atan, "fld1; fpatan", "0" (__x) : "st(1)")
468
469 __inline_mathcode_ (long double, __sgn1l, __x, \
470 __extension__ union { long double __xld; unsigned int __xi[3]; } __n = \
471 { __xld: __x }; \
472 __n.__xi[2] = (__n.__xi[2] & 0x8000) | 0x3fff; \
473 __n.__xi[1] = 0x80000000; \
474 __n.__xi[0] = 0; \
475 return __n.__xld)
476
477
478 #ifdef __FAST_MATH__
479 /* The argument range of the inline version of sinhl is slightly reduced. */
480 __inline_mathcodeNP (sinh, __x, \
481 register long double __exm1 = __expm1l (__fabsl (__x)); \
482 return 0.5 * (__exm1 / (__exm1 + 1.0) + __exm1) * __sgn1l (__x))
483
484 __inline_mathcodeNP (cosh, __x, \
485 register long double __ex = __expl (__x); \
486 return 0.5 * (__ex + 1.0 / __ex))
487
488 __inline_mathcodeNP (tanh, __x, \
489 register long double __exm1 = __expm1l (-__fabsl (__x + __x)); \
490 return __exm1 / (__exm1 + 2.0) * __sgn1l (-__x))
491 #endif
492
493 __inline_mathcodeNP (floor, __x, \
494 register long double __value; \
495 __volatile unsigned short int __cw; \
496 __volatile unsigned short int __cwtmp; \
497 __asm __volatile ("fnstcw %0" : "=m" (__cw)); \
498 __cwtmp = (__cw & 0xf3ff) | 0x0400; /* rounding down */ \
499 __asm __volatile ("fldcw %0" : : "m" (__cwtmp)); \
500 __asm __volatile ("frndint" : "=t" (__value) : "0" (__x)); \
501 __asm __volatile ("fldcw %0" : : "m" (__cw)); \
502 return __value)
503
504 28 2 17 3 9 1 0 0 0 0 __inline_mathcodeNP (ceil, __x, \
505 register long double __value; \
506 __volatile unsigned short int __cw; \
507 __volatile unsigned short int __cwtmp; \
508 __asm __volatile ("fnstcw %0" : "=m" (__cw)); \
509 __cwtmp = (__cw & 0xf3ff) | 0x0800; /* rounding up */ \
510 __asm __volatile ("fldcw %0" : : "m" (__cwtmp)); \
511 __asm __volatile ("frndint" : "=t" (__value) : "0" (__x)); \
512 __asm __volatile ("fldcw %0" : : "m" (__cw)); \
513 return __value)
514
515 #define __ldexp_code \
516 register long double __value; \
517 __asm __volatile__ \
518 ("fscale" \
519 : "=t" (__value) : "0" (__x), "u" ((long double) __y)); \
520 return __value
521
522 __MATH_INLINE double
523 ldexp (double __x, int __y) __THROW
524 {
525 __ldexp_code;
526 }
527
528
529 /* Optimized versions for some non-standardized functions. */
530 #if defined __USE_ISOC99 || defined __USE_MISC
531
532 # ifdef __FAST_MATH__
533 __inline_mathcodeNP (expm1, __x, __expm1_code)
534 # endif
535
536 /* We cannot rely on M_SQRT being defined. So we do it for ourself
537 here. */
538 # define __M_SQRT2 1.41421356237309504880L /* sqrt(2) */
539
540 __inline_mathcodeNP (log1p, __x, \
541 register long double __value; \
542 if (__fabsl (__x) >= 1.0 - 0.5 * __M_SQRT2) \
543 __value = logl (1.0 + __x); \
544 else \
545 __asm __volatile__ \
546 ("fldln2\n\t" \
547 "fxch\n\t" \
548 "fyl2xp1" \
549 : "=t" (__value) : "0" (__x) : "st(1)"); \
550 return __value)
551
552
553 /* The argument range of the inline version of asinhl is slightly reduced. */
554 __inline_mathcodeNP (asinh, __x, \
555 register long double __y = __fabsl (__x); \
556 return (log1pl (__y * __y / (__sqrtl (__y * __y + 1.0) + 1.0) + __y) \
557 * __sgn1l (__x)))
558
559 __inline_mathcodeNP (acosh, __x, \
560 return logl (__x + __sqrtl (__x - 1.0) * __sqrtl (__x + 1.0)))
561
562 __inline_mathcodeNP (atanh, __x, \
563 register long double __y = __fabsl (__x); \
564 return -0.5 * log1pl (-(__y + __y) / (1.0 + __y)) * __sgn1l (__x))
565
566 /* The argument range of the inline version of hypotl is slightly reduced. */
567 __inline_mathcodeNP2 (hypot, __x, __y, return __sqrtl (__x * __x + __y * __y))
568
569 __inline_mathcodeNP(logb, __x, \
570 register long double __value; \
571 register long double __junk; \
572 __asm __volatile__ \
573 ("fxtract\n\t" \
574 : "=t" (__junk), "=u" (__value) : "0" (__x)); \
575 return __value)
576
577 #endif
578
579 #ifdef __USE_ISOC99
580 #ifdef __FAST_MATH__
581 __inline_mathop_declNP (log2, "fld1; fxch; fyl2x", "0" (__x) : "st(1)")
582 #endif /* __FAST_MATH__ */
583
584 __MATH_INLINE float
585 ldexpf (float __x, int __y) __THROW
586 {
587 __ldexp_code;
588 }
589
590 __MATH_INLINE long double
591 ldexpl (long double __x, int __y) __THROW
592 {
593 __ldexp_code;
594 }
595
596 #ifdef __FAST_MATH__
597 __inline_mathcodeNP3 (fma, __x, __y, __z, return (__x * __y) + __z)
598
599 __inline_mathopNP (rint, "frndint")
600 #endif /* __FAST_MATH__ */
601
602 #define __lrint_code \
603 long int __lrintres; \
604 __asm__ __volatile__ \
605 ("fistpl %0" \
606 : "=m" (__lrintres) : "t" (__x) : "st"); \
607 return __lrintres
608 __MATH_INLINE long int
609 lrintf (float __x) __THROW
610 {
611 __lrint_code;
612 }
613 __MATH_INLINE long int
614 lrint (double __x) __THROW
615 {
616 __lrint_code;
617 }
618 __MATH_INLINE long int
619 lrintl (long double __x) __THROW
620 {
621 __lrint_code;
622 }
623 #undef __lrint_code
624
625 #define __llrint_code \
626 long long int __llrintres; \
627 __asm__ __volatile__ \
628 ("fistpll %0" \
629 : "=m" (__llrintres) : "t" (__x) : "st"); \
630 return __llrintres
631 __MATH_INLINE long long int
632 llrintf (float __x) __THROW
633 {
634 __llrint_code;
635 }
636 __MATH_INLINE long long int
637 llrint (double __x) __THROW
638 {
639 __llrint_code;
640 }
641 __MATH_INLINE long long int
642 llrintl (long double __x) __THROW
643 {
644 __llrint_code;
645 }
646 #undef __llrint_code
647
648 #endif
649
650
651 #ifdef __USE_MISC
652
653 __inline_mathcodeNP2 (drem, __x, __y, \
654 register double __value; \
655 register int __clobbered; \
656 __asm __volatile__ \
657 ("1: fprem1\n\t" \
658 "fstsw %%ax\n\t" \
659 "sahf\n\t" \
660 "jp 1b" \
661 : "=t" (__value), "=&a" (__clobbered) : "0" (__x), "u" (__y) : "cc"); \
662 return __value)
663
664
665 /* This function is used in the `isfinite' macro. */
666 __MATH_INLINE int
667 __finite (double __x) __THROW
668 {
669 return (__extension__
670 (((((union { double __d; int __i[2]; }) {__d: __x}).__i[1]
671 | 0x800fffffu) + 1) >> 31));
672 }
673
674 /* Miscellaneous functions */
675 #ifdef __FAST_MATH__
676 __inline_mathcode (__coshm1, __x, \
677 register long double __exm1 = __expm1l (__fabsl (__x)); \
678 return 0.5 * (__exm1 / (__exm1 + 1.0)) * __exm1)
679
680 __inline_mathcode (__acosh1p, __x, \
681 return log1pl (__x + __sqrtl (__x) * __sqrtl (__x + 2.0)))
682
683 #endif /* __FAST_MATH__ */
684 #endif /* __USE_MISC */
685
686 /* Undefine some of the large macros which are not used anymore. */
687 #undef __atan2_code
688 #ifdef __FAST_MATH__
689 # undef __expm1_code
690 # undef __exp_code
691 # undef __sincos_code
692 #endif /* __FAST_MATH__ */
693
694 #endif /* __NO_MATH_INLINES */
695
696
697 /* This code is used internally in the GNU libc. */
698 #ifdef __LIBC_INTERNAL_MATH_INLINES
699 __inline_mathop (__ieee754_sqrt, "fsqrt")
700 __inline_mathcode2 (__ieee754_atan2, __y, __x,
701 register long double __value;
702 __asm __volatile__ ("fpatan\n\t"
703 : "=t" (__value)
704 : "0" (__x), "u" (__y) : "st(1)");
705 return __value;)
706 #endif
707
708 #endif /* __GNUC__ */
709