1    	/* Inline math functions for i387 and SSE.
2    	   Copyright (C) 1995-2015 Free Software Foundation, Inc.
3    	   This file is part of the GNU C Library.
4    	
5    	   The GNU C Library is free software; you can redistribute it and/or
6    	   modify it under the terms of the GNU Lesser General Public
7    	   License as published by the Free Software Foundation; either
8    	   version 2.1 of the License, or (at your option) any later version.
9    	
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   	   Lesser General Public License for more details.
14   	
15   	   You should have received a copy of the GNU Lesser General Public
16   	   License along with the GNU C Library; if not, see
17   	   <http://www.gnu.org/licenses/>.  */
18   	
19   	#ifndef _MATH_H
20   	# error "Never use <bits/mathinline.h> directly; include <math.h> instead."
21   	#endif
22   	
23   	#ifndef __extern_always_inline
24   	# define __MATH_INLINE __inline
25   	#else
26   	# define __MATH_INLINE __extern_always_inline
27   	#endif
28   	
29   	
30   	#if defined __USE_ISOC99 && defined __GNUC__ && __GNUC__ >= 2
31   	/* GCC 2.97 and up have builtins that actually can be used.  */
32   	# if !__GNUC_PREREQ (2,97)
33   	/* ISO C99 defines some macros to perform unordered comparisons.  The
34   	   ix87 FPU supports this with special opcodes and we should use them.
35   	   These must not be inline functions since we have to be able to handle
36   	   all floating-point types.  */
37   	#  undef isgreater
38   	#  undef isgreaterequal
39   	#  undef isless
40   	#  undef islessequal
41   	#  undef islessgreater
42   	#  undef isunordered
43   	#  ifdef __i686__
44   	/* For the PentiumPro and more recent processors we can provide
45   	   better code.  */
46   	#   define isgreater(x, y) \
47   	     ({ register char __result;						      \
48   		__asm__ ("fucomip %%st(1), %%st; seta %%al"			      \
49   			 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st");	      \
50   		__result; })
51   	#   define isgreaterequal(x, y) \
52   	     ({ register char __result;						      \
53   		__asm__ ("fucomip %%st(1), %%st; setae %%al"			      \
54   			 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st");	      \
55   		__result; })
56   	
57   	#   define isless(x, y) \
58   	     ({ register char __result;						      \
59   		__asm__ ("fucomip %%st(1), %%st; seta %%al"			      \
60   			 : "=a" (__result) : "u" (x), "t" (y) : "cc", "st");	      \
61   		__result; })
62   	
63   	#   define islessequal(x, y) \
64   	     ({ register char __result;						      \
65   		__asm__ ("fucomip %%st(1), %%st; setae %%al"			      \
66   			 : "=a" (__result) : "u" (x), "t" (y) : "cc", "st");	      \
67   		__result; })
68   	
69   	#   define islessgreater(x, y) \
70   	     ({ register char __result;						      \
71   		__asm__ ("fucomip %%st(1), %%st; setne %%al"			      \
72   			 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st");	      \
73   		__result; })
74   	
75   	#   define isunordered(x, y) \
76   	     ({ register char __result;						      \
77   		__asm__ ("fucomip %%st(1), %%st; setp %%al"			      \
78   			 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st");	      \
79   		__result; })
80   	#  else
81   	/* This is the dumb, portable code for i386 and above.  */
82   	#   define isgreater(x, y) \
83   	     ({ register char __result;						      \
84   		__asm__ ("fucompp; fnstsw; testb $0x45, %%ah; setz %%al"	      \
85   			 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
86   		__result; })
87   	
88   	#   define isgreaterequal(x, y) \
89   	     ({ register char __result;						      \
90   		__asm__ ("fucompp; fnstsw; testb $0x05, %%ah; setz %%al"	      \
91   			 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
92   		__result; })
93   	
94   	#   define isless(x, y) \
95   	     ({ register char __result;						      \
96   		__asm__ ("fucompp; fnstsw; testb $0x45, %%ah; setz %%al"	      \
97   			 : "=a" (__result) : "u" (x), "t" (y) : "cc", "st", "st(1)"); \
98   		__result; })
99   	
100  	#   define islessequal(x, y) \
101  	     ({ register char __result;						      \
102  		__asm__ ("fucompp; fnstsw; testb $0x05, %%ah; setz %%al"	      \
103  			 : "=a" (__result) : "u" (x), "t" (y) : "cc", "st", "st(1)"); \
104  		__result; })
105  	
106  	#   define islessgreater(x, y) \
107  	     ({ register char __result;						      \
108  		__asm__ ("fucompp; fnstsw; testb $0x44, %%ah; setz %%al"	      \
109  			 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
110  		__result; })
111  	
112  	#   define isunordered(x, y) \
113  	     ({ register char __result;						      \
114  		__asm__ ("fucompp; fnstsw; sahf; setp %%al"			      \
115  			 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
116  		__result; })
117  	#  endif /* __i686__ */
118  	# endif	/* GCC 2.97 */
119  	
120  	/* The gcc, version 2.7 or below, has problems with all this inlining
121  	   code.  So disable it for this version of the compiler.  */
122  	# if __GNUC_PREREQ (2, 8)
123  	__BEGIN_NAMESPACE_C99
124  	
125  	/* Test for negative number.  Used in the signbit() macro.  */
126  	__MATH_INLINE int
127  	__NTH (__signbitf (float __x))
128  	{
129  	#  ifdef __SSE2_MATH__
130  	  int __m;
131  	  __asm ("pmovmskb %1, %0" : "=r" (__m) : "x" (__x));
132  	  return (__m & 0x8) != 0;
133  	#  else
134  	  __extension__ union { float __f; int __i; } __u = { __f: __x };
135  	  return __u.__i < 0;
136  	#  endif
137  	}
138  	__MATH_INLINE int
139  	__NTH (__signbit (double __x))
140  	{
141  	#  ifdef __SSE2_MATH__
142  	  int __m;
143  	  __asm ("pmovmskb %1, %0" : "=r" (__m) : "x" (__x));
144  	  return (__m & 0x80) != 0;
145  	#  else
146  	  __extension__ union { double __d; int __i[2]; } __u = { __d: __x };
147  	  return __u.__i[1] < 0;
148  	#  endif
149  	}
150  	__MATH_INLINE int
151  	__NTH (__signbitl (long double __x))
152  	{
153  	  __extension__ union { long double __l; int __i[3]; } __u = { __l: __x };
154  	  return (__u.__i[2] & 0x8000) != 0;
155  	}
156  	
157  	__END_NAMESPACE_C99
158  	# endif
159  	#endif
160  	
161  	
162  	/* The gcc, version 2.7 or below, has problems with all this inlining
163  	   code.  So disable it for this version of the compiler.  */
164  	#if __GNUC_PREREQ (2, 8)
165  	# if !__GNUC_PREREQ (3, 4) && !defined __NO_MATH_INLINES \
166  	     && defined __OPTIMIZE__
167  	/* GCC 3.4 introduced builtins for all functions below, so
168  	   there's no need to define any of these inline functions.  */
169  	
170  	#  ifdef __USE_ISOC99
171  	__BEGIN_NAMESPACE_C99
172  	
173  	/* Round to nearest integer.  */
174  	#   ifdef __SSE_MATH__
175  	__MATH_INLINE long int
176  	__NTH (lrintf (float __x))
177  	{
178  	  long int __res;
179  	  /* Mark as volatile since the result is dependent on the state of
180  	     the SSE control register (the rounding mode).  Otherwise GCC might
181  	     remove these assembler instructions since it does not know about
182  	     the rounding mode change and cannot currently be told.  */
183  	  __asm __volatile__ ("cvtss2si %1, %0" : "=r" (__res) : "xm" (__x));
184  	  return __res;
185  	}
186  	#   endif
187  	#   ifdef __SSE2_MATH__
188  	__MATH_INLINE long int
189  	__NTH (lrint (double __x))
190  	{
191  	  long int __res;
192  	  /* Mark as volatile since the result is dependent on the state of
193  	     the SSE control register (the rounding mode).  Otherwise GCC might
194  	     remove these assembler instructions since it does not know about
195  	     the rounding mode change and cannot currently be told.  */
196  	  __asm __volatile__ ("cvtsd2si %1, %0" : "=r" (__res) : "xm" (__x));
197  	  return __res;
198  	}
199  	#   endif
200  	#   ifdef __x86_64__
201  	__extension__
202  	__MATH_INLINE long long int
203  	__NTH (llrintf (float __x))
204  	{
205  	  long long int __res;
206  	  /* Mark as volatile since the result is dependent on the state of
207  	     the SSE control register (the rounding mode).  Otherwise GCC might
208  	     remove these assembler instructions since it does not know about
209  	     the rounding mode change and cannot currently be told.  */
210  	  __asm __volatile__ ("cvtss2si %1, %0" : "=r" (__res) : "xm" (__x));
211  	  return __res;
212  	}
213  	__extension__
214  	__MATH_INLINE long long int
215  	__NTH (llrint (double __x))
216  	{
217  	  long long int __res;
218  	  /* Mark as volatile since the result is dependent on the state of
219  	     the SSE control register (the rounding mode).  Otherwise GCC might
220  	     remove these assembler instructions since it does not know about
221  	     the rounding mode change and cannot currently be told.  */
222  	  __asm __volatile__ ("cvtsd2si %1, %0" : "=r" (__res) : "xm" (__x));
223  	  return __res;
224  	}
225  	#   endif
226  	
227  	#   if defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0 \
228  	       && defined __SSE2_MATH__
229  	/* Determine maximum of two values.  */
230  	__MATH_INLINE float
231  	__NTH (fmaxf (float __x, float __y))
232  	{
233  	#    ifdef __AVX__
234  	  float __res;
235  	  __asm ("vmaxss %2, %1, %0" : "=x" (__res) : "x" (x), "xm" (__y));
236  	  return __res;
237  	#    else
238  	  __asm ("maxss %1, %0" : "+x" (__x) : "xm" (__y));
239  	  return __x;
240  	#    endif
241  	}
242  	__MATH_INLINE double
243  	__NTH (fmax (double __x, double __y))
244  	{
245  	#    ifdef __AVX__
246  	  float __res;
247  	  __asm ("vmaxsd %2, %1, %0" : "=x" (__res) : "x" (x), "xm" (__y));
248  	  return __res;
249  	#    else
250  	  __asm ("maxsd %1, %0" : "+x" (__x) : "xm" (__y));
251  	  return __x;
252  	#    endif
253  	}
254  	
255  	/* Determine minimum of two values.  */
256  	__MATH_INLINE float
257  	__NTH (fminf (float __x, float __y))
258  	{
259  	#    ifdef __AVX__
260  	  float __res;
261  	  __asm ("vminss %2, %1, %0" : "=x" (__res) : "x" (x), "xm" (__y));
262  	  return __res;
263  	#    else
264  	  __asm ("minss %1, %0" : "+x" (__x) : "xm" (__y));
265  	  return __x;
266  	#    endif
267  	}
268  	__MATH_INLINE double
269  	__NTH (fmin (double __x, double __y))
270  	{
271  	#    ifdef __AVX__
272  	  float __res;
273  	  __asm ("vminsd %2, %1, %0" : "=x" (__res) : "x" (x), "xm" (__y));
274  	  return __res;
275  	#    else
276  	  __asm ("minsd %1, %0" : "+x" (__x) : "xm" (__y));
277  	  return __x;
278  	#    endif
279  	}
280  	#   endif
281  	
282  	__END_NAMESPACE_C99
283  	#  endif
284  	
285  	#  if defined __SSE4_1__ && defined __SSE2_MATH__
286  	#   if defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99
287  	__BEGIN_NAMESPACE_C99
288  	
289  	/* Round to nearest integer.  */
290  	__MATH_INLINE double
291  	__NTH (rint (double __x))
292  	{
293  	  double __res;
294  	  /* Mark as volatile since the result is dependent on the state of
295  	     the SSE control register (the rounding mode).  Otherwise GCC might
296  	     remove these assembler instructions since it does not know about
297  	     the rounding mode change and cannot currently be told.  */
298  	  __asm __volatile__ ("roundsd $4, %1, %0" : "=x" (__res) : "xm" (__x));
299  	  return __res;
300  	}
301  	__MATH_INLINE float
302  	__NTH (rintf (float __x))
303  	{
304  	  float __res;
305  	  /* Mark as volatile since the result is dependent on the state of
306  	     the SSE control register (the rounding mode).  Otherwise GCC might
307  	     remove these assembler instructions since it does not know about
308  	     the rounding mode change and cannot currently be told.  */
309  	  __asm __volatile__ ("roundss $4, %1, %0" : "=x" (__res) : "xm" (__x));
310  	  return __res;
311  	}
312  	
313  	#    ifdef __USE_ISOC99
314  	/* Round to nearest integer without raising inexact exception.  */
315  	__MATH_INLINE double
316  	__NTH (nearbyint (double __x))
317  	{
318  	  double __res;
319  	  /* Mark as volatile since the result is dependent on the state of
320  	     the SSE control register (the rounding mode).  Otherwise GCC might
321  	     remove these assembler instructions since it does not know about
322  	     the rounding mode change and cannot currently be told.  */
323  	  __asm __volatile__ ("roundsd $0xc, %1, %0" : "=x" (__res) : "xm" (__x));
324  	  return __res;
325  	}
326  	__MATH_INLINE float
327  	__NTH (nearbyintf (float __x))
328  	{
329  	  float __res;
330  	  /* Mark as volatile since the result is dependent on the state of
331  	     the SSE control register (the rounding mode).  Otherwise GCC might
332  	     remove these assembler instructions since it does not know about
333  	     the rounding mode change and cannot currently be told.  */
334  	  __asm __volatile__ ("roundss $0xc, %1, %0" : "=x" (__res) : "xm" (__x));
335  	  return __res;
336  	}
337  	#    endif
338  	
339  	__END_NAMESPACE_C99
340  	#   endif
341  	
342  	__BEGIN_NAMESPACE_STD
343  	/* Smallest integral value not less than X.  */
344  	__MATH_INLINE double
345  	__NTH (ceil (double __x))
346  	{
347  	  double __res;
348  	  __asm ("roundsd $2, %1, %0" : "=x" (__res) : "xm" (__x));
349  	  return __res;
350  	}
351  	__END_NAMESPACE_STD
352  	
353  	__BEGIN_NAMESPACE_C99
354  	__MATH_INLINE float
355  	__NTH (ceilf (float __x))
356  	{
357  	  float __res;
358  	  __asm ("roundss $2, %1, %0" : "=x" (__res) : "xm" (__x));
359  	  return __res;
360  	}
361  	__END_NAMESPACE_C99
362  	
363  	__BEGIN_NAMESPACE_STD
364  	/* Largest integer not greater than X.  */
365  	__MATH_INLINE double
366  	__NTH (floor (double __x))
367  	{
368  	  double __res;
369  	  __asm ("roundsd $1, %1, %0" : "=x" (__res) : "xm" (__x));
370  	  return __res;
371  	}
372  	__END_NAMESPACE_STD
373  	
374  	__BEGIN_NAMESPACE_C99
375  	__MATH_INLINE float
376  	__NTH (floorf (float __x))
377  	{
378  	  float __res;
379  	  __asm ("roundss $1, %1, %0" : "=x" (__res) : "xm" (__x));
380  	  return __res;
381  	}
382  	__END_NAMESPACE_C99
383  	#  endif
384  	# endif
385  	#endif
386  	
387  	/* Disable x87 inlines when -fpmath=sse is passed and also when we're building
388  	   on x86_64.  Older gcc (gcc-3.2 for example) does not define __SSE2_MATH__
389  	   for x86_64.  */
390  	#if !defined __SSE2_MATH__ && !defined __x86_64__
391  	# if ((!defined __NO_MATH_INLINES || defined __LIBC_INTERNAL_MATH_INLINES) \
392  	     && defined __OPTIMIZE__)
393  	
394  	/* The inline functions do not set errno or raise necessarily the
395  	   correct exceptions.  */
396  	#  undef math_errhandling
397  	
398  	/* A macro to define float, double, and long double versions of various
399  	   math functions for the ix87 FPU.  FUNC is the function name (which will
400  	   be suffixed with f and l for the float and long double version,
401  	   respectively).  OP is the name of the FPU operation.
402  	   We define two sets of macros.  The set with the additional NP
403  	   doesn't add a prototype declaration.  */
404  	
405  	#  ifdef __USE_ISOC99
406  	#   define __inline_mathop(func, op) \
407  	  __inline_mathop_ (double, func, op)					      \
408  	  __inline_mathop_ (float, __CONCAT(func,f), op)			      \
409  	  __inline_mathop_ (long double, __CONCAT(func,l), op)
410  	#   define __inline_mathopNP(func, op) \
411  	  __inline_mathopNP_ (double, func, op)					      \
412  	  __inline_mathopNP_ (float, __CONCAT(func,f), op)			      \
413  	  __inline_mathopNP_ (long double, __CONCAT(func,l), op)
414  	#  else
415  	#   define __inline_mathop(func, op) \
416  	  __inline_mathop_ (double, func, op)
417  	#   define __inline_mathopNP(func, op) \
418  	  __inline_mathopNP_ (double, func, op)
419  	#  endif
420  	
421  	#  define __inline_mathop_(float_type, func, op) \
422  	  __inline_mathop_decl_ (float_type, func, op, "0" (__x))
423  	#  define __inline_mathopNP_(float_type, func, op) \
424  	  __inline_mathop_declNP_ (float_type, func, op, "0" (__x))
425  	
426  	
427  	#  ifdef __USE_ISOC99
428  	#   define __inline_mathop_decl(func, op, params...) \
429  	  __inline_mathop_decl_ (double, func, op, params)			      \
430  	  __inline_mathop_decl_ (float, __CONCAT(func,f), op, params)		      \
431  	  __inline_mathop_decl_ (long double, __CONCAT(func,l), op, params)
432  	#   define __inline_mathop_declNP(func, op, params...) \
433  	  __inline_mathop_declNP_ (double, func, op, params)			      \
434  	  __inline_mathop_declNP_ (float, __CONCAT(func,f), op, params)		      \
435  	  __inline_mathop_declNP_ (long double, __CONCAT(func,l), op, params)
436  	#  else
437  	#   define __inline_mathop_decl(func, op, params...) \
438  	  __inline_mathop_decl_ (double, func, op, params)
439  	#   define __inline_mathop_declNP(func, op, params...) \
440  	  __inline_mathop_declNP_ (double, func, op, params)
441  	#  endif
442  	
443  	#  define __inline_mathop_decl_(float_type, func, op, params...) \
444  	  __MATH_INLINE float_type func (float_type) __THROW;			      \
445  	  __inline_mathop_declNP_ (float_type, func, op, params)
446  	
447  	#  define __inline_mathop_declNP_(float_type, func, op, params...) \
448  	  __MATH_INLINE float_type __NTH (func (float_type __x))		      \
449  	  {									      \
450  	    register float_type __result;					      \
451  	    __asm __volatile__ (op : "=t" (__result) : params);			      \
452  	    return __result;							      \
453  	  }
454  	
455  	
456  	#  ifdef __USE_ISOC99
457  	#   define __inline_mathcode(func, arg, code) \
458  	  __inline_mathcode_ (double, func, arg, code)				      \
459  	  __inline_mathcode_ (float, __CONCAT(func,f), arg, code)		      \
460  	  __inline_mathcode_ (long double, __CONCAT(func,l), arg, code)
461  	#   define __inline_mathcodeNP(func, arg, code) \
462  	  __inline_mathcodeNP_ (double, func, arg, code)			      \
463  	  __inline_mathcodeNP_ (float, __CONCAT(func,f), arg, code)		      \
464  	  __inline_mathcodeNP_ (long double, __CONCAT(func,l), arg, code)
465  	#   define __inline_mathcode2(func, arg1, arg2, code) \
466  	  __inline_mathcode2_ (double, func, arg1, arg2, code)			      \
467  	  __inline_mathcode2_ (float, __CONCAT(func,f), arg1, arg2, code)	      \
468  	  __inline_mathcode2_ (long double, __CONCAT(func,l), arg1, arg2, code)
469  	#   define __inline_mathcodeNP2(func, arg1, arg2, code) \
470  	  __inline_mathcodeNP2_ (double, func, arg1, arg2, code)		      \
471  	  __inline_mathcodeNP2_ (float, __CONCAT(func,f), arg1, arg2, code)	      \
472  	  __inline_mathcodeNP2_ (long double, __CONCAT(func,l), arg1, arg2, code)
473  	#   define __inline_mathcode3(func, arg1, arg2, arg3, code) \
474  	  __inline_mathcode3_ (double, func, arg1, arg2, arg3, code)		      \
475  	  __inline_mathcode3_ (float, __CONCAT(func,f), arg1, arg2, arg3, code)	      \
476  	  __inline_mathcode3_ (long double, __CONCAT(func,l), arg1, arg2, arg3, code)
477  	#   define __inline_mathcodeNP3(func, arg1, arg2, arg3, code) \
478  	  __inline_mathcodeNP3_ (double, func, arg1, arg2, arg3, code)		      \
479  	  __inline_mathcodeNP3_ (float, __CONCAT(func,f), arg1, arg2, arg3, code)     \
480  	  __inline_mathcodeNP3_ (long double, __CONCAT(func,l), arg1, arg2, arg3, code)
481  	#  else
482  	#   define __inline_mathcode(func, arg, code) \
483  	  __inline_mathcode_ (double, func, (arg), code)
484  	#   define __inline_mathcodeNP(func, arg, code) \
485  	  __inline_mathcodeNP_ (double, func, (arg), code)
486  	#   define __inline_mathcode2(func, arg1, arg2, code) \
487  	  __inline_mathcode2_ (double, func, arg1, arg2, code)
488  	#   define __inline_mathcodeNP2(func, arg1, arg2, code) \
489  	  __inline_mathcodeNP2_ (double, func, arg1, arg2, code)
490  	#   define __inline_mathcode3(func, arg1, arg2, arg3, code) \
491  	  __inline_mathcode3_ (double, func, arg1, arg2, arg3, code)
492  	#   define __inline_mathcodeNP3(func, arg1, arg2, arg3, code) \
493  	  __inline_mathcodeNP3_ (double, func, arg1, arg2, arg3, code)
494  	#  endif
495  	
496  	#  define __inline_mathcode_(float_type, func, arg, code) \
497  	  __MATH_INLINE float_type func (float_type) __THROW;			      \
498  	  __inline_mathcodeNP_(float_type, func, arg, code)
499  	
500  	#  define __inline_mathcodeNP_(float_type, func, arg, code) \
501  	  __MATH_INLINE float_type __NTH (func (float_type arg))		      \
502  	  {									      \
503  	    code;								      \
504  	  }
505  	
506  	
507  	#  define __inline_mathcode2_(float_type, func, arg1, arg2, code) \
508  	  __MATH_INLINE float_type func (float_type, float_type) __THROW;	      \
509  	  __inline_mathcodeNP2_ (float_type, func, arg1, arg2, code)
510  	
511  	#  define __inline_mathcodeNP2_(float_type, func, arg1, arg2, code) \
512  	  __MATH_INLINE float_type __NTH (func (float_type arg1, float_type arg2))    \
513  	  {									      \
514  	    code;								      \
515  	  }
516  	
517  	#  define __inline_mathcode3_(float_type, func, arg1, arg2, arg3, code) \
518  	  __MATH_INLINE float_type func (float_type, float_type, float_type) __THROW; \
519  	  __inline_mathcodeNP3_(float_type, func, arg1, arg2, arg3, code)
520  	
521  	#  define __inline_mathcodeNP3_(float_type, func, arg1, arg2, arg3, code) \
522  	  __MATH_INLINE float_type __NTH (func (float_type arg1, float_type arg2,     \
523  						float_type arg3))		      \
524  	  {									      \
525  	    code;								      \
526  	  }
527  	# endif
528  	
529  	
530  	# if !defined __NO_MATH_INLINES && defined __OPTIMIZE__
531  	/* Miscellaneous functions  */
532  	
533  	/* __FAST_MATH__ is defined by gcc -ffast-math.  */
534  	#  ifdef __FAST_MATH__
535  	#   ifdef __USE_GNU
536  	#    define __sincos_code \
537  	  register long double __cosr;						      \
538  	  register long double __sinr;						      \
539  	  register unsigned int __swtmp;					      \
540  	  __asm __volatile__							      \
541  	    ("fsincos\n\t"							      \
542  	     "fnstsw	%w2\n\t"						      \
543  	     "testl	$0x400, %2\n\t"						      \
544  	     "jz	1f\n\t"							      \
545  	     "fldpi\n\t"							      \
546  	     "fadd	%%st(0)\n\t"						      \
547  	     "fxch	%%st(1)\n\t"						      \
548  	     "2: fprem1\n\t"							      \
549  	     "fnstsw	%w2\n\t"						      \
550  	     "testl	$0x400, %2\n\t"						      \
551  	     "jnz	2b\n\t"							      \
552  	     "fstp	%%st(1)\n\t"						      \
553  	     "fsincos\n\t"							      \
554  	     "1:"								      \
555  	     : "=t" (__cosr), "=u" (__sinr), "=a" (__swtmp) : "0" (__x));	      \
556  	  *__sinx = __sinr;							      \
557  	  *__cosx = __cosr
558  	
559  	__MATH_INLINE void
560  	__NTH (__sincos (double __x, double *__sinx, double *__cosx))
561  	{
562  	  __sincos_code;
563  	}
564  	
565  	__MATH_INLINE void
566  	__NTH (__sincosf (float __x, float *__sinx, float *__cosx))
567  	{
568  	  __sincos_code;
569  	}
570  	
571  	__MATH_INLINE void
572  	__NTH (__sincosl (long double __x, long double *__sinx, long double *__cosx))
573  	{
574  	  __sincos_code;
575  	}
576  	#   endif
577  	
578  	
579  	/* Optimized inline implementation, sometimes with reduced precision
580  	   and/or argument range.  */
581  	
582  	#   if __GNUC_PREREQ (3, 5)
583  	#    define __expm1_code \
584  	  register long double __temp;						      \
585  	  __temp = __builtin_expm1l (__x);					      \
586  	  return __temp ? __temp : __x
587  	#   else
588  	#    define __expm1_code \
589  	  register long double __value;						      \
590  	  register long double __exponent;					      \
591  	  register long double __temp;						      \
592  	  __asm __volatile__							      \
593  	    ("fldl2e			# e^x - 1 = 2^(x * log2(e)) - 1\n\t"	      \
594  	     "fmul	%%st(1)		# x * log2(e)\n\t"			      \
595  	     "fst	%%st(1)\n\t"						      \
596  	     "frndint			# int(x * log2(e))\n\t"			      \
597  	     "fxch\n\t"								      \
598  	     "fsub	%%st(1)		# fract(x * log2(e))\n\t"		      \
599  	     "f2xm1			# 2^(fract(x * log2(e))) - 1\n\t"	      \
600  	     "fscale			# 2^(x * log2(e)) - 2^(int(x * log2(e)))\n\t" \
601  	     : "=t" (__value), "=u" (__exponent) : "0" (__x));			      \
602  	  __asm __volatile__							      \
603  	    ("fscale			# 2^int(x * log2(e))\n\t"		      \
604  	     : "=t" (__temp) : "0" (1.0), "u" (__exponent));			      \
605  	  __temp -= 1.0;							      \
606  	  __temp += __value;							      \
607  	  return __temp ? __temp : __x
608  	#   endif
609  	__inline_mathcodeNP_ (long double, __expm1l, __x, __expm1_code)
610  	
611  	#   if __GNUC_PREREQ (3, 4)
612  	__inline_mathcodeNP_ (long double, __expl, __x, return __builtin_expl (__x))
613  	#   else
614  	#    define __exp_code \
615  	  register long double __value;						      \
616  	  register long double __exponent;					      \
617  	  __asm __volatile__							      \
618  	    ("fldl2e			# e^x = 2^(x * log2(e))\n\t"		      \
619  	     "fmul	%%st(1)		# x * log2(e)\n\t"			      \
620  	     "fst	%%st(1)\n\t"						      \
621  	     "frndint			# int(x * log2(e))\n\t"			      \
622  	     "fxch\n\t"								      \
623  	     "fsub	%%st(1)		# fract(x * log2(e))\n\t"		      \
624  	     "f2xm1			# 2^(fract(x * log2(e))) - 1\n\t"	      \
625  	     : "=t" (__value), "=u" (__exponent) : "0" (__x));			      \
626  	  __value += 1.0;							      \
627  	  __asm __volatile__							      \
628  	    ("fscale"								      \
629  	     : "=t" (__value) : "0" (__value), "u" (__exponent));		      \
630  	  return __value
631  	__inline_mathcodeNP (exp, __x, __exp_code)
632  	__inline_mathcodeNP_ (long double, __expl, __x, __exp_code)
633  	#   endif
634  	
635  	
636  	#   if !__GNUC_PREREQ (3, 5)
637  	__inline_mathcodeNP (tan, __x, \
638  	  register long double __value;						      \
639  	  register long double __value2 __attribute__ ((__unused__));		      \
640  	  __asm __volatile__							      \
641  	    ("fptan"								      \
642  	     : "=t" (__value2), "=u" (__value) : "0" (__x));			      \
643  	  return __value)
644  	#   endif
645  	#  endif /* __FAST_MATH__ */
646  	
647  	
648  	#  if __GNUC_PREREQ (3, 4)
649  	__inline_mathcodeNP2_ (long double, __atan2l, __y, __x,
650  			       return __builtin_atan2l (__y, __x))
651  	#  else
652  	#   define __atan2_code \
653  	  register long double __value;						      \
654  	  __asm __volatile__							      \
655  	    ("fpatan"								      \
656  	     : "=t" (__value) : "0" (__x), "u" (__y) : "st(1)");		      \
657  	  return __value
658  	#   ifdef __FAST_MATH__
659  	__inline_mathcodeNP2 (atan2, __y, __x, __atan2_code)
660  	#   endif
661  	__inline_mathcodeNP2_ (long double, __atan2l, __y, __x, __atan2_code)
662  	#  endif
663  	
664  	
665  	#  if defined __FAST_MATH__ && !__GNUC_PREREQ (3, 5)
666  	__inline_mathcodeNP2 (fmod, __x, __y, \
667  	  register long double __value;						      \
668  	  __asm __volatile__							      \
669  	    ("1:	fprem\n\t"						      \
670  	     "fnstsw	%%ax\n\t"						      \
671  	     "sahf\n\t"								      \
672  	     "jp	1b"							      \
673  	     : "=t" (__value) : "0" (__x), "u" (__y) : "ax", "cc");		      \
674  	  return __value)
675  	#  endif
676  	
677  	
678  	#  ifdef __FAST_MATH__
679  	#   if !__GNUC_PREREQ (3,3)
680  	__inline_mathopNP (sqrt, "fsqrt")
681  	__inline_mathopNP_ (long double, __sqrtl, "fsqrt")
682  	#    define __libc_sqrtl(n) __sqrtl (n)
683  	#   else
684  	#    define __libc_sqrtl(n) __builtin_sqrtl (n)
685  	#   endif
686  	#  endif
687  	
688  	#  if __GNUC_PREREQ (2, 8)
689  	__inline_mathcodeNP_ (double, fabs, __x, return __builtin_fabs (__x))
690  	#   ifdef __USE_ISOC99
691  	__inline_mathcodeNP_ (float, fabsf, __x, return __builtin_fabsf (__x))
692  	__inline_mathcodeNP_ (long double, fabsl, __x, return __builtin_fabsl (__x))
693  	#   endif
694  	__inline_mathcodeNP_ (long double, __fabsl, __x, return __builtin_fabsl (__x))
695  	#  else
696  	__inline_mathop (fabs, "fabs")
697  	__inline_mathop_ (long double, __fabsl, "fabs")
698  	# endif
699  	
700  	#  ifdef __FAST_MATH__
701  	#   if !__GNUC_PREREQ (3, 4)
702  	/* The argument range of this inline version is reduced.  */
703  	__inline_mathopNP (sin, "fsin")
704  	/* The argument range of this inline version is reduced.  */
705  	__inline_mathopNP (cos, "fcos")
706  	
707  	__inline_mathop_declNP (log, "fldln2; fxch; fyl2x", "0" (__x) : "st(1)")
708  	#   endif
709  	
710  	#   if !__GNUC_PREREQ (3, 5)
711  	__inline_mathop_declNP (log10, "fldlg2; fxch; fyl2x", "0" (__x) : "st(1)")
712  	
713  	__inline_mathcodeNP (asin, __x, return __atan2l (__x, __libc_sqrtl (1.0 - __x * __x)))
714  	__inline_mathcodeNP (acos, __x, return __atan2l (__libc_sqrtl (1.0 - __x * __x), __x))
715  	#   endif
716  	
717  	#   if !__GNUC_PREREQ (3, 4)
718  	__inline_mathop_declNP (atan, "fld1; fpatan", "0" (__x) : "st(1)")
719  	#   endif
720  	#  endif /* __FAST_MATH__ */
721  	
722  	__inline_mathcode_ (long double, __sgn1l, __x, \
723  	  __extension__ union { long double __xld; unsigned int __xi[3]; } __n =      \
724  	    { __xld: __x };							      \
725  	  __n.__xi[2] = (__n.__xi[2] & 0x8000) | 0x3fff;			      \
726  	  __n.__xi[1] = 0x80000000;						      \
727  	  __n.__xi[0] = 0;							      \
728  	  return __n.__xld)
729  	
730  	
731  	#  ifdef __FAST_MATH__
732  	/* The argument range of the inline version of sinhl is slightly reduced.  */
733  	__inline_mathcodeNP (sinh, __x, \
734  	  register long double __exm1 = __expm1l (__fabsl (__x));		      \
735  	  return 0.5 * (__exm1 / (__exm1 + 1.0) + __exm1) * __sgn1l (__x))
736  	
737  	__inline_mathcodeNP (cosh, __x, \
738  	  register long double __ex = __expl (__x);				      \
739  	  return 0.5 * (__ex + 1.0 / __ex))
740  	
741  	__inline_mathcodeNP (tanh, __x, \
742  	  register long double __exm1 = __expm1l (-__fabsl (__x + __x));	      \
743  	  return __exm1 / (__exm1 + 2.0) * __sgn1l (-__x))
744  	#  endif
745  	
746  	__inline_mathcodeNP (floor, __x, \
747  	  register long double __value;						      \
748  	  register int __ignore;						      \
749  	  unsigned short int __cw;						      \
750  	  unsigned short int __cwtmp;						      \
751  	  __asm __volatile ("fnstcw %3\n\t"					      \
752  			    "movzwl %3, %1\n\t"					      \
753  			    "andl $0xf3ff, %1\n\t"				      \
754  			    "orl $0x0400, %1\n\t"	/* rounding down */	      \
755  			    "movw %w1, %2\n\t"					      \
756  			    "fldcw %2\n\t"					      \
757  			    "frndint\n\t"					      \
758  			    "fldcw %3"						      \
759  			    : "=t" (__value), "=&q" (__ignore), "=m" (__cwtmp),	      \
760  			      "=m" (__cw)					      \
761  			    : "0" (__x));					      \
762  	  return __value)
763  	
764  	__inline_mathcodeNP (ceil, __x, \
765  	  register long double __value;						      \
766  	  register int __ignore;						      \
767  	  unsigned short int __cw;						      \
768  	  unsigned short int __cwtmp;						      \
769  	  __asm __volatile ("fnstcw %3\n\t"					      \
770  			    "movzwl %3, %1\n\t"					      \
771  			    "andl $0xf3ff, %1\n\t"				      \
772  			    "orl $0x0800, %1\n\t"	/* rounding up */	      \
773  			    "movw %w1, %2\n\t"					      \
774  			    "fldcw %2\n\t"					      \
775  			    "frndint\n\t"					      \
776  			    "fldcw %3"						      \
777  			    : "=t" (__value), "=&q" (__ignore), "=m" (__cwtmp),	      \
778  			      "=m" (__cw)					      \
779  			    : "0" (__x));					      \
780  	  return __value)
781  	
782  	#  ifdef __FAST_MATH__
783  	#   define __ldexp_code \
784  	  register long double __value;						      \
785  	  __asm __volatile__							      \
786  	    ("fscale"								      \
787  	     : "=t" (__value) : "0" (__x), "u" ((long double) __y));		      \
788  	  return __value
789  	
790  	__MATH_INLINE double
791  	__NTH (ldexp (double __x, int __y))
792  	{
793  	  __ldexp_code;
794  	}
795  	#  endif
796  	
797  	
798  	/* Optimized versions for some non-standardized functions.  */
799  	#  ifdef __USE_ISOC99
800  	
801  	#   ifdef __FAST_MATH__
802  	__inline_mathcodeNP (expm1, __x, __expm1_code)
803  	
804  	/* We cannot rely on M_SQRT being defined.  So we do it for ourself
805  	   here.  */
806  	#    define __M_SQRT2	1.41421356237309504880L	/* sqrt(2) */
807  	
808  	#    if !__GNUC_PREREQ (3, 5)
809  	__inline_mathcodeNP (log1p, __x, \
810  	  register long double __value;						      \
811  	  if (__fabsl (__x) >= 1.0 - 0.5 * __M_SQRT2)				      \
812  	    __value = logl (1.0 + __x);						      \
813  	  else									      \
814  	    __asm __volatile__							      \
815  	      ("fldln2\n\t"							      \
816  	       "fxch\n\t"							      \
817  	       "fyl2xp1"							      \
818  	       : "=t" (__value) : "0" (__x) : "st(1)");				      \
819  	  return __value)
820  	#    endif
821  	
822  	
823  	/* The argument range of the inline version of asinhl is slightly reduced.  */
824  	__inline_mathcodeNP (asinh, __x, \
825  	  register long double  __y = __fabsl (__x);				      \
826  	  return (log1pl (__y * __y / (__libc_sqrtl (__y * __y + 1.0) + 1.0) + __y)   \
827  		  * __sgn1l (__x)))
828  	
829  	__inline_mathcodeNP (acosh, __x, \
830  	  return logl (__x + __libc_sqrtl (__x - 1.0) * __libc_sqrtl (__x + 1.0)))
831  	
832  	__inline_mathcodeNP (atanh, __x, \
833  	  register long double __y = __fabsl (__x);				      \
834  	  return -0.5 * log1pl (-(__y + __y) / (1.0 + __y)) * __sgn1l (__x))
835  	
836  	/* The argument range of the inline version of hypotl is slightly reduced.  */
837  	__inline_mathcodeNP2 (hypot, __x, __y,
838  			      return __libc_sqrtl (__x * __x + __y * __y))
839  	
840  	#    if !__GNUC_PREREQ (3, 5)
841  	__inline_mathcodeNP(logb, __x, \
842  	  register long double __value;						      \
843  	  register long double __junk;						      \
844  	  __asm __volatile__							      \
845  	    ("fxtract\n\t"							      \
846  	     : "=t" (__junk), "=u" (__value) : "0" (__x));			      \
847  	  return __value)
848  	#    endif
849  	
850  	#   endif
851  	#  endif
852  	
853  	#  ifdef __USE_ISOC99
854  	#   ifdef __FAST_MATH__
855  	
856  	#    if !__GNUC_PREREQ (3, 5)
857  	__inline_mathop_declNP (log2, "fld1; fxch; fyl2x", "0" (__x) : "st(1)")
858  	#    endif
859  	
860  	__MATH_INLINE float
861  	__NTH (ldexpf (float __x, int __y))
862  	{
863  	  __ldexp_code;
864  	}
865  	
866  	__MATH_INLINE long double
867  	__NTH (ldexpl (long double __x, int __y))
868  	{
869  	  __ldexp_code;
870  	}
871  	
872  	__inline_mathopNP (rint, "frndint")
873  	#   endif /* __FAST_MATH__ */
874  	
875  	#   define __lrint_code \
876  	  long int __lrintres;							      \
877  	  __asm__ __volatile__							      \
878  	    ("fistpl %0"							      \
879  	     : "=m" (__lrintres) : "t" (__x) : "st");				      \
880  	  return __lrintres
881  	__MATH_INLINE long int
882  	__NTH (lrintf (float __x))
883  	{
884  	  __lrint_code;
885  	}
886  	__MATH_INLINE long int
887  	__NTH (lrint (double __x))
888  	{
889  	  __lrint_code;
890  	}
891  	__MATH_INLINE long int
892  	__NTH (lrintl (long double __x))
893  	{
894  	  __lrint_code;
895  	}
896  	#   undef __lrint_code
897  	
898  	#   define __llrint_code \
899  	  long long int __llrintres;						      \
900  	  __asm__ __volatile__							      \
901  	    ("fistpll %0"							      \
902  	     : "=m" (__llrintres) : "t" (__x) : "st");				      \
903  	  return __llrintres
904  	__extension__
905  	__MATH_INLINE long long int
906  	__NTH (llrintf (float __x))
907  	{
908  	  __llrint_code;
909  	}
910  	__extension__
911  	__MATH_INLINE long long int
912  	__NTH (llrint (double __x))
913  	{
914  	  __llrint_code;
915  	}
916  	__extension__
917  	__MATH_INLINE long long int
918  	__NTH (llrintl (long double __x))
919  	{
920  	  __llrint_code;
921  	}
922  	#   undef __llrint_code
923  	
924  	# endif
925  	
926  	
927  	#  ifdef __USE_MISC
928  	
929  	#   if defined __FAST_MATH__ && !__GNUC_PREREQ (3, 5)
930  	__inline_mathcodeNP2 (drem, __x, __y, \
931  	  register double __value;						      \
932  	  register int __clobbered;						      \
933  	  __asm __volatile__							      \
934  	    ("1:	fprem1\n\t"						      \
935  	     "fstsw	%%ax\n\t"						      \
936  	     "sahf\n\t"								      \
937  	     "jp	1b"							      \
938  	     : "=t" (__value), "=&a" (__clobbered) : "0" (__x), "u" (__y) : "cc");    \
939  	  return __value)
940  	#  endif
941  	
942  	
943  	/* This function is used in the `isfinite' macro.  */
944  	__MATH_INLINE int
945  	__NTH (__finite (double __x))
946  	{
947  	  return (__extension__
948  		  (((((union { double __d; int __i[2]; }) {__d: __x}).__i[1]
949  		     | 0x800fffffu) + 1) >> 31));
950  	}
951  	
952  	#  endif /* __USE_MISC  */
953  	
954  	/* Undefine some of the large macros which are not used anymore.  */
955  	#  undef __atan2_code
956  	#  ifdef __FAST_MATH__
957  	#   undef __expm1_code
958  	#   undef __exp_code
959  	#   undef __sincos_code
960  	#  endif /* __FAST_MATH__ */
961  	
962  	# endif /* __NO_MATH_INLINES  */
963  	
964  	
965  	/* This code is used internally in the GNU libc.  */
966  	# ifdef __LIBC_INTERNAL_MATH_INLINES
967  	__inline_mathop (__ieee754_sqrt, "fsqrt")
968  	__inline_mathcode2_ (long double, __ieee754_atan2l, __y, __x,
969  			     register long double __value;
970  			     __asm __volatile__ ("fpatan\n\t"
971  						 : "=t" (__value)
972  						 : "0" (__x), "u" (__y) : "st(1)");
973  			     return __value;)
974  	# endif
975  	
976  	#endif /* !__SSE2_MATH__ && !__x86_64__ */
977