/* Support code for testing libm functions (driver).
- Copyright (C) 1997-2017 Free Software Foundation, Inc.
+ Copyright (C) 1997-2023 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
+ <https://www.gnu.org/licenses/>. */
#include "libm-test-support.h"
/* Flags set by the including file. */
const int flag_test_errno = TEST_ERRNO;
const int flag_test_exceptions = TEST_EXCEPTIONS;
-const int flag_test_finite = TEST_FINITE;
-const int flag_test_inline = TEST_INLINE;
const int flag_test_mathvec = TEST_MATHVEC;
+#if TEST_NARROW
+const int snan_tests_arg = SNAN_TESTS (ARG_FLOAT);
+#else
+const int snan_tests_arg = SNAN_TESTS (FLOAT);
+#endif
+
#define STRX(x) #x
#define STR(x) STRX (x)
#define STR_FLOAT STR (FLOAT)
+#define STR_ARG_FLOAT STR (ARG_FLOAT)
#define STR_VEC_LEN STR (VEC_LEN)
/* Informal description of the functions being tested. */
#if TEST_MATHVEC
# define TEST_MSG "testing " STR_FLOAT " (vector length " STR_VEC_LEN ")\n"
-#elif TEST_INLINE
-# define TEST_MSG "testing " STR_FLOAT " (inline functions)\n"
-#elif TEST_FINITE
-# define TEST_MSG "testing " STR_FLOAT " (finite-math-only)\n"
+#elif TEST_NARROW
+# define TEST_MSG "testing " STR_FLOAT " (argument " STR_ARG_FLOAT ")\n"
#else
# define TEST_MSG "testing " STR_FLOAT " (without inline functions)\n"
#endif
? TEST_NAN_PAYLOAD \
: 0)
-#if TEST_INLINE
-const char qtype_str[] = "i" TYPE_STR;
-#else
const char qtype_str[] = TYPE_STR;
-#endif
/* Various constants derived from pi. We must supply them precalculated for
accuracy. They are written as a series of postfix operations to keep
#define min_value TYPE_MIN
#define min_subnorm_value TYPE_TRUE_MIN
+#define arg_plus_zero ARG_LIT (0.0)
+#define arg_minus_zero ARG_LIT (-0.0)
+#define arg_plus_infty ARG_FUNC (__builtin_inf) ()
+#define arg_minus_infty -(ARG_FUNC (__builtin_inf) ())
+#define arg_qnan_value_pl(S) ARG_FUNC (__builtin_nan) (S)
+#define arg_qnan_value arg_qnan_value_pl ("")
+#define arg_snan_value_pl(S) ARG_FUNC (__builtin_nans) (S)
+#define arg_snan_value arg_snan_value_pl ("")
+#define arg_max_value ARG_TYPE_MAX
+#define arg_min_value ARG_TYPE_MIN
+#define arg_min_subnorm_value ARG_TYPE_TRUE_MIN
+
/* For nexttoward tests. */
#define snan_value_ld __builtin_nansl ("")
+/* For pseudo-normal number tests. */
+#if TEST_COND_intel96
+# include <math_ldbl.h>
+#define pseudo_inf { .parts = { 0x00000000, 0x00000000, 0x7fff }}
+#define pseudo_zero { .parts = { 0x00000000, 0x00000000, 0x0100 }}
+#define pseudo_qnan { .parts = { 0x00000001, 0x00000000, 0x7fff }}
+#define pseudo_snan { .parts = { 0x00000001, 0x40000000, 0x7fff }}
+#define pseudo_unnormal { .parts = { 0x00000001, 0x40000000, 0x0100 }}
+#endif
+
/* Structures for each kind of test. */
/* Used for both RUN_TEST_LOOP_f_f and RUN_TEST_LOOP_fp_f. */
struct test_f_f_data
int exceptions;
} rd, rn, rz, ru;
};
-/* Strictly speaking, a j type argument is one gen-libm-test.pl will not
+/* Strictly speaking, a j type argument is one gen-libm-test.py will not
attempt to muck with. For now, it is only used to prevent it from
mucking up an explicitly long double argument. */
struct test_fj_f_data
int exceptions;
} rd, rn, rz, ru;
};
+#ifdef ARG_FLOAT
+struct test_a_f_data
+{
+ const char *arg_str;
+ ARG_FLOAT arg;
+ struct
+ {
+ FLOAT expected;
+ int exceptions;
+ } rd, rn, rz, ru;
+};
+struct test_aa_f_data
+{
+ const char *arg_str;
+ ARG_FLOAT arg1, arg2;
+ struct
+ {
+ FLOAT expected;
+ int exceptions;
+ } rd, rn, rz, ru;
+};
+struct test_aaa_f_data
+{
+ const char *arg_str;
+ ARG_FLOAT arg1, arg2, arg3;
+ struct
+ {
+ FLOAT expected;
+ int exceptions;
+ } rd, rn, rz, ru;
+};
+#endif
struct test_fi_f_data
{
const char *arg_str;
int exceptions;
} rd, rn, rz, ru;
};
-/* Used for both RUN_TEST_LOOP_ff_b and RUN_TEST_LOOP_ff_i_tg. */
+/* Used for RUN_TEST_LOOP_f_i_tg_u and RUN_TEST_LOOP_f_b_tg_u. */
+#if TEST_COND_intel96
+struct test_j_i_data_u
+{
+ const char *arg_str;
+ ieee_long_double_shape_type arg;
+ struct
+ {
+ int expected;
+ int exceptions;
+ } rd, rn, rz, ru;
+};
+#endif
+/* Used for RUN_TEST_LOOP_ff_b, RUN_TEST_LOOP_fpfp_b and
+ RUN_TEST_LOOP_ff_i_tg. */
struct test_ff_i_data
{
const char *arg_str;
#define IF_ROUND_INIT_FE_DOWNWARD \
int save_round_mode = fegetround (); \
if (ROUNDING_TESTS (FLOAT, FE_DOWNWARD) \
+ && !TEST_MATHVEC \
&& fesetround (FE_DOWNWARD) == 0)
#define IF_ROUND_INIT_FE_TONEAREST \
int save_round_mode = fegetround (); \
#define IF_ROUND_INIT_FE_TOWARDZERO \
int save_round_mode = fegetround (); \
if (ROUNDING_TESTS (FLOAT, FE_TOWARDZERO) \
+ && !TEST_MATHVEC \
&& fesetround (FE_TOWARDZERO) == 0)
#define IF_ROUND_INIT_FE_UPWARD \
int save_round_mode = fegetround (); \
if (ROUNDING_TESTS (FLOAT, FE_UPWARD) \
+ && !TEST_MATHVEC \
&& fesetround (FE_UPWARD) == 0)
#define ROUND_RESTORE_ /* Empty. */
#define ROUND_RESTORE_FE_DOWNWARD \
/* Run an individual test, including any required setup and checking
of results, or loop over all tests in an array. */
-#define RUN_TEST_f_f(ARG_STR, FUNC_NAME, ARG, EXPECTED, \
+#define RUN_TEST_1_f(ARG_STR, FUNC_NAME, ARG, EXPECTED, \
EXCEPTIONS) \
do \
if (enable_test (EXCEPTIONS)) \
COMMON_TEST_CLEANUP; \
} \
while (0)
-#define RUN_TEST_LOOP_f_f(FUNC_NAME, ARRAY, ROUNDING_MODE) \
+#define RUN_TEST_LOOP_1_f(FUNC_NAME, ARRAY, ROUNDING_MODE) \
IF_ROUND_INIT_ ## ROUNDING_MODE \
for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
- RUN_TEST_f_f ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
+ RUN_TEST_1_f ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
(ARRAY)[i].RM_##ROUNDING_MODE.expected, \
(ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
ROUND_RESTORE_ ## ROUNDING_MODE
+#define RUN_TEST_LOOP_f_f RUN_TEST_LOOP_1_f
+#define RUN_TEST_LOOP_a_f RUN_TEST_LOOP_1_f
#define RUN_TEST_fp_f(ARG_STR, FUNC_NAME, ARG, EXPECTED, \
EXCEPTIONS) \
do \
#define RUN_TEST_ff_f RUN_TEST_2_f
#define RUN_TEST_LOOP_ff_f RUN_TEST_LOOP_2_f
#define RUN_TEST_LOOP_fj_f RUN_TEST_LOOP_2_f
+#define RUN_TEST_LOOP_aa_f RUN_TEST_LOOP_2_f
#define RUN_TEST_fi_f RUN_TEST_2_f
#define RUN_TEST_LOOP_fi_f RUN_TEST_LOOP_2_f
#define RUN_TEST_fl_f RUN_TEST_2_f
#define RUN_TEST_LOOP_fl_f RUN_TEST_LOOP_2_f
#define RUN_TEST_if_f RUN_TEST_2_f
#define RUN_TEST_LOOP_if_f RUN_TEST_LOOP_2_f
-#define RUN_TEST_fff_f(ARG_STR, FUNC_NAME, ARG1, ARG2, ARG3, \
- EXPECTED, EXCEPTIONS) \
+#define RUN_TEST_3_f(ARG_STR, FUNC_NAME, ARG1, ARG2, ARG3, \
+ EXPECTED, EXCEPTIONS) \
do \
if (enable_test (EXCEPTIONS)) \
{ \
COMMON_TEST_CLEANUP; \
} \
while (0)
-#define RUN_TEST_LOOP_fff_f(FUNC_NAME, ARRAY, ROUNDING_MODE) \
+#define RUN_TEST_LOOP_3_f(FUNC_NAME, ARRAY, ROUNDING_MODE) \
IF_ROUND_INIT_ ## ROUNDING_MODE \
for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
- RUN_TEST_fff_f ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg1, \
- (ARRAY)[i].arg2, (ARRAY)[i].arg3, \
- (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
- (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
+ RUN_TEST_3_f ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg1, \
+ (ARRAY)[i].arg2, (ARRAY)[i].arg3, \
+ (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
+ (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
ROUND_RESTORE_ ## ROUNDING_MODE
+#define RUN_TEST_LOOP_fff_f RUN_TEST_LOOP_3_f
+#define RUN_TEST_LOOP_aaa_f RUN_TEST_LOOP_3_f
#define RUN_TEST_fiu_M(ARG_STR, FUNC_NAME, ARG1, ARG2, ARG3, \
EXPECTED, EXCEPTIONS) \
do \
(ARRAY)[i].RM_##ROUNDING_MODE.expected, \
(ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
ROUND_RESTORE_ ## ROUNDING_MODE
+#define RUN_TEST_LOOP_j_b_tg_u(FUNC_NAME, ARRAY, ROUNDING_MODE) \
+ IF_ROUND_INIT_ ## ROUNDING_MODE \
+ for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
+ RUN_TEST_f_b_tg ((ARRAY)[i].arg_str, FUNC_NAME, \
+ (FLOAT)(ARRAY)[i].arg.value, \
+ (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
+ (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
+ ROUND_RESTORE_ ## ROUNDING_MODE
+#define RUN_TEST_LOOP_j_i_tg_u(FUNC_NAME, ARRAY, ROUNDING_MODE) \
+ IF_ROUND_INIT_ ## ROUNDING_MODE \
+ for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
+ RUN_TEST_f_i_tg ((ARRAY)[i].arg_str, FUNC_NAME, \
+ (FLOAT)(ARRAY)[i].arg.value, \
+ (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
+ (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
+ ROUND_RESTORE_ ## ROUNDING_MODE
#define RUN_TEST_ff_b(ARG_STR, FUNC_NAME, ARG1, ARG2, EXPECTED, \
EXCEPTIONS) \
do \
(ARRAY)[i].RM_##ROUNDING_MODE.expected, \
(ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
ROUND_RESTORE_ ## ROUNDING_MODE
+#define RUN_TEST_fpfp_b(ARG_STR, FUNC_NAME, ARG1, ARG2, EXPECTED, \
+ EXCEPTIONS) \
+ do \
+ if (enable_test (EXCEPTIONS)) \
+ { \
+ COMMON_TEST_SETUP (ARG_STR); \
+ check_bool (test_name, \
+ FUNC_TEST (FUNC_NAME) (&(ARG1), &(ARG2)), \
+ EXPECTED, EXCEPTIONS); \
+ COMMON_TEST_CLEANUP; \
+ } \
+ while (0)
+#define RUN_TEST_LOOP_fpfp_b(FUNC_NAME, ARRAY, ROUNDING_MODE) \
+ IF_ROUND_INIT_ ## ROUNDING_MODE \
+ for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
+ RUN_TEST_fpfp_b ((ARRAY)[i].arg_str, FUNC_NAME, \
+ (ARRAY)[i].arg1, (ARRAY)[i].arg2, \
+ (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
+ (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
+ ROUND_RESTORE_ ## ROUNDING_MODE
#define RUN_TEST_ff_i_tg(ARG_STR, FUNC_NAME, ARG1, ARG2, EXPECTED, \
EXCEPTIONS) \
do \
(ARRAY)[i].RM_##ROUNDING_MODE.extra2_expected); \
ROUND_RESTORE_ ## ROUNDING_MODE
-#if !TEST_MATHVEC
-# define VEC_SUFF
+#if TEST_MATHVEC
+# define TEST_SUFF VEC_SUFF
+# define TEST_SUFF_STR
+#elif TEST_NARROW
+# define TEST_SUFF
+# define TEST_SUFF_STR "_" ARG_TYPE_STR
+#else
+# define TEST_SUFF
+# define TEST_SUFF_STR
#endif
#define STR_CONCAT(a, b, c) __STRING (a##b##c)
#define STR_CON3(a, b, c) STR_CONCAT (a, b, c)
+#if TEST_NARROW
+# define TEST_COND_any_ibm128 (TEST_COND_ibm128 || TEST_COND_arg_ibm128)
+#else
+# define TEST_COND_any_ibm128 TEST_COND_ibm128
+#endif
+
/* Start and end the tests for a given function. */
#define START(FUN, SUFF, EXACT) \
CHECK_ARCH_EXT; \
- const char *this_func = STR_CON3 (FUN, SUFF, VEC_SUFF); \
- init_max_error (this_func, EXACT)
+ const char *this_func \
+ = STR_CON3 (FUN, SUFF, TEST_SUFF) TEST_SUFF_STR; \
+ init_max_error (this_func, EXACT, TEST_COND_any_ibm128)
#define END \
print_max_error (this_func)
#define END_COMPLEX \