Commit 3bf5906b by Kaveh R. Ghazi Committed by Kaveh Ghazi

builtin-types.def (BT_FN_INT_INT_INT_INT_INT_INT_VAR): New.

	* builtin-types.def (BT_FN_INT_INT_INT_INT_INT_INT_VAR): New.
	* builtins.c (fold_builtin_fpclassify): New.
	(fold_builtin_varargs): Handle BUILT_IN_FPCLASSIFY.
	* builtins.def (BUILT_IN_FPCLASSIFY): New.
	* c-common.c (handle_type_generic_attribute): Adjust to accept
	fixed arguments before an elipsis.
	(check_builtin_function_arguments): Handle BUILT_IN_FPCLASSIFY.
	* doc/extend.texi: Document __builtin_fpclassify.

testsuite:
	* gcc.dg/builtins-error.c: Test __builtin_fpclassify.  Also
	add tests for all previous type-generic builtins.
	* gcc.dg/pr28796-2.c: Add -DUNSAFE flag.
	* gcc.dg/tg-tests.h: Test __builtin_fpclassify.

From-SVN: r135789
parent 2aa5c17c
2008-05-23 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* builtin-types.def (BT_FN_INT_INT_INT_INT_INT_INT_VAR): New.
* builtins.c (fold_builtin_fpclassify): New.
(fold_builtin_varargs): Handle BUILT_IN_FPCLASSIFY.
* builtins.def (BUILT_IN_FPCLASSIFY): New.
* c-common.c (handle_type_generic_attribute): Adjust to accept
fixed arguments before an elipsis.
(check_builtin_function_arguments): Handle BUILT_IN_FPCLASSIFY.
* doc/extend.texi: Document __builtin_fpclassify.
2008-05-22 Aldy Hernandez <aldyh@redhat.com> 2008-05-22 Aldy Hernandez <aldyh@redhat.com>
* omp-low.c (gate_expand_omp_ssa): Remove. * omp-low.c (gate_expand_omp_ssa): Remove.
......
...@@ -449,6 +449,9 @@ DEF_FUNCTION_TYPE_VAR_5 (BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VAR, ...@@ -449,6 +449,9 @@ DEF_FUNCTION_TYPE_VAR_5 (BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VAR,
BT_INT, BT_STRING, BT_SIZE, BT_INT, BT_SIZE, BT_INT, BT_STRING, BT_SIZE, BT_INT, BT_SIZE,
BT_CONST_STRING) BT_CONST_STRING)
DEF_FUNCTION_TYPE_VAR_5 (BT_FN_INT_INT_INT_INT_INT_INT_VAR,
BT_INT, BT_INT, BT_INT, BT_INT, BT_INT, BT_INT)
DEF_POINTER_TYPE (BT_PTR_FN_VOID_VAR, BT_FN_VOID_VAR) DEF_POINTER_TYPE (BT_PTR_FN_VOID_VAR, BT_FN_VOID_VAR)
DEF_FUNCTION_TYPE_3 (BT_FN_PTR_PTR_FN_VOID_VAR_PTR_SIZE, DEF_FUNCTION_TYPE_3 (BT_FN_PTR_PTR_FN_VOID_VAR_PTR_SIZE,
BT_PTR, BT_PTR_FN_VOID_VAR, BT_PTR, BT_SIZE) BT_PTR, BT_PTR_FN_VOID_VAR, BT_PTR, BT_SIZE)
...@@ -9744,6 +9744,70 @@ fold_builtin_classify (tree fndecl, tree arg, int builtin_index) ...@@ -9744,6 +9744,70 @@ fold_builtin_classify (tree fndecl, tree arg, int builtin_index)
} }
} }
/* Fold a call to __builtin_fpclassify(int, int, int, int, int, ...).
This builtin will generate code to return the appropriate floating
point classification depending on the value of the floating point
number passed in. The possible return values must be supplied as
int arguments to the call in the following order: FP_NAN, FP_INF,
FP_NORMAL, FP_SUBNORMAL and FP_ZERO. The ellipses is for exactly
one floating point argument which is "type generic". */
static tree
fold_builtin_fpclassify (tree exp)
{
tree fp_nan, fp_inf, fp_normal, fp_subnormal, fp_zero, arg, type, res, tmp;
enum machine_mode mode;
REAL_VALUE_TYPE r;
char buf[128];
/* Verify the required arguments in the original call. */
if (!validate_arglist (exp, INTEGER_TYPE, INTEGER_TYPE,
INTEGER_TYPE, INTEGER_TYPE,
INTEGER_TYPE, REAL_TYPE, VOID_TYPE))
return NULL_TREE;
fp_nan = CALL_EXPR_ARG (exp, 0);
fp_inf = CALL_EXPR_ARG (exp, 1);
fp_normal = CALL_EXPR_ARG (exp, 2);
fp_subnormal = CALL_EXPR_ARG (exp, 3);
fp_zero = CALL_EXPR_ARG (exp, 4);
arg = CALL_EXPR_ARG (exp, 5);
type = TREE_TYPE (arg);
mode = TYPE_MODE (type);
arg = builtin_save_expr (fold_build1 (ABS_EXPR, type, arg));
/* fpclassify(x) ->
isnan(x) ? FP_NAN :
(fabs(x) == Inf ? FP_INF :
(fabs(x) >= DBL_MIN ? FP_NORMAL :
(x == 0 ? FP_ZERO : FP_SUBNORMAL))). */
tmp = fold_build2 (EQ_EXPR, integer_type_node, arg,
build_real (type, dconst0));
res = fold_build3 (COND_EXPR, integer_type_node, tmp, fp_zero, fp_subnormal);
sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
real_from_string (&r, buf);
tmp = fold_build2 (GE_EXPR, integer_type_node, arg, build_real (type, r));
res = fold_build3 (COND_EXPR, integer_type_node, tmp, fp_normal, res);
if (HONOR_INFINITIES (mode))
{
real_inf (&r);
tmp = fold_build2 (EQ_EXPR, integer_type_node, arg,
build_real (type, r));
res = fold_build3 (COND_EXPR, integer_type_node, tmp, fp_inf, res);
}
if (HONOR_NANS (mode))
{
tmp = fold_build2 (ORDERED_EXPR, integer_type_node, arg, arg);
res = fold_build3 (COND_EXPR, integer_type_node, tmp, res, fp_nan);
}
return res;
}
/* Fold a call to an unordered comparison function such as /* Fold a call to an unordered comparison function such as
__builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
being called and ARG0 and ARG1 are the arguments for the call. being called and ARG0 and ARG1 are the arguments for the call.
...@@ -10528,6 +10592,11 @@ fold_builtin_varargs (tree fndecl, tree exp, bool ignore ATTRIBUTE_UNUSED) ...@@ -10528,6 +10592,11 @@ fold_builtin_varargs (tree fndecl, tree exp, bool ignore ATTRIBUTE_UNUSED)
case BUILT_IN_SNPRINTF_CHK: case BUILT_IN_SNPRINTF_CHK:
case BUILT_IN_VSNPRINTF_CHK: case BUILT_IN_VSNPRINTF_CHK:
ret = fold_builtin_snprintf_chk (exp, NULL_TREE, fcode); ret = fold_builtin_snprintf_chk (exp, NULL_TREE, fcode);
break;
case BUILT_IN_FPCLASSIFY:
ret = fold_builtin_fpclassify (exp);
break;
default: default:
break; break;
......
...@@ -654,6 +654,7 @@ DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITEL, "finitel", BT_FN_INT_LONGDOUBLE, ATTR_ ...@@ -654,6 +654,7 @@ DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITEL, "finitel", BT_FN_INT_LONGDOUBLE, ATTR_
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED32, "finited32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LIST) DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED32, "finited32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED64, "finited64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LIST) DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED64, "finited64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED128, "finited128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LIST) DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED128, "finited128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LIST)
DEF_GCC_BUILTIN (BUILT_IN_FPCLASSIFY, "fpclassify", BT_FN_INT_INT_INT_INT_INT_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC)
DEF_GCC_BUILTIN (BUILT_IN_ISFINITE, "isfinite", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC) DEF_GCC_BUILTIN (BUILT_IN_ISFINITE, "isfinite", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC)
DEF_GCC_BUILTIN (BUILT_IN_ISINF_SIGN, "isinf_sign", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC) DEF_GCC_BUILTIN (BUILT_IN_ISINF_SIGN, "isinf_sign", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC)
DEF_C99_C90RES_BUILTIN (BUILT_IN_ISINF, "isinf", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC) DEF_C99_C90RES_BUILTIN (BUILT_IN_ISINF, "isinf", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC)
......
...@@ -6528,8 +6528,17 @@ handle_type_generic_attribute (tree *node, tree ARG_UNUSED (name), ...@@ -6528,8 +6528,17 @@ handle_type_generic_attribute (tree *node, tree ARG_UNUSED (name),
tree ARG_UNUSED (args), int ARG_UNUSED (flags), tree ARG_UNUSED (args), int ARG_UNUSED (flags),
bool * ARG_UNUSED (no_add_attrs)) bool * ARG_UNUSED (no_add_attrs))
{ {
/* Ensure we have a function type, with no arguments. */ tree params;
gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE && ! TYPE_ARG_TYPES (*node));
/* Ensure we have a function type. */
gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);
params = TYPE_ARG_TYPES (*node);
while (params && ! VOID_TYPE_P (TREE_VALUE (params)))
params = TREE_CHAIN (params);
/* Ensure we have a variadic function. */
gcc_assert (!params);
return NULL_TREE; return NULL_TREE;
} }
...@@ -6712,6 +6721,29 @@ check_builtin_function_arguments (tree fndecl, int nargs, tree *args) ...@@ -6712,6 +6721,29 @@ check_builtin_function_arguments (tree fndecl, int nargs, tree *args)
} }
return false; return false;
case BUILT_IN_FPCLASSIFY:
if (validate_nargs (fndecl, nargs, 6))
{
unsigned i;
for (i=0; i<5; i++)
if (TREE_CODE (args[i]) != INTEGER_CST)
{
error ("non-const integer argument %u in call to function %qE",
i+1, fndecl);
return false;
}
if (TREE_CODE (TREE_TYPE (args[5])) != REAL_TYPE)
{
error ("non-floating-point argument in call to function %qE",
fndecl);
return false;
}
return true;
}
return false;
default: default:
return true; return true;
} }
......
...@@ -5764,6 +5764,7 @@ should be called and the @var{flag} argument passed to it. ...@@ -5764,6 +5764,7 @@ should be called and the @var{flag} argument passed to it.
@node Other Builtins @node Other Builtins
@section Other built-in functions provided by GCC @section Other built-in functions provided by GCC
@cindex built-in functions @cindex built-in functions
@findex __builtin_fpclassify
@findex __builtin_isfinite @findex __builtin_isfinite
@findex __builtin_isnormal @findex __builtin_isnormal
@findex __builtin_isgreater @findex __builtin_isgreater
...@@ -6295,10 +6296,10 @@ the same names as the standard macros ( @code{isgreater}, ...@@ -6295,10 +6296,10 @@ the same names as the standard macros ( @code{isgreater},
@code{islessgreater}, and @code{isunordered}) , with @code{__builtin_} @code{islessgreater}, and @code{isunordered}) , with @code{__builtin_}
prefixed. We intend for a library implementor to be able to simply prefixed. We intend for a library implementor to be able to simply
@code{#define} each standard macro to its built-in equivalent. @code{#define} each standard macro to its built-in equivalent.
In the same fashion, GCC provides @code{isfinite}, @code{isinf_sign} In the same fashion, GCC provides @code{fpclassify}, @code{isfinite},
and @code{isnormal} built-ins used with @code{__builtin_} prefixed. @code{isinf_sign} and @code{isnormal} built-ins used with
The @code{isinf} and @code{isnan} builtins appear both with and @code{__builtin_} prefixed. The @code{isinf} and @code{isnan}
without the @code{__builtin_} prefix. builtins appear both with and without the @code{__builtin_} prefix.
@deftypefn {Built-in Function} int __builtin_types_compatible_p (@var{type1}, @var{type2}) @deftypefn {Built-in Function} int __builtin_types_compatible_p (@var{type1}, @var{type2})
...@@ -6555,6 +6556,17 @@ Similar to @code{__builtin_huge_val}, except the return ...@@ -6555,6 +6556,17 @@ Similar to @code{__builtin_huge_val}, except the return
type is @code{long double}. type is @code{long double}.
@end deftypefn @end deftypefn
@deftypefn {Built-in Function} int __builtin_fpclassify (int, int, int, int, int, ...)
This built-in implements the C99 fpclassify functionality. The first
five int arguments should be the target library's notion of the
possible FP classes and are used for return values. They must be
constant values and they must appear in this order: @code{FP_NAN},
@code{FP_INF}, @code{FP_NORMAL}, @code{FP_SUBNORMAL} and
@code{FP_ZERO}. The ellipsis is for exactly one floating point value
to classify. GCC treats the last argument as type-generic, which
means it does not do default promotion from float to double.
@end deftypefn
@deftypefn {Built-in Function} double __builtin_inf (void) @deftypefn {Built-in Function} double __builtin_inf (void)
Similar to @code{__builtin_huge_val}, except a warning is generated Similar to @code{__builtin_huge_val}, except a warning is generated
if the target floating-point format does not support infinities. if the target floating-point format does not support infinities.
......
2008-05-23 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* gcc.dg/builtins-error.c: Test __builtin_fpclassify. Also
add tests for all previous type-generic builtins.
* gcc.dg/pr28796-2.c: Add -DUNSAFE flag.
* gcc.dg/tg-tests.h: Test __builtin_fpclassify.
2008-05-22 Thomas Koenig <tkoenig@gcc.gnu.org> 2008-05-22 Thomas Koenig <tkoenig@gcc.gnu.org>
PR libgfortran/36302 PR libgfortran/36302
......
...@@ -4,20 +4,62 @@ struct X { int x; }; ...@@ -4,20 +4,62 @@ struct X { int x; };
int test1(struct X x) int test1(struct X x)
{ {
return __builtin_isnormal(x); /* { dg-error "non-floating-point argument" } */ if (x.x == 1) return __builtin_fpclassify(1,2,3,4,5,x); /* { dg-error "non-floating-point argument" } */
if (x.x == 2) return __builtin_isfinite(x); /* { dg-error "non-floating-point argument" } */
if (x.x == 3) return __builtin_isinf_sign(x); /* { dg-error "non-floating-point argument" } */
if (x.x == 4) return __builtin_isinf(x); /* { dg-error "non-floating-point argument" } */
if (x.x == 5) return __builtin_isnan(x); /* { dg-error "non-floating-point argument" } */
if (x.x == 6) return __builtin_isnormal(x); /* { dg-error "non-floating-point argument" } */
if (x.x == 7) return __builtin_isgreater(x, x); /* { dg-error "non-floating-point arguments" } */
if (x.x == 8) return __builtin_isgreaterequal(x, x); /* { dg-error "non-floating-point arguments" } */
if (x.x == 9) return __builtin_isless(x, x); /* { dg-error "non-floating-point arguments" } */
if (x.x == 10) return __builtin_islessequal(x, x); /* { dg-error "non-floating-point arguments" } */
if (x.x == 11) return __builtin_islessgreater(x, x); /* { dg-error "non-floating-point arguments" } */
if (x.x == 12) return __builtin_isunordered(x, x); /* { dg-error "non-floating-point arguments" } */
return 0;
} }
int test2(double x) int test2(double x)
{ {
return __builtin_isgreater(x); /* { dg-error "not enough arguments" } */ if (x == 1) return __builtin_fpclassify(1,2,3,4,5); /* { dg-error "not enough arguments" } */
if (x == 2) return __builtin_isfinite(); /* { dg-error "not enough arguments" } */
if (x == 3) return __builtin_isinf_sign(); /* { dg-error "not enough arguments" } */
if (x == 4) return __builtin_isinf(); /* { dg-error "not enough arguments" } */
if (x == 5) return __builtin_isnan(); /* { dg-error "not enough arguments" } */
if (x == 6) return __builtin_isnormal(); /* { dg-error "not enough arguments" } */
if (x == 7) return __builtin_isgreater(x); /* { dg-error "not enough arguments" } */
if (x == 8) return __builtin_isgreaterequal(x); /* { dg-error "not enough arguments" } */
if (x == 9) return __builtin_isless(x); /* { dg-error "not enough arguments" } */
if (x == 10) return __builtin_islessequal(x); /* { dg-error "not enough arguments" } */
if (x == 11) return __builtin_islessgreater(x); /* { dg-error "not enough arguments" } */
if (x == 12) return __builtin_isunordered(x); /* { dg-error "not enough arguments" } */
return 0;
} }
int test3(double x) int test3(double x)
{ {
return __builtin_isinf(x, x); /* { dg-error "too many arguments" } */ if (x == 1) return __builtin_fpclassify(1,2,3,4,5,x,x); /* { dg-error "too many arguments" } */
if (x == 2) return __builtin_isfinite(x, x); /* { dg-error "too many arguments" } */
if (x == 3) return __builtin_isinf_sign(x, x); /* { dg-error "too many arguments" } */
if (x == 4) return __builtin_isinf(x, x); /* { dg-error "too many arguments" } */
if (x == 5) return __builtin_isnan(x, x); /* { dg-error "too many arguments" } */
if (x == 6) return __builtin_isnormal(x, x); /* { dg-error "too many arguments" } */
if (x == 7) return __builtin_isgreater(x, x, x); /* { dg-error "too many arguments" } */
if (x == 8) return __builtin_isgreaterequal(x, x, x); /* { dg-error "too many arguments" } */
if (x == 9) return __builtin_isless(x, x, x); /* { dg-error "too many arguments" } */
if (x == 10) return __builtin_islessequal(x, x, x); /* { dg-error "too many arguments" } */
if (x == 11) return __builtin_islessgreater(x, x, x); /* { dg-error "too many arguments" } */
if (x == 12) return __builtin_isunordered(x, x, x); /* { dg-error "too many arguments" } */
return 0;
} }
int test4(double x) int test4(int i, double x)
{ {
return __builtin_isinf_sign(x, x); /* { dg-error "too many arguments" } */ if (x == 1) return __builtin_fpclassify(i,2,3,4,5,x); /* { dg-error "non-const integer argument" } */
if (x == 2) return __builtin_fpclassify(1,i,3,4,5,x); /* { dg-error "non-const integer argument" } */
if (x == 3) return __builtin_fpclassify(1,2,i,4,5,x); /* { dg-error "non-const integer argument" } */
if (x == 4) return __builtin_fpclassify(1,2,3,i,5,x); /* { dg-error "non-const integer argument" } */
if (x == 5) return __builtin_fpclassify(1,2,3,4,i,x); /* { dg-error "non-const integer argument" } */
return 0;
} }
/* { dg-do run } */ /* { dg-do run } */
/* { dg-options "-O2 -funsafe-math-optimizations -fno-finite-math-only" } */ /* { dg-options "-O2 -funsafe-math-optimizations -fno-finite-math-only -DUNSAFE" } */
/* { dg-options "-mieee -O2 -funsafe-math-optimizations -fno-finite-math-only" { target alpha*-*-* } } */ /* { dg-options "-mieee -O2 -funsafe-math-optimizations -fno-finite-math-only -DUNSAFE" { target alpha*-*-* } } */
#include "tg-tests.h" #include "tg-tests.h"
......
/* Test various type-generic builtins by calling "main_tests()". */ /* Test various type-generic builtins by calling "main_tests()". */
#define FP_NAN 1
#define FP_INF 2
#define FP_NORMAL 3
#define FP_SUBNORMAL 4
#define FP_ZERO 5
#define fpclassify(X) __builtin_fpclassify(FP_NAN, FP_INF, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, (X))
void __attribute__ ((__noinline__)) void __attribute__ ((__noinline__))
foo_1 (float f, double d, long double ld, foo_1 (float f, double d, long double ld,
int res_unord, int res_isnan, int res_isinf, int res_unord, int res_isnan, int res_isinf,
int res_isinf_sign, int res_isfin, int res_isnorm) int res_isinf_sign, int res_isfin, int res_isnorm,
int classification)
{ {
if (__builtin_isunordered (f, 0) != res_unord) if (__builtin_isunordered (f, 0) != res_unord)
__builtin_abort (); __builtin_abort ();
...@@ -71,16 +79,30 @@ foo_1 (float f, double d, long double ld, ...@@ -71,16 +79,30 @@ foo_1 (float f, double d, long double ld,
__builtin_abort (); __builtin_abort ();
if (__builtin_finitel (ld) != res_isfin) if (__builtin_finitel (ld) != res_isfin)
__builtin_abort (); __builtin_abort ();
/* Subnormals can abruptly underflow to zero in unsafe math
mode, so bypass testing these numbers if necessary. */
#ifdef UNSAFE
if (classification != FP_SUBNORMAL)
#endif
{
if (fpclassify(f) != classification)
__builtin_abort ();
if (fpclassify(d) != classification)
__builtin_abort ();
if (fpclassify(ld) != classification)
__builtin_abort ();
}
} }
void __attribute__ ((__noinline__)) void __attribute__ ((__noinline__))
foo (float f, double d, long double ld, foo (float f, double d, long double ld,
int res_unord, int res_isnan, int res_isinf, int res_unord, int res_isnan, int res_isinf,
int res_isfin, int res_isnorm) int res_isfin, int res_isnorm, int classification)
{ {
foo_1 (f, d, ld, res_unord, res_isnan, res_isinf, res_isinf, res_isfin, res_isnorm); foo_1 (f, d, ld, res_unord, res_isnan, res_isinf, res_isinf, res_isfin, res_isnorm, classification);
/* Try all the values negated as well. */ /* Try all the values negated as well. */
foo_1 (-f, -d, -ld, res_unord, res_isnan, res_isinf, -res_isinf, res_isfin, res_isnorm); foo_1 (-f, -d, -ld, res_unord, res_isnan, res_isinf, -res_isinf, res_isfin, res_isnorm, classification);
} }
int __attribute__ ((__noinline__)) int __attribute__ ((__noinline__))
...@@ -92,35 +114,35 @@ main_tests (void) ...@@ -92,35 +114,35 @@ main_tests (void)
/* Test NaN. */ /* Test NaN. */
f = __builtin_nanf(""); d = __builtin_nan(""); ld = __builtin_nanl(""); f = __builtin_nanf(""); d = __builtin_nan(""); ld = __builtin_nanl("");
foo(f, d, ld, /*unord=*/ 1, /*isnan=*/ 1, /*isinf=*/ 0, /*isfin=*/ 0, /*isnorm=*/ 0); foo(f, d, ld, /*unord=*/ 1, /*isnan=*/ 1, /*isinf=*/ 0, /*isfin=*/ 0, /*isnorm=*/ 0, FP_NAN);
/* Test infinity. */ /* Test infinity. */
f = __builtin_inff(); d = __builtin_inf(); ld = __builtin_infl(); f = __builtin_inff(); d = __builtin_inf(); ld = __builtin_infl();
foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 1, /*isfin=*/ 0, /*isnorm=*/ 0); foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 1, /*isfin=*/ 0, /*isnorm=*/ 0, FP_INF);
/* Test zero. */ /* Test zero. */
f = 0; d = 0; ld = 0; f = 0; d = 0; ld = 0;
foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 0, /*isfin=*/ 1, /*isnorm=*/ 0); foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 0, /*isfin=*/ 1, /*isnorm=*/ 0, FP_ZERO);
/* Test one. */ /* Test one. */
f = 1; d = 1; ld = 1; f = 1; d = 1; ld = 1;
foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 0, /*isfin=*/ 1, /*isnorm=*/ 1); foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 0, /*isfin=*/ 1, /*isnorm=*/ 1, FP_NORMAL);
/* Test minimum values. */ /* Test minimum values. */
f = __FLT_MIN__; d = __DBL_MIN__; ld = __LDBL_MIN__; f = __FLT_MIN__; d = __DBL_MIN__; ld = __LDBL_MIN__;
foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 0, /*isfin=*/ 1, /*isnorm=*/ 1); foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 0, /*isfin=*/ 1, /*isnorm=*/ 1, FP_NORMAL);
/* Test subnormal values. */ /* Test subnormal values. */
f = __FLT_MIN__/2; d = __DBL_MIN__/2; ld = __LDBL_MIN__/2; f = __FLT_MIN__/2; d = __DBL_MIN__/2; ld = __LDBL_MIN__/2;
foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 0, /*isfin=*/ 1, /*isnorm=*/ 0); foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 0, /*isfin=*/ 1, /*isnorm=*/ 0, FP_SUBNORMAL);
/* Test maximum values. */ /* Test maximum values. */
f = __FLT_MAX__; d = __DBL_MAX__; ld = __LDBL_MAX__; f = __FLT_MAX__; d = __DBL_MAX__; ld = __LDBL_MAX__;
foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 0, /*isfin=*/ 1, /*isnorm=*/ 1); foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 0, /*isfin=*/ 1, /*isnorm=*/ 1, FP_NORMAL);
/* Test overflow values. */ /* Test overflow values. */
f = __FLT_MAX__*2; d = __DBL_MAX__*2; ld = __LDBL_MAX__*2; f = __FLT_MAX__*2; d = __DBL_MAX__*2; ld = __LDBL_MAX__*2;
foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 1, /*isfin=*/ 0, /*isnorm=*/ 0); foo(f, d, ld, /*unord=*/ 0, /*isnan=*/ 0, /*isinf=*/ 1, /*isfin=*/ 0, /*isnorm=*/ 0, FP_INF);
return 0; return 0;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment