aboutsummaryrefslogtreecommitdiff
path: root/math/math.h
diff options
context:
space:
mode:
authorWilco Dijkstra <wdijkstr@arm.com>2017-09-28 19:20:33 +0100
committerWilco Dijkstra <wdijkstr@arm.com>2017-09-28 19:43:54 +0100
commit1e6d07234fc0edcf0e88d75cf48f0b0dbbea3f39 (patch)
tree55a43e82f97a2b808f13effeec49df332dfbc400 /math/math.h
parentb2f03cf3a4b7ae4d1db155fba2180e3f580ce805 (diff)
downloadglibc-1e6d07234fc0edcf0e88d75cf48f0b0dbbea3f39.zip
glibc-1e6d07234fc0edcf0e88d75cf48f0b0dbbea3f39.tar.gz
glibc-1e6d07234fc0edcf0e88d75cf48f0b0dbbea3f39.tar.bz2
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 'math/math.h')
-rw-r--r--math/math.h95
1 files changed, 32 insertions, 63 deletions
diff --git a/math/math.h b/math/math.h
index c6c289d..e72c12f 100644
--- a/math/math.h
+++ b/math/math.h
@@ -652,19 +652,41 @@ iszero (__T __val)
# define __NO_MATH_INLINES 1
#endif
-#if defined __USE_ISOC99 && __GNUC_PREREQ(2,97)
+#ifdef __USE_ISOC99
+# if __GNUC_PREREQ (3, 1)
/* ISO C99 defines some macros to compare number while taking care for
unordered numbers. Many FPUs provide special instructions to support
these operations. Generic support in GCC for these as builtins went
- in before 3.0.0, but not all cpus added their patterns. We define
- versions that use the builtins here, and <bits/mathinline.h> will
- undef/redefine as appropriate for the specific GCC version in use. */
-# define isgreater(x, y) __builtin_isgreater(x, y)
-# define isgreaterequal(x, y) __builtin_isgreaterequal(x, y)
-# define isless(x, y) __builtin_isless(x, y)
-# define islessequal(x, y) __builtin_islessequal(x, y)
-# define islessgreater(x, y) __builtin_islessgreater(x, y)
-# define isunordered(u, v) __builtin_isunordered(u, v)
+ in 2.97, but not all cpus added their patterns until 3.1. Therefore
+ we enable the builtins from 3.1 onwards and use a generic implementation
+ othwerwise. */
+# define isgreater(x, y) __builtin_isgreater(x, y)
+# define isgreaterequal(x, y) __builtin_isgreaterequal(x, y)
+# define isless(x, y) __builtin_isless(x, y)
+# define islessequal(x, y) __builtin_islessequal(x, y)
+# define islessgreater(x, y) __builtin_islessgreater(x, y)
+# define isunordered(x, y) __builtin_isunordered(x, y)
+# else
+# define isgreater(x, y) \
+ (__extension__ ({ __typeof__ (x) __x = (x); __typeof__ (y) __y = (y); \
+ !isunordered (__x, __y) && __x > __y; }))
+# define isgreaterequal(x, y) \
+ (__extension__ ({ __typeof__ (x) __x = (x); __typeof__ (y) __y = (y); \
+ !isunordered (__x, __y) && __x >= __y; }))
+# define isless(x, y) \
+ (__extension__ ({ __typeof__ (x) __x = (x); __typeof__ (y) __y = (y); \
+ !isunordered (__x, __y) && __x < __y; }))
+# define islessequal(x, y) \
+ (__extension__ ({ __typeof__ (x) __x = (x); __typeof__ (y) __y = (y); \
+ !isunordered (__x, __y) && __x <= __y; }))
+# define islessgreater(x, y) \
+ (__extension__ ({ __typeof__ (x) __x = (x); __typeof__ (y) __y = (y); \
+ !isunordered (__x, __y) && __x != __y; }))
+/* isunordered must always check both operands first for signaling NaNs. */
+# define isunordered(x, y) \
+ (__extension__ ({ __typeof__ (x) __u = (x); __typeof__ (y) __v = (y); \
+ __u != __v && (__u != __u || __v != __v); }))
+# endif
#endif
/* Get machine-dependent inline versions (if there are any). */
@@ -758,59 +780,6 @@ iszero (__T __val)
# endif
#endif /* __FINITE_MATH_ONLY__ > 0. */
-#ifdef __USE_ISOC99
-/* If we've still got undefined comparison macros, provide defaults. */
-
-/* Return nonzero value if X is greater than Y. */
-# ifndef isgreater
-# define isgreater(x, y) \
- (__extension__ \
- ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \
- !isunordered (__x, __y) && __x > __y; }))
-# endif
-
-/* Return nonzero value if X is greater than or equal to Y. */
-# ifndef isgreaterequal
-# define isgreaterequal(x, y) \
- (__extension__ \
- ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \
- !isunordered (__x, __y) && __x >= __y; }))
-# endif
-
-/* Return nonzero value if X is less than Y. */
-# ifndef isless
-# define isless(x, y) \
- (__extension__ \
- ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \
- !isunordered (__x, __y) && __x < __y; }))
-# endif
-
-/* Return nonzero value if X is less than or equal to Y. */
-# ifndef islessequal
-# define islessequal(x, y) \
- (__extension__ \
- ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \
- !isunordered (__x, __y) && __x <= __y; }))
-# endif
-
-/* Return nonzero value if either X is less than Y or Y is less than X. */
-# ifndef islessgreater
-# define islessgreater(x, y) \
- (__extension__ \
- ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \
- !isunordered (__x, __y) && (__x < __y || __y < __x); }))
-# endif
-
-/* Return nonzero value if arguments are unordered. */
-# ifndef isunordered
-# define isunordered(u, v) \
- (__extension__ \
- ({ __typeof__(u) __u = (u); __typeof__(v) __v = (v); \
- fpclassify (__u) == FP_NAN || fpclassify (__v) == FP_NAN; }))
-# endif
-
-#endif
-
#if __GLIBC_USE (IEC_60559_BFP_EXT)
/* An expression whose type has the widest of the evaluation formats
of X and Y (which are of floating-point types). */