diff --git a/SingleSource/UnitTests/Float/classify-f32.h b/SingleSource/UnitTests/Float/classify-f32.h --- a/SingleSource/UnitTests/Float/classify-f32.h +++ b/SingleSource/UnitTests/Float/classify-f32.h @@ -131,9 +131,12 @@ uint32_t IX = *IPtr; float X = *(float *)IPtr; CHECK_VALUE(__builtin_isnan(X), IX); + CHECK_VALUE(!__builtin_issignaling(X), IX); CHECK_VALUE(!__builtin_isinf(X), IX); CHECK_VALUE(!__builtin_isfinite(X), IX); CHECK_VALUE(!__builtin_isnormal(X), IX); + CHECK_VALUE(!__builtin_issubnormal(X), IX); + CHECK_VALUE(!__builtin_iszero(X), IX); CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 0, IX); } for (unsigned i = 0; i < DimOf(FloatSNaNValues); i++) { @@ -141,9 +144,12 @@ uint32_t IX = *IPtr; float X = *(float *)IPtr; CHECK_VALUE(__builtin_isnan(X), IX); + CHECK_VALUE(__builtin_issignaling(X), IX); CHECK_VALUE(!__builtin_isinf(X), IX); CHECK_VALUE(!__builtin_isfinite(X), IX); CHECK_VALUE(!__builtin_isnormal(X), IX); + CHECK_VALUE(!__builtin_issubnormal(X), IX); + CHECK_VALUE(!__builtin_iszero(X), IX); CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 0, IX); } for (unsigned i = 0; i < DimOf(FloatInfValues); i++) { @@ -151,9 +157,12 @@ uint32_t IX = *IPtr; float X = *(float *)IPtr; CHECK_VALUE(!__builtin_isnan(X), IX); + CHECK_VALUE(!__builtin_issignaling(X), IX); CHECK_VALUE(__builtin_isinf(X), IX); CHECK_VALUE(!__builtin_isfinite(X), IX); CHECK_VALUE(!__builtin_isnormal(X), IX); + CHECK_VALUE(!__builtin_issubnormal(X), IX); + CHECK_VALUE(!__builtin_iszero(X), IX); CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 1, IX); } for (unsigned i = 0; i < DimOf(FloatZeroValues); i++) { @@ -161,9 +170,12 @@ uint32_t IX = *IPtr; float X = *(float *)IPtr; CHECK_VALUE(!__builtin_isnan(X), IX); + CHECK_VALUE(!__builtin_issignaling(X), IX); CHECK_VALUE(!__builtin_isinf(X), IX); CHECK_VALUE(__builtin_isfinite(X), IX); CHECK_VALUE(!__builtin_isnormal(X), IX); + CHECK_VALUE(!__builtin_issubnormal(X), IX); + CHECK_VALUE(__builtin_iszero(X), IX); CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 4, IX); } for (unsigned i = 0; i < DimOf(FloatDenormValues); i++) { @@ -171,9 +183,12 @@ uint32_t IX = *IPtr; float X = *(float *)IPtr; CHECK_VALUE(!__builtin_isnan(X), IX); + CHECK_VALUE(!__builtin_issignaling(X), IX); CHECK_VALUE(!__builtin_isinf(X), IX); CHECK_VALUE(__builtin_isfinite(X), IX); CHECK_VALUE(!__builtin_isnormal(X), IX); + CHECK_VALUE(__builtin_issubnormal(X), IX); + CHECK_VALUE(!__builtin_iszero(X), IX); CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 3, IX); } for (unsigned i = 0; i < DimOf(FloatNormalValues); i++) { @@ -181,15 +196,59 @@ uint32_t IX = *IPtr; float X = *(float *)IPtr; CHECK_VALUE(!__builtin_isnan(X), IX); + CHECK_VALUE(!__builtin_issignaling(X), IX); CHECK_VALUE(!__builtin_isinf(X), IX); CHECK_VALUE(__builtin_isfinite(X), IX); CHECK_VALUE(__builtin_isnormal(X), IX); + CHECK_VALUE(!__builtin_issubnormal(X), IX); + CHECK_VALUE(!__builtin_iszero(X), IX); CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 2, IX); } return 0; } + +#include "gen_isfpclass_funcs.h" + +void test_isfpclass_float() { + for (unsigned i = 0; i < DimOf(FloatQNaNValues); i++) { + uint32_t *IPtr = FloatQNaNValues + i; + uint32_t IX = *IPtr; + float X = *(float *)IPtr; + test_fcQNan_float(X); + } + for (unsigned i = 0; i < DimOf(FloatSNaNValues); i++) { + uint32_t *IPtr = FloatSNaNValues + i; + uint32_t IX = *IPtr; + float X = *(float *)IPtr; + test_fcSNan_float(X); + } + test_fcPosInf_float(__builtin_inff()); + test_fcNegInf_float(-__builtin_inff()); + test_fcPosZero_float(0.0F); + test_fcNegZero_float(-0.0F); + for (unsigned i = 0; i < DimOf(FloatDenormValues); i++) { + uint32_t *IPtr = FloatDenormValues + i; + uint32_t IX = *IPtr; + float X = *(float *)IPtr; + if (X < 0) + test_fcNegSubnormal_float(X); + else + test_fcPosSubnormal_float(X); + } + for (unsigned i = 0; i < DimOf(FloatNormalValues); i++) { + uint32_t *IPtr = FloatNormalValues + i; + uint32_t IX = *IPtr; + float X = *(float *)IPtr; + if (X < 0) + test_fcNegNormal_float(X); + else + test_fcPosNormal_float(X); + } +} + + #undef INT_FORMAT #undef FLOAT_FORMAT #undef VAL_FORMAT diff --git a/SingleSource/UnitTests/Float/classify-f64.h b/SingleSource/UnitTests/Float/classify-f64.h --- a/SingleSource/UnitTests/Float/classify-f64.h +++ b/SingleSource/UnitTests/Float/classify-f64.h @@ -131,9 +131,12 @@ uint64_t IX = *IPtr; double X = *(double *)IPtr; CHECK_VALUE(__builtin_isnan(X), IX); + CHECK_VALUE(!__builtin_issignaling(X), IX); CHECK_VALUE(!__builtin_isinf(X), IX); CHECK_VALUE(!__builtin_isfinite(X), IX); CHECK_VALUE(!__builtin_isnormal(X), IX); + CHECK_VALUE(!__builtin_issubnormal(X), IX); + CHECK_VALUE(!__builtin_iszero(X), IX); CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 0, IX); } for (unsigned i = 0; i < DimOf(DoubleSNaNValues); i++) { @@ -141,9 +144,12 @@ uint64_t IX = *IPtr; double X = *(double *)IPtr; CHECK_VALUE(__builtin_isnan(X), IX); + CHECK_VALUE(__builtin_issignaling(X), IX); CHECK_VALUE(!__builtin_isinf(X), IX); CHECK_VALUE(!__builtin_isfinite(X), IX); CHECK_VALUE(!__builtin_isnormal(X), IX); + CHECK_VALUE(!__builtin_issubnormal(X), IX); + CHECK_VALUE(!__builtin_iszero(X), IX); CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 0, IX); } for (unsigned i = 0; i < DimOf(DoubleInfValues); i++) { @@ -151,9 +157,12 @@ uint64_t IX = *IPtr; double X = *(double *)IPtr; CHECK_VALUE(!__builtin_isnan(X), IX); + CHECK_VALUE(!__builtin_issignaling(X), IX); CHECK_VALUE(__builtin_isinf(X), IX); CHECK_VALUE(!__builtin_isfinite(X), IX); CHECK_VALUE(!__builtin_isnormal(X), IX); + CHECK_VALUE(!__builtin_issubnormal(X), IX); + CHECK_VALUE(!__builtin_iszero(X), IX); CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 1, IX); } for (unsigned i = 0; i < DimOf(DoubleZeroValues); i++) { @@ -161,9 +170,12 @@ uint64_t IX = *IPtr; double X = *(double *)IPtr; CHECK_VALUE(!__builtin_isnan(X), IX); + CHECK_VALUE(!__builtin_issignaling(X), IX); CHECK_VALUE(!__builtin_isinf(X), IX); CHECK_VALUE(__builtin_isfinite(X), IX); CHECK_VALUE(!__builtin_isnormal(X), IX); + CHECK_VALUE(!__builtin_issubnormal(X), IX); + CHECK_VALUE(__builtin_iszero(X), IX); CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 4, IX); } for (unsigned i = 0; i < DimOf(DoubleDenormValues); i++) { @@ -171,9 +183,12 @@ uint64_t IX = *IPtr; double X = *(double *)IPtr; CHECK_VALUE(!__builtin_isnan(X), IX); + CHECK_VALUE(!__builtin_issignaling(X), IX); CHECK_VALUE(!__builtin_isinf(X), IX); CHECK_VALUE(__builtin_isfinite(X), IX); CHECK_VALUE(!__builtin_isnormal(X), IX); + CHECK_VALUE(__builtin_issubnormal(X), IX); + CHECK_VALUE(!__builtin_iszero(X), IX); CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 3, IX); } for (unsigned i = 0; i < DimOf(DoubleNormalValues); i++) { @@ -181,15 +196,58 @@ uint64_t IX = *IPtr; double X = *(double *)IPtr; CHECK_VALUE(!__builtin_isnan(X), IX); + CHECK_VALUE(!__builtin_issignaling(X), IX); CHECK_VALUE(!__builtin_isinf(X), IX); CHECK_VALUE(__builtin_isfinite(X), IX); CHECK_VALUE(__builtin_isnormal(X), IX); + CHECK_VALUE(!__builtin_issubnormal(X), IX); + CHECK_VALUE(!__builtin_iszero(X), IX); CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 2, IX); } return 0; } + +#include "gen_isfpclass_funcs.h" + +void test_isfpclass_double() { + for (unsigned i = 0; i < DimOf(DoubleQNaNValues); i++) { + uint64_t *IPtr = DoubleQNaNValues + i; + uint64_t IX = *IPtr; + double X = *(double *)IPtr; + test_fcQNan_double(X); + } + for (unsigned i = 0; i < DimOf(DoubleSNaNValues); i++) { + uint64_t *IPtr = DoubleSNaNValues + i; + uint64_t IX = *IPtr; + double X = *(double *)IPtr; + test_fcSNan_double(X); + } + test_fcPosInf_double(__builtin_inf()); + test_fcNegInf_double(-__builtin_inf()); + test_fcPosZero_double(0.0); + test_fcNegZero_double(-0.0); + for (unsigned i = 0; i < DimOf(DoubleDenormValues); i++) { + uint64_t *IPtr = DoubleDenormValues + i; + uint64_t IX = *IPtr; + double X = *(double *)IPtr; + if (X < 0) + test_fcNegSubnormal_double(X); + else + test_fcPosSubnormal_double(X); + } + for (unsigned i = 0; i < DimOf(DoubleNormalValues); i++) { + uint64_t *IPtr = DoubleNormalValues + i; + uint64_t IX = *IPtr; + double X = *(double *)IPtr; + if (X < 0) + test_fcNegNormal_double(X); + else + test_fcPosNormal_double(X); + } +} + #undef INT_FORMAT #undef FLOAT_FORMAT #undef VAL_FORMAT diff --git a/SingleSource/UnitTests/Float/classify-ldouble.h b/SingleSource/UnitTests/Float/classify-ldouble.h --- a/SingleSource/UnitTests/Float/classify-ldouble.h +++ b/SingleSource/UnitTests/Float/classify-ldouble.h @@ -20,6 +20,8 @@ #include +typedef long double ldouble; + // The type long double does not have definite representation, it may be mapped // to various float types. So instead of preparing bit patterns, rely on builtin // functions and macro definitions provided by the compiler. @@ -37,7 +39,7 @@ #define FLOAT_FORMAT "Lg" #define VAL_FORMAT FLOAT_FORMAT -#define FLOAT_TYPE long double +#define FLOAT_TYPE ldouble void prepare_ldouble_tables() { LongDoubleQNaNValues[0] = __builtin_nanl(""); @@ -71,59 +73,111 @@ for (unsigned i = 0; i < DimOf(LongDoubleQNaNValues); i++) { long double X = LongDoubleQNaNValues[i]; CHECK_VALUE(__builtin_isnan(X), X); + CHECK_VALUE(!__builtin_issignaling(X), X); CHECK_VALUE(!__builtin_isinf(X), X); CHECK_VALUE(!__builtin_isfinite(X), X); CHECK_VALUE(!__builtin_isnormal(X), X); + CHECK_VALUE(!__builtin_issubnormal(X), X); + CHECK_VALUE(!__builtin_iszero(X), X); CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 0, X); } for (unsigned i = 0; i < DimOf(LongDoubleSNaNValues); i++) { long double X = LongDoubleSNaNValues[i]; CHECK_VALUE(__builtin_isnan(X), X); + CHECK_VALUE(__builtin_issignaling(X), X); CHECK_VALUE(!__builtin_isinf(X), X); CHECK_VALUE(!__builtin_isfinite(X), X); CHECK_VALUE(!__builtin_isnormal(X), X); + CHECK_VALUE(!__builtin_issubnormal(X), X); + CHECK_VALUE(!__builtin_iszero(X), X); CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 0, X); } #ifdef __LDBL_HAS_INFINITY__ for (unsigned i = 0; i < DimOf(LongDoubleInfValues); i++) { long double X = LongDoubleInfValues[i]; CHECK_VALUE(!__builtin_isnan(X), X); + CHECK_VALUE(!__builtin_issignaling(X), X); CHECK_VALUE(__builtin_isinf(X), X); CHECK_VALUE(!__builtin_isfinite(X), X); CHECK_VALUE(!__builtin_isnormal(X), X); + CHECK_VALUE(!__builtin_issubnormal(X), X); + CHECK_VALUE(!__builtin_iszero(X), X); CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 1, X); } #endif for (unsigned i = 0; i < DimOf(LongDoubleZeroValues); i++) { long double X = LongDoubleZeroValues[i]; CHECK_VALUE(!__builtin_isnan(X), X); + CHECK_VALUE(!__builtin_issignaling(X), X); CHECK_VALUE(!__builtin_isinf(X), X); CHECK_VALUE(__builtin_isfinite(X), X); CHECK_VALUE(!__builtin_isnormal(X), X); + CHECK_VALUE(!__builtin_issubnormal(X), X); + CHECK_VALUE(__builtin_iszero(X), X); CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 4, X); } #ifdef __LDBL_HAS_DENORM__ for (unsigned i = 0; i < DimOf(LongDoubleDenormValues); i++) { long double X = LongDoubleDenormValues[i]; CHECK_VALUE(!__builtin_isnan(X), X); + CHECK_VALUE(!__builtin_issignaling(X), X); CHECK_VALUE(!__builtin_isinf(X), X); CHECK_VALUE(__builtin_isfinite(X), X); CHECK_VALUE(!__builtin_isnormal(X), X); + CHECK_VALUE(__builtin_issubnormal(X), X); + CHECK_VALUE(!__builtin_iszero(X), X); CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 3, X); } #endif for (unsigned i = 0; i < DimOf(LongDoubleNormalValues); i++) { long double X = LongDoubleNormalValues[i]; CHECK_VALUE(!__builtin_isnan(X), X); + CHECK_VALUE(!__builtin_issignaling(X), X); CHECK_VALUE(!__builtin_isinf(X), X); CHECK_VALUE(__builtin_isfinite(X), X); CHECK_VALUE(__builtin_isnormal(X), X); + CHECK_VALUE(!__builtin_issubnormal(X), X); + CHECK_VALUE(!__builtin_iszero(X), X); CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 2, X); } return 0; } + +#include "gen_isfpclass_funcs.h" + +void test_isfpclass_ldouble() { + for (unsigned i = 0; i < DimOf(LongDoubleQNaNValues); i++) { + test_fcQNan_ldouble(LongDoubleQNaNValues[i]); + } +// for (unsigned i = 0; i < DimOf(DoubleSNaNValues); i++) { +// test_fcSNan_ldouble(LongDoubleSNaNValues[i]); +// } +#ifdef __LDBL_HAS_INFINITY__ + test_fcPosInf_ldouble(__builtin_infl()); + test_fcNegInf_ldouble(-__builtin_infl()); +#endif + test_fcPosZero_ldouble(0.0L); + test_fcNegZero_ldouble(-0.0L); +#ifdef __LDBL_HAS_DENORM__ + for (unsigned i = 0; i < DimOf(LongDoubleDenormValues); i++) { + long double X = LongDoubleDenormValues[i]; + if (X < 0) + test_fcNegSubnormal_ldouble(X); + else + test_fcPosSubnormal_ldouble(X); + } +#endif + for (unsigned i = 0; i < DimOf(LongDoubleNormalValues); i++) { + long double X = LongDoubleNormalValues[i]; + if (X < 0) + test_fcNegNormal_ldouble(X); + else + test_fcPosNormal_ldouble(X); + } +} + #undef FLOAT_FORMAT #undef VAL_FORMAT #undef FLOAT_TYPE diff --git a/SingleSource/UnitTests/Float/classify.c b/SingleSource/UnitTests/Float/classify.c --- a/SingleSource/UnitTests/Float/classify.c +++ b/SingleSource/UnitTests/Float/classify.c @@ -18,9 +18,12 @@ int main() { test_float(); + test_isfpclass_float(); test_double(); + test_isfpclass_double(); prepare_ldouble_tables(); test_ldouble(); + test_isfpclass_ldouble(); return 0; } diff --git a/SingleSource/UnitTests/Float/gen_isfpclass_funcs.h b/SingleSource/UnitTests/Float/gen_isfpclass_funcs.h new file mode 100644 --- /dev/null +++ b/SingleSource/UnitTests/Float/gen_isfpclass_funcs.h @@ -0,0 +1,90 @@ +//===--- gen_isfpclass_funcs.h ------------------------------------*- C -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This header file contains definition of functions that test a value of the +// specified floating point type for each of the floating point classes. +// +//===----------------------------------------------------------------------===// + +// Requires the following macros to be defined: +// +// FLOAT_TYPE - type of the values to test. +// INT_TYPE - corresponding integer type. +// FLOAT_FORMAT - printf format specifier without % to print 'value'. +// INT_FORMAT - printf format specifier without %, like "d" or "llx", +// which should be used to print integer representaion. + +#ifndef _GEN_ISFPCLASS_FUNCS_H_ +#define _GEN_ISFPCLASS_FUNCS_H_ + +enum FPClassCheck { + fcBad = 0, + fcSNan = 0x0001, + fcQNan = 0x0002, + fcNegInf = 0x0004, + fcNegNormal = 0x0008, + fcNegSubnormal = 0x0010, + fcNegZero = 0x0020, + fcPosZero = 0x0040, + fcPosSubnormal = 0x0080, + fcPosNormal = 0x0100, + fcPosInf = 0x0200, + + fcNan = fcSNan | fcQNan, + fcInf = fcPosInf | fcNegInf, + fcNormal = fcPosNormal | fcNegNormal, + fcSubnormal = fcPosSubnormal | fcNegSubnormal, + fcZero = fcPosZero | fcNegZero, + fcPosFinite = fcPosNormal | fcPosSubnormal | fcPosZero, + fcNegFinite = fcNegNormal | fcNegSubnormal | fcNegZero, + fcFinite = fcPosFinite | fcNegFinite, + fcAllFlags = fcNan | fcInf | fcFinite +}; + +#endif + + +#define FPCLASS fcSNan +#include "test_isfpclass.h" +#undef FPCLASS + +#define FPCLASS fcQNan +#include "test_isfpclass.h" +#undef FPCLASS + +#define FPCLASS fcPosInf +#include "test_isfpclass.h" +#undef FPCLASS + +#define FPCLASS fcNegInf +#include "test_isfpclass.h" +#undef FPCLASS + +#define FPCLASS fcPosNormal +#include "test_isfpclass.h" +#undef FPCLASS + +#define FPCLASS fcNegNormal +#include "test_isfpclass.h" +#undef FPCLASS + +#define FPCLASS fcPosSubnormal +#include "test_isfpclass.h" +#undef FPCLASS + +#define FPCLASS fcNegSubnormal +#include "test_isfpclass.h" +#undef FPCLASS + +#define FPCLASS fcPosZero +#include "test_isfpclass.h" +#undef FPCLASS + +#define FPCLASS fcNegZero +#include "test_isfpclass.h" +#undef FPCLASS diff --git a/SingleSource/UnitTests/Float/test_isfpclass.h b/SingleSource/UnitTests/Float/test_isfpclass.h new file mode 100644 --- /dev/null +++ b/SingleSource/UnitTests/Float/test_isfpclass.h @@ -0,0 +1,207 @@ +//===--- test_isfpclass.h -----------------------------------------*- C -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This header file contains definition of a function that tests a value of +// the specified floating point class for various combinations of the check +// made by `__builtin_isfpclass`. The function has a name and arguments like: +// `test_fcSNan_float(float x)` +// +//===----------------------------------------------------------------------===// + + +// Requires the following macros to be defined: +// +// FLOAT_TYPE - type of the values to test. +// FPCLASS - floating point class of the tested values. + +#define CONCAT(fpclass, fptype) test_ ## fpclass ## _ ## fptype +#define TEST_FUNC(fpclass, fptype) CONCAT(fpclass, fptype) + +#ifdef INT_TYPE +#define CHECK_CLASS(cond, value) \ + do { \ + if (!(cond)) { \ + union { \ + INT_TYPE i; \ + FLOAT_TYPE f; \ + } u; \ + u.f = (value); \ + printf("Check '%s' failed for the value '%" FLOAT_FORMAT "' " \ + "(%" INT_FORMAT "), FPCLASS=0x%x\n", #cond, u.f, u.i, FPCLASS); \ + exit(-1); \ + } \ + } while(0) +#else +#define CHECK_CLASS(cond, value) \ + do { \ + if (!(cond)) { \ + printf("Check '%s' failed for the value '%" FLOAT_FORMAT "' " \ + ", FPCLASS=0x%x\n", #cond, (value), FPCLASS); \ + exit(-1); \ + } \ + } while(0) +#endif + +#define CHECK(flags, value) \ + CHECK_CLASS(!!((flags)&FPCLASS) == !!__builtin_isfpclass((flags),(value)), (value)) + +void TEST_FUNC(FPCLASS, FLOAT_TYPE)(FLOAT_TYPE x) { + CHECK(fcSNan, x); + CHECK(fcQNan, x); + CHECK(fcNan, x); + CHECK(fcPosInf, x); + CHECK(fcNegInf, x); + CHECK(fcInf, x); + CHECK(fcPosNormal, x); + CHECK(fcNegNormal, x); + CHECK(fcNormal, x); + CHECK(fcPosSubnormal, x); + CHECK(fcNegSubnormal, x); + CHECK(fcSubnormal, x); + CHECK(fcPosZero, x); + CHECK(fcNegZero, x); + CHECK(fcZero, x); + CHECK(fcPosFinite, x); + CHECK(fcNegFinite, x); + CHECK(fcFinite, x); + + CHECK(fcQNan|fcInf|fcNormal|fcSubnormal|fcZero, x); + CHECK(fcSNan|fcInf|fcNormal|fcSubnormal|fcZero, x); + CHECK(fcInf|fcNormal|fcSubnormal|fcZero, x); + CHECK(fcNan|fcNegInf|fcNormal|fcSubnormal|fcZero, x); + CHECK(fcNan|fcPosInf|fcNormal|fcSubnormal|fcZero, x); + CHECK(fcNan|fcNormal|fcSubnormal|fcZero, x); + CHECK(fcNan|fcInf|fcNegNormal|fcSubnormal|fcZero, x); + CHECK(fcNan|fcInf|fcPosNormal|fcSubnormal|fcZero, x); + CHECK(fcNan|fcInf|fcSubnormal|fcZero, x); + CHECK(fcNan|fcInf|fcNormal|fcNegSubnormal|fcZero, x); + CHECK(fcNan|fcInf|fcNormal|fcPosSubnormal|fcZero, x); + CHECK(fcNan|fcInf|fcNormal|fcZero, x); + CHECK(fcNan|fcInf|fcNormal|fcSubnormal|fcNegZero, x); + CHECK(fcNan|fcInf|fcNormal|fcSubnormal|fcPosZero, x); + CHECK(fcNan|fcInf|fcNormal|fcSubnormal, x); + CHECK(fcNan|fcInf|fcNegNormal|fcNegSubnormal|fcNegZero, x); + CHECK(fcNan|fcInf|fcPosNormal|fcPosSubnormal|fcPosZero, x); + CHECK(fcNan|fcInf, x); + + CHECK(fcSNan|fcPosInf, x); + CHECK(fcSNan|fcNegInf, x); + CHECK(fcSNan|fcInf, x); + CHECK(fcSNan|fcPosNormal, x); + CHECK(fcSNan|fcNegNormal, x); + CHECK(fcSNan|fcNormal, x); + CHECK(fcSNan|fcPosSubnormal, x); + CHECK(fcSNan|fcNegSubnormal, x); + CHECK(fcSNan|fcSubnormal, x); + CHECK(fcSNan|fcPosZero, x); + CHECK(fcSNan|fcNegZero, x); + CHECK(fcSNan|fcZero, x); + CHECK(fcSNan|fcPosNormal|fcPosSubnormal|fcPosZero, x); + CHECK(fcSNan|fcNegNormal|fcNegSubnormal|fcNegZero, x); + CHECK(fcSNan|fcNormal|fcSubnormal|fcZero, x); + CHECK(fcQNan|fcPosInf, x); + CHECK(fcQNan|fcNegInf, x); + CHECK(fcQNan|fcInf, x); + CHECK(fcQNan|fcPosNormal, x); + CHECK(fcQNan|fcNegNormal, x); + CHECK(fcQNan|fcNormal, x); + CHECK(fcQNan|fcPosSubnormal, x); + CHECK(fcQNan|fcNegSubnormal, x); + CHECK(fcQNan|fcSubnormal, x); + CHECK(fcQNan|fcPosZero, x); + CHECK(fcQNan|fcNegZero, x); + CHECK(fcQNan|fcZero, x); + CHECK(fcQNan|fcPosNormal|fcPosSubnormal|fcPosZero, x); + CHECK(fcQNan|fcNegNormal|fcNegSubnormal|fcNegZero, x); + CHECK(fcQNan|fcNormal|fcSubnormal|fcZero, x); + CHECK(fcNan|fcPosInf, x); + CHECK(fcNan|fcNegInf, x); + CHECK(fcNan|fcPosNormal, x); + CHECK(fcNan|fcNegNormal, x); + CHECK(fcNan|fcNormal, x); + CHECK(fcNan|fcPosSubnormal, x); + CHECK(fcNan|fcNegSubnormal, x); + CHECK(fcNan|fcSubnormal, x); + CHECK(fcNan|fcPosZero, x); + CHECK(fcNan|fcNegZero, x); + CHECK(fcNan|fcZero, x); + CHECK(fcNan|fcPosNormal|fcPosSubnormal|fcPosZero, x); + CHECK(fcNan|fcNegNormal|fcNegSubnormal|fcNegZero, x); + CHECK(fcPosInf|fcPosNormal, x); + CHECK(fcPosInf|fcNegNormal, x); + CHECK(fcPosInf|fcNormal, x); + CHECK(fcPosInf|fcPosSubnormal, x); + CHECK(fcPosInf|fcNegSubnormal, x); + CHECK(fcPosInf|fcSubnormal, x); + CHECK(fcPosInf|fcPosZero, x); + CHECK(fcPosInf|fcNegZero, x); + CHECK(fcPosInf|fcZero, x); + CHECK(fcPosInf|fcPosNormal|fcPosSubnormal|fcPosZero, x); + CHECK(fcPosInf|fcNegNormal|fcNegSubnormal|fcNegZero, x); + CHECK(fcPosInf|fcNormal|fcSubnormal|fcZero, x); + CHECK(fcNegInf|fcPosNormal, x); + CHECK(fcNegInf|fcNegNormal, x); + CHECK(fcNegInf|fcNormal, x); + CHECK(fcNegInf|fcPosSubnormal, x); + CHECK(fcNegInf|fcNegSubnormal, x); + CHECK(fcNegInf|fcSubnormal, x); + CHECK(fcNegInf|fcPosZero, x); + CHECK(fcNegInf|fcNegZero, x); + CHECK(fcNegInf|fcZero, x); + CHECK(fcNegInf|fcPosNormal|fcPosSubnormal|fcPosZero, x); + CHECK(fcNegInf|fcNegNormal|fcNegSubnormal|fcNegZero, x); + CHECK(fcNegInf|fcNormal|fcSubnormal|fcZero, x); + CHECK(fcInf|fcPosNormal, x); + CHECK(fcInf|fcNegNormal, x); + CHECK(fcInf|fcNormal, x); + CHECK(fcInf|fcPosSubnormal, x); + CHECK(fcInf|fcNegSubnormal, x); + CHECK(fcInf|fcSubnormal, x); + CHECK(fcInf|fcPosZero, x); + CHECK(fcInf|fcNegZero, x); + CHECK(fcInf|fcZero, x); + CHECK(fcInf|fcPosNormal|fcPosSubnormal|fcPosZero, x); + CHECK(fcInf|fcNegNormal|fcNegSubnormal|fcNegZero, x); + CHECK(fcPosNormal|fcPosSubnormal, x); + CHECK(fcPosNormal|fcNegSubnormal, x); + CHECK(fcPosNormal|fcSubnormal, x); + CHECK(fcPosNormal|fcPosZero, x); + CHECK(fcPosNormal|fcNegZero, x); + CHECK(fcPosNormal|fcZero, x); + CHECK(fcNegNormal|fcPosSubnormal, x); + CHECK(fcNegNormal|fcNegSubnormal, x); + CHECK(fcNegNormal|fcSubnormal, x); + CHECK(fcNegNormal|fcPosZero, x); + CHECK(fcNegNormal|fcNegZero, x); + CHECK(fcNegNormal|fcZero, x); + CHECK(fcNormal|fcPosSubnormal, x); + CHECK(fcNormal|fcNegSubnormal, x); + CHECK(fcNormal|fcSubnormal, x); + CHECK(fcNormal|fcPosZero, x); + CHECK(fcNormal|fcNegZero, x); + CHECK(fcNormal|fcZero, x); + CHECK(fcPosSubnormal|fcPosZero, x); + CHECK(fcPosSubnormal|fcNegZero, x); + CHECK(fcPosSubnormal|fcZero, x); + CHECK(fcNegNormal|fcSubnormal|fcNegZero, x); + CHECK(fcNegSubnormal|fcPosZero, x); + CHECK(fcNegSubnormal|fcNegZero, x); + CHECK(fcNegSubnormal|fcZero, x); + CHECK(fcPosNormal|fcSubnormal|fcPosZero, x); + CHECK(fcSubnormal|fcPosZero, x); + CHECK(fcSubnormal|fcNegZero, x); + CHECK(fcSubnormal|fcZero, x); + CHECK(fcNegNormal|fcNegSubnormal|fcZero, x); + CHECK(fcPosNormal|fcPosSubnormal|fcZero, x); + +} + +#undef CHECK +#undef CHECK_CLASS +#undef TEST_FUNC +#undef CONCAT