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_6 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
702 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
703 assert_exact (mpfr_set_si_2exp (res0
, 1, -1, MPFR_RNDN
));
704 mpfr_asin (res0
, res0
, MPFR_RNDU
);
705 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
706 assert_exact (mpfr_set_si_2exp (res1
, 1, -1, MPFR_RNDN
));
707 mpfr_asin (res1
, res1
, MPFR_RNDD
);
712 special_fill_minus_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_pi_3 (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_acos (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_acos (res1
, res1
, MPFR_RNDD
);
736 special_fill_2pi_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_e (mpfr_t res0
, mpfr_t res1
, fp_format format
)
750 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
751 assert_exact (mpfr_set_si (res0
, 1, MPFR_RNDN
));
752 mpfr_exp (res0
, res0
, MPFR_RNDU
);
753 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
754 assert_exact (mpfr_set_si (res1
, 1, MPFR_RNDN
));
755 mpfr_exp (res1
, res1
, MPFR_RNDD
);
760 special_fill_1_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_e_minus_1 (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_expm1 (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_expm1 (res1
, res1
, MPFR_RNDD
);
783 /* A special string accepted in input arguments. */
788 /* The function that interprets it for a given floating-point
789 format, filling in up to two mpfr_t values and returning the
790 number of values filled. */
791 size_t (*func
) (mpfr_t
, mpfr_t
, fp_format
);
792 } special_real_input
;
794 /* List of special strings accepted in input arguments. */
796 static const special_real_input special_real_inputs
[] =
798 { "max", special_fill_max
},
799 { "-max", special_fill_minus_max
},
800 { "pi", special_fill_pi
},
801 { "-pi", special_fill_minus_pi
},
802 { "pi/2", special_fill_pi_2
},
803 { "-pi/2", special_fill_minus_pi_2
},
804 { "pi/6", special_fill_pi_6
},
805 { "-pi/6", special_fill_minus_pi_6
},
806 { "pi/3", special_fill_pi_3
},
807 { "2pi/3", special_fill_2pi_3
},
808 { "e", special_fill_e
},
809 { "1/e", special_fill_1_e
},
810 { "e-1", special_fill_e_minus_1
},
813 /* Given a real number R computed in round-to-zero mode, set the
814 lowest bit as a sticky bit if INEXACT, and saturate the exponent
815 range for very large or small values. */
818 adjust_real (mpfr_t r
, bool inexact
)
822 /* NaNs are exact, as are infinities in round-to-zero mode. */
823 assert (mpfr_number_p (r
));
824 if (mpfr_cmpabs (r
, global_min
) < 0)
825 assert_exact (mpfr_copysign (r
, global_min
, r
, MPFR_RNDN
));
826 else if (mpfr_cmpabs (r
, global_max
) > 0)
827 assert_exact (mpfr_copysign (r
, global_max
, r
, MPFR_RNDN
));
832 mpfr_exp_t e
= mpfr_get_z_2exp (tmp
, r
);
834 assert_exact (mpfr_set_z_2exp (r
, tmp
, e
, MPFR_RNDN
));
839 /* Given a finite real number R with sticky bit, compute the roundings
840 to FORMAT in each rounding mode, storing the results in RES, the
841 before-rounding exceptions in EXC_BEFORE and the after-rounding
842 exceptions in EXC_AFTER. */
845 round_real (mpfr_t res
[rm_num_modes
],
846 unsigned int exc_before
[rm_num_modes
],
847 unsigned int exc_after
[rm_num_modes
],
848 mpfr_t r
, fp_format format
)
850 assert (mpfr_number_p (r
));
851 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
853 mpfr_init2 (res
[m
], fp_formats
[format
].mant_dig
);
854 exc_before
[m
] = exc_after
[m
] = 0;
855 bool inexact
= mpfr_set (res
[m
], r
, rounding_modes
[m
].mpfr_mode
);
856 if (mpfr_cmpabs (res
[m
], fp_formats
[format
].max
) > 0)
859 exc_before
[m
] |= 1U << exc_overflow
;
860 exc_after
[m
] |= 1U << exc_overflow
;
868 overflow_inf
= false;
871 overflow_inf
= mpfr_signbit (res
[m
]);
874 overflow_inf
= !mpfr_signbit (res
[m
]);
880 mpfr_set_inf (res
[m
], mpfr_signbit (res
[m
]) ? -1 : 1);
882 assert_exact (mpfr_copysign (res
[m
], fp_formats
[format
].max
,
885 if (mpfr_cmpabs (r
, fp_formats
[format
].min
) < 0)
887 /* Tiny before rounding; may or may not be tiny after
888 rounding, and underflow applies only if also inexact
889 around rounding to a possibly subnormal value. */
890 bool tiny_after_rounding
891 = mpfr_cmpabs (res
[m
], fp_formats
[format
].min
) < 0;
892 /* To round to a possibly subnormal value, and determine
893 inexactness as a subnormal in the process, scale up and
894 round to integer, then scale back down. */
897 assert_exact (mpfr_mul_2si (tmp
, r
, (fp_formats
[format
].mant_dig
898 - fp_formats
[format
].min_exp
),
900 int rint_res
= mpfr_rint (tmp
, tmp
, rounding_modes
[m
].mpfr_mode
);
901 /* The integer must be representable. */
902 assert (rint_res
== 0 || rint_res
== 2 || rint_res
== -2);
903 /* If rounding to full precision was inexact, so must
904 rounding to subnormal precision be inexact. */
906 assert (rint_res
!= 0);
908 inexact
= rint_res
!= 0;
909 assert_exact (mpfr_mul_2si (res
[m
], tmp
,
910 (fp_formats
[format
].min_exp
911 - fp_formats
[format
].mant_dig
),
916 exc_before
[m
] |= 1U << exc_underflow
;
917 if (tiny_after_rounding
)
918 exc_after
[m
] |= 1U << exc_underflow
;
923 exc_before
[m
] |= 1U << exc_inexact
;
924 exc_after
[m
] |= 1U << exc_inexact
;
929 /* Handle the input argument at ARG (NUL-terminated), updating the
930 lists of test inputs in IT accordingly. NUM_PREV_ARGS arguments
931 are already in those lists. The argument, of type GTYPE, comes
932 from file FILENAME, line LINENO. */
935 handle_input_arg (const char *arg
, input_test
*it
, size_t num_prev_args
,
936 generic_value_type gtype
,
937 const char *filename
, unsigned int lineno
)
939 size_t num_values
= 0;
940 generic_value values
[2 * fp_num_formats
];
944 for (fp_format f
= fp_first_format
; f
< fp_num_formats
; f
++)
946 mpfr_t extra_values
[2];
947 size_t num_extra_values
= 0;
948 for (size_t i
= 0; i
< ARRAY_SIZE (special_real_inputs
); i
++)
950 if (strcmp (arg
, special_real_inputs
[i
].str
) == 0)
953 = special_real_inputs
[i
].func (extra_values
[0],
955 assert (num_extra_values
> 0
956 && num_extra_values
<= ARRAY_SIZE (extra_values
));
960 if (num_extra_values
== 0)
965 bool inexact
= mpfr_strtofr (tmp
, arg
, &ep
, 0, MPFR_RNDZ
);
966 if (*ep
!= 0 || !mpfr_number_p (tmp
))
967 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
968 "bad floating-point argument: '%s'", arg
);
969 adjust_real (tmp
, inexact
);
970 mpfr_t rounded
[rm_num_modes
];
971 unsigned int exc_before
[rm_num_modes
];
972 unsigned int exc_after
[rm_num_modes
];
973 round_real (rounded
, exc_before
, exc_after
, tmp
, f
);
975 if (mpfr_number_p (rounded
[rm_upward
]))
977 mpfr_init2 (extra_values
[num_extra_values
],
978 fp_formats
[f
].mant_dig
);
979 assert_exact (mpfr_set (extra_values
[num_extra_values
],
980 rounded
[rm_upward
], MPFR_RNDN
));
983 if (mpfr_number_p (rounded
[rm_downward
]))
985 mpfr_init2 (extra_values
[num_extra_values
],
986 fp_formats
[f
].mant_dig
);
987 assert_exact (mpfr_set (extra_values
[num_extra_values
],
988 rounded
[rm_downward
], MPFR_RNDN
));
991 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
992 mpfr_clear (rounded
[m
]);
994 for (size_t i
= 0; i
< num_extra_values
; i
++)
997 for (size_t j
= 0; j
< num_values
; j
++)
999 if (mpfr_equal_p (values
[j
].value
.f
, extra_values
[i
])
1000 && ((mpfr_signbit (values
[j
].value
.f
) != 0)
1001 == (mpfr_signbit (extra_values
[i
]) != 0)))
1009 assert (num_values
< ARRAY_SIZE (values
));
1010 values
[num_values
].type
= gtype_fp
;
1011 mpfr_init2 (values
[num_values
].value
.f
,
1012 fp_formats
[f
].mant_dig
);
1013 assert_exact (mpfr_set (values
[num_values
].value
.f
,
1014 extra_values
[i
], MPFR_RNDN
));
1017 mpfr_clear (extra_values
[i
]);
1024 values
[0].type
= gtype_int
;
1025 int ret
= mpz_init_set_str (values
[0].value
.i
, arg
, 0);
1027 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1028 "bad integer argument: '%s'", arg
);
1034 assert (num_values
> 0 && num_values
<= ARRAY_SIZE (values
));
1035 if (it
->num_input_cases
>= SIZE_MAX
/ num_values
)
1036 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
, "too many input cases");
1037 generic_value
**old_inputs
= it
->inputs
;
1038 size_t new_num_input_cases
= it
->num_input_cases
* num_values
;
1039 generic_value
**new_inputs
= xmalloc (new_num_input_cases
1040 * sizeof (new_inputs
[0]));
1041 for (size_t i
= 0; i
< it
->num_input_cases
; i
++)
1043 for (size_t j
= 0; j
< num_values
; j
++)
1045 size_t idx
= i
* num_values
+ j
;
1046 new_inputs
[idx
] = xmalloc ((num_prev_args
+ 1)
1047 * sizeof (new_inputs
[idx
][0]));
1048 for (size_t k
= 0; k
< num_prev_args
; k
++)
1049 generic_value_copy (&new_inputs
[idx
][k
], &old_inputs
[i
][k
]);
1050 generic_value_copy (&new_inputs
[idx
][num_prev_args
], &values
[j
]);
1052 for (size_t j
= 0; j
< num_prev_args
; j
++)
1053 generic_value_free (&old_inputs
[i
][j
]);
1054 free (old_inputs
[i
]);
1057 for (size_t i
= 0; i
< num_values
; i
++)
1058 generic_value_free (&values
[i
]);
1059 it
->inputs
= new_inputs
;
1060 it
->num_input_cases
= new_num_input_cases
;
1063 /* Handle the input flag ARG (NUL-terminated), storing it in *FLAG.
1064 The flag comes from file FILENAME, line LINENO. */
1067 handle_input_flag (char *arg
, input_flag
*flag
,
1068 const char *filename
, unsigned int lineno
)
1070 char *ep
= strchr (arg
, ':');
1073 ep
= strchr (arg
, 0);
1074 assert (ep
!= NULL
);
1079 for (input_flag_type i
= flag_first_flag
; i
<= num_input_flag_types
; i
++)
1081 if (strcmp (arg
, input_flags
[i
]) == 0)
1089 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
, "unknown flag: '%s'",
1095 flag
->cond
= xstrdup (ep
);
1098 /* Add the test LINE (file FILENAME, line LINENO) to the test
1102 add_test (char *line
, const char *filename
, unsigned int lineno
)
1104 size_t num_tokens
= 1;
1106 while ((p
= strchr (p
, ' ')) != NULL
)
1112 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1113 "line too short: '%s'", line
);
1114 p
= strchr (line
, ' ');
1115 size_t func_name_len
= p
- line
;
1116 for (size_t i
= 0; i
< ARRAY_SIZE (test_functions
); i
++)
1118 if (func_name_len
== strlen (test_functions
[i
].name
)
1119 && strncmp (line
, test_functions
[i
].name
, func_name_len
) == 0)
1121 test_function
*tf
= &test_functions
[i
];
1122 if (num_tokens
< 1 + tf
->num_args
)
1123 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1124 "line too short: '%s'", line
);
1125 if (tf
->num_tests
== tf
->num_tests_alloc
)
1127 tf
->num_tests_alloc
= 2 * tf
->num_tests_alloc
+ 16;
1129 = xrealloc (tf
->tests
,
1130 tf
->num_tests_alloc
* sizeof (tf
->tests
[0]));
1132 input_test
*it
= &tf
->tests
[tf
->num_tests
];
1134 it
->num_input_cases
= 1;
1135 it
->inputs
= xmalloc (sizeof (it
->inputs
[0]));
1136 it
->inputs
[0] = NULL
;
1137 it
->old_output
= NULL
;
1139 for (size_t j
= 0; j
< tf
->num_args
; j
++)
1141 char *ep
= strchr (p
, ' ');
1144 ep
= strchr (p
, '\n');
1145 assert (ep
!= NULL
);
1148 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1149 "empty token in line: '%s'", line
);
1150 for (char *t
= p
; t
< ep
; t
++)
1151 if (isspace ((unsigned char) *t
))
1152 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1153 "whitespace in token in line: '%s'", line
);
1156 handle_input_arg (p
, it
, j
,
1157 generic_arg_ret_type (tf
->arg_types
[j
]),
1162 it
->num_flags
= num_tokens
- 1 - tf
->num_args
;
1163 it
->flags
= xmalloc (it
->num_flags
* sizeof (it
->flags
[0]));
1164 for (size_t j
= 0; j
< it
->num_flags
; j
++)
1166 char *ep
= strchr (p
, ' ');
1169 ep
= strchr (p
, '\n');
1170 assert (ep
!= NULL
);
1173 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1174 "empty token in line: '%s'", line
);
1175 for (char *t
= p
; t
< ep
; t
++)
1176 if (isspace ((unsigned char) *t
))
1177 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1178 "whitespace in token in line: '%s'", line
);
1181 handle_input_flag (p
, &it
->flags
[j
], filename
, lineno
);
1190 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1191 "unknown function in line: '%s'", line
);
1194 /* Read in the test input data from FILENAME. */
1197 read_input (const char *filename
)
1199 FILE *fp
= fopen (filename
, "r");
1201 error (EXIT_FAILURE
, errno
, "open '%s'", filename
);
1202 unsigned int lineno
= 0;
1207 ssize_t ret
= getline (&line
, &size
, fp
);
1211 if (line
[0] == '#' || line
[0] == '\n')
1213 add_test (line
, filename
, lineno
);
1216 error (EXIT_FAILURE
, errno
, "read from '%s'", filename
);
1217 if (fclose (fp
) != 0)
1218 error (EXIT_FAILURE
, errno
, "close '%s'", filename
);
1221 /* Calculate the generic results (round-to-zero with sticky bit) for
1222 the function described by CALC, with inputs INPUTS. */
1225 calc_generic_results (generic_value
*outputs
, generic_value
*inputs
,
1226 const func_calc_desc
*calc
)
1229 switch (calc
->method
)
1232 assert (inputs
[0].type
== gtype_fp
);
1233 outputs
[0].type
= gtype_fp
;
1234 mpfr_init (outputs
[0].value
.f
);
1235 inexact
= calc
->func
.mpfr_f_f (outputs
[0].value
.f
, inputs
[0].value
.f
,
1237 adjust_real (outputs
[0].value
.f
, inexact
);
1245 /* Return the number of bits for integer type TYPE, where "long" has
1246 LONG_BITS bits (32 or 64). */
1249 int_type_bits (arg_ret_type type
, int long_bits
)
1251 assert (long_bits
== 32 || long_bits
== 64);
1262 case type_long_long
:
1271 /* Check whether an integer Z fits a given type TYPE, where "long" has
1272 LONG_BITS bits (32 or 64). */
1275 int_fits_type (mpz_t z
, arg_ret_type type
, int long_bits
)
1277 int bits
= int_type_bits (type
, long_bits
);
1281 mpz_ui_pow_ui (t
, 2, bits
- 1);
1282 if (mpz_cmp (z
, t
) >= 0)
1285 if (mpz_cmp (z
, t
) < 0)
1291 /* Print a generic value V to FP (name FILENAME), preceded by a space,
1292 for type TYPE, floating-point format FORMAT, LONG_BITS bits per
1293 long, printing " IGNORE" instead if IGNORE. */
1296 output_generic_value (FILE *fp
, const char *filename
, const generic_value
*v
,
1297 bool ignore
, arg_ret_type type
, fp_format format
,
1302 if (fputs (" IGNORE", fp
) < 0)
1303 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1306 assert (v
->type
== generic_arg_ret_type (type
));
1311 suffix
= fp_formats
[format
].suffix
;
1322 case type_long_long
:
1332 if (mpfr_inf_p (v
->value
.f
))
1334 if (fputs ((mpfr_signbit (v
->value
.f
)
1335 ? " minus_infty" : " plus_infty"), fp
) < 0)
1336 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1340 assert (mpfr_number_p (v
->value
.f
));
1341 if (mpfr_fprintf (fp
, " %Ra%s", v
->value
.f
, suffix
) < 0)
1342 error (EXIT_FAILURE
, errno
, "mpfr_fprintf to '%s'", filename
);
1347 int bits
= int_type_bits (type
, long_bits
);
1350 mpz_ui_pow_ui (tmp
, 2, bits
- 1);
1352 if (mpz_cmp (v
->value
.i
, tmp
) == 0)
1354 mpz_add_ui (tmp
, tmp
, 1);
1355 if (mpfr_fprintf (fp
, " (%Zd%s-1)", tmp
, suffix
) < 0)
1356 error (EXIT_FAILURE
, errno
, "mpfr_fprintf to '%s'", filename
);
1360 if (mpfr_fprintf (fp
, " %Zd%s", v
->value
.i
, suffix
) < 0)
1361 error (EXIT_FAILURE
, errno
, "mpfr_fprintf to '%s'", filename
);
1371 /* Generate test output to FP (name FILENAME) for test function TF,
1372 input test IT, choice of input values INPUTS. */
1375 output_for_one_input_case (FILE *fp
, const char *filename
, test_function
*tf
,
1376 input_test
*it
, generic_value
*inputs
)
1378 bool long_bits_matters
= false;
1379 bool fits_long32
= true;
1380 for (size_t i
= 0; i
< tf
->num_args
; i
++)
1382 generic_value_type gtype
= generic_arg_ret_type (tf
->arg_types
[i
]);
1383 assert (inputs
[i
].type
== gtype
);
1384 if (gtype
== gtype_int
)
1386 bool fits_64
= int_fits_type (inputs
[i
].value
.i
, tf
->arg_types
[i
],
1390 if (tf
->arg_types
[i
] == type_long
1391 && !int_fits_type (inputs
[i
].value
.i
, tf
->arg_types
[i
], 32))
1393 long_bits_matters
= true;
1394 fits_long32
= false;
1398 generic_value generic_outputs
[MAX_NRET
];
1399 calc_generic_results (generic_outputs
, inputs
, &tf
->calc
);
1400 bool ignore_output_long32
[MAX_NRET
] = { false };
1401 bool ignore_output_long64
[MAX_NRET
] = { false };
1402 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
1404 assert (generic_outputs
[i
].type
1405 == generic_arg_ret_type (tf
->ret_types
[i
]));
1406 switch (generic_outputs
[i
].type
)
1409 if (!mpfr_number_p (generic_outputs
[i
].value
.f
))
1410 goto out
; /* Result is NaN or exact infinity. */
1414 ignore_output_long32
[i
] = !int_fits_type (generic_outputs
[i
].value
.i
,
1415 tf
->ret_types
[i
], 32);
1416 ignore_output_long64
[i
] = !int_fits_type (generic_outputs
[i
].value
.i
,
1417 tf
->ret_types
[i
], 64);
1418 if (ignore_output_long32
[i
] != ignore_output_long64
[i
])
1419 long_bits_matters
= true;
1426 /* Iterate over relevant sizes of long and floating-point formats. */
1427 for (int long_bits
= 32; long_bits
<= 64; long_bits
+= 32)
1429 if (long_bits
== 32 && !fits_long32
)
1431 if (long_bits
== 64 && !long_bits_matters
)
1433 const char *long_cond
;
1434 if (long_bits_matters
)
1435 long_cond
= (long_bits
== 32 ? ":long32" : ":long64");
1438 bool *ignore_output
= (long_bits
== 32
1439 ? ignore_output_long32
1440 : ignore_output_long64
);
1441 for (fp_format f
= fp_first_format
; f
< fp_num_formats
; f
++)
1444 mpfr_t res
[rm_num_modes
];
1445 unsigned int exc_before
[rm_num_modes
];
1446 unsigned int exc_after
[rm_num_modes
];
1447 for (size_t i
= 0; i
< tf
->num_args
; i
++)
1449 if (inputs
[i
].type
== gtype_fp
)
1450 round_real (res
, exc_before
, exc_after
, inputs
[i
].value
.f
, f
);
1451 if (!mpfr_equal_p (res
[rm_tonearest
], inputs
[i
].value
.f
))
1453 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1454 mpfr_clear (res
[m
]);
1460 /* The inputs fit this type, so compute the ideal outputs
1462 mpfr_t all_res
[MAX_NRET
][rm_num_modes
];
1463 unsigned int all_exc_before
[MAX_NRET
][rm_num_modes
];
1464 unsigned int all_exc_after
[MAX_NRET
][rm_num_modes
];
1465 unsigned int merged_exc_before
[rm_num_modes
] = { 0 };
1466 unsigned int merged_exc_after
[rm_num_modes
] = { 0 };
1467 /* For functions not exactly determined, track whether
1468 underflow is required (some result is inexact, and
1469 magnitude does not exceed the greatest magnitude
1470 subnormal), and permitted (not an exact zero, and
1471 magnitude does not exceed the least magnitude
1473 bool must_underflow
= false;
1474 bool may_underflow
= false;
1475 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
1477 switch (generic_outputs
[i
].type
)
1480 round_real (all_res
[i
], all_exc_before
[i
], all_exc_after
[i
],
1481 generic_outputs
[i
].value
.f
, f
);
1482 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1484 merged_exc_before
[m
] |= all_exc_before
[i
][m
];
1485 merged_exc_after
[m
] |= all_exc_after
[i
][m
];
1489 |= ((all_exc_before
[i
][m
]
1490 & (1U << exc_inexact
)) != 0
1491 && (mpfr_cmpabs (generic_outputs
[i
].value
.f
,
1492 fp_formats
[f
].subnorm_max
)
1495 |= (!mpfr_zero_p (generic_outputs
[i
].value
.f
)
1496 && mpfr_cmpabs (generic_outputs
[i
].value
.f
,
1497 fp_formats
[f
].min
) <= 0);
1503 if (ignore_output
[i
])
1504 for (rounding_mode m
= rm_first_mode
;
1508 merged_exc_before
[m
] |= 1U << exc_invalid
;
1509 merged_exc_after
[m
] |= 1U << exc_invalid
;
1517 assert (may_underflow
|| !must_underflow
);
1518 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1520 bool before_after_matters
1521 = tf
->exact
&& merged_exc_before
[m
] != merged_exc_after
[m
];
1522 for (int after
= 0; after
<= 1; after
++)
1524 if (after
== 1 && !before_after_matters
)
1526 const char *after_cond
;
1527 if (before_after_matters
)
1530 : ":before-rounding");
1533 unsigned int merged_exc
= (after
1534 ? merged_exc_after
[m
]
1535 : merged_exc_before
[m
]);
1536 if (fprintf (fp
, "= %s %s %s%s%s", tf
->name
,
1537 rounding_modes
[m
].name
, fp_formats
[f
].name
,
1538 long_cond
, after_cond
) < 0)
1539 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1541 for (size_t i
= 0; i
< tf
->num_args
; i
++)
1542 output_generic_value (fp
, filename
, &inputs
[i
], false,
1543 tf
->arg_types
[i
], f
, long_bits
);
1544 if (fputs (" :", fp
) < 0)
1545 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1546 /* Print outputs. */
1547 bool must_erange
= false;
1548 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
1551 g
.type
= generic_outputs
[i
].type
;
1555 if (mpfr_inf_p (all_res
[i
][m
])
1556 && (all_exc_before
[i
][m
]
1557 & (1U << exc_overflow
)) != 0)
1559 if (mpfr_zero_p (all_res
[i
][m
])
1561 || mpfr_zero_p (all_res
[i
][rm_tonearest
]))
1562 && (all_exc_before
[i
][m
]
1563 & (1U << exc_underflow
)) != 0)
1565 mpfr_init2 (g
.value
.f
, fp_formats
[f
].mant_dig
);
1566 assert_exact (mpfr_set (g
.value
.f
, all_res
[i
][m
],
1571 mpz_init (g
.value
.i
);
1572 mpz_set (g
.value
.i
, generic_outputs
[i
].value
.i
);
1578 output_generic_value (fp
, filename
, &g
, ignore_output
[i
],
1579 tf
->ret_types
[i
], f
, long_bits
);
1580 generic_value_free (&g
);
1582 if (fputs (" :", fp
) < 0)
1583 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1584 /* Print miscellaneous flags (passed through from
1586 for (size_t i
= 0; i
< it
->num_flags
; i
++)
1587 switch (it
->flags
[i
].type
)
1589 case flag_no_test_inline
:
1591 if (fprintf (fp
, " %s%s",
1592 input_flags
[it
->flags
[i
].type
],
1596 error (EXIT_FAILURE
, errno
, "write to '%s'",
1599 case flag_xfail_rounding
:
1600 if (m
!= rm_tonearest
)
1601 if (fprintf (fp
, " xfail%s",
1605 error (EXIT_FAILURE
, errno
, "write to '%s'",
1611 /* Print exception flags and compute errno
1612 expectations where not already computed. */
1613 bool may_edom
= false;
1614 bool must_edom
= false;
1615 bool may_erange
= must_erange
|| may_underflow
;
1616 for (fp_exception e
= exc_first_exception
;
1617 e
< exc_num_exceptions
;
1620 bool expect_e
= (merged_exc
& (1U << e
)) != 0;
1621 bool e_optional
= false;
1626 may_erange
= must_erange
= true;
1636 may_edom
= must_edom
= true;
1649 if (may_underflow
&& !must_underflow
)
1658 if (fprintf (fp
, " %s-ok", exceptions
[e
]) < 0)
1659 error (EXIT_FAILURE
, errno
, "write to '%s'",
1665 if (fprintf (fp
, " %s", exceptions
[e
]) < 0)
1666 error (EXIT_FAILURE
, errno
, "write to '%s'",
1668 input_flag_type okflag
;
1670 ? flag_missing_first
1671 : flag_spurious_first
) + e
;
1672 for (size_t i
= 0; i
< it
->num_flags
; i
++)
1673 if (it
->flags
[i
].type
== okflag
)
1674 if (fprintf (fp
, " %s-ok%s",
1679 error (EXIT_FAILURE
, errno
, "write to '%s'",
1683 /* Print errno expectations. */
1687 must_erange
= false;
1689 if (may_edom
&& !must_edom
)
1691 if (fputs (" errno-edom-ok", fp
) < 0)
1692 error (EXIT_FAILURE
, errno
, "write to '%s'",
1698 if (fputs (" errno-edom", fp
) < 0)
1699 error (EXIT_FAILURE
, errno
, "write to '%s'",
1701 input_flag_type okflag
= (must_edom
1702 ? flag_missing_errno
1703 : flag_spurious_errno
);
1704 for (size_t i
= 0; i
< it
->num_flags
; i
++)
1705 if (it
->flags
[i
].type
== okflag
)
1706 if (fprintf (fp
, " errno-edom-ok%s",
1710 error (EXIT_FAILURE
, errno
, "write to '%s'",
1713 if (may_erange
&& !must_erange
)
1715 if (fputs (" errno-erange-ok", fp
) < 0)
1716 error (EXIT_FAILURE
, errno
, "write to '%s'",
1722 if (fputs (" errno-erange", fp
) < 0)
1723 error (EXIT_FAILURE
, errno
, "write to '%s'",
1725 input_flag_type okflag
= (must_erange
1726 ? flag_missing_errno
1727 : flag_spurious_errno
);
1728 for (size_t i
= 0; i
< it
->num_flags
; i
++)
1729 if (it
->flags
[i
].type
== okflag
)
1730 if (fprintf (fp
, " errno-erange-ok%s",
1734 error (EXIT_FAILURE
, errno
, "write to '%s'",
1737 if (putc ('\n', fp
) < 0)
1738 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1741 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
1743 if (generic_outputs
[i
].type
== gtype_fp
)
1744 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1745 mpfr_clear (all_res
[i
][m
]);
1750 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
1751 generic_value_free (&generic_outputs
[i
]);
1754 /* Generate test output data to FILENAME. */
1757 generate_output (const char *filename
)
1759 FILE *fp
= fopen (filename
, "w");
1761 error (EXIT_FAILURE
, errno
, "open '%s'", filename
);
1762 for (size_t i
= 0; i
< ARRAY_SIZE (test_functions
); i
++)
1764 test_function
*tf
= &test_functions
[i
];
1765 for (size_t j
= 0; j
< tf
->num_tests
; j
++)
1767 input_test
*it
= &tf
->tests
[j
];
1768 if (fputs (it
->line
, fp
) < 0)
1769 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1770 for (size_t k
= 0; k
< it
->num_input_cases
; k
++)
1771 output_for_one_input_case (fp
, filename
, tf
, it
, it
->inputs
[k
]);
1774 if (fclose (fp
) != 0)
1775 error (EXIT_FAILURE
, errno
, "close '%s'", filename
);
1779 main (int argc
, char **argv
)
1782 error (EXIT_FAILURE
, 0, "usage: gen-auto-libm-tests <input> <output>");
1783 const char *input_filename
= argv
[1];
1784 const char *output_filename
= argv
[2];
1786 read_input (input_filename
);
1787 generate_output (output_filename
);
1788 exit (EXIT_SUCCESS
);