diff options
author | Wilco Dijkstra <wdijkstr@arm.com> | 2017-09-28 19:20:33 +0100 |
---|---|---|
committer | Wilco Dijkstra <wdijkstr@arm.com> | 2017-09-28 19:43:54 +0100 |
commit | 1e6d07234fc0edcf0e88d75cf48f0b0dbbea3f39 (patch) | |
tree | 55a43e82f97a2b808f13effeec49df332dfbc400 /sysdeps | |
parent | b2f03cf3a4b7ae4d1db155fba2180e3f580ce805 (diff) | |
download | glibc-1e6d07234fc0edcf0e88d75cf48f0b0dbbea3f39.tar.gz glibc-1e6d07234fc0edcf0e88d75cf48f0b0dbbea3f39.tar.xz glibc-1e6d07234fc0edcf0e88d75cf48f0b0dbbea3f39.zip |
Simplify C99 isgreater macros
Simplify the C99 isgreater macros. Although some support was added in GCC 2.97, not all targets added support until GCC 3.1. Therefore only use the builtins in math.h from GCC 3.1 onwards, and defer to generic macros otherwise. Improve the generic isunordered macro to use compares rather than call fpclassify twice - this is not only faster but also correct for signaling NaNs. * math/math.h: Improve handling of C99 isgreater macros. * sysdeps/alpha/fpu/bits/mathinline.h: Remove isgreater macros. * sysdeps/m68k/m680x0/fpu/bits/mathinline.h: Likewise. * sysdeps/powerpc/bits/mathinline.h: Likewise. * sysdeps/sparc/fpu/bits/mathinline.h: Likewise. * sysdeps/x86/fpu/bits/mathinline.h: Likewise.
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/alpha/fpu/bits/mathinline.h | 15 | ||||
-rw-r--r-- | sysdeps/m68k/m680x0/fpu/bits/mathinline.h | 54 | ||||
-rw-r--r-- | sysdeps/powerpc/bits/mathinline.h | 25 | ||||
-rw-r--r-- | sysdeps/sparc/fpu/bits/mathinline.h | 99 | ||||
-rw-r--r-- | sysdeps/x86/fpu/bits/mathinline.h | 93 |
5 files changed, 0 insertions, 286 deletions
diff --git a/sysdeps/alpha/fpu/bits/mathinline.h b/sysdeps/alpha/fpu/bits/mathinline.h index 00c8c42a83..dad99d3f64 100644 --- a/sysdeps/alpha/fpu/bits/mathinline.h +++ b/sysdeps/alpha/fpu/bits/mathinline.h @@ -27,21 +27,6 @@ # define __MATH_INLINE __extern_inline #endif -#if defined __USE_ISOC99 && defined __GNUC__ && !__GNUC_PREREQ(3,0) -# undef isgreater -# undef isgreaterequal -# undef isless -# undef islessequal -# undef islessgreater -# undef isunordered -# define isunordered(u, v) \ - (__extension__ \ - ({ double __r, __u = (u), __v = (v); \ - __asm ("cmptun/su %1,%2,%0\n\ttrapb" \ - : "=&f" (__r) : "f" (__u), "f"(__v)); \ - __r != 0; })) -#endif /* ISO C99 */ - #if (!defined __NO_MATH_INLINES || defined __LIBC_INTERNAL_MATH_INLINES) \ && defined __OPTIMIZE__ diff --git a/sysdeps/m68k/m680x0/fpu/bits/mathinline.h b/sysdeps/m68k/m680x0/fpu/bits/mathinline.h index b92b1f83e7..07ba1454b9 100644 --- a/sysdeps/m68k/m680x0/fpu/bits/mathinline.h +++ b/sysdeps/m68k/m680x0/fpu/bits/mathinline.h @@ -29,60 +29,6 @@ #ifdef __GNUC__ #ifdef __USE_ISOC99 -/* GCC 3.1 and up have builtins that actually can be used. */ -# if !__GNUC_PREREQ (3,1) -/* ISO C99 defines some macros to perform unordered comparisons. The - m68k FPU supports this with special opcodes and we should use them. - These must not be inline functions since we have to be able to handle - all floating-point types. */ -# undef isgreater -# undef isgreaterequal -# undef isless -# undef islessequal -# undef islessgreater -# undef isunordered -# define isgreater(x, y) \ - __extension__ \ - ({ char __result; \ - __asm__ ("fcmp%.x %2,%1; fsogt %0" \ - : "=dm" (__result) : "f" (x), "f" (y)); \ - __result != 0; }) - -# define isgreaterequal(x, y) \ - __extension__ \ - ({ char __result; \ - __asm__ ("fcmp%.x %2,%1; fsoge %0" \ - : "=dm" (__result) : "f" (x), "f" (y)); \ - __result != 0; }) - -# define isless(x, y) \ - __extension__ \ - ({ char __result; \ - __asm__ ("fcmp%.x %2,%1; fsolt %0" \ - : "=dm" (__result) : "f" (x), "f" (y)); \ - __result != 0; }) - -# define islessequal(x, y) \ - __extension__ \ - ({ char __result; \ - __asm__ ("fcmp%.x %2,%1; fsole %0" \ - : "=dm" (__result) : "f" (x), "f" (y)); \ - __result != 0; }) - -# define islessgreater(x, y) \ - __extension__ \ - ({ char __result; \ - __asm__ ("fcmp%.x %2,%1; fsogl %0" \ - : "=dm" (__result) : "f" (x), "f" (y)); \ - __result != 0; }) - -# define isunordered(x, y) \ - __extension__ \ - ({ char __result; \ - __asm__ ("fcmp%.x %2,%1; fsun %0" \ - : "=dm" (__result) : "f" (x), "f" (y)); \ - __result != 0; }) -# endif /* GCC 3.1 */ /* Test for negative number. Used in the signbit() macro. */ __MATH_INLINE int diff --git a/sysdeps/powerpc/bits/mathinline.h b/sysdeps/powerpc/bits/mathinline.h index e5f0cd30f2..406465f3c5 100644 --- a/sysdeps/powerpc/bits/mathinline.h +++ b/sysdeps/powerpc/bits/mathinline.h @@ -29,31 +29,6 @@ #if defined __GNUC__ && !defined _SOFT_FLOAT && !defined __NO_FPRS__ #ifdef __USE_ISOC99 -# if !__GNUC_PREREQ (2,97) -# define __unordered_cmp(x, y) \ - (__extension__ \ - ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \ - unsigned __r; \ - __asm__("fcmpu 7,%1,%2 ; mfcr %0" : "=r" (__r) : "f" (__x), "f"(__y) \ - : "cr7"); \ - __r; })) - -# undef isgreater -# undef isgreaterequal -# undef isless -# undef islessequal -# undef islessgreater -# undef isunordered - -# define isgreater(x, y) (__unordered_cmp (x, y) >> 2 & 1) -# define isgreaterequal(x, y) ((__unordered_cmp (x, y) & 6) != 0) -# define isless(x, y) (__unordered_cmp (x, y) >> 3 & 1) -# define islessequal(x, y) ((__unordered_cmp (x, y) & 0xA) != 0) -# define islessgreater(x, y) ((__unordered_cmp (x, y) & 0xC) != 0) -# define isunordered(x, y) (__unordered_cmp (x, y) & 1) - -# endif /* __GNUC_PREREQ (2,97) */ - /* The gcc, version 2.7 or below, has problems with all this inlining code. So disable it for this version of the compiler. */ # if __GNUC_PREREQ (2, 8) diff --git a/sysdeps/sparc/fpu/bits/mathinline.h b/sysdeps/sparc/fpu/bits/mathinline.h index 60a2028f2c..6d6813687d 100644 --- a/sysdeps/sparc/fpu/bits/mathinline.h +++ b/sysdeps/sparc/fpu/bits/mathinline.h @@ -25,105 +25,6 @@ #ifdef __GNUC__ -#if defined __USE_ISOC99 && !__GNUC_PREREQ (3, 0) -# undef isgreater -# undef isgreaterequal -# undef isless -# undef islessequal -# undef islessgreater -# undef isunordered - -# if __WORDSIZE == 32 - -# ifndef __NO_LONG_DOUBLE_MATH - -# define __unordered_cmp(x, y) \ - (__extension__ \ - ({ unsigned __r; \ - if (sizeof (x) == 4 && sizeof (y) == 4) \ - { \ - float __x = (x); float __y = (y); \ - __asm__ ("fcmps %1,%2; st %%fsr, %0" : "=m" (__r) : "f" (__x), \ - "f" (__y) : "cc"); \ - } \ - else if (sizeof (x) <= 8 && sizeof (y) <= 8) \ - { \ - double __x = (x); double __y = (y); \ - __asm__ ("fcmpd\t%1,%2\n\tst\t%%fsr,%0" : "=m" (__r) : "f" (__x), \ - "f" (__y) : "cc"); \ - } \ - else \ - { \ - long double __x = (x); long double __y = (y); \ - extern int _Q_cmp (const long double a, const long double b); \ - __r = _Q_cmp (__x, __y) << 10; \ - } \ - __r; })) - -# else - -# define __unordered_cmp(x, y) \ - (__extension__ \ - ({ unsigned __r; \ - if (sizeof (x) == 4 && sizeof (y) == 4) \ - { \ - float __x = (x); float __y = (y); \ - __asm__ ("fcmps %1,%2; st %%fsr, %0" : "=m" (__r) : "f" (__x), \ - "f" (__y) : "cc"); \ - } \ - else \ - { \ - double __x = (x); double __y = (y); \ - __asm__ ("fcmpd\t%1,%2\n\tst\t%%fsr,%0" : "=m" (__r) : "f" (__x), \ - "f" (__y) : "cc"); \ - } \ - __r; })) - -# endif - -# define isgreater(x, y) ((__unordered_cmp (x, y) & (3 << 10)) == (2 << 10)) -# define isgreaterequal(x, y) ((__unordered_cmp (x, y) & (1 << 10)) == 0) -# define isless(x, y) ((__unordered_cmp (x, y) & (3 << 10)) == (1 << 10)) -# define islessequal(x, y) ((__unordered_cmp (x, y) & (2 << 10)) == 0) -# define islessgreater(x, y) (((__unordered_cmp (x, y) + (1 << 10)) & (2 << 10)) != 0) -# define isunordered(x, y) ((__unordered_cmp (x, y) & (3 << 10)) == (3 << 10)) - -# else /* sparc64 */ - -# define __unordered_v9cmp(x, y, op, qop) \ - (__extension__ \ - ({ unsigned __r; \ - if (sizeof (x) == 4 && sizeof (y) == 4) \ - { \ - float __x = (x); float __y = (y); \ - __asm__ ("fcmps\t%%fcc3,%1,%2\n\tmov" op "\t%%fcc3,1,%0" \ - : "=r" (__r) : "f" (__x), "f" (__y), "0" (0) : "cc"); \ - } \ - else if (sizeof (x) <= 8 && sizeof (y) <= 8) \ - { \ - double __x = (x); double __y = (y); \ - __asm__ ("fcmpd\t%%fcc3,%1,%2\n\tmov" op "\t%%fcc3,1,%0" \ - : "=r" (__r) : "f" (__x), "f" (__y), "0" (0) : "cc"); \ - } \ - else \ - { \ - long double __x = (x); long double __y = (y); \ - extern int _Qp_cmp (const long double *a, const long double *b); \ - __r = qop; \ - } \ - __r; })) - -# define isgreater(x, y) __unordered_v9cmp(x, y, "g", _Qp_cmp (&__x, &__y) == 2) -# define isgreaterequal(x, y) __unordered_v9cmp(x, y, "ge", (_Qp_cmp (&__x, &__y) & 1) == 0) -# define isless(x, y) __unordered_v9cmp(x, y, "l", _Qp_cmp (&__x, &__y) == 1) -# define islessequal(x, y) __unordered_v9cmp(x, y, "le", (_Qp_cmp (&__x, &__y) & 2) == 0) -# define islessgreater(x, y) __unordered_v9cmp(x, y, "lg", ((_Qp_cmp (&__x, &__y) + 1) & 2) != 0) -# define isunordered(x, y) __unordered_v9cmp(x, y, "u", _Qp_cmp (&__x, &__y) == 3) - -# endif /* sparc64 */ - -#endif /* __USE_ISOC99 */ - #if (!defined __NO_MATH_INLINES || defined __LIBC_INTERNAL_MATH_INLINES) && defined __OPTIMIZE__ # ifndef __extern_inline diff --git a/sysdeps/x86/fpu/bits/mathinline.h b/sysdeps/x86/fpu/bits/mathinline.h index bcd99bdf74..ac31dee820 100644 --- a/sysdeps/x86/fpu/bits/mathinline.h +++ b/sysdeps/x86/fpu/bits/mathinline.h @@ -26,97 +26,6 @@ # define __MATH_INLINE __extern_always_inline #endif - -#if defined __USE_ISOC99 && defined __GNUC__ && __GNUC__ >= 2 -/* GCC 2.97 and up have builtins that actually can be used. */ -# if !__GNUC_PREREQ (2,97) -/* ISO C99 defines some macros to perform unordered comparisons. The - ix87 FPU supports this with special opcodes and we should use them. - These must not be inline functions since we have to be able to handle - all floating-point types. */ -# undef isgreater -# undef isgreaterequal -# undef isless -# undef islessequal -# undef islessgreater -# undef isunordered -# ifdef __i686__ -/* For the PentiumPro and more recent processors we can provide - better code. */ -# define isgreater(x, y) \ - ({ register char __result; \ - __asm__ ("fucomip %%st(1), %%st; seta %%al" \ - : "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \ - __result; }) -# define isgreaterequal(x, y) \ - ({ register char __result; \ - __asm__ ("fucomip %%st(1), %%st; setae %%al" \ - : "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \ - __result; }) - -# define isless(x, y) \ - ({ register char __result; \ - __asm__ ("fucomip %%st(1), %%st; seta %%al" \ - : "=a" (__result) : "u" (x), "t" (y) : "cc", "st"); \ - __result; }) - -# define islessequal(x, y) \ - ({ register char __result; \ - __asm__ ("fucomip %%st(1), %%st; setae %%al" \ - : "=a" (__result) : "u" (x), "t" (y) : "cc", "st"); \ - __result; }) - -# define islessgreater(x, y) \ - ({ register char __result; \ - __asm__ ("fucomip %%st(1), %%st; setne %%al" \ - : "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \ - __result; }) - -# define isunordered(x, y) \ - ({ register char __result; \ - __asm__ ("fucomip %%st(1), %%st; setp %%al" \ - : "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \ - __result; }) -# else -/* This is the dumb, portable code for i386 and above. */ -# define isgreater(x, y) \ - ({ register char __result; \ - __asm__ ("fucompp; fnstsw; testb $0x45, %%ah; setz %%al" \ - : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \ - __result; }) - -# define isgreaterequal(x, y) \ - ({ register char __result; \ - __asm__ ("fucompp; fnstsw; testb $0x05, %%ah; setz %%al" \ - : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \ - __result; }) - -# define isless(x, y) \ - ({ register char __result; \ - __asm__ ("fucompp; fnstsw; testb $0x45, %%ah; setz %%al" \ - : "=a" (__result) : "u" (x), "t" (y) : "cc", "st", "st(1)"); \ - __result; }) - -# define islessequal(x, y) \ - ({ register char __result; \ - __asm__ ("fucompp; fnstsw; testb $0x05, %%ah; setz %%al" \ - : "=a" (__result) : "u" (x), "t" (y) : "cc", "st", "st(1)"); \ - __result; }) - -# define islessgreater(x, y) \ - ({ register char __result; \ - __asm__ ("fucompp; fnstsw; testb $0x44, %%ah; setz %%al" \ - : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \ - __result; }) - -# define isunordered(x, y) \ - ({ register char __result; \ - __asm__ ("fucompp; fnstsw; sahf; setp %%al" \ - : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \ - __result; }) -# endif /* __i686__ */ -# endif /* GCC 2.97 */ - /* The gcc, version 2.7 or below, has problems with all this inlining code. So disable it for this version of the compiler. */ # if __GNUC_PREREQ (2, 8) @@ -154,8 +63,6 @@ __NTH (__signbitl (long double __x)) } # endif -#endif - /* The gcc, version 2.7 or below, has problems with all this inlining code. So disable it for this version of the compiler. */ |