1 /* Generate expected output for libm tests with MPFR and MPC.
2 Copyright (C) 2013-2014 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
19 /* Compile this program as:
21 gcc -std=gnu99 -O2 -Wall -Wextra gen-auto-libm-tests.c -lmpc -lmpfr -lgmp \
22 -o gen-auto-libm-tests
24 (use of current MPC and MPFR versions recommended) and run it as:
26 gen-auto-libm-tests auto-libm-test-in auto-libm-test-out
28 The input file auto-libm-test-in contains three kinds of lines:
30 Lines beginning with "#" are comments, and are ignored, as are
33 Other lines are test lines, of the form "function input1 input2
34 ... [flag1 flag2 ...]". Inputs are either finite real numbers or
35 integers, depending on the function under test. Real numbers may
36 be in any form acceptable to mpfr_strtofr (base 0); integers in any
37 form acceptable to mpz_set_str (base 0). In addition, real numbers
38 may be certain special strings such as "pi", as listed in the
39 special_real_inputs array.
41 Each flag is a flag name possibly followed by a series of
42 ":condition". Conditions may be any of the names of floating-point
43 formats in the floating_point_formats array, "long32" and "long64"
44 to indicate the number of bits in the "long" type, or other strings
45 for which libm-test.inc defines a TEST_COND_<condition> macro (with
46 "-"- changed to "_" in the condition name) evaluating to nonzero
47 when the condition is true and zero when the condition is false.
48 The meaning is that the flag applies to the test if all the listed
49 conditions are true. "flag:cond1:cond2 flag:cond3:cond4" means the
50 flag applies if ((cond1 && cond2) || (cond3 && cond4)).
52 A real number specified as an input is considered to represent the
53 set of real numbers arising from rounding the given number in any
54 direction for any supported floating-point format; any roundings
55 that give infinity are ignored. Each input on a test line has all
56 the possible roundings considered independently. Each resulting
57 choice of the tuple of inputs to the function is ignored if the
58 mathematical result of the function involves a NaN or an exact
59 infinity, and is otherwise considered for each floating-point
60 format for which all those inputs are exactly representable. Thus
61 tests may result in "overflow", "underflow" and "inexact"
62 exceptions; "invalid" may arise only when the final result type is
63 an integer type and it is the conversion of a mathematically
64 defined finite result to integer type that results in that
67 By default, it is assumed that "overflow" and "underflow"
68 exceptions should be correct, but that "inexact" exceptions should
69 only be correct for functions listed as exactly determined. For
70 such functions, "underflow" exceptions should respect whether the
71 machine has before-rounding or after-rounding tininess detection.
72 For other functions, it is considered that if the exact result is
73 somewhere between the greatest magnitude subnormal of a given sign
74 (exclusive) and the least magnitude normal of that sign
75 (inclusive), underflow exceptions are permitted but optional on all
76 machines, and they are also permitted but optional for smaller
77 subnormal exact results for functions that are not exactly
78 determined. errno setting is expected for overflow to infinity and
79 underflow to zero (for real functions), and for out-of-range
80 conversion of a finite result to integer type, and is considered
81 permitted but optional for all other cases where overflow
82 exceptions occur, and where underflow exceptions occur or are
83 permitted. In other cases (where no overflow or underflow is
84 permitted), errno is expected to be left unchanged.
86 The flag "no-test-inline" indicates a test is disabled for inline
87 function testing; "xfail" indicates the test is disabled as
88 expected to produce incorrect results, "xfail-rounding" indicates
89 the test is disabled only in rounding modes other than
90 round-to-nearest. Otherwise, test flags are of the form
91 "spurious-<exception>" and "missing-<exception>", for any exception
92 ("overflow", "underflow", "inexact", "invalid", "divbyzero"),
93 "spurious-errno" and "missing-errno", to indicate when tests are
94 expected to deviate from the exception and errno settings
95 corresponding to the mathematical results. "xfail",
96 "xfail-rounding", "spurious-" and "missing-" flags should be
97 accompanied by a comment referring to an open bug in glibc
100 The output file auto-libm-test-out contains the test lines from
101 auto-libm-test-in, and, after the line for a given test, some
102 number of output test lines. An output test line is of the form "=
103 function rounding-mode format input1 input2 ... : output1 output2
104 ... : flags". rounding-mode is "tonearest", "towardzero", "upward"
105 or "downward". format is a name from the floating_point_formats
106 array, possibly followed by a sequence of ":flag" for flags from
107 "long32" and "long64". Inputs and outputs are specified as hex
108 floats with the required suffix for the floating-point type, or
109 plus_infty or minus_infty for infinite expected results, or as
110 integer constant expressions (not necessarily with the right type)
111 or IGNORE for integer inputs and outputs. Flags are
112 "no-test-inline", "xfail", "<exception>", "<exception>-ok",
113 "errno-<value>", "errno-<value>-ok", which may be unconditional or
114 conditional. "<exception>" indicates that a correct result means
115 the given exception should be raised. "errno-<value>" indicates
116 that a correct result means errno should be set to the given value.
117 "-ok" means not to test for the given exception or errno value
118 (whether because it was marked as possibly missing or spurious, or
119 because the calculation of correct results indicated it was
120 optional). Conditions "before-rounding" and "after-rounding"
121 indicate tests where expectations for underflow exceptions depend
122 on how the architecture detects tininess. */
140 #define ARRAY_SIZE(A) (sizeof (A) / sizeof ((A)[0]))
142 /* The supported floating-point formats. */
155 /* Structure describing a single floating-point format. */
158 /* The name of the format. */
160 /* The suffix to use on floating-point constants with this
163 /* A string for the largest normal value, or NULL for IEEE formats
164 where this can be determined automatically. */
165 const char *max_string
;
166 /* The number of mantissa bits. */
168 /* The least N such that 2^N overflows. */
170 /* One more than the least N such that 2^N is normal. */
172 /* The largest normal value. */
174 /* The least positive normal value, 2^(MIN_EXP-1). */
176 /* The greatest positive subnormal value. */
178 /* The least positive subnormal value, 2^(MIN_EXP-MANT_DIG). */
182 /* List of floating-point formats, in the same order as the fp_format
184 static fp_format_desc fp_formats
[fp_num_formats
] =
186 { "flt-32", "f", NULL
, 24, 128, -125, {}, {}, {}, {} },
187 { "dbl-64", "", NULL
, 53, 1024, -1021, {}, {}, {}, {} },
188 { "ldbl-96-intel", "L", NULL
, 64, 16384, -16381, {}, {}, {}, {} },
189 { "ldbl-96-m68k", "L", NULL
, 64, 16384, -16382, {}, {}, {}, {} },
190 { "ldbl-128", "L", NULL
, 113, 16384, -16381, {}, {}, {}, {} },
191 { "ldbl-128ibm", "L", "0x1.fffffffffffff7ffffffffffff8p+1023",
192 106, 1024, -968, {}, {}, {}, {} },
195 /* The supported rounding modes. */
206 /* Structure describing a single rounding mode. */
209 /* The name of the rounding mode. */
211 /* The MPFR rounding mode. */
212 mpfr_rnd_t mpfr_mode
;
213 /* The MPC rounding mode. */
215 } rounding_mode_desc
;
217 /* List of rounding modes, in the same order as the rounding_mode
219 static const rounding_mode_desc rounding_modes
[rm_num_modes
] =
221 { "downward", MPFR_RNDD
, MPC_RNDDD
},
222 { "tonearest", MPFR_RNDN
, MPC_RNDNN
},
223 { "towardzero", MPFR_RNDZ
, MPC_RNDZZ
},
224 { "upward", MPFR_RNDU
, MPC_RNDUU
},
227 /* The supported exceptions. */
236 exc_first_exception
= 0
239 /* List of exceptions, in the same order as the fp_exception
241 static const char *const exceptions
[exc_num_exceptions
] =
250 /* The internal precision to use for most MPFR calculations, which
251 must be at least 2 more than the greatest precision of any
252 supported floating-point format. */
253 static int internal_precision
;
255 /* A value that overflows all supported floating-point formats. */
256 static mpfr_t global_max
;
258 /* A value that is at most half the least subnormal in any
259 floating-point format and so is rounded the same way as all
260 sufficiently small positive values. */
261 static mpfr_t global_min
;
263 /* The maximum number of (real or integer) arguments to a function
264 handled by this program (complex arguments count as two real
268 /* The maximum number of (real or integer) return values from a
269 function handled by this program. */
272 /* A type of a function argument or return value. */
275 /* No type (not a valid argument or return value). */
277 /* A floating-point value with the type corresponding to that of
280 /* An integer value of type int. */
282 /* An integer value of type long. */
284 /* An integer value of type long long. */
288 /* A type of a generic real or integer value. */
293 /* Floating-point (represented with MPFR). */
295 /* Integer (represented with GMP). */
297 } generic_value_type
;
299 /* A generic value (argument or result). */
302 /* The type of this value. */
303 generic_value_type type
;
312 /* A type of input flag. */
318 /* The "spurious" and "missing" flags must be in the same order as
319 the fp_exception enumeration. */
320 flag_spurious_divbyzero
,
321 flag_spurious_inexact
,
322 flag_spurious_invalid
,
323 flag_spurious_overflow
,
324 flag_spurious_underflow
,
326 flag_missing_divbyzero
,
327 flag_missing_inexact
,
328 flag_missing_invalid
,
329 flag_missing_overflow
,
330 flag_missing_underflow
,
332 num_input_flag_types
,
334 flag_spurious_first
= flag_spurious_divbyzero
,
335 flag_missing_first
= flag_missing_divbyzero
338 /* List of flags, in the same order as the input_flag_type
340 static const char *const input_flags
[num_input_flag_types
] =
345 "spurious-divbyzero",
349 "spurious-underflow",
359 /* An input flag, possibly conditional. */
362 /* The type of this flag. */
363 input_flag_type type
;
364 /* The conditions on this flag, as a string ":cond1:cond2..." or
369 /* Structure describing a single test from the input file (which may
370 expand into many tests in the output). The choice of function,
371 which implies the numbers and types of arguments and results, is
372 implicit rather than stored in this structure (except as part of
376 /* The text of the input line describing the test, including the
379 /* The number of combinations of interpretations of input values for
380 different floating-point formats and rounding modes. */
381 size_t num_input_cases
;
382 /* The corresponding lists of inputs. */
383 generic_value
**inputs
;
384 /* The number of flags for this test. */
386 /* The corresponding list of flags. */
388 /* The old output for this test. */
389 const char *old_output
;
392 /* Ways to calculate a function. */
395 /* MPFR function with a single argument and result. */
397 /* MPFR function with two arguments and one result. */
399 /* MPFR function with three arguments and one result. */
401 /* MPFR function with a single argument and floating-point and
404 /* MPFR function with integer and floating-point arguments and one
407 /* MPFR function with a single argument and two floating-point
410 /* MPC function with a single complex argument and one real
413 /* MPC function with a single complex argument and one complex
416 /* MPC function with two complex arguments and one complex
421 /* Description of how to calculate a function. */
424 /* Which method is used to calculate the function. */
425 func_calc_method method
;
426 /* The specific function called. */
429 int (*mpfr_f_f
) (mpfr_t
, const mpfr_t
, mpfr_rnd_t
);
430 int (*mpfr_ff_f
) (mpfr_t
, const mpfr_t
, const mpfr_t
, mpfr_rnd_t
);
431 int (*mpfr_fff_f
) (mpfr_t
, const mpfr_t
, const mpfr_t
, const mpfr_t
,
433 int (*mpfr_f_f1
) (mpfr_t
, int *, const mpfr_t
, mpfr_rnd_t
);
434 int (*mpfr_if_f
) (mpfr_t
, long, const mpfr_t
, mpfr_rnd_t
);
435 int (*mpfr_f_11
) (mpfr_t
, mpfr_t
, const mpfr_t
, mpfr_rnd_t
);
436 int (*mpc_c_f
) (mpfr_t
, const mpc_t
, mpfr_rnd_t
);
437 int (*mpc_c_c
) (mpc_t
, const mpc_t
, mpc_rnd_t
);
438 int (*mpc_cc_c
) (mpc_t
, const mpc_t
, const mpc_t
, mpc_rnd_t
);
442 /* Structure describing a function handled by this program. */
445 /* The name of the function. */
447 /* The number of arguments. */
449 /* The types of the arguments. */
450 arg_ret_type arg_types
[MAX_NARGS
];
451 /* The number of return values. */
453 /* The types of the return values. */
454 arg_ret_type ret_types
[MAX_NRET
];
455 /* Whether the function has exactly determined results and
458 /* Whether the function is a complex function, so errno setting is
461 /* Whether to treat arguments given as floating-point constants as
462 exact only, rather than rounding them up and down to all
465 /* How to calculate this function. */
467 /* The number of tests allocated for this function. */
468 size_t num_tests_alloc
;
469 /* The number of tests for this function. */
471 /* The tests themselves. */
475 #define ARGS1(T1) 1, { T1 }
476 #define ARGS2(T1, T2) 2, { T1, T2 }
477 #define ARGS3(T1, T2, T3) 3, { T1, T2, T3 }
478 #define ARGS4(T1, T2, T3, T4) 4, { T1, T2, T3, T4 }
479 #define RET1(T1) 1, { T1 }
480 #define RET2(T1, T2) 2, { T1, T2 }
481 #define CALC(TYPE, FN) { TYPE, { .TYPE = FN } }
482 #define FUNC(NAME, ARGS, RET, EXACT, COMPLEX_FN, EXACT_ARGS, CALC) \
484 NAME, ARGS, RET, EXACT, COMPLEX_FN, EXACT_ARGS, CALC, 0, 0, NULL \
487 #define FUNC_mpfr_f_f(NAME, MPFR_FUNC, EXACT) \
488 FUNC (NAME, ARGS1 (type_fp), RET1 (type_fp), EXACT, false, false, \
489 CALC (mpfr_f_f, MPFR_FUNC))
490 #define FUNC_mpfr_ff_f(NAME, MPFR_FUNC, EXACT) \
491 FUNC (NAME, ARGS2 (type_fp, type_fp), RET1 (type_fp), EXACT, false, \
492 false, CALC (mpfr_ff_f, MPFR_FUNC))
493 #define FUNC_mpfr_if_f(NAME, MPFR_FUNC, EXACT) \
494 FUNC (NAME, ARGS2 (type_int, type_fp), RET1 (type_fp), EXACT, false, \
495 false, CALC (mpfr_if_f, MPFR_FUNC))
496 #define FUNC_mpc_c_f(NAME, MPFR_FUNC, EXACT) \
497 FUNC (NAME, ARGS2 (type_fp, type_fp), RET1 (type_fp), EXACT, true, \
498 false, CALC (mpc_c_f, MPFR_FUNC))
499 #define FUNC_mpc_c_c(NAME, MPFR_FUNC, EXACT) \
500 FUNC (NAME, ARGS2 (type_fp, type_fp), RET2 (type_fp, type_fp), EXACT, \
501 true, false, CALC (mpc_c_c, MPFR_FUNC))
503 /* List of functions handled by this program. */
504 static test_function test_functions
[] =
506 FUNC_mpfr_f_f ("acos", mpfr_acos
, false),
507 FUNC_mpfr_f_f ("acosh", mpfr_acosh
, false),
508 FUNC_mpfr_f_f ("asin", mpfr_asin
, false),
509 FUNC_mpfr_f_f ("asinh", mpfr_asinh
, false),
510 FUNC_mpfr_f_f ("atan", mpfr_atan
, false),
511 FUNC_mpfr_ff_f ("atan2", mpfr_atan2
, false),
512 FUNC_mpfr_f_f ("atanh", mpfr_atanh
, false),
513 FUNC_mpc_c_f ("cabs", mpc_abs
, false),
514 FUNC_mpc_c_c ("cacos", mpc_acos
, false),
515 FUNC_mpc_c_c ("cacosh", mpc_acosh
, false),
516 FUNC_mpc_c_f ("carg", mpc_arg
, false),
517 FUNC_mpc_c_c ("casin", mpc_asin
, false),
518 FUNC_mpc_c_c ("casinh", mpc_asinh
, false),
519 FUNC_mpc_c_c ("catan", mpc_atan
, false),
520 FUNC_mpc_c_c ("catanh", mpc_atanh
, false),
521 FUNC_mpfr_f_f ("cbrt", mpfr_cbrt
, false),
522 FUNC_mpc_c_c ("ccos", mpc_cos
, false),
523 FUNC_mpc_c_c ("ccosh", mpc_cosh
, false),
524 FUNC_mpc_c_c ("cexp", mpc_exp
, false),
525 FUNC_mpc_c_c ("clog", mpc_log
, false),
526 FUNC_mpc_c_c ("clog10", mpc_log10
, false),
527 FUNC_mpfr_f_f ("cos", mpfr_cos
, false),
528 FUNC_mpfr_f_f ("cosh", mpfr_cosh
, false),
529 FUNC ("cpow", ARGS4 (type_fp
, type_fp
, type_fp
, type_fp
),
530 RET2 (type_fp
, type_fp
), false, true, false,
531 CALC (mpc_cc_c
, mpc_pow
)),
532 FUNC_mpc_c_c ("csin", mpc_sin
, false),
533 FUNC_mpc_c_c ("csinh", mpc_sinh
, false),
534 FUNC_mpc_c_c ("csqrt", mpc_sqrt
, false),
535 FUNC_mpc_c_c ("ctan", mpc_tan
, false),
536 FUNC_mpc_c_c ("ctanh", mpc_tanh
, false),
537 FUNC_mpfr_f_f ("erf", mpfr_erf
, false),
538 FUNC_mpfr_f_f ("erfc", mpfr_erfc
, false),
539 FUNC_mpfr_f_f ("exp", mpfr_exp
, false),
540 FUNC_mpfr_f_f ("exp10", mpfr_exp10
, false),
541 FUNC_mpfr_f_f ("exp2", mpfr_exp2
, false),
542 FUNC_mpfr_f_f ("expm1", mpfr_expm1
, false),
543 FUNC ("fma", ARGS3 (type_fp
, type_fp
, type_fp
), RET1 (type_fp
),
544 true, false, true, CALC (mpfr_fff_f
, mpfr_fma
)),
545 FUNC_mpfr_ff_f ("hypot", mpfr_hypot
, false),
546 FUNC_mpfr_f_f ("j0", mpfr_j0
, false),
547 FUNC_mpfr_f_f ("j1", mpfr_j1
, false),
548 FUNC_mpfr_if_f ("jn", mpfr_jn
, false),
549 FUNC ("lgamma", ARGS1 (type_fp
), RET2 (type_fp
, type_int
), false, false,
550 false, CALC (mpfr_f_f1
, mpfr_lgamma
)),
551 FUNC_mpfr_f_f ("log", mpfr_log
, false),
552 FUNC_mpfr_f_f ("log10", mpfr_log10
, false),
553 FUNC_mpfr_f_f ("log1p", mpfr_log1p
, false),
554 FUNC_mpfr_f_f ("log2", mpfr_log2
, false),
555 FUNC_mpfr_ff_f ("pow", mpfr_pow
, false),
556 FUNC_mpfr_f_f ("sin", mpfr_sin
, false),
557 FUNC ("sincos", ARGS1 (type_fp
), RET2 (type_fp
, type_fp
), false, false,
558 false, CALC (mpfr_f_11
, mpfr_sin_cos
)),
559 FUNC_mpfr_f_f ("sinh", mpfr_sinh
, false),
560 FUNC_mpfr_f_f ("sqrt", mpfr_sqrt
, true),
561 FUNC_mpfr_f_f ("tan", mpfr_tan
, false),
562 FUNC_mpfr_f_f ("tanh", mpfr_tanh
, false),
563 FUNC_mpfr_f_f ("tgamma", mpfr_gamma
, false),
564 FUNC_mpfr_f_f ("y0", mpfr_y0
, false),
565 FUNC_mpfr_f_f ("y1", mpfr_y1
, false),
566 FUNC_mpfr_if_f ("yn", mpfr_yn
, false),
569 /* Allocate memory, with error checking. */
574 void *p
= malloc (n
);
576 error (EXIT_FAILURE
, errno
, "xmalloc failed");
581 xrealloc (void *p
, size_t n
)
585 error (EXIT_FAILURE
, errno
, "xrealloc failed");
590 xstrdup (const char *s
)
592 char *p
= strdup (s
);
594 error (EXIT_FAILURE
, errno
, "xstrdup failed");
598 /* Assert that the result of an MPFR operation was exact; that is,
599 that the returned ternary value was 0. */
607 /* Return the generic type of an argument or return value type T. */
609 static generic_value_type
610 generic_arg_ret_type (arg_ret_type t
)
627 /* Free a generic_value *V. */
630 generic_value_free (generic_value
*v
)
635 mpfr_clear (v
->value
.f
);
639 mpz_clear (v
->value
.i
);
647 /* Copy a generic_value *SRC to *DEST. */
650 generic_value_copy (generic_value
*dest
, const generic_value
*src
)
652 dest
->type
= src
->type
;
656 mpfr_init (dest
->value
.f
);
657 assert_exact (mpfr_set (dest
->value
.f
, src
->value
.f
, MPFR_RNDN
));
661 mpz_init (dest
->value
.i
);
662 mpz_set (dest
->value
.i
, src
->value
.i
);
670 /* Initialize data for floating-point formats. */
675 int global_max_exp
= 0, global_min_subnorm_exp
= 0;
676 for (fp_format f
= fp_first_format
; f
< fp_num_formats
; f
++)
678 if (fp_formats
[f
].mant_dig
+ 2 > internal_precision
)
679 internal_precision
= fp_formats
[f
].mant_dig
+ 2;
680 if (fp_formats
[f
].max_exp
> global_max_exp
)
681 global_max_exp
= fp_formats
[f
].max_exp
;
682 int min_subnorm_exp
= fp_formats
[f
].min_exp
- fp_formats
[f
].mant_dig
;
683 if (min_subnorm_exp
< global_min_subnorm_exp
)
684 global_min_subnorm_exp
= min_subnorm_exp
;
685 mpfr_init2 (fp_formats
[f
].max
, fp_formats
[f
].mant_dig
);
686 if (fp_formats
[f
].max_string
!= NULL
)
689 assert_exact (mpfr_strtofr (fp_formats
[f
].max
,
690 fp_formats
[f
].max_string
,
696 assert_exact (mpfr_set_ui_2exp (fp_formats
[f
].max
, 1,
697 fp_formats
[f
].max_exp
,
699 mpfr_nextbelow (fp_formats
[f
].max
);
701 mpfr_init2 (fp_formats
[f
].min
, fp_formats
[f
].mant_dig
);
702 assert_exact (mpfr_set_ui_2exp (fp_formats
[f
].min
, 1,
703 fp_formats
[f
].min_exp
- 1,
705 mpfr_init2 (fp_formats
[f
].subnorm_max
, fp_formats
[f
].mant_dig
);
706 assert_exact (mpfr_set (fp_formats
[f
].subnorm_max
, fp_formats
[f
].min
,
708 mpfr_nextbelow (fp_formats
[f
].subnorm_max
);
709 mpfr_nextbelow (fp_formats
[f
].subnorm_max
);
710 mpfr_init2 (fp_formats
[f
].subnorm_min
, fp_formats
[f
].mant_dig
);
711 assert_exact (mpfr_set_ui_2exp (fp_formats
[f
].subnorm_min
, 1,
712 min_subnorm_exp
, MPFR_RNDN
));
714 mpfr_set_default_prec (internal_precision
);
715 mpfr_init (global_max
);
716 assert_exact (mpfr_set_ui_2exp (global_max
, 1, global_max_exp
, MPFR_RNDN
));
717 mpfr_init (global_min
);
718 assert_exact (mpfr_set_ui_2exp (global_min
, 1, global_min_subnorm_exp
- 1,
722 /* Fill in mpfr_t values for special strings in input arguments. */
725 special_fill_max (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
728 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
729 assert_exact (mpfr_set (res0
, fp_formats
[format
].max
, MPFR_RNDN
));
734 special_fill_minus_max (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
737 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
738 assert_exact (mpfr_neg (res0
, fp_formats
[format
].max
, MPFR_RNDN
));
743 special_fill_min (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
746 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
747 assert_exact (mpfr_set (res0
, fp_formats
[format
].min
, MPFR_RNDN
));
752 special_fill_minus_min (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
755 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
756 assert_exact (mpfr_neg (res0
, fp_formats
[format
].min
, MPFR_RNDN
));
761 special_fill_min_subnorm (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
764 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
765 assert_exact (mpfr_set (res0
, fp_formats
[format
].subnorm_min
, MPFR_RNDN
));
770 special_fill_minus_min_subnorm (mpfr_t res0
,
771 mpfr_t res1
__attribute__ ((unused
)),
774 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
775 assert_exact (mpfr_neg (res0
, fp_formats
[format
].subnorm_min
, MPFR_RNDN
));
780 special_fill_min_subnorm_p120 (mpfr_t res0
,
781 mpfr_t res1
__attribute__ ((unused
)),
784 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
785 assert_exact (mpfr_mul_2ui (res0
, fp_formats
[format
].subnorm_min
,
791 special_fill_pi (mpfr_t res0
, mpfr_t res1
, fp_format format
)
793 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
794 mpfr_const_pi (res0
, MPFR_RNDU
);
795 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
796 mpfr_const_pi (res1
, MPFR_RNDD
);
801 special_fill_minus_pi (mpfr_t res0
, mpfr_t res1
, fp_format format
)
803 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
804 mpfr_const_pi (res0
, MPFR_RNDU
);
805 assert_exact (mpfr_neg (res0
, res0
, MPFR_RNDN
));
806 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
807 mpfr_const_pi (res1
, MPFR_RNDD
);
808 assert_exact (mpfr_neg (res1
, res1
, MPFR_RNDN
));
813 special_fill_pi_2 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
815 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
816 mpfr_const_pi (res0
, MPFR_RNDU
);
817 assert_exact (mpfr_div_ui (res0
, res0
, 2, MPFR_RNDN
));
818 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
819 mpfr_const_pi (res1
, MPFR_RNDD
);
820 assert_exact (mpfr_div_ui (res1
, res1
, 2, MPFR_RNDN
));
825 special_fill_minus_pi_2 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
827 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
828 mpfr_const_pi (res0
, MPFR_RNDU
);
829 assert_exact (mpfr_div_ui (res0
, res0
, 2, MPFR_RNDN
));
830 assert_exact (mpfr_neg (res0
, res0
, MPFR_RNDN
));
831 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
832 mpfr_const_pi (res1
, MPFR_RNDD
);
833 assert_exact (mpfr_div_ui (res1
, res1
, 2, MPFR_RNDN
));
834 assert_exact (mpfr_neg (res1
, res1
, MPFR_RNDN
));
839 special_fill_pi_4 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
841 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
842 assert_exact (mpfr_set_si (res0
, 1, MPFR_RNDN
));
843 mpfr_atan (res0
, res0
, MPFR_RNDU
);
844 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
845 assert_exact (mpfr_set_si (res1
, 1, MPFR_RNDN
));
846 mpfr_atan (res1
, res1
, MPFR_RNDD
);
851 special_fill_pi_6 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
853 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
854 assert_exact (mpfr_set_si_2exp (res0
, 1, -1, MPFR_RNDN
));
855 mpfr_asin (res0
, res0
, MPFR_RNDU
);
856 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
857 assert_exact (mpfr_set_si_2exp (res1
, 1, -1, MPFR_RNDN
));
858 mpfr_asin (res1
, res1
, MPFR_RNDD
);
863 special_fill_minus_pi_6 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
865 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
866 assert_exact (mpfr_set_si_2exp (res0
, -1, -1, MPFR_RNDN
));
867 mpfr_asin (res0
, res0
, MPFR_RNDU
);
868 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
869 assert_exact (mpfr_set_si_2exp (res1
, -1, -1, MPFR_RNDN
));
870 mpfr_asin (res1
, res1
, MPFR_RNDD
);
875 special_fill_pi_3 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
877 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
878 assert_exact (mpfr_set_si_2exp (res0
, 1, -1, MPFR_RNDN
));
879 mpfr_acos (res0
, res0
, MPFR_RNDU
);
880 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
881 assert_exact (mpfr_set_si_2exp (res1
, 1, -1, MPFR_RNDN
));
882 mpfr_acos (res1
, res1
, MPFR_RNDD
);
887 special_fill_2pi_3 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
889 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
890 assert_exact (mpfr_set_si_2exp (res0
, -1, -1, MPFR_RNDN
));
891 mpfr_acos (res0
, res0
, MPFR_RNDU
);
892 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
893 assert_exact (mpfr_set_si_2exp (res1
, -1, -1, MPFR_RNDN
));
894 mpfr_acos (res1
, res1
, MPFR_RNDD
);
899 special_fill_2pi (mpfr_t res0
, mpfr_t res1
, fp_format format
)
901 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
902 mpfr_const_pi (res0
, MPFR_RNDU
);
903 assert_exact (mpfr_mul_ui (res0
, res0
, 2, MPFR_RNDN
));
904 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
905 mpfr_const_pi (res1
, MPFR_RNDD
);
906 assert_exact (mpfr_mul_ui (res1
, res1
, 2, MPFR_RNDN
));
911 special_fill_e (mpfr_t res0
, mpfr_t res1
, fp_format format
)
913 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
914 assert_exact (mpfr_set_si (res0
, 1, MPFR_RNDN
));
915 mpfr_exp (res0
, res0
, MPFR_RNDU
);
916 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
917 assert_exact (mpfr_set_si (res1
, 1, MPFR_RNDN
));
918 mpfr_exp (res1
, res1
, MPFR_RNDD
);
923 special_fill_1_e (mpfr_t res0
, mpfr_t res1
, fp_format format
)
925 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
926 assert_exact (mpfr_set_si (res0
, -1, MPFR_RNDN
));
927 mpfr_exp (res0
, res0
, MPFR_RNDU
);
928 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
929 assert_exact (mpfr_set_si (res1
, -1, MPFR_RNDN
));
930 mpfr_exp (res1
, res1
, MPFR_RNDD
);
935 special_fill_e_minus_1 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
937 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
938 assert_exact (mpfr_set_si (res0
, 1, MPFR_RNDN
));
939 mpfr_expm1 (res0
, res0
, MPFR_RNDU
);
940 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
941 assert_exact (mpfr_set_si (res1
, 1, MPFR_RNDN
));
942 mpfr_expm1 (res1
, res1
, MPFR_RNDD
);
946 /* A special string accepted in input arguments. */
951 /* The function that interprets it for a given floating-point
952 format, filling in up to two mpfr_t values and returning the
953 number of values filled. */
954 size_t (*func
) (mpfr_t
, mpfr_t
, fp_format
);
955 } special_real_input
;
957 /* List of special strings accepted in input arguments. */
959 static const special_real_input special_real_inputs
[] =
961 { "max", special_fill_max
},
962 { "-max", special_fill_minus_max
},
963 { "min", special_fill_min
},
964 { "-min", special_fill_minus_min
},
965 { "min_subnorm", special_fill_min_subnorm
},
966 { "-min_subnorm", special_fill_minus_min_subnorm
},
967 { "min_subnorm_p120", special_fill_min_subnorm_p120
},
968 { "pi", special_fill_pi
},
969 { "-pi", special_fill_minus_pi
},
970 { "pi/2", special_fill_pi_2
},
971 { "-pi/2", special_fill_minus_pi_2
},
972 { "pi/4", special_fill_pi_4
},
973 { "pi/6", special_fill_pi_6
},
974 { "-pi/6", special_fill_minus_pi_6
},
975 { "pi/3", special_fill_pi_3
},
976 { "2pi/3", special_fill_2pi_3
},
977 { "2pi", special_fill_2pi
},
978 { "e", special_fill_e
},
979 { "1/e", special_fill_1_e
},
980 { "e-1", special_fill_e_minus_1
},
983 /* Given a real number R computed in round-to-zero mode, set the
984 lowest bit as a sticky bit if INEXACT, and saturate the exponent
985 range for very large or small values. */
988 adjust_real (mpfr_t r
, bool inexact
)
992 /* NaNs are exact, as are infinities in round-to-zero mode. */
993 assert (mpfr_number_p (r
));
994 if (mpfr_cmpabs (r
, global_min
) < 0)
995 assert_exact (mpfr_copysign (r
, global_min
, r
, MPFR_RNDN
));
996 else if (mpfr_cmpabs (r
, global_max
) > 0)
997 assert_exact (mpfr_copysign (r
, global_max
, r
, MPFR_RNDN
));
1002 mpfr_exp_t e
= mpfr_get_z_2exp (tmp
, r
);
1003 if (mpz_sgn (tmp
) < 0)
1006 mpz_setbit (tmp
, 0);
1010 mpz_setbit (tmp
, 0);
1011 assert_exact (mpfr_set_z_2exp (r
, tmp
, e
, MPFR_RNDN
));
1016 /* Given a finite real number R with sticky bit, compute the roundings
1017 to FORMAT in each rounding mode, storing the results in RES, the
1018 before-rounding exceptions in EXC_BEFORE and the after-rounding
1019 exceptions in EXC_AFTER. */
1022 round_real (mpfr_t res
[rm_num_modes
],
1023 unsigned int exc_before
[rm_num_modes
],
1024 unsigned int exc_after
[rm_num_modes
],
1025 mpfr_t r
, fp_format format
)
1027 assert (mpfr_number_p (r
));
1028 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1030 mpfr_init2 (res
[m
], fp_formats
[format
].mant_dig
);
1031 exc_before
[m
] = exc_after
[m
] = 0;
1032 bool inexact
= mpfr_set (res
[m
], r
, rounding_modes
[m
].mpfr_mode
);
1033 if (mpfr_cmpabs (res
[m
], fp_formats
[format
].max
) > 0)
1036 exc_before
[m
] |= 1U << exc_overflow
;
1037 exc_after
[m
] |= 1U << exc_overflow
;
1042 overflow_inf
= true;
1045 overflow_inf
= false;
1048 overflow_inf
= mpfr_signbit (res
[m
]);
1051 overflow_inf
= !mpfr_signbit (res
[m
]);
1057 mpfr_set_inf (res
[m
], mpfr_signbit (res
[m
]) ? -1 : 1);
1059 assert_exact (mpfr_copysign (res
[m
], fp_formats
[format
].max
,
1060 res
[m
], MPFR_RNDN
));
1062 if (mpfr_cmpabs (r
, fp_formats
[format
].min
) < 0)
1064 /* Tiny before rounding; may or may not be tiny after
1065 rounding, and underflow applies only if also inexact
1066 around rounding to a possibly subnormal value. */
1067 bool tiny_after_rounding
1068 = mpfr_cmpabs (res
[m
], fp_formats
[format
].min
) < 0;
1069 /* To round to a possibly subnormal value, and determine
1070 inexactness as a subnormal in the process, scale up and
1071 round to integer, then scale back down. */
1074 assert_exact (mpfr_mul_2si (tmp
, r
, (fp_formats
[format
].mant_dig
1075 - fp_formats
[format
].min_exp
),
1077 int rint_res
= mpfr_rint (tmp
, tmp
, rounding_modes
[m
].mpfr_mode
);
1078 /* The integer must be representable. */
1079 assert (rint_res
== 0 || rint_res
== 2 || rint_res
== -2);
1080 /* If rounding to full precision was inexact, so must
1081 rounding to subnormal precision be inexact. */
1083 assert (rint_res
!= 0);
1085 inexact
= rint_res
!= 0;
1086 assert_exact (mpfr_mul_2si (res
[m
], tmp
,
1087 (fp_formats
[format
].min_exp
1088 - fp_formats
[format
].mant_dig
),
1093 exc_before
[m
] |= 1U << exc_underflow
;
1094 if (tiny_after_rounding
)
1095 exc_after
[m
] |= 1U << exc_underflow
;
1100 exc_before
[m
] |= 1U << exc_inexact
;
1101 exc_after
[m
] |= 1U << exc_inexact
;
1106 /* Handle the input argument at ARG (NUL-terminated), updating the
1107 lists of test inputs in IT accordingly. NUM_PREV_ARGS arguments
1108 are already in those lists. If EXACT_ARGS, interpret a value given
1109 as a floating-point constant exactly (it must be exact for some
1110 supported format) rather than rounding up and down. The argument,
1111 of type GTYPE, comes from file FILENAME, line LINENO. */
1114 handle_input_arg (const char *arg
, input_test
*it
, size_t num_prev_args
,
1115 generic_value_type gtype
, bool exact_args
,
1116 const char *filename
, unsigned int lineno
)
1118 size_t num_values
= 0;
1119 generic_value values
[2 * fp_num_formats
];
1120 bool check_empty_list
= false;
1124 for (fp_format f
= fp_first_format
; f
< fp_num_formats
; f
++)
1126 mpfr_t extra_values
[2];
1127 size_t num_extra_values
= 0;
1128 for (size_t i
= 0; i
< ARRAY_SIZE (special_real_inputs
); i
++)
1130 if (strcmp (arg
, special_real_inputs
[i
].str
) == 0)
1133 = special_real_inputs
[i
].func (extra_values
[0],
1134 extra_values
[1], f
);
1135 assert (num_extra_values
> 0
1136 && num_extra_values
<= ARRAY_SIZE (extra_values
));
1140 if (num_extra_values
== 0)
1145 check_empty_list
= true;
1147 bool inexact
= mpfr_strtofr (tmp
, arg
, &ep
, 0, MPFR_RNDZ
);
1148 if (*ep
!= 0 || !mpfr_number_p (tmp
))
1149 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1150 "bad floating-point argument: '%s'", arg
);
1151 adjust_real (tmp
, inexact
);
1152 mpfr_t rounded
[rm_num_modes
];
1153 unsigned int exc_before
[rm_num_modes
];
1154 unsigned int exc_after
[rm_num_modes
];
1155 round_real (rounded
, exc_before
, exc_after
, tmp
, f
);
1157 if (mpfr_number_p (rounded
[rm_upward
])
1158 && (!exact_args
|| mpfr_equal_p (rounded
[rm_upward
],
1159 rounded
[rm_downward
])))
1161 mpfr_init2 (extra_values
[num_extra_values
],
1162 fp_formats
[f
].mant_dig
);
1163 assert_exact (mpfr_set (extra_values
[num_extra_values
],
1164 rounded
[rm_upward
], MPFR_RNDN
));
1167 if (mpfr_number_p (rounded
[rm_downward
]) && !exact_args
)
1169 mpfr_init2 (extra_values
[num_extra_values
],
1170 fp_formats
[f
].mant_dig
);
1171 assert_exact (mpfr_set (extra_values
[num_extra_values
],
1172 rounded
[rm_downward
], MPFR_RNDN
));
1175 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1176 mpfr_clear (rounded
[m
]);
1178 for (size_t i
= 0; i
< num_extra_values
; i
++)
1181 for (size_t j
= 0; j
< num_values
; j
++)
1183 if (mpfr_equal_p (values
[j
].value
.f
, extra_values
[i
])
1184 && ((mpfr_signbit (values
[j
].value
.f
) != 0)
1185 == (mpfr_signbit (extra_values
[i
]) != 0)))
1193 assert (num_values
< ARRAY_SIZE (values
));
1194 values
[num_values
].type
= gtype_fp
;
1195 mpfr_init2 (values
[num_values
].value
.f
,
1196 fp_formats
[f
].mant_dig
);
1197 assert_exact (mpfr_set (values
[num_values
].value
.f
,
1198 extra_values
[i
], MPFR_RNDN
));
1201 mpfr_clear (extra_values
[i
]);
1208 values
[0].type
= gtype_int
;
1209 int ret
= mpz_init_set_str (values
[0].value
.i
, arg
, 0);
1211 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1212 "bad integer argument: '%s'", arg
);
1218 if (check_empty_list
&& num_values
== 0)
1219 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1220 "floating-point argument not exact for any format: '%s'",
1222 assert (num_values
> 0 && num_values
<= ARRAY_SIZE (values
));
1223 if (it
->num_input_cases
>= SIZE_MAX
/ num_values
)
1224 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
, "too many input cases");
1225 generic_value
**old_inputs
= it
->inputs
;
1226 size_t new_num_input_cases
= it
->num_input_cases
* num_values
;
1227 generic_value
**new_inputs
= xmalloc (new_num_input_cases
1228 * sizeof (new_inputs
[0]));
1229 for (size_t i
= 0; i
< it
->num_input_cases
; i
++)
1231 for (size_t j
= 0; j
< num_values
; j
++)
1233 size_t idx
= i
* num_values
+ j
;
1234 new_inputs
[idx
] = xmalloc ((num_prev_args
+ 1)
1235 * sizeof (new_inputs
[idx
][0]));
1236 for (size_t k
= 0; k
< num_prev_args
; k
++)
1237 generic_value_copy (&new_inputs
[idx
][k
], &old_inputs
[i
][k
]);
1238 generic_value_copy (&new_inputs
[idx
][num_prev_args
], &values
[j
]);
1240 for (size_t j
= 0; j
< num_prev_args
; j
++)
1241 generic_value_free (&old_inputs
[i
][j
]);
1242 free (old_inputs
[i
]);
1245 for (size_t i
= 0; i
< num_values
; i
++)
1246 generic_value_free (&values
[i
]);
1247 it
->inputs
= new_inputs
;
1248 it
->num_input_cases
= new_num_input_cases
;
1251 /* Handle the input flag ARG (NUL-terminated), storing it in *FLAG.
1252 The flag comes from file FILENAME, line LINENO. */
1255 handle_input_flag (char *arg
, input_flag
*flag
,
1256 const char *filename
, unsigned int lineno
)
1258 char *ep
= strchr (arg
, ':');
1261 ep
= strchr (arg
, 0);
1262 assert (ep
!= NULL
);
1267 for (input_flag_type i
= flag_first_flag
; i
<= num_input_flag_types
; i
++)
1269 if (strcmp (arg
, input_flags
[i
]) == 0)
1277 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
, "unknown flag: '%s'",
1283 flag
->cond
= xstrdup (ep
);
1286 /* Add the test LINE (file FILENAME, line LINENO) to the test
1290 add_test (char *line
, const char *filename
, unsigned int lineno
)
1292 size_t num_tokens
= 1;
1294 while ((p
= strchr (p
, ' ')) != NULL
)
1300 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1301 "line too short: '%s'", line
);
1302 p
= strchr (line
, ' ');
1303 size_t func_name_len
= p
- line
;
1304 for (size_t i
= 0; i
< ARRAY_SIZE (test_functions
); i
++)
1306 if (func_name_len
== strlen (test_functions
[i
].name
)
1307 && strncmp (line
, test_functions
[i
].name
, func_name_len
) == 0)
1309 test_function
*tf
= &test_functions
[i
];
1310 if (num_tokens
< 1 + tf
->num_args
)
1311 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1312 "line too short: '%s'", line
);
1313 if (tf
->num_tests
== tf
->num_tests_alloc
)
1315 tf
->num_tests_alloc
= 2 * tf
->num_tests_alloc
+ 16;
1317 = xrealloc (tf
->tests
,
1318 tf
->num_tests_alloc
* sizeof (tf
->tests
[0]));
1320 input_test
*it
= &tf
->tests
[tf
->num_tests
];
1322 it
->num_input_cases
= 1;
1323 it
->inputs
= xmalloc (sizeof (it
->inputs
[0]));
1324 it
->inputs
[0] = NULL
;
1325 it
->old_output
= NULL
;
1327 for (size_t j
= 0; j
< tf
->num_args
; j
++)
1329 char *ep
= strchr (p
, ' ');
1332 ep
= strchr (p
, '\n');
1333 assert (ep
!= NULL
);
1336 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1337 "empty token in line: '%s'", line
);
1338 for (char *t
= p
; t
< ep
; t
++)
1339 if (isspace ((unsigned char) *t
))
1340 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1341 "whitespace in token in line: '%s'", line
);
1344 handle_input_arg (p
, it
, j
,
1345 generic_arg_ret_type (tf
->arg_types
[j
]),
1346 tf
->exact_args
, filename
, lineno
);
1350 it
->num_flags
= num_tokens
- 1 - tf
->num_args
;
1351 it
->flags
= xmalloc (it
->num_flags
* sizeof (it
->flags
[0]));
1352 for (size_t j
= 0; j
< it
->num_flags
; j
++)
1354 char *ep
= strchr (p
, ' ');
1357 ep
= strchr (p
, '\n');
1358 assert (ep
!= NULL
);
1361 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1362 "empty token in line: '%s'", line
);
1363 for (char *t
= p
; t
< ep
; t
++)
1364 if (isspace ((unsigned char) *t
))
1365 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1366 "whitespace in token in line: '%s'", line
);
1369 handle_input_flag (p
, &it
->flags
[j
], filename
, lineno
);
1378 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1379 "unknown function in line: '%s'", line
);
1382 /* Read in the test input data from FILENAME. */
1385 read_input (const char *filename
)
1387 FILE *fp
= fopen (filename
, "r");
1389 error (EXIT_FAILURE
, errno
, "open '%s'", filename
);
1390 unsigned int lineno
= 0;
1395 ssize_t ret
= getline (&line
, &size
, fp
);
1399 if (line
[0] == '#' || line
[0] == '\n')
1401 add_test (line
, filename
, lineno
);
1404 error (EXIT_FAILURE
, errno
, "read from '%s'", filename
);
1405 if (fclose (fp
) != 0)
1406 error (EXIT_FAILURE
, errno
, "close '%s'", filename
);
1409 /* Calculate the generic results (round-to-zero with sticky bit) for
1410 the function described by CALC, with inputs INPUTS, if MODE is
1411 rm_towardzero; for other modes, calculate results in that mode,
1412 which must be exact zero results. */
1415 calc_generic_results (generic_value
*outputs
, generic_value
*inputs
,
1416 const func_calc_desc
*calc
, rounding_mode mode
)
1421 mpfr_rnd_t mode_mpfr
= rounding_modes
[mode
].mpfr_mode
;
1422 mpc_rnd_t mode_mpc
= rounding_modes
[mode
].mpc_mode
;
1424 switch (calc
->method
)
1427 assert (inputs
[0].type
== gtype_fp
);
1428 outputs
[0].type
= gtype_fp
;
1429 mpfr_init (outputs
[0].value
.f
);
1430 inexact
= calc
->func
.mpfr_f_f (outputs
[0].value
.f
, inputs
[0].value
.f
,
1432 if (mode
!= rm_towardzero
)
1433 assert (!inexact
&& mpfr_zero_p (outputs
[0].value
.f
));
1434 adjust_real (outputs
[0].value
.f
, inexact
);
1438 assert (inputs
[0].type
== gtype_fp
);
1439 assert (inputs
[1].type
== gtype_fp
);
1440 outputs
[0].type
= gtype_fp
;
1441 mpfr_init (outputs
[0].value
.f
);
1442 inexact
= calc
->func
.mpfr_ff_f (outputs
[0].value
.f
, inputs
[0].value
.f
,
1443 inputs
[1].value
.f
, mode_mpfr
);
1444 if (mode
!= rm_towardzero
)
1445 assert (!inexact
&& mpfr_zero_p (outputs
[0].value
.f
));
1446 adjust_real (outputs
[0].value
.f
, inexact
);
1450 assert (inputs
[0].type
== gtype_fp
);
1451 assert (inputs
[1].type
== gtype_fp
);
1452 assert (inputs
[2].type
== gtype_fp
);
1453 outputs
[0].type
= gtype_fp
;
1454 mpfr_init (outputs
[0].value
.f
);
1455 inexact
= calc
->func
.mpfr_fff_f (outputs
[0].value
.f
, inputs
[0].value
.f
,
1456 inputs
[1].value
.f
, inputs
[2].value
.f
,
1458 if (mode
!= rm_towardzero
)
1459 assert (!inexact
&& mpfr_zero_p (outputs
[0].value
.f
));
1460 adjust_real (outputs
[0].value
.f
, inexact
);
1464 assert (inputs
[0].type
== gtype_fp
);
1465 outputs
[0].type
= gtype_fp
;
1466 outputs
[1].type
= gtype_int
;
1467 mpfr_init (outputs
[0].value
.f
);
1469 inexact
= calc
->func
.mpfr_f_f1 (outputs
[0].value
.f
, &i
,
1470 inputs
[0].value
.f
, mode_mpfr
);
1471 if (mode
!= rm_towardzero
)
1472 assert (!inexact
&& mpfr_zero_p (outputs
[0].value
.f
));
1473 adjust_real (outputs
[0].value
.f
, inexact
);
1474 mpz_init_set_si (outputs
[1].value
.i
, i
);
1478 assert (inputs
[0].type
== gtype_int
);
1479 assert (inputs
[1].type
== gtype_fp
);
1480 outputs
[0].type
= gtype_fp
;
1481 mpfr_init (outputs
[0].value
.f
);
1482 assert (mpz_fits_slong_p (inputs
[0].value
.i
));
1483 long l
= mpz_get_si (inputs
[0].value
.i
);
1484 inexact
= calc
->func
.mpfr_if_f (outputs
[0].value
.f
, l
,
1485 inputs
[1].value
.f
, mode_mpfr
);
1486 if (mode
!= rm_towardzero
)
1487 assert (!inexact
&& mpfr_zero_p (outputs
[0].value
.f
));
1488 adjust_real (outputs
[0].value
.f
, inexact
);
1492 assert (inputs
[0].type
== gtype_fp
);
1493 outputs
[0].type
= gtype_fp
;
1494 mpfr_init (outputs
[0].value
.f
);
1495 outputs
[1].type
= gtype_fp
;
1496 mpfr_init (outputs
[1].value
.f
);
1497 int comb_ternary
= calc
->func
.mpfr_f_11 (outputs
[0].value
.f
,
1501 if (mode
!= rm_towardzero
)
1502 assert (((comb_ternary
& 0x3) == 0
1503 && mpfr_zero_p (outputs
[0].value
.f
))
1504 || ((comb_ternary
& 0xc) == 0
1505 && mpfr_zero_p (outputs
[1].value
.f
)));
1506 adjust_real (outputs
[0].value
.f
, (comb_ternary
& 0x3) != 0);
1507 adjust_real (outputs
[1].value
.f
, (comb_ternary
& 0xc) != 0);
1511 assert (inputs
[0].type
== gtype_fp
);
1512 assert (inputs
[1].type
== gtype_fp
);
1513 outputs
[0].type
= gtype_fp
;
1514 mpfr_init (outputs
[0].value
.f
);
1515 mpc_init2 (ci1
, internal_precision
);
1516 assert_exact (mpc_set_fr_fr (ci1
, inputs
[0].value
.f
, inputs
[1].value
.f
,
1518 inexact
= calc
->func
.mpc_c_f (outputs
[0].value
.f
, ci1
, mode_mpfr
);
1519 if (mode
!= rm_towardzero
)
1520 assert (!inexact
&& mpfr_zero_p (outputs
[0].value
.f
));
1521 adjust_real (outputs
[0].value
.f
, inexact
);
1526 assert (inputs
[0].type
== gtype_fp
);
1527 assert (inputs
[1].type
== gtype_fp
);
1528 outputs
[0].type
= gtype_fp
;
1529 mpfr_init (outputs
[0].value
.f
);
1530 outputs
[1].type
= gtype_fp
;
1531 mpfr_init (outputs
[1].value
.f
);
1532 mpc_init2 (ci1
, internal_precision
);
1533 mpc_init2 (co
, internal_precision
);
1534 assert_exact (mpc_set_fr_fr (ci1
, inputs
[0].value
.f
, inputs
[1].value
.f
,
1536 mpc_ternary
= calc
->func
.mpc_c_c (co
, ci1
, mode_mpc
);
1537 if (mode
!= rm_towardzero
)
1538 assert ((!MPC_INEX_RE (mpc_ternary
)
1539 && mpfr_zero_p (mpc_realref (co
)))
1540 || (!MPC_INEX_IM (mpc_ternary
)
1541 && mpfr_zero_p (mpc_imagref (co
))));
1542 assert_exact (mpfr_set (outputs
[0].value
.f
, mpc_realref (co
),
1544 assert_exact (mpfr_set (outputs
[1].value
.f
, mpc_imagref (co
),
1546 adjust_real (outputs
[0].value
.f
, MPC_INEX_RE (mpc_ternary
));
1547 adjust_real (outputs
[1].value
.f
, MPC_INEX_IM (mpc_ternary
));
1553 assert (inputs
[0].type
== gtype_fp
);
1554 assert (inputs
[1].type
== gtype_fp
);
1555 assert (inputs
[2].type
== gtype_fp
);
1556 assert (inputs
[3].type
== gtype_fp
);
1557 outputs
[0].type
= gtype_fp
;
1558 mpfr_init (outputs
[0].value
.f
);
1559 outputs
[1].type
= gtype_fp
;
1560 mpfr_init (outputs
[1].value
.f
);
1561 mpc_init2 (ci1
, internal_precision
);
1562 mpc_init2 (ci2
, internal_precision
);
1563 mpc_init2 (co
, internal_precision
);
1564 assert_exact (mpc_set_fr_fr (ci1
, inputs
[0].value
.f
, inputs
[1].value
.f
,
1566 assert_exact (mpc_set_fr_fr (ci2
, inputs
[2].value
.f
, inputs
[3].value
.f
,
1568 mpc_ternary
= calc
->func
.mpc_cc_c (co
, ci1
, ci2
, mode_mpc
);
1569 if (mode
!= rm_towardzero
)
1570 assert ((!MPC_INEX_RE (mpc_ternary
)
1571 && mpfr_zero_p (mpc_realref (co
)))
1572 || (!MPC_INEX_IM (mpc_ternary
)
1573 && mpfr_zero_p (mpc_imagref (co
))));
1574 assert_exact (mpfr_set (outputs
[0].value
.f
, mpc_realref (co
),
1576 assert_exact (mpfr_set (outputs
[1].value
.f
, mpc_imagref (co
),
1578 adjust_real (outputs
[0].value
.f
, MPC_INEX_RE (mpc_ternary
));
1579 adjust_real (outputs
[1].value
.f
, MPC_INEX_IM (mpc_ternary
));
1590 /* Return the number of bits for integer type TYPE, where "long" has
1591 LONG_BITS bits (32 or 64). */
1594 int_type_bits (arg_ret_type type
, int long_bits
)
1596 assert (long_bits
== 32 || long_bits
== 64);
1607 case type_long_long
:
1616 /* Check whether an integer Z fits a given type TYPE, where "long" has
1617 LONG_BITS bits (32 or 64). */
1620 int_fits_type (mpz_t z
, arg_ret_type type
, int long_bits
)
1622 int bits
= int_type_bits (type
, long_bits
);
1626 mpz_ui_pow_ui (t
, 2, bits
- 1);
1627 if (mpz_cmp (z
, t
) >= 0)
1630 if (mpz_cmp (z
, t
) < 0)
1636 /* Print a generic value V to FP (name FILENAME), preceded by a space,
1637 for type TYPE, floating-point format FORMAT, LONG_BITS bits per
1638 long, printing " IGNORE" instead if IGNORE. */
1641 output_generic_value (FILE *fp
, const char *filename
, const generic_value
*v
,
1642 bool ignore
, arg_ret_type type
, fp_format format
,
1647 if (fputs (" IGNORE", fp
) < 0)
1648 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1651 assert (v
->type
== generic_arg_ret_type (type
));
1656 suffix
= fp_formats
[format
].suffix
;
1667 case type_long_long
:
1677 if (mpfr_inf_p (v
->value
.f
))
1679 if (fputs ((mpfr_signbit (v
->value
.f
)
1680 ? " minus_infty" : " plus_infty"), fp
) < 0)
1681 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1685 assert (mpfr_number_p (v
->value
.f
));
1686 if (mpfr_fprintf (fp
, " %Ra%s", v
->value
.f
, suffix
) < 0)
1687 error (EXIT_FAILURE
, errno
, "mpfr_fprintf to '%s'", filename
);
1692 int bits
= int_type_bits (type
, long_bits
);
1695 mpz_ui_pow_ui (tmp
, 2, bits
- 1);
1697 if (mpz_cmp (v
->value
.i
, tmp
) == 0)
1699 mpz_add_ui (tmp
, tmp
, 1);
1700 if (mpfr_fprintf (fp
, " (%Zd%s-1)", tmp
, suffix
) < 0)
1701 error (EXIT_FAILURE
, errno
, "mpfr_fprintf to '%s'", filename
);
1705 if (mpfr_fprintf (fp
, " %Zd%s", v
->value
.i
, suffix
) < 0)
1706 error (EXIT_FAILURE
, errno
, "mpfr_fprintf to '%s'", filename
);
1716 /* Generate test output to FP (name FILENAME) for test function TF,
1717 input test IT, choice of input values INPUTS. */
1720 output_for_one_input_case (FILE *fp
, const char *filename
, test_function
*tf
,
1721 input_test
*it
, generic_value
*inputs
)
1723 bool long_bits_matters
= false;
1724 bool fits_long32
= true;
1725 for (size_t i
= 0; i
< tf
->num_args
; i
++)
1727 generic_value_type gtype
= generic_arg_ret_type (tf
->arg_types
[i
]);
1728 assert (inputs
[i
].type
== gtype
);
1729 if (gtype
== gtype_int
)
1731 bool fits_64
= int_fits_type (inputs
[i
].value
.i
, tf
->arg_types
[i
],
1735 if (tf
->arg_types
[i
] == type_long
1736 && !int_fits_type (inputs
[i
].value
.i
, tf
->arg_types
[i
], 32))
1738 long_bits_matters
= true;
1739 fits_long32
= false;
1743 generic_value generic_outputs
[MAX_NRET
];
1744 calc_generic_results (generic_outputs
, inputs
, &tf
->calc
, rm_towardzero
);
1745 bool ignore_output_long32
[MAX_NRET
] = { false };
1746 bool ignore_output_long64
[MAX_NRET
] = { false };
1747 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
1749 assert (generic_outputs
[i
].type
1750 == generic_arg_ret_type (tf
->ret_types
[i
]));
1751 switch (generic_outputs
[i
].type
)
1754 if (!mpfr_number_p (generic_outputs
[i
].value
.f
))
1755 goto out
; /* Result is NaN or exact infinity. */
1759 ignore_output_long32
[i
] = !int_fits_type (generic_outputs
[i
].value
.i
,
1760 tf
->ret_types
[i
], 32);
1761 ignore_output_long64
[i
] = !int_fits_type (generic_outputs
[i
].value
.i
,
1762 tf
->ret_types
[i
], 64);
1763 if (ignore_output_long32
[i
] != ignore_output_long64
[i
])
1764 long_bits_matters
= true;
1771 /* Iterate over relevant sizes of long and floating-point formats. */
1772 for (int long_bits
= 32; long_bits
<= 64; long_bits
+= 32)
1774 if (long_bits
== 32 && !fits_long32
)
1776 if (long_bits
== 64 && !long_bits_matters
)
1778 const char *long_cond
;
1779 if (long_bits_matters
)
1780 long_cond
= (long_bits
== 32 ? ":long32" : ":long64");
1783 bool *ignore_output
= (long_bits
== 32
1784 ? ignore_output_long32
1785 : ignore_output_long64
);
1786 for (fp_format f
= fp_first_format
; f
< fp_num_formats
; f
++)
1789 mpfr_t res
[rm_num_modes
];
1790 unsigned int exc_before
[rm_num_modes
];
1791 unsigned int exc_after
[rm_num_modes
];
1792 for (size_t i
= 0; i
< tf
->num_args
; i
++)
1794 if (inputs
[i
].type
== gtype_fp
)
1796 round_real (res
, exc_before
, exc_after
, inputs
[i
].value
.f
,
1798 if (!mpfr_equal_p (res
[rm_tonearest
], inputs
[i
].value
.f
))
1800 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1801 mpfr_clear (res
[m
]);
1808 /* The inputs fit this type, so compute the ideal outputs
1810 mpfr_t all_res
[MAX_NRET
][rm_num_modes
];
1811 unsigned int all_exc_before
[MAX_NRET
][rm_num_modes
];
1812 unsigned int all_exc_after
[MAX_NRET
][rm_num_modes
];
1813 unsigned int merged_exc_before
[rm_num_modes
] = { 0 };
1814 unsigned int merged_exc_after
[rm_num_modes
] = { 0 };
1815 /* For functions not exactly determined, track whether
1816 underflow is required (some result is inexact, and
1817 magnitude does not exceed the greatest magnitude
1818 subnormal), and permitted (not an exact zero, and
1819 magnitude does not exceed the least magnitude
1821 bool must_underflow
= false;
1822 bool may_underflow
= false;
1823 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
1825 switch (generic_outputs
[i
].type
)
1828 round_real (all_res
[i
], all_exc_before
[i
], all_exc_after
[i
],
1829 generic_outputs
[i
].value
.f
, f
);
1830 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1832 merged_exc_before
[m
] |= all_exc_before
[i
][m
];
1833 merged_exc_after
[m
] |= all_exc_after
[i
][m
];
1837 |= ((all_exc_before
[i
][m
]
1838 & (1U << exc_inexact
)) != 0
1839 && (mpfr_cmpabs (generic_outputs
[i
].value
.f
,
1840 fp_formats
[f
].subnorm_max
)
1843 |= (!mpfr_zero_p (generic_outputs
[i
].value
.f
)
1844 && mpfr_cmpabs (generic_outputs
[i
].value
.f
,
1845 fp_formats
[f
].min
) <= 0);
1847 /* If the result is an exact zero, the sign may
1848 depend on the rounding mode, so recompute it
1849 directly in that mode. */
1850 if (mpfr_zero_p (all_res
[i
][m
])
1851 && (all_exc_before
[i
][m
] & (1U << exc_inexact
)) == 0)
1853 generic_value outputs_rm
[MAX_NRET
];
1854 calc_generic_results (outputs_rm
, inputs
,
1856 assert_exact (mpfr_set (all_res
[i
][m
],
1857 outputs_rm
[i
].value
.f
,
1859 for (size_t j
= 0; j
< tf
->num_ret
; j
++)
1860 generic_value_free (&outputs_rm
[j
]);
1866 if (ignore_output
[i
])
1867 for (rounding_mode m
= rm_first_mode
;
1871 merged_exc_before
[m
] |= 1U << exc_invalid
;
1872 merged_exc_after
[m
] |= 1U << exc_invalid
;
1880 assert (may_underflow
|| !must_underflow
);
1881 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1883 bool before_after_matters
1884 = tf
->exact
&& merged_exc_before
[m
] != merged_exc_after
[m
];
1885 if (before_after_matters
)
1887 assert ((merged_exc_before
[m
] ^ merged_exc_after
[m
])
1888 == (1U << exc_underflow
));
1889 assert ((merged_exc_before
[m
] & (1U << exc_underflow
)) != 0);
1891 unsigned int merged_exc
= merged_exc_before
[m
];
1892 if (fprintf (fp
, "= %s %s %s%s", tf
->name
,
1893 rounding_modes
[m
].name
, fp_formats
[f
].name
,
1895 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1897 for (size_t i
= 0; i
< tf
->num_args
; i
++)
1898 output_generic_value (fp
, filename
, &inputs
[i
], false,
1899 tf
->arg_types
[i
], f
, long_bits
);
1900 if (fputs (" :", fp
) < 0)
1901 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1902 /* Print outputs. */
1903 bool must_erange
= false;
1904 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
1907 g
.type
= generic_outputs
[i
].type
;
1911 if (mpfr_inf_p (all_res
[i
][m
])
1912 && (all_exc_before
[i
][m
]
1913 & (1U << exc_overflow
)) != 0)
1915 if (mpfr_zero_p (all_res
[i
][m
])
1917 || mpfr_zero_p (all_res
[i
][rm_tonearest
]))
1918 && (all_exc_before
[i
][m
]
1919 & (1U << exc_underflow
)) != 0)
1921 mpfr_init2 (g
.value
.f
, fp_formats
[f
].mant_dig
);
1922 assert_exact (mpfr_set (g
.value
.f
, all_res
[i
][m
],
1927 mpz_init (g
.value
.i
);
1928 mpz_set (g
.value
.i
, generic_outputs
[i
].value
.i
);
1934 output_generic_value (fp
, filename
, &g
, ignore_output
[i
],
1935 tf
->ret_types
[i
], f
, long_bits
);
1936 generic_value_free (&g
);
1938 if (fputs (" :", fp
) < 0)
1939 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1940 /* Print miscellaneous flags (passed through from
1942 for (size_t i
= 0; i
< it
->num_flags
; i
++)
1943 switch (it
->flags
[i
].type
)
1945 case flag_no_test_inline
:
1947 if (fprintf (fp
, " %s%s",
1948 input_flags
[it
->flags
[i
].type
],
1952 error (EXIT_FAILURE
, errno
, "write to '%s'",
1955 case flag_xfail_rounding
:
1956 if (m
!= rm_tonearest
)
1957 if (fprintf (fp
, " xfail%s",
1961 error (EXIT_FAILURE
, errno
, "write to '%s'",
1967 /* Print exception flags and compute errno
1968 expectations where not already computed. */
1969 bool may_edom
= false;
1970 bool must_edom
= false;
1971 bool may_erange
= must_erange
|| may_underflow
;
1972 for (fp_exception e
= exc_first_exception
;
1973 e
< exc_num_exceptions
;
1976 bool expect_e
= (merged_exc
& (1U << e
)) != 0;
1977 bool e_optional
= false;
1982 may_erange
= must_erange
= true;
1992 may_edom
= must_edom
= true;
2005 if (may_underflow
&& !must_underflow
)
2014 assert (!before_after_matters
);
2015 if (fprintf (fp
, " %s-ok", exceptions
[e
]) < 0)
2016 error (EXIT_FAILURE
, errno
, "write to '%s'",
2022 if (fprintf (fp
, " %s", exceptions
[e
]) < 0)
2023 error (EXIT_FAILURE
, errno
, "write to '%s'",
2025 if (before_after_matters
&& e
== exc_underflow
)
2026 if (fputs (":before-rounding", fp
) < 0)
2027 error (EXIT_FAILURE
, errno
, "write to '%s'",
2029 for (int after
= 0; after
<= 1; after
++)
2031 bool expect_e_here
= expect_e
;
2032 if (after
== 1 && (!before_after_matters
2033 || e
!= exc_underflow
))
2035 const char *after_cond
;
2036 if (before_after_matters
&& e
== exc_underflow
)
2040 : ":before-rounding");
2041 expect_e_here
= !after
;
2045 input_flag_type okflag
;
2046 okflag
= (expect_e_here
2047 ? flag_missing_first
2048 : flag_spurious_first
) + e
;
2049 for (size_t i
= 0; i
< it
->num_flags
; i
++)
2050 if (it
->flags
[i
].type
== okflag
)
2051 if (fprintf (fp
, " %s-ok%s%s",
2055 : ""), after_cond
) < 0)
2056 error (EXIT_FAILURE
, errno
, "write to '%s'",
2061 /* Print errno expectations. */
2065 must_erange
= false;
2067 if (may_edom
&& !must_edom
)
2069 if (fputs (" errno-edom-ok", fp
) < 0)
2070 error (EXIT_FAILURE
, errno
, "write to '%s'",
2076 if (fputs (" errno-edom", fp
) < 0)
2077 error (EXIT_FAILURE
, errno
, "write to '%s'",
2079 input_flag_type okflag
= (must_edom
2080 ? flag_missing_errno
2081 : flag_spurious_errno
);
2082 for (size_t i
= 0; i
< it
->num_flags
; i
++)
2083 if (it
->flags
[i
].type
== okflag
)
2084 if (fprintf (fp
, " errno-edom-ok%s",
2088 error (EXIT_FAILURE
, errno
, "write to '%s'",
2091 if (before_after_matters
)
2092 assert (may_erange
&& !must_erange
);
2093 if (may_erange
&& !must_erange
)
2095 if (fprintf (fp
, " errno-erange-ok%s",
2096 (before_after_matters
2097 ? ":before-rounding"
2099 error (EXIT_FAILURE
, errno
, "write to '%s'",
2102 if (before_after_matters
|| !(may_erange
&& !must_erange
))
2105 if (fputs (" errno-erange", fp
) < 0)
2106 error (EXIT_FAILURE
, errno
, "write to '%s'",
2108 input_flag_type okflag
= (must_erange
2109 ? flag_missing_errno
2110 : flag_spurious_errno
);
2111 for (size_t i
= 0; i
< it
->num_flags
; i
++)
2112 if (it
->flags
[i
].type
== okflag
)
2113 if (fprintf (fp
, " errno-erange-ok%s%s",
2117 (before_after_matters
2120 error (EXIT_FAILURE
, errno
, "write to '%s'",
2123 if (putc ('\n', fp
) < 0)
2124 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
2126 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
2128 if (generic_outputs
[i
].type
== gtype_fp
)
2129 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
2130 mpfr_clear (all_res
[i
][m
]);
2135 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
2136 generic_value_free (&generic_outputs
[i
]);
2139 /* Generate test output data to FILENAME. */
2142 generate_output (const char *filename
)
2144 FILE *fp
= fopen (filename
, "w");
2146 error (EXIT_FAILURE
, errno
, "open '%s'", filename
);
2147 for (size_t i
= 0; i
< ARRAY_SIZE (test_functions
); i
++)
2149 test_function
*tf
= &test_functions
[i
];
2150 for (size_t j
= 0; j
< tf
->num_tests
; j
++)
2152 input_test
*it
= &tf
->tests
[j
];
2153 if (fputs (it
->line
, fp
) < 0)
2154 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
2155 for (size_t k
= 0; k
< it
->num_input_cases
; k
++)
2156 output_for_one_input_case (fp
, filename
, tf
, it
, it
->inputs
[k
]);
2159 if (fclose (fp
) != 0)
2160 error (EXIT_FAILURE
, errno
, "close '%s'", filename
);
2164 main (int argc
, char **argv
)
2167 error (EXIT_FAILURE
, 0, "usage: gen-auto-libm-tests <input> <output>");
2168 const char *input_filename
= argv
[1];
2169 const char *output_filename
= argv
[2];
2171 read_input (input_filename
);
2172 generate_output (output_filename
);
2173 exit (EXIT_SUCCESS
);