1 /* Generate expected output for libm tests with MPFR and MPC.
2 Copyright (C) 2013 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", "long64", "before-rounding" and "after-rounding" (the
108 last two indicating tests where expectations for underflow
109 exceptions depend on how the architecture detects tininess).
110 Inputs and outputs are specified as hex floats with the required
111 suffix for the floating-point type, or plus_infty or minus_infty
112 for infinite expected results, or as integer constant expressions
113 (not necessarily with the right type) or IGNORE for integer inputs
114 and outputs. Flags are "no-test-inline", "xfail", "<exception>",
115 "<exception>-ok", "errno-<value>", "errno-<value>-ok", where
116 "<exception>" and "errno-<value>" are unconditional, indicating
117 that a correct result means the given exception should be raised or
118 errno should be set to the given value, and other settings may be
119 conditional or unconditional; "-ok" means not to test for the given
120 exception or errno value (whether because it was marked as possibly
121 missing or spurious, or because the calculation of correct results
122 indicated it was optional). */
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 } rounding_mode_desc;
215 /* List of rounding modes, in the same order as the rounding_mode
217 static const rounding_mode_desc rounding_modes[rm_num_modes] =
219 { "downward", MPFR_RNDD },
220 { "tonearest", MPFR_RNDN },
221 { "towardzero", MPFR_RNDZ },
222 { "upward", MPFR_RNDU },
225 /* The supported exceptions. */
234 exc_first_exception = 0
237 /* List of exceptions, in the same order as the fp_exception
239 static const char *const exceptions[exc_num_exceptions] =
248 /* The internal precision to use for most MPFR calculations, which
249 must be at least 2 more than the greatest precision of any
250 supported floating-point format. */
251 static int internal_precision;
253 /* A value that overflows all supported floating-point formats. */
254 static mpfr_t global_max;
256 /* A value that is at most half the least subnormal in any
257 floating-point format and so is rounded the same way as all
258 sufficiently small positive values. */
259 static mpfr_t global_min;
261 /* The maximum number of (real or integer) arguments to a function
262 handled by this program (complex arguments count as two real
266 /* The maximum number of (real or integer) return values from a
267 function handled by this program. */
270 /* A type of a function argument or return value. */
273 /* No type (not a valid argument or return value). */
275 /* A floating-point value with the type corresponding to that of
278 /* An integer value of type int. */
280 /* An integer value of type long. */
282 /* An integer value of type long long. */
286 /* A type of a generic real or integer value. */
291 /* Floating-point (represented with MPFR). */
293 /* Integer (represented with GMP). */
295 } generic_value_type;
297 /* A generic value (argument or result). */
300 /* The type of this value. */
301 generic_value_type type;
310 /* A type of input flag. */
316 /* The "spurious" and "missing" flags must be in the same order as
317 the fp_exception enumeration. */
318 flag_spurious_divbyzero,
319 flag_spurious_inexact,
320 flag_spurious_invalid,
321 flag_spurious_overflow,
322 flag_spurious_underflow,
324 flag_missing_divbyzero,
325 flag_missing_inexact,
326 flag_missing_invalid,
327 flag_missing_overflow,
328 flag_missing_underflow,
330 num_input_flag_types,
332 flag_spurious_first = flag_spurious_divbyzero,
333 flag_missing_first = flag_missing_divbyzero
336 /* List of flags, in the same order as the input_flag_type
338 static const char *const input_flags[num_input_flag_types] =
343 "spurious-divbyzero",
347 "spurious-underflow",
357 /* An input flag, possibly conditional. */
360 /* The type of this flag. */
361 input_flag_type type;
362 /* The conditions on this flag, as a string ":cond1:cond2..." or
367 /* Structure describing a single test from the input file (which may
368 expand into many tests in the output). The choice of function,
369 which implies the numbers and types of arguments and results, is
370 implicit rather than stored in this structure (except as part of
374 /* The text of the input line describing the test, including the
377 /* The number of combinations of interpretations of input values for
378 different floating-point formats and rounding modes. */
379 size_t num_input_cases;
380 /* The corresponding lists of inputs. */
381 generic_value **inputs;
382 /* The number of flags for this test. */
384 /* The corresponding list of flags. */
386 /* The old output for this test. */
387 const char *old_output;
390 /* Ways to calculate a function. */
393 /* MPFR function with a single argument and result. */
397 /* Description of how to calculate a function. */
400 /* Which method is used to calculate the function. */
401 func_calc_method method;
402 /* The specific function called. */
405 int (*mpfr_f_f) (mpfr_t, const mpfr_t, mpfr_rnd_t);
409 /* Structure describing a function handled by this program. */
412 /* The name of the function. */
414 /* The number of arguments. */
416 /* The types of the arguments. */
417 arg_ret_type arg_types[MAX_NARGS];
418 /* The number of return values. */
420 /* The types of the return values. */
421 arg_ret_type ret_types[MAX_NRET];
422 /* Whether the function has exactly determined results and
425 /* Whether the function is a complex function, so errno setting is
428 /* How to calculate this function. */
430 /* The number of tests allocated for this function. */
431 size_t num_tests_alloc;
432 /* The number of tests for this function. */
434 /* The tests themselves. */
438 #define FUNC_mpfr_f_f(NAME, MPFR_FUNC, EXACT) \
440 NAME, 1, { type_fp }, 1, { type_fp }, EXACT, false, \
441 { mpfr_f_f, { .mpfr_f_f = MPFR_FUNC } }, 0, 0, NULL \
444 /* List of functions handled by this program. */
445 static test_function test_functions[] =
447 FUNC_mpfr_f_f ("acos", mpfr_acos, false),
448 FUNC_mpfr_f_f ("acosh", mpfr_acosh, false),
449 FUNC_mpfr_f_f ("asin", mpfr_asin, false),
450 FUNC_mpfr_f_f ("asinh", mpfr_asinh, false),
451 FUNC_mpfr_f_f ("atan", mpfr_atan, false),
452 FUNC_mpfr_f_f ("atanh", mpfr_atanh, false),
453 FUNC_mpfr_f_f ("cbrt", mpfr_cbrt, false),
454 FUNC_mpfr_f_f ("cos", mpfr_cos, false),
455 FUNC_mpfr_f_f ("cosh", mpfr_cosh, false),
456 FUNC_mpfr_f_f ("erf", mpfr_erf, false),
457 FUNC_mpfr_f_f ("erfc", mpfr_erfc, false),
458 FUNC_mpfr_f_f ("exp", mpfr_exp, false),
459 FUNC_mpfr_f_f ("exp10", mpfr_exp10, false),
460 FUNC_mpfr_f_f ("exp2", mpfr_exp2, false),
461 FUNC_mpfr_f_f ("expm1", mpfr_expm1, false),
462 FUNC_mpfr_f_f ("j0", mpfr_j0, false),
463 FUNC_mpfr_f_f ("j1", mpfr_j1, false),
464 FUNC_mpfr_f_f ("log", mpfr_log, false),
465 FUNC_mpfr_f_f ("log10", mpfr_log10, false),
466 FUNC_mpfr_f_f ("log1p", mpfr_log1p, false),
467 FUNC_mpfr_f_f ("log2", mpfr_log2, false),
468 FUNC_mpfr_f_f ("sin", mpfr_sin, false),
469 FUNC_mpfr_f_f ("sinh", mpfr_sinh, false),
470 FUNC_mpfr_f_f ("sqrt", mpfr_sqrt, true),
471 FUNC_mpfr_f_f ("tan", mpfr_tan, false),
472 FUNC_mpfr_f_f ("tanh", mpfr_tanh, false),
473 FUNC_mpfr_f_f ("tgamma", mpfr_gamma, false),
474 FUNC_mpfr_f_f ("y0", mpfr_y0, false),
475 FUNC_mpfr_f_f ("y1", mpfr_y1, false),
478 /* Allocate memory, with error checking. */
483 void *p = malloc (n);
485 error (EXIT_FAILURE, errno, "xmalloc failed");
490 xrealloc (void *p, size_t n)
494 error (EXIT_FAILURE, errno, "xrealloc failed");
499 xstrdup (const char *s)
501 char *p = strdup (s);
503 error (EXIT_FAILURE, errno, "xstrdup failed");
507 /* Assert that the result of an MPFR operation was exact; that is,
508 that the returned ternary value was 0. */
516 /* Return the generic type of an argument or return value type T. */
518 static generic_value_type
519 generic_arg_ret_type (arg_ret_type t)
536 /* Free a generic_value *V. */
539 generic_value_free (generic_value *v)
544 mpfr_clear (v->value.f);
548 mpz_clear (v->value.i);
556 /* Copy a generic_value *SRC to *DEST. */
559 generic_value_copy (generic_value *dest, const generic_value *src)
561 dest->type = src->type;
565 mpfr_init (dest->value.f);
566 assert_exact (mpfr_set (dest->value.f, src->value.f, MPFR_RNDN));
570 mpz_init (dest->value.i);
571 mpz_set (dest->value.i, src->value.i);
579 /* Initialize data for floating-point formats. */
584 int global_max_exp = 0, global_min_subnorm_exp = 0;
585 for (fp_format f = fp_first_format; f < fp_num_formats; f++)
587 if (fp_formats[f].mant_dig + 2 > internal_precision)
588 internal_precision = fp_formats[f].mant_dig + 2;
589 if (fp_formats[f].max_exp > global_max_exp)
590 global_max_exp = fp_formats[f].max_exp;
591 int min_subnorm_exp = fp_formats[f].min_exp - fp_formats[f].mant_dig;
592 if (min_subnorm_exp < global_min_subnorm_exp)
593 global_min_subnorm_exp = min_subnorm_exp;
594 mpfr_init2 (fp_formats[f].max, fp_formats[f].mant_dig);
595 if (fp_formats[f].max_string != NULL)
598 assert_exact (mpfr_strtofr (fp_formats[f].max,
599 fp_formats[f].max_string,
605 assert_exact (mpfr_set_ui_2exp (fp_formats[f].max, 1,
606 fp_formats[f].max_exp,
608 mpfr_nextbelow (fp_formats[f].max);
610 mpfr_init2 (fp_formats[f].min, fp_formats[f].mant_dig);
611 assert_exact (mpfr_set_ui_2exp (fp_formats[f].min, 1,
612 fp_formats[f].min_exp - 1,
614 mpfr_init2 (fp_formats[f].subnorm_max, fp_formats[f].mant_dig);
615 assert_exact (mpfr_set (fp_formats[f].subnorm_max, fp_formats[f].min,
617 mpfr_nextbelow (fp_formats[f].subnorm_max);
618 mpfr_nextbelow (fp_formats[f].subnorm_max);
619 mpfr_init2 (fp_formats[f].subnorm_min, fp_formats[f].mant_dig);
620 assert_exact (mpfr_set_ui_2exp (fp_formats[f].subnorm_min, 1,
621 min_subnorm_exp, MPFR_RNDN));
623 mpfr_set_default_prec (internal_precision);
624 mpfr_init (global_max);
625 assert_exact (mpfr_set_ui_2exp (global_max, 1, global_max_exp, MPFR_RNDN));
626 mpfr_init (global_min);
627 assert_exact (mpfr_set_ui_2exp (global_min, 1, global_min_subnorm_exp - 1,
631 /* Fill in mpfr_t values for special strings in input arguments. */
634 special_fill_max (mpfr_t res0, mpfr_t res1 __attribute__ ((unused)),
637 mpfr_init2 (res0, fp_formats[format].mant_dig);
638 assert_exact (mpfr_set (res0, fp_formats[format].max, MPFR_RNDN));
643 special_fill_minus_max (mpfr_t res0, mpfr_t res1 __attribute__ ((unused)),
646 mpfr_init2 (res0, fp_formats[format].mant_dig);
647 assert_exact (mpfr_neg (res0, fp_formats[format].max, MPFR_RNDN));
652 special_fill_pi (mpfr_t res0, mpfr_t res1, fp_format format)
654 mpfr_init2 (res0, fp_formats[format].mant_dig);
655 mpfr_const_pi (res0, MPFR_RNDU);
656 mpfr_init2 (res1, fp_formats[format].mant_dig);
657 mpfr_const_pi (res1, MPFR_RNDD);
662 special_fill_minus_pi (mpfr_t res0, mpfr_t res1, fp_format format)
664 mpfr_init2 (res0, fp_formats[format].mant_dig);
665 mpfr_const_pi (res0, MPFR_RNDU);
666 assert_exact (mpfr_neg (res0, res0, MPFR_RNDN));
667 mpfr_init2 (res1, fp_formats[format].mant_dig);
668 mpfr_const_pi (res1, MPFR_RNDD);
669 assert_exact (mpfr_neg (res1, res1, MPFR_RNDN));
674 special_fill_pi_2 (mpfr_t res0, mpfr_t res1, fp_format format)
676 mpfr_init2 (res0, fp_formats[format].mant_dig);
677 mpfr_const_pi (res0, MPFR_RNDU);
678 assert_exact (mpfr_div_ui (res0, res0, 2, MPFR_RNDN));
679 mpfr_init2 (res1, fp_formats[format].mant_dig);
680 mpfr_const_pi (res1, MPFR_RNDD);
681 assert_exact (mpfr_div_ui (res1, res1, 2, MPFR_RNDN));
686 special_fill_minus_pi_2 (mpfr_t res0, mpfr_t res1, fp_format format)
688 mpfr_init2 (res0, fp_formats[format].mant_dig);
689 mpfr_const_pi (res0, MPFR_RNDU);
690 assert_exact (mpfr_div_ui (res0, res0, 2, MPFR_RNDN));
691 assert_exact (mpfr_neg (res0, res0, MPFR_RNDN));
692 mpfr_init2 (res1, fp_formats[format].mant_dig);
693 mpfr_const_pi (res1, MPFR_RNDD);
694 assert_exact (mpfr_div_ui (res1, res1, 2, MPFR_RNDN));
695 assert_exact (mpfr_neg (res1, res1, MPFR_RNDN));
700 special_fill_pi_4 (mpfr_t res0, mpfr_t res1, fp_format format)
702 mpfr_init2 (res0, fp_formats[format].mant_dig);
703 assert_exact (mpfr_set_si (res0, 1, MPFR_RNDN));
704 mpfr_atan (res0, res0, MPFR_RNDU);
705 mpfr_init2 (res1, fp_formats[format].mant_dig);
706 assert_exact (mpfr_set_si (res1, 1, MPFR_RNDN));
707 mpfr_atan (res1, res1, MPFR_RNDD);
712 special_fill_pi_6 (mpfr_t res0, mpfr_t res1, fp_format format)
714 mpfr_init2 (res0, fp_formats[format].mant_dig);
715 assert_exact (mpfr_set_si_2exp (res0, 1, -1, MPFR_RNDN));
716 mpfr_asin (res0, res0, MPFR_RNDU);
717 mpfr_init2 (res1, fp_formats[format].mant_dig);
718 assert_exact (mpfr_set_si_2exp (res1, 1, -1, MPFR_RNDN));
719 mpfr_asin (res1, res1, MPFR_RNDD);
724 special_fill_minus_pi_6 (mpfr_t res0, mpfr_t res1, fp_format format)
726 mpfr_init2 (res0, fp_formats[format].mant_dig);
727 assert_exact (mpfr_set_si_2exp (res0, -1, -1, MPFR_RNDN));
728 mpfr_asin (res0, res0, MPFR_RNDU);
729 mpfr_init2 (res1, fp_formats[format].mant_dig);
730 assert_exact (mpfr_set_si_2exp (res1, -1, -1, MPFR_RNDN));
731 mpfr_asin (res1, res1, MPFR_RNDD);
736 special_fill_pi_3 (mpfr_t res0, mpfr_t res1, fp_format format)
738 mpfr_init2 (res0, fp_formats[format].mant_dig);
739 assert_exact (mpfr_set_si_2exp (res0, 1, -1, MPFR_RNDN));
740 mpfr_acos (res0, res0, MPFR_RNDU);
741 mpfr_init2 (res1, fp_formats[format].mant_dig);
742 assert_exact (mpfr_set_si_2exp (res1, 1, -1, MPFR_RNDN));
743 mpfr_acos (res1, res1, MPFR_RNDD);
748 special_fill_2pi_3 (mpfr_t res0, mpfr_t res1, fp_format format)
750 mpfr_init2 (res0, fp_formats[format].mant_dig);
751 assert_exact (mpfr_set_si_2exp (res0, -1, -1, MPFR_RNDN));
752 mpfr_acos (res0, res0, MPFR_RNDU);
753 mpfr_init2 (res1, fp_formats[format].mant_dig);
754 assert_exact (mpfr_set_si_2exp (res1, -1, -1, MPFR_RNDN));
755 mpfr_acos (res1, res1, MPFR_RNDD);
760 special_fill_e (mpfr_t res0, mpfr_t res1, fp_format format)
762 mpfr_init2 (res0, fp_formats[format].mant_dig);
763 assert_exact (mpfr_set_si (res0, 1, MPFR_RNDN));
764 mpfr_exp (res0, res0, MPFR_RNDU);
765 mpfr_init2 (res1, fp_formats[format].mant_dig);
766 assert_exact (mpfr_set_si (res1, 1, MPFR_RNDN));
767 mpfr_exp (res1, res1, MPFR_RNDD);
772 special_fill_1_e (mpfr_t res0, mpfr_t res1, fp_format format)
774 mpfr_init2 (res0, fp_formats[format].mant_dig);
775 assert_exact (mpfr_set_si (res0, -1, MPFR_RNDN));
776 mpfr_exp (res0, res0, MPFR_RNDU);
777 mpfr_init2 (res1, fp_formats[format].mant_dig);
778 assert_exact (mpfr_set_si (res1, -1, MPFR_RNDN));
779 mpfr_exp (res1, res1, MPFR_RNDD);
784 special_fill_e_minus_1 (mpfr_t res0, mpfr_t res1, fp_format format)
786 mpfr_init2 (res0, fp_formats[format].mant_dig);
787 assert_exact (mpfr_set_si (res0, 1, MPFR_RNDN));
788 mpfr_expm1 (res0, res0, MPFR_RNDU);
789 mpfr_init2 (res1, fp_formats[format].mant_dig);
790 assert_exact (mpfr_set_si (res1, 1, MPFR_RNDN));
791 mpfr_expm1 (res1, res1, MPFR_RNDD);
795 /* A special string accepted in input arguments. */
800 /* The function that interprets it for a given floating-point
801 format, filling in up to two mpfr_t values and returning the
802 number of values filled. */
803 size_t (*func) (mpfr_t, mpfr_t, fp_format);
804 } special_real_input;
806 /* List of special strings accepted in input arguments. */
808 static const special_real_input special_real_inputs[] =
810 { "max", special_fill_max },
811 { "-max", special_fill_minus_max },
812 { "pi", special_fill_pi },
813 { "-pi", special_fill_minus_pi },
814 { "pi/2", special_fill_pi_2 },
815 { "-pi/2", special_fill_minus_pi_2 },
816 { "pi/4", special_fill_pi_4 },
817 { "pi/6", special_fill_pi_6 },
818 { "-pi/6", special_fill_minus_pi_6 },
819 { "pi/3", special_fill_pi_3 },
820 { "2pi/3", special_fill_2pi_3 },
821 { "e", special_fill_e },
822 { "1/e", special_fill_1_e },
823 { "e-1", special_fill_e_minus_1 },
826 /* Given a real number R computed in round-to-zero mode, set the
827 lowest bit as a sticky bit if INEXACT, and saturate the exponent
828 range for very large or small values. */
831 adjust_real (mpfr_t r, bool inexact)
835 /* NaNs are exact, as are infinities in round-to-zero mode. */
836 assert (mpfr_number_p (r));
837 if (mpfr_cmpabs (r, global_min) < 0)
838 assert_exact (mpfr_copysign (r, global_min, r, MPFR_RNDN));
839 else if (mpfr_cmpabs (r, global_max) > 0)
840 assert_exact (mpfr_copysign (r, global_max, r, MPFR_RNDN));
845 mpfr_exp_t e = mpfr_get_z_2exp (tmp, r);
847 assert_exact (mpfr_set_z_2exp (r, tmp, e, MPFR_RNDN));
852 /* Given a finite real number R with sticky bit, compute the roundings
853 to FORMAT in each rounding mode, storing the results in RES, the
854 before-rounding exceptions in EXC_BEFORE and the after-rounding
855 exceptions in EXC_AFTER. */
858 round_real (mpfr_t res[rm_num_modes],
859 unsigned int exc_before[rm_num_modes],
860 unsigned int exc_after[rm_num_modes],
861 mpfr_t r, fp_format format)
863 assert (mpfr_number_p (r));
864 for (rounding_mode m = rm_first_mode; m < rm_num_modes; m++)
866 mpfr_init2 (res[m], fp_formats[format].mant_dig);
867 exc_before[m] = exc_after[m] = 0;
868 bool inexact = mpfr_set (res[m], r, rounding_modes[m].mpfr_mode);
869 if (mpfr_cmpabs (res[m], fp_formats[format].max) > 0)
872 exc_before[m] |= 1U << exc_overflow;
873 exc_after[m] |= 1U << exc_overflow;
881 overflow_inf = false;
884 overflow_inf = mpfr_signbit (res[m]);
887 overflow_inf = !mpfr_signbit (res[m]);
893 mpfr_set_inf (res[m], mpfr_signbit (res[m]) ? -1 : 1);
895 assert_exact (mpfr_copysign (res[m], fp_formats[format].max,
898 if (mpfr_cmpabs (r, fp_formats[format].min) < 0)
900 /* Tiny before rounding; may or may not be tiny after
901 rounding, and underflow applies only if also inexact
902 around rounding to a possibly subnormal value. */
903 bool tiny_after_rounding
904 = mpfr_cmpabs (res[m], fp_formats[format].min) < 0;
905 /* To round to a possibly subnormal value, and determine
906 inexactness as a subnormal in the process, scale up and
907 round to integer, then scale back down. */
910 assert_exact (mpfr_mul_2si (tmp, r, (fp_formats[format].mant_dig
911 - fp_formats[format].min_exp),
913 int rint_res = mpfr_rint (tmp, tmp, rounding_modes[m].mpfr_mode);
914 /* The integer must be representable. */
915 assert (rint_res == 0 || rint_res == 2 || rint_res == -2);
916 /* If rounding to full precision was inexact, so must
917 rounding to subnormal precision be inexact. */
919 assert (rint_res != 0);
921 inexact = rint_res != 0;
922 assert_exact (mpfr_mul_2si (res[m], tmp,
923 (fp_formats[format].min_exp
924 - fp_formats[format].mant_dig),
929 exc_before[m] |= 1U << exc_underflow;
930 if (tiny_after_rounding)
931 exc_after[m] |= 1U << exc_underflow;
936 exc_before[m] |= 1U << exc_inexact;
937 exc_after[m] |= 1U << exc_inexact;
942 /* Handle the input argument at ARG (NUL-terminated), updating the
943 lists of test inputs in IT accordingly. NUM_PREV_ARGS arguments
944 are already in those lists. The argument, of type GTYPE, comes
945 from file FILENAME, line LINENO. */
948 handle_input_arg (const char *arg, input_test *it, size_t num_prev_args,
949 generic_value_type gtype,
950 const char *filename, unsigned int lineno)
952 size_t num_values = 0;
953 generic_value values[2 * fp_num_formats];
957 for (fp_format f = fp_first_format; f < fp_num_formats; f++)
959 mpfr_t extra_values[2];
960 size_t num_extra_values = 0;
961 for (size_t i = 0; i < ARRAY_SIZE (special_real_inputs); i++)
963 if (strcmp (arg, special_real_inputs[i].str) == 0)
966 = special_real_inputs[i].func (extra_values[0],
968 assert (num_extra_values > 0
969 && num_extra_values <= ARRAY_SIZE (extra_values));
973 if (num_extra_values == 0)
978 bool inexact = mpfr_strtofr (tmp, arg, &ep, 0, MPFR_RNDZ);
979 if (*ep != 0 || !mpfr_number_p (tmp))
980 error_at_line (EXIT_FAILURE, 0, filename, lineno,
981 "bad floating-point argument: '%s'", arg);
982 adjust_real (tmp, inexact);
983 mpfr_t rounded[rm_num_modes];
984 unsigned int exc_before[rm_num_modes];
985 unsigned int exc_after[rm_num_modes];
986 round_real (rounded, exc_before, exc_after, tmp, f);
988 if (mpfr_number_p (rounded[rm_upward]))
990 mpfr_init2 (extra_values[num_extra_values],
991 fp_formats[f].mant_dig);
992 assert_exact (mpfr_set (extra_values[num_extra_values],
993 rounded[rm_upward], MPFR_RNDN));
996 if (mpfr_number_p (rounded[rm_downward]))
998 mpfr_init2 (extra_values[num_extra_values],
999 fp_formats[f].mant_dig);
1000 assert_exact (mpfr_set (extra_values[num_extra_values],
1001 rounded[rm_downward], MPFR_RNDN));
1004 for (rounding_mode m = rm_first_mode; m < rm_num_modes; m++)
1005 mpfr_clear (rounded[m]);
1007 for (size_t i = 0; i < num_extra_values; i++)
1010 for (size_t j = 0; j < num_values; j++)
1012 if (mpfr_equal_p (values[j].value.f, extra_values[i])
1013 && ((mpfr_signbit (values[j].value.f) != 0)
1014 == (mpfr_signbit (extra_values[i]) != 0)))
1022 assert (num_values < ARRAY_SIZE (values));
1023 values[num_values].type = gtype_fp;
1024 mpfr_init2 (values[num_values].value.f,
1025 fp_formats[f].mant_dig);
1026 assert_exact (mpfr_set (values[num_values].value.f,
1027 extra_values[i], MPFR_RNDN));
1030 mpfr_clear (extra_values[i]);
1037 values[0].type = gtype_int;
1038 int ret = mpz_init_set_str (values[0].value.i, arg, 0);
1040 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1041 "bad integer argument: '%s'", arg);
1047 assert (num_values > 0 && num_values <= ARRAY_SIZE (values));
1048 if (it->num_input_cases >= SIZE_MAX / num_values)
1049 error_at_line (EXIT_FAILURE, 0, filename, lineno, "too many input cases");
1050 generic_value **old_inputs = it->inputs;
1051 size_t new_num_input_cases = it->num_input_cases * num_values;
1052 generic_value **new_inputs = xmalloc (new_num_input_cases
1053 * sizeof (new_inputs[0]));
1054 for (size_t i = 0; i < it->num_input_cases; i++)
1056 for (size_t j = 0; j < num_values; j++)
1058 size_t idx = i * num_values + j;
1059 new_inputs[idx] = xmalloc ((num_prev_args + 1)
1060 * sizeof (new_inputs[idx][0]));
1061 for (size_t k = 0; k < num_prev_args; k++)
1062 generic_value_copy (&new_inputs[idx][k], &old_inputs[i][k]);
1063 generic_value_copy (&new_inputs[idx][num_prev_args], &values[j]);
1065 for (size_t j = 0; j < num_prev_args; j++)
1066 generic_value_free (&old_inputs[i][j]);
1067 free (old_inputs[i]);
1070 for (size_t i = 0; i < num_values; i++)
1071 generic_value_free (&values[i]);
1072 it->inputs = new_inputs;
1073 it->num_input_cases = new_num_input_cases;
1076 /* Handle the input flag ARG (NUL-terminated), storing it in *FLAG.
1077 The flag comes from file FILENAME, line LINENO. */
1080 handle_input_flag (char *arg, input_flag *flag,
1081 const char *filename, unsigned int lineno)
1083 char *ep = strchr (arg, ':');
1086 ep = strchr (arg, 0);
1087 assert (ep != NULL);
1092 for (input_flag_type i = flag_first_flag; i <= num_input_flag_types; i++)
1094 if (strcmp (arg, input_flags[i]) == 0)
1102 error_at_line (EXIT_FAILURE, 0, filename, lineno, "unknown flag: '%s'",
1108 flag->cond = xstrdup (ep);
1111 /* Add the test LINE (file FILENAME, line LINENO) to the test
1115 add_test (char *line, const char *filename, unsigned int lineno)
1117 size_t num_tokens = 1;
1119 while ((p = strchr (p, ' ')) != NULL)
1125 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1126 "line too short: '%s'", line);
1127 p = strchr (line, ' ');
1128 size_t func_name_len = p - line;
1129 for (size_t i = 0; i < ARRAY_SIZE (test_functions); i++)
1131 if (func_name_len == strlen (test_functions[i].name)
1132 && strncmp (line, test_functions[i].name, func_name_len) == 0)
1134 test_function *tf = &test_functions[i];
1135 if (num_tokens < 1 + tf->num_args)
1136 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1137 "line too short: '%s'", line);
1138 if (tf->num_tests == tf->num_tests_alloc)
1140 tf->num_tests_alloc = 2 * tf->num_tests_alloc + 16;
1142 = xrealloc (tf->tests,
1143 tf->num_tests_alloc * sizeof (tf->tests[0]));
1145 input_test *it = &tf->tests[tf->num_tests];
1147 it->num_input_cases = 1;
1148 it->inputs = xmalloc (sizeof (it->inputs[0]));
1149 it->inputs[0] = NULL;
1150 it->old_output = NULL;
1152 for (size_t j = 0; j < tf->num_args; j++)
1154 char *ep = strchr (p, ' ');
1157 ep = strchr (p, '\n');
1158 assert (ep != NULL);
1161 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1162 "empty token in line: '%s'", line);
1163 for (char *t = p; t < ep; t++)
1164 if (isspace ((unsigned char) *t))
1165 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1166 "whitespace in token in line: '%s'", line);
1169 handle_input_arg (p, it, j,
1170 generic_arg_ret_type (tf->arg_types[j]),
1175 it->num_flags = num_tokens - 1 - tf->num_args;
1176 it->flags = xmalloc (it->num_flags * sizeof (it->flags[0]));
1177 for (size_t j = 0; j < it->num_flags; j++)
1179 char *ep = strchr (p, ' ');
1182 ep = strchr (p, '\n');
1183 assert (ep != NULL);
1186 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1187 "empty token in line: '%s'", line);
1188 for (char *t = p; t < ep; t++)
1189 if (isspace ((unsigned char) *t))
1190 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1191 "whitespace in token in line: '%s'", line);
1194 handle_input_flag (p, &it->flags[j], filename, lineno);
1203 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1204 "unknown function in line: '%s'", line);
1207 /* Read in the test input data from FILENAME. */
1210 read_input (const char *filename)
1212 FILE *fp = fopen (filename, "r");
1214 error (EXIT_FAILURE, errno, "open '%s'", filename);
1215 unsigned int lineno = 0;
1220 ssize_t ret = getline (&line, &size, fp);
1224 if (line[0] == '#' || line[0] == '\n')
1226 add_test (line, filename, lineno);
1229 error (EXIT_FAILURE, errno, "read from '%s'", filename);
1230 if (fclose (fp) != 0)
1231 error (EXIT_FAILURE, errno, "close '%s'", filename);
1234 /* Calculate the generic results (round-to-zero with sticky bit) for
1235 the function described by CALC, with inputs INPUTS. */
1238 calc_generic_results (generic_value *outputs, generic_value *inputs,
1239 const func_calc_desc *calc)
1242 switch (calc->method)
1245 assert (inputs[0].type == gtype_fp);
1246 outputs[0].type = gtype_fp;
1247 mpfr_init (outputs[0].value.f);
1248 inexact = calc->func.mpfr_f_f (outputs[0].value.f, inputs[0].value.f,
1250 adjust_real (outputs[0].value.f, inexact);
1258 /* Return the number of bits for integer type TYPE, where "long" has
1259 LONG_BITS bits (32 or 64). */
1262 int_type_bits (arg_ret_type type, int long_bits)
1264 assert (long_bits == 32 || long_bits == 64);
1275 case type_long_long:
1284 /* Check whether an integer Z fits a given type TYPE, where "long" has
1285 LONG_BITS bits (32 or 64). */
1288 int_fits_type (mpz_t z, arg_ret_type type, int long_bits)
1290 int bits = int_type_bits (type, long_bits);
1294 mpz_ui_pow_ui (t, 2, bits - 1);
1295 if (mpz_cmp (z, t) >= 0)
1298 if (mpz_cmp (z, t) < 0)
1304 /* Print a generic value V to FP (name FILENAME), preceded by a space,
1305 for type TYPE, floating-point format FORMAT, LONG_BITS bits per
1306 long, printing " IGNORE" instead if IGNORE. */
1309 output_generic_value (FILE *fp, const char *filename, const generic_value *v,
1310 bool ignore, arg_ret_type type, fp_format format,
1315 if (fputs (" IGNORE", fp) < 0)
1316 error (EXIT_FAILURE, errno, "write to '%s'", filename);
1319 assert (v->type == generic_arg_ret_type (type));
1324 suffix = fp_formats[format].suffix;
1335 case type_long_long:
1345 if (mpfr_inf_p (v->value.f))
1347 if (fputs ((mpfr_signbit (v->value.f)
1348 ? " minus_infty" : " plus_infty"), fp) < 0)
1349 error (EXIT_FAILURE, errno, "write to '%s'", filename);
1353 assert (mpfr_number_p (v->value.f));
1354 if (mpfr_fprintf (fp, " %Ra%s", v->value.f, suffix) < 0)
1355 error (EXIT_FAILURE, errno, "mpfr_fprintf to '%s'", filename);
1360 int bits = int_type_bits (type, long_bits);
1363 mpz_ui_pow_ui (tmp, 2, bits - 1);
1365 if (mpz_cmp (v->value.i, tmp) == 0)
1367 mpz_add_ui (tmp, tmp, 1);
1368 if (mpfr_fprintf (fp, " (%Zd%s-1)", tmp, suffix) < 0)
1369 error (EXIT_FAILURE, errno, "mpfr_fprintf to '%s'", filename);
1373 if (mpfr_fprintf (fp, " %Zd%s", v->value.i, suffix) < 0)
1374 error (EXIT_FAILURE, errno, "mpfr_fprintf to '%s'", filename);
1384 /* Generate test output to FP (name FILENAME) for test function TF,
1385 input test IT, choice of input values INPUTS. */
1388 output_for_one_input_case (FILE *fp, const char *filename, test_function *tf,
1389 input_test *it, generic_value *inputs)
1391 bool long_bits_matters = false;
1392 bool fits_long32 = true;
1393 for (size_t i = 0; i < tf->num_args; i++)
1395 generic_value_type gtype = generic_arg_ret_type (tf->arg_types[i]);
1396 assert (inputs[i].type == gtype);
1397 if (gtype == gtype_int)
1399 bool fits_64 = int_fits_type (inputs[i].value.i, tf->arg_types[i],
1403 if (tf->arg_types[i] == type_long
1404 && !int_fits_type (inputs[i].value.i, tf->arg_types[i], 32))
1406 long_bits_matters = true;
1407 fits_long32 = false;
1411 generic_value generic_outputs[MAX_NRET];
1412 calc_generic_results (generic_outputs, inputs, &tf->calc);
1413 bool ignore_output_long32[MAX_NRET] = { false };
1414 bool ignore_output_long64[MAX_NRET] = { false };
1415 for (size_t i = 0; i < tf->num_ret; i++)
1417 assert (generic_outputs[i].type
1418 == generic_arg_ret_type (tf->ret_types[i]));
1419 switch (generic_outputs[i].type)
1422 if (!mpfr_number_p (generic_outputs[i].value.f))
1423 goto out; /* Result is NaN or exact infinity. */
1427 ignore_output_long32[i] = !int_fits_type (generic_outputs[i].value.i,
1428 tf->ret_types[i], 32);
1429 ignore_output_long64[i] = !int_fits_type (generic_outputs[i].value.i,
1430 tf->ret_types[i], 64);
1431 if (ignore_output_long32[i] != ignore_output_long64[i])
1432 long_bits_matters = true;
1439 /* Iterate over relevant sizes of long and floating-point formats. */
1440 for (int long_bits = 32; long_bits <= 64; long_bits += 32)
1442 if (long_bits == 32 && !fits_long32)
1444 if (long_bits == 64 && !long_bits_matters)
1446 const char *long_cond;
1447 if (long_bits_matters)
1448 long_cond = (long_bits == 32 ? ":long32" : ":long64");
1451 bool *ignore_output = (long_bits == 32
1452 ? ignore_output_long32
1453 : ignore_output_long64);
1454 for (fp_format f = fp_first_format; f < fp_num_formats; f++)
1457 mpfr_t res[rm_num_modes];
1458 unsigned int exc_before[rm_num_modes];
1459 unsigned int exc_after[rm_num_modes];
1460 for (size_t i = 0; i < tf->num_args; i++)
1462 if (inputs[i].type == gtype_fp)
1463 round_real (res, exc_before, exc_after, inputs[i].value.f, f);
1464 if (!mpfr_equal_p (res[rm_tonearest], inputs[i].value.f))
1466 for (rounding_mode m = rm_first_mode; m < rm_num_modes; m++)
1467 mpfr_clear (res[m]);
1473 /* The inputs fit this type, so compute the ideal outputs
1475 mpfr_t all_res[MAX_NRET][rm_num_modes];
1476 unsigned int all_exc_before[MAX_NRET][rm_num_modes];
1477 unsigned int all_exc_after[MAX_NRET][rm_num_modes];
1478 unsigned int merged_exc_before[rm_num_modes] = { 0 };
1479 unsigned int merged_exc_after[rm_num_modes] = { 0 };
1480 /* For functions not exactly determined, track whether
1481 underflow is required (some result is inexact, and
1482 magnitude does not exceed the greatest magnitude
1483 subnormal), and permitted (not an exact zero, and
1484 magnitude does not exceed the least magnitude
1486 bool must_underflow = false;
1487 bool may_underflow = false;
1488 for (size_t i = 0; i < tf->num_ret; i++)
1490 switch (generic_outputs[i].type)
1493 round_real (all_res[i], all_exc_before[i], all_exc_after[i],
1494 generic_outputs[i].value.f, f);
1495 for (rounding_mode m = rm_first_mode; m < rm_num_modes; m++)
1497 merged_exc_before[m] |= all_exc_before[i][m];
1498 merged_exc_after[m] |= all_exc_after[i][m];
1502 |= ((all_exc_before[i][m]
1503 & (1U << exc_inexact)) != 0
1504 && (mpfr_cmpabs (generic_outputs[i].value.f,
1505 fp_formats[f].subnorm_max)
1508 |= (!mpfr_zero_p (generic_outputs[i].value.f)
1509 && mpfr_cmpabs (generic_outputs[i].value.f,
1510 fp_formats[f].min) <= 0);
1516 if (ignore_output[i])
1517 for (rounding_mode m = rm_first_mode;
1521 merged_exc_before[m] |= 1U << exc_invalid;
1522 merged_exc_after[m] |= 1U << exc_invalid;
1530 assert (may_underflow || !must_underflow);
1531 for (rounding_mode m = rm_first_mode; m < rm_num_modes; m++)
1533 bool before_after_matters
1534 = tf->exact && merged_exc_before[m] != merged_exc_after[m];
1535 for (int after = 0; after <= 1; after++)
1537 if (after == 1 && !before_after_matters)
1539 const char *after_cond;
1540 if (before_after_matters)
1543 : ":before-rounding");
1546 unsigned int merged_exc = (after
1547 ? merged_exc_after[m]
1548 : merged_exc_before[m]);
1549 if (fprintf (fp, "= %s %s %s%s%s", tf->name,
1550 rounding_modes[m].name, fp_formats[f].name,
1551 long_cond, after_cond) < 0)
1552 error (EXIT_FAILURE, errno, "write to '%s'", filename);
1554 for (size_t i = 0; i < tf->num_args; i++)
1555 output_generic_value (fp, filename, &inputs[i], false,
1556 tf->arg_types[i], f, long_bits);
1557 if (fputs (" :", fp) < 0)
1558 error (EXIT_FAILURE, errno, "write to '%s'", filename);
1559 /* Print outputs. */
1560 bool must_erange = false;
1561 for (size_t i = 0; i < tf->num_ret; i++)
1564 g.type = generic_outputs[i].type;
1568 if (mpfr_inf_p (all_res[i][m])
1569 && (all_exc_before[i][m]
1570 & (1U << exc_overflow)) != 0)
1572 if (mpfr_zero_p (all_res[i][m])
1574 || mpfr_zero_p (all_res[i][rm_tonearest]))
1575 && (all_exc_before[i][m]
1576 & (1U << exc_underflow)) != 0)
1578 mpfr_init2 (g.value.f, fp_formats[f].mant_dig);
1579 assert_exact (mpfr_set (g.value.f, all_res[i][m],
1584 mpz_init (g.value.i);
1585 mpz_set (g.value.i, generic_outputs[i].value.i);
1591 output_generic_value (fp, filename, &g, ignore_output[i],
1592 tf->ret_types[i], f, long_bits);
1593 generic_value_free (&g);
1595 if (fputs (" :", fp) < 0)
1596 error (EXIT_FAILURE, errno, "write to '%s'", filename);
1597 /* Print miscellaneous flags (passed through from
1599 for (size_t i = 0; i < it->num_flags; i++)
1600 switch (it->flags[i].type)
1602 case flag_no_test_inline:
1604 if (fprintf (fp, " %s%s",
1605 input_flags[it->flags[i].type],
1609 error (EXIT_FAILURE, errno, "write to '%s'",
1612 case flag_xfail_rounding:
1613 if (m != rm_tonearest)
1614 if (fprintf (fp, " xfail%s",
1618 error (EXIT_FAILURE, errno, "write to '%s'",
1624 /* Print exception flags and compute errno
1625 expectations where not already computed. */
1626 bool may_edom = false;
1627 bool must_edom = false;
1628 bool may_erange = must_erange || may_underflow;
1629 for (fp_exception e = exc_first_exception;
1630 e < exc_num_exceptions;
1633 bool expect_e = (merged_exc & (1U << e)) != 0;
1634 bool e_optional = false;
1639 may_erange = must_erange = true;
1649 may_edom = must_edom = true;
1662 if (may_underflow && !must_underflow)
1671 if (fprintf (fp, " %s-ok", exceptions[e]) < 0)
1672 error (EXIT_FAILURE, errno, "write to '%s'",
1678 if (fprintf (fp, " %s", exceptions[e]) < 0)
1679 error (EXIT_FAILURE, errno, "write to '%s'",
1681 input_flag_type okflag;
1683 ? flag_missing_first
1684 : flag_spurious_first) + e;
1685 for (size_t i = 0; i < it->num_flags; i++)
1686 if (it->flags[i].type == okflag)
1687 if (fprintf (fp, " %s-ok%s",
1692 error (EXIT_FAILURE, errno, "write to '%s'",
1696 /* Print errno expectations. */
1700 must_erange = false;
1702 if (may_edom && !must_edom)
1704 if (fputs (" errno-edom-ok", fp) < 0)
1705 error (EXIT_FAILURE, errno, "write to '%s'",
1711 if (fputs (" errno-edom", fp) < 0)
1712 error (EXIT_FAILURE, errno, "write to '%s'",
1714 input_flag_type okflag = (must_edom
1715 ? flag_missing_errno
1716 : flag_spurious_errno);
1717 for (size_t i = 0; i < it->num_flags; i++)
1718 if (it->flags[i].type == okflag)
1719 if (fprintf (fp, " errno-edom-ok%s",
1723 error (EXIT_FAILURE, errno, "write to '%s'",
1726 if (may_erange && !must_erange)
1728 if (fputs (" errno-erange-ok", fp) < 0)
1729 error (EXIT_FAILURE, errno, "write to '%s'",
1735 if (fputs (" errno-erange", fp) < 0)
1736 error (EXIT_FAILURE, errno, "write to '%s'",
1738 input_flag_type okflag = (must_erange
1739 ? flag_missing_errno
1740 : flag_spurious_errno);
1741 for (size_t i = 0; i < it->num_flags; i++)
1742 if (it->flags[i].type == okflag)
1743 if (fprintf (fp, " errno-erange-ok%s",
1747 error (EXIT_FAILURE, errno, "write to '%s'",
1750 if (putc ('\n', fp) < 0)
1751 error (EXIT_FAILURE, errno, "write to '%s'", filename);
1754 for (size_t i = 0; i < tf->num_ret; i++)
1756 if (generic_outputs[i].type == gtype_fp)
1757 for (rounding_mode m = rm_first_mode; m < rm_num_modes; m++)
1758 mpfr_clear (all_res[i][m]);
1763 for (size_t i = 0; i < tf->num_ret; i++)
1764 generic_value_free (&generic_outputs[i]);
1767 /* Generate test output data to FILENAME. */
1770 generate_output (const char *filename)
1772 FILE *fp = fopen (filename, "w");
1774 error (EXIT_FAILURE, errno, "open '%s'", filename);
1775 for (size_t i = 0; i < ARRAY_SIZE (test_functions); i++)
1777 test_function *tf = &test_functions[i];
1778 for (size_t j = 0; j < tf->num_tests; j++)
1780 input_test *it = &tf->tests[j];
1781 if (fputs (it->line, fp) < 0)
1782 error (EXIT_FAILURE, errno, "write to '%s'", filename);
1783 for (size_t k = 0; k < it->num_input_cases; k++)
1784 output_for_one_input_case (fp, filename, tf, it, it->inputs[k]);
1787 if (fclose (fp) != 0)
1788 error (EXIT_FAILURE, errno, "close '%s'", filename);
1792 main (int argc, char **argv)
1795 error (EXIT_FAILURE, 0, "usage: gen-auto-libm-tests <input> <output>");
1796 const char *input_filename = argv[1];
1797 const char *output_filename = argv[2];
1799 read_input (input_filename);
1800 generate_output (output_filename);
1801 exit (EXIT_SUCCESS);