math.h: Use GCC builtins for C99 macros where available
GCCs builtin functions are mostly type agnostic and architecture indepedent. Prefer to use them if available. * libc/include/math.h (fpclassify, isfinite, isinf, isnan, isnormal): Use matching GCC builtin functions if built with GCC 4.4 or later. (signbit): Use matching GCC builtin functions if built with GCC 4.0 or later. (isgreater, isgreaterequal, isless, islessequal, islessgreater, isunordered): Use matching GCC builtin functions if built with GCC 2.97 or later. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
		| @@ -204,35 +204,70 @@ extern int __fpclassifyd (double x); | |||||||
| extern int __signbitf (float x); | extern int __signbitf (float x); | ||||||
| extern int __signbitd (double x); | extern int __signbitd (double x); | ||||||
|  |  | ||||||
| #define fpclassify(__x) \ |  | ||||||
| 	((sizeof(__x) == sizeof(float))  ? __fpclassifyf(__x) : \ |  | ||||||
| 	__fpclassifyd(__x)) |  | ||||||
|  |  | ||||||
| #ifndef isfinite |  | ||||||
|   #define isfinite(__y) \ |  | ||||||
|           (__extension__ ({int __cy = fpclassify(__y); \ |  | ||||||
|                            __cy != FP_INFINITE && __cy != FP_NAN;})) |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| /* Note: isinf and isnan were once functions in newlib that took double | /* Note: isinf and isnan were once functions in newlib that took double | ||||||
|  *       arguments.  C99 specifies that these names are reserved for macros |  *       arguments.  C99 specifies that these names are reserved for macros | ||||||
|  *       supporting multiple floating point types.  Thus, they are |  *       supporting multiple floating point types.  Thus, they are | ||||||
|  *       now defined as macros.  Implementations of the old functions |  *       now defined as macros.  Implementations of the old functions | ||||||
|  *       taking double arguments still exist for compatibility purposes |  *       taking double arguments still exist for compatibility purposes | ||||||
|  *       (prototypes for them are in <ieeefp.h>).  */ |  *       (prototypes for them are in <ieeefp.h>).  */ | ||||||
| #ifndef isinf |  | ||||||
|   #define isinf(y) (fpclassify(y) == FP_INFINITE) | #if __GNUC_PREREQ (4, 4) | ||||||
|  |   #define fpclassify(__x) (__builtin_fpclassify (FP_NAN, FP_INFINITE, \ | ||||||
|  | 						 FP_NORMAL, FP_SUBNORMAL, \ | ||||||
|  | 						 FP_ZERO, __x)) | ||||||
|  |   #ifndef isfinite | ||||||
|  |     #define isfinite(__x)	(__builtin_isfinite (__x)) | ||||||
|  |   #endif | ||||||
|  |   #ifndef isinf | ||||||
|  |     #define isinf(__x) (__builtin_isinf_sign (__x)) | ||||||
|  |   #endif | ||||||
|  |   #ifndef isnan | ||||||
|  |     #define isnan(__x) (__builtin_isnan (__x)) | ||||||
|  |   #endif | ||||||
|  |   #define isnormal(__x) (__builtin_isnormal (__x)) | ||||||
|  | #else | ||||||
|  |   #define fpclassify(__x) \ | ||||||
|  | 	  ((sizeof(__x) == sizeof(float))  ? __fpclassifyf(__x) : \ | ||||||
|  | 	  __fpclassifyd(__x)) | ||||||
|  |   #ifndef isfinite | ||||||
|  |     #define isfinite(__y) \ | ||||||
|  | 	    (__extension__ ({int __cy = fpclassify(__y); \ | ||||||
|  | 			     __cy != FP_INFINITE && __cy != FP_NAN;})) | ||||||
|  |   #endif | ||||||
|  |   #ifndef isinf | ||||||
|  |     #define isinf(__x) (fpclassify(__x) == FP_INFINITE) | ||||||
|  |   #endif | ||||||
|  |   #ifndef isnan | ||||||
|  |     #define isnan(__x) (fpclassify(__x) == FP_NAN) | ||||||
|  |   #endif | ||||||
|  |   #define isnormal(__x) (fpclassify(__x) == FP_NORMAL) | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #ifndef isnan | #if __GNUC_PREREQ (4, 0) | ||||||
|   #define isnan(y) (fpclassify(y) == FP_NAN) |   #if defined(_HAVE_LONG_DOUBLE) | ||||||
|  |     #define signbit(__x) \ | ||||||
|  | 	    ((sizeof(__x) == sizeof(float))  ? __builtin_signbitf(__x) : \ | ||||||
|  | 	     (sizeof(__x) == sizeof(double)) ? __builtin_signbit (__x) : \ | ||||||
|  | 					       __builtin_signbitl(__x)) | ||||||
|  |   #else | ||||||
|  |     #define signbit(__x) \ | ||||||
|  | 	    ((sizeof(__x) == sizeof(float))  ? __builtin_signbitf(__x) : \ | ||||||
|  | 					       __builtin_signbit (__x)) | ||||||
|  |   #endif | ||||||
|  | #else | ||||||
|  |   #define signbit(__x) \ | ||||||
|  | 	  ((sizeof(__x) == sizeof(float))  ?  __signbitf(__x) : \ | ||||||
|  | 		  __signbitd(__x)) | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #define isnormal(y) (fpclassify(y) == FP_NORMAL) | #if __GNUC_PREREQ (2, 97) | ||||||
| #define signbit(__x) \ | #define isgreater(__x,__y)	(__builtin_isgreater (__x, __y)) | ||||||
| 	((sizeof(__x) == sizeof(float))  ?  __signbitf(__x) : \ | #define isgreaterequal(__x,__y)	(__builtin_isgreaterequal (__x, __y)) | ||||||
| 		__signbitd(__x)) | #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) \ | #define isgreater(x,y) \ | ||||||
|           (__extension__ ({__typeof__(x) __x = (x); __typeof__(y) __y = (y); \ |           (__extension__ ({__typeof__(x) __x = (x); __typeof__(y) __y = (y); \ | ||||||
|                            !isunordered(__x,__y) && (__x > __y);})) |                            !isunordered(__x,__y) && (__x > __y);})) | ||||||
| @@ -252,6 +287,7 @@ extern int __signbitd (double x); | |||||||
| #define isunordered(a,b) \ | #define isunordered(a,b) \ | ||||||
|           (__extension__ ({__typeof__(a) __a = (a); __typeof__(b) __b = (b); \ |           (__extension__ ({__typeof__(a) __a = (a); __typeof__(b) __b = (b); \ | ||||||
|                            fpclassify(__a) == FP_NAN || fpclassify(__b) == FP_NAN;})) |                            fpclassify(__a) == FP_NAN || fpclassify(__b) == FP_NAN;})) | ||||||
|  | #endif | ||||||
|  |  | ||||||
| /* Non ANSI long double precision functions.  */ | /* Non ANSI long double precision functions.  */ | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user