From 5f7b8f457f5ec9c93664e3e78efe8c2585efc34b Mon Sep 17 00:00:00 2001 From: "Paul E. Murphy" Date: Fri, 27 May 2016 09:53:51 -0500 Subject: Begin refactor of libm-test.inc Attempt to creatively redefine the macros to choose tests based on the format being tested, not the type. Note, TS 18661 does not define any printf modifiers, so we need to be a little more verbose about constructing strings to output. --- math/libm-test.inc | 209 +++++++++++++++++++++++++++++----------------------- math/test-double.h | 4 + math/test-float.h | 4 + math/test-ldouble.h | 4 + 4 files changed, 127 insertions(+), 94 deletions(-) (limited to 'math') diff --git a/math/libm-test.inc b/math/libm-test.inc index 84104b4..6dddf7c 100644 --- a/math/libm-test.inc +++ b/math/libm-test.inc @@ -34,7 +34,13 @@ the specifier, not the percent and width arguments, e.g. "f". PRINTF_XEXPR Like PRINTF_EXPR, but print in hexadecimal format. - PRINTF_NEXPR Like PRINTF_EXPR, but print nice. */ + PRINTF_NEXPR Like PRINTF_EXPR, but print nice. + PREFIX A macro which defines the prefix for common macros for the + type (i.e LDBL, DBL, or FLT). + LIT A function which appends the correct suffix to a literal. + TYPE_STR A macro which defines a stringitized name of the type. + FTOSTR This macro defines a function similar in type to snprintf + which converts a FLOAT to a string. */ /* This testsuite has currently tests for: acos, acosh, asin, asinh, atan, atan2, atanh, @@ -183,31 +189,74 @@ struct ulp_data #define NON_FINITE 0x40000 #define TEST_SNAN 0x80000 +#define __CONCATX(a,b) __CONCAT(a,b) + +#define TYPE_MIN __CONCATX (PREFIX, _MIN) +#define TYPE_TRUE_MIN __CONCATX (PREFIX, _TRUE_MIN) +#define TYPE_MAX __CONCATX (PREFIX, _MAX) +#define MIN_EXP __CONCATX (PREFIX, _MIN_EXP) +#define MAX_EXP __CONCATX (PREFIX, _MAX_EXP) +#define MANT_DIG __CONCATX (PREFIX, _MANT_DIG) + +/* Maximum character buffer to store a stringitized FLOAT value. */ +#define FSTR_MAX (128) + +#if TEST_INLINE +# define QTYPE_STR "i" TYPE_STR +#else +# define QTYPE_STR TYPE_STR +#endif + +/* Format specific test macros. */ +#define TEST_COND_binary32 (MANT_DIG == 24 \ + && MIN_EXP == -125 \ + && MAX_EXP == 128) + +#define TEST_COND_binary64 (MANT_DIG == 53 \ + && MIN_EXP == -1021 \ + && MAX_EXP == 1024) + +#define TEST_COND_binary128 (MANT_DIG == 113 \ + && MIN_EXP == -16381 \ + && MAX_EXP == 16384) + +#define TEST_COND_ibm128 (MANT_DIG == 106) + +#define TEST_COND_intel96 (MANT_DIG == 64 \ + && MIN_EXP == -16381 \ + && MAX_EXP == 16384) + +#define TEST_COND_m68k96 (MANT_DIG == 64 \ + && MIN_EXP == -16382 \ + && MAX_EXP == 16384) + /* Values underflowing only for float. */ -#ifdef TEST_FLOAT +#if TEST_COND_binary32 # define UNDERFLOW_EXCEPTION_FLOAT UNDERFLOW_EXCEPTION # define UNDERFLOW_EXCEPTION_OK_FLOAT UNDERFLOW_EXCEPTION_OK #else # define UNDERFLOW_EXCEPTION_FLOAT 0 # define UNDERFLOW_EXCEPTION_OK_FLOAT 0 #endif + /* Values underflowing only for double or types with a larger least positive normal value. */ -#if defined TEST_FLOAT || defined TEST_DOUBLE \ - || (defined TEST_LDOUBLE && LDBL_MIN_EXP >= DBL_MIN_EXP) +#if TEST_COND_binary32 || TEST_COND_binary64 || TEST_COND_ibm128 # define UNDERFLOW_EXCEPTION_DOUBLE UNDERFLOW_EXCEPTION # define UNDERFLOW_EXCEPTION_OK_DOUBLE UNDERFLOW_EXCEPTION_OK #else # define UNDERFLOW_EXCEPTION_DOUBLE 0 # define UNDERFLOW_EXCEPTION_OK_DOUBLE 0 #endif + /* Values underflowing only for IBM long double or types with a larger least positive normal value. */ -#if defined TEST_FLOAT || (defined TEST_LDOUBLE && LDBL_MIN_EXP > DBL_MIN_EXP) +#if TEST_COND_binary32 || TEST_COND_ibm128 # define UNDERFLOW_EXCEPTION_LDOUBLE_IBM UNDERFLOW_EXCEPTION #else # define UNDERFLOW_EXCEPTION_LDOUBLE_IBM 0 #endif + /* Values underflowing on architectures detecting tininess before rounding, but not on those detecting tininess after rounding. */ #define UNDERFLOW_EXCEPTION_BEFORE_ROUNDING (TININESS_AFTER_ROUNDING \ @@ -227,36 +276,13 @@ struct ulp_data #endif /* Conditions used by tests generated by gen-auto-libm-tests.c. */ -#ifdef TEST_FLOAT -# define TEST_COND_flt_32 1 -#else -# define TEST_COND_flt_32 0 -#endif -#if defined TEST_DOUBLE || (defined TEST_LDOUBLE && LDBL_MANT_DIG == 53) -# define TEST_COND_dbl_64 1 -#else -# define TEST_COND_dbl_64 0 -#endif -#if defined TEST_LDOUBLE && LDBL_MANT_DIG == 64 && LDBL_MIN_EXP == -16381 -# define TEST_COND_ldbl_96_intel 1 -#else -# define TEST_COND_ldbl_96_intel 0 -#endif -#if defined TEST_LDOUBLE && LDBL_MANT_DIG == 64 && LDBL_MIN_EXP == -16382 -# define TEST_COND_ldbl_96_m68k 1 -#else -# define TEST_COND_ldbl_96_m68k 0 -#endif -#if defined TEST_LDOUBLE && LDBL_MANT_DIG == 113 -# define TEST_COND_ldbl_128 1 -#else -# define TEST_COND_ldbl_128 0 -#endif -#if defined TEST_LDOUBLE && LDBL_MANT_DIG == 106 -# define TEST_COND_ldbl_128ibm 1 -#else -# define TEST_COND_ldbl_128ibm 0 -#endif +#define TEST_COND_flt_32 TEST_COND_binary32 +#define TEST_COND_dbl_64 TEST_COND_binary64 +#define TEST_COND_ldbl_96_intel TEST_COND_intel96 +#define TEST_COND_ldbl_96_m68k TEST_COND_m68k96 +#define TEST_COND_ldbl_128 TEST_COND_binary128 +#define TEST_COND_ldbl_128ibm TEST_COND_ibm128 + #if LONG_MAX == 0x7fffffff # define TEST_COND_long32 1 # define TEST_COND_long64 0 @@ -302,26 +328,15 @@ static int output_max_error; /* Should the maximal errors printed? */ static int output_points; /* Should the single function results printed? */ static int ignore_max_ulp; /* Should we ignore max_ulp? */ -#define plus_zero CHOOSE (0.0L, 0.0, 0.0f, \ - 0.0L, 0.0, 0.0f) -#define minus_zero CHOOSE (-0.0L, -0.0, -0.0f, \ - -0.0L, -0.0, -0.0f) -#define plus_infty CHOOSE (HUGE_VALL, HUGE_VAL, HUGE_VALF, \ - HUGE_VALL, HUGE_VAL, HUGE_VALF) -#define minus_infty CHOOSE (-HUGE_VALL, -HUGE_VAL, -HUGE_VALF, \ - -HUGE_VALL, -HUGE_VAL, -HUGE_VALF) +#define plus_zero LIT (0.0) +#define minus_zero LIT (-0.0) +#define plus_infty FUNC (__builtin_inf) () +#define minus_infty -(FUNC (__builtin_inf) ()) #define qnan_value FUNC (__builtin_nan) ("") #define snan_value FUNC (__builtin_nans) ("") -#define max_value CHOOSE (LDBL_MAX, DBL_MAX, FLT_MAX, \ - LDBL_MAX, DBL_MAX, FLT_MAX) -#define min_value CHOOSE (LDBL_MIN, DBL_MIN, FLT_MIN, \ - LDBL_MIN, DBL_MIN, FLT_MIN) -#define min_subnorm_value CHOOSE (LDBL_TRUE_MIN, \ - DBL_TRUE_MIN, \ - FLT_TRUE_MIN, \ - LDBL_TRUE_MIN, \ - DBL_TRUE_MIN, \ - FLT_TRUE_MIN) +#define max_value TYPE_MAX +#define min_value TYPE_MIN +#define min_subnorm_value TYPE_TRUE_MIN static FLOAT max_error, real_max_error, imag_max_error; @@ -329,23 +344,12 @@ static FLOAT prev_max_error, prev_real_max_error, prev_imag_max_error; static FLOAT max_valid_error; -#define MANT_DIG CHOOSE (LDBL_MANT_DIG, DBL_MANT_DIG, FLT_MANT_DIG, \ - LDBL_MANT_DIG, DBL_MANT_DIG, FLT_MANT_DIG) -#define MIN_EXP CHOOSE (LDBL_MIN_EXP, DBL_MIN_EXP, FLT_MIN_EXP, \ - LDBL_MIN_EXP, DBL_MIN_EXP, FLT_MIN_EXP) -#define MAX_EXP CHOOSE (LDBL_MAX_EXP, DBL_MAX_EXP, FLT_MAX_EXP, \ - LDBL_MAX_EXP, DBL_MAX_EXP, FLT_MAX_EXP) /* Sufficient numbers of digits to represent any floating-point value unambiguously (for any choice of the number of bits in the first hex digit, in the case of TYPE_HEX_DIG). When used with printf formats where the precision counts only digits after the point, 1 is subtracted from these values. */ -#define TYPE_DECIMAL_DIG CHOOSE (LDBL_DECIMAL_DIG, \ - DBL_DECIMAL_DIG, \ - FLT_DECIMAL_DIG, \ - LDBL_DECIMAL_DIG, \ - DBL_DECIMAL_DIG, \ - FLT_DECIMAL_DIG) +#define TYPE_DECIMAL_DIG __CONCATX (PREFIX, _DECIMAL_DIG) #define TYPE_HEX_DIG ((MANT_DIG + 6) / 4) /* Compare KEY (a string, with the name of a function) with ULP (a @@ -428,8 +432,12 @@ print_float (FLOAT f) else if (isnan (f)) printf ("qNaN\n"); else - printf ("% .*" PRINTF_EXPR " % .*" PRINTF_XEXPR "\n", - TYPE_DECIMAL_DIG - 1, f, TYPE_HEX_DIG - 1, f); + { + char fstrn[FSTR_MAX], fstrx[FSTR_MAX]; + FTOSTR (fstrn, FSTR_MAX, "% .*" PRINTF_EXPR, TYPE_DECIMAL_DIG - 1, f); + FTOSTR (fstrx, FSTR_MAX, "% .*" PRINTF_XEXPR, TYPE_HEX_DIG - 1, f); + printf ("%s %s\n", fstrn, fstrx); + } } /* Should the message print to screen? This depends on the verbose flag, @@ -471,11 +479,10 @@ print_function_ulps (const char *function_name, FLOAT ulp) { if (output_ulps) { + char ustrn[FSTR_MAX]; + FTOSTR (ustrn, FSTR_MAX, "%.0" PRINTF_NEXPR, FUNC (ceil) (ulp)); fprintf (ulps_file, "Function: \"%s\":\n", function_name); - fprintf (ulps_file, "%s: %.0" PRINTF_NEXPR "\n", - CHOOSE("ldouble", "double", "float", - "ildouble", "idouble", "ifloat"), - FUNC(ceil) (ulp)); + fprintf (ulps_file, QTYPE_STR ": %s\n", ustrn); } } @@ -486,21 +493,20 @@ print_complex_function_ulps (const char *function_name, FLOAT real_ulp, { if (output_ulps) { + char fstrn[FSTR_MAX]; if (real_ulp != 0.0) { + FTOSTR (fstrn, FSTR_MAX, "%.0" PRINTF_NEXPR, + FUNC (ceil) (real_ulp)); fprintf (ulps_file, "Function: Real part of \"%s\":\n", function_name); - fprintf (ulps_file, "%s: %.0" PRINTF_NEXPR "\n", - CHOOSE("ldouble", "double", "float", - "ildouble", "idouble", "ifloat"), - FUNC(ceil) (real_ulp)); + fprintf (ulps_file, QTYPE_STR ": %s\n", fstrn); } if (imag_ulp != 0.0) { + FTOSTR (fstrn, FSTR_MAX, "%.0" PRINTF_NEXPR, + FUNC (ceil) (imag_ulp)); fprintf (ulps_file, "Function: Imaginary part of \"%s\":\n", function_name); - fprintf (ulps_file, "%s: %.0" PRINTF_NEXPR "\n", - CHOOSE("ldouble", "double", "float", - "ildouble", "idouble", "ifloat"), - FUNC(ceil) (imag_ulp)); + fprintf (ulps_file, QTYPE_STR ": %s\n", fstrn); } @@ -548,10 +554,12 @@ print_max_error (const char *func_name) if (print_screen_max_error (ok)) { + char mestr[FSTR_MAX], pmestr[FSTR_MAX]; + FTOSTR (mestr, FSTR_MAX, "%.0" PRINTF_NEXPR, FUNC (ceil) (max_error)); + FTOSTR (pmestr, FSTR_MAX, "%.0" PRINTF_NEXPR, FUNC (ceil) (prev_max_error)); printf ("Maximal error of `%s'\n", func_name); - printf (" is : %.0" PRINTF_NEXPR " ulp\n", FUNC(ceil) (max_error)); - printf (" accepted: %.0" PRINTF_NEXPR " ulp\n", - FUNC(ceil) (prev_max_error)); + printf (" is : %s ulp\n", mestr); + printf (" accepted: %s ulp\n", pmestr); } update_stats (ok); @@ -584,16 +592,22 @@ print_complex_max_error (const char *func_name) if (print_screen_max_error (ok)) { + char rmestr[FSTR_MAX], prmestr[FSTR_MAX]; + char imestr[FSTR_MAX], pimestr[FSTR_MAX]; + FTOSTR (rmestr, FSTR_MAX, "%.0" PRINTF_NEXPR, + FUNC (ceil) (real_max_error)); + FTOSTR (prmestr, FSTR_MAX, "%.0" PRINTF_NEXPR, + FUNC (ceil) (prev_real_max_error)); + FTOSTR (imestr, FSTR_MAX, "%.0" PRINTF_NEXPR, + FUNC (ceil) (imag_max_error)); + FTOSTR (pimestr, FSTR_MAX, "%.0" PRINTF_NEXPR, + FUNC (ceil) (prev_imag_max_error)); printf ("Maximal error of real part of: %s\n", func_name); - printf (" is : %.0" PRINTF_NEXPR " ulp\n", - FUNC(ceil) (real_max_error)); - printf (" accepted: %.0" PRINTF_NEXPR " ulp\n", - FUNC(ceil) (prev_real_max_error)); + printf (" is : %s ulp\n", rmestr); + printf (" accepted: %s ulp\n", prmestr); printf ("Maximal error of imaginary part of: %s\n", func_name); - printf (" is : %.0" PRINTF_NEXPR " ulp\n", - FUNC(ceil) (imag_max_error)); - printf (" accepted: %.0" PRINTF_NEXPR " ulp\n", - FUNC(ceil) (prev_imag_max_error)); + printf (" is : %s ulp\n", imestr); + printf (" accepted: %s ulp\n", pimestr); } update_stats (ok); @@ -851,10 +865,17 @@ check_float_internal (const char *test_name, FLOAT computed, FLOAT expected, print_float (expected); if (print_diff) { - printf (" difference: % .*" PRINTF_EXPR " % .*" PRINTF_XEXPR - "\n", TYPE_DECIMAL_DIG - 1, diff, TYPE_HEX_DIG - 1, diff); - printf (" ulp : % .4" PRINTF_NEXPR "\n", ulps); - printf (" max.ulp : % .4" PRINTF_NEXPR "\n", max_ulp); + char dstrn[FSTR_MAX], dstrx[FSTR_MAX]; + char ustrn[FSTR_MAX], mustrn[FSTR_MAX]; + FTOSTR (dstrn, FSTR_MAX, "% .*" PRINTF_EXPR, + TYPE_DECIMAL_DIG - 1, diff); + FTOSTR (dstrx, FSTR_MAX, "% .*" PRINTF_XEXPR, + TYPE_HEX_DIG - 1, diff); + FTOSTR (ustrn, FSTR_MAX, "% .4" PRINTF_NEXPR, ulps); + FTOSTR (mustrn, FSTR_MAX, "% .4" PRINTF_NEXPR, max_ulp); + printf (" difference: %s %s\n", dstrn, dstrx); + printf (" ulp : %s\n", ustrn); + printf (" max.ulp : %s\n", mustrn); } } update_stats (ok); diff --git a/math/test-double.h b/math/test-double.h index 16b4ce8..6783b44 100644 --- a/math/test-double.h +++ b/math/test-double.h @@ -23,3 +23,7 @@ #define PRINTF_NEXPR "f" #define TEST_DOUBLE 1 #define BUILD_COMPLEX(real, imag) (CMPLX ((real), (imag))) +#define PREFIX DBL +#define LIT(x) (x) +#define TYPE_STR "double" +#define FTOSTR snprintf diff --git a/math/test-float.h b/math/test-float.h index 629f6ee..9bb3b84 100644 --- a/math/test-float.h +++ b/math/test-float.h @@ -23,3 +23,7 @@ #define PRINTF_NEXPR "f" #define TEST_FLOAT 1 #define BUILD_COMPLEX(real, imag) (CMPLXF ((real), (imag))) +#define PREFIX FLT +#define TYPE_STR "float" +#define LIT(x) (x ## f) +#define FTOSTR snprintf diff --git a/math/test-ldouble.h b/math/test-ldouble.h index 481561f..63f5008 100644 --- a/math/test-ldouble.h +++ b/math/test-ldouble.h @@ -23,3 +23,7 @@ #define PRINTF_NEXPR "Lf" #define TEST_LDOUBLE 1 #define BUILD_COMPLEX(real, imag) (CMPLXL ((real), (imag))) +#define PREFIX LDBL +#define TYPE_STR "ldouble" +#define LIT(x) (x ## L) +#define FTOSTR snprintf -- cgit v1.1