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 __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 | ||||
|  *       arguments.  C99 specifies that these names are reserved for macros | ||||
|  *       supporting multiple floating point types.  Thus, they are | ||||
|  *       now defined as macros.  Implementations of the old functions | ||||
|  *       taking double arguments still exist for compatibility purposes | ||||
|  *       (prototypes for them are in <ieeefp.h>).  */ | ||||
|  | ||||
| #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(y) (fpclassify(y) == FP_INFINITE) | ||||
|     #define isinf(__x) (__builtin_isinf_sign (__x)) | ||||
|   #endif | ||||
|  | ||||
|   #ifndef isnan | ||||
|   #define isnan(y) (fpclassify(y) == FP_NAN) | ||||
|     #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 | ||||
|  | ||||
| #define isnormal(y) (fpclassify(y) == FP_NORMAL) | ||||
| #if __GNUC_PREREQ (4, 0) | ||||
|   #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 | ||||
|  | ||||
| #if __GNUC_PREREQ (2, 97) | ||||
| #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);})) | ||||
| @@ -252,6 +287,7 @@ extern int __signbitd (double x); | ||||
| #define isunordered(a,b) \ | ||||
|           (__extension__ ({__typeof__(a) __a = (a); __typeof__(b) __b = (b); \ | ||||
|                            fpclassify(__a) == FP_NAN || fpclassify(__b) == FP_NAN;})) | ||||
| #endif | ||||
|  | ||||
| /* Non ANSI long double precision functions.  */ | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user