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 value 0.5ulp above the least positive normal value. */
175 mpfr_t min_plus_half
;
176 /* The least positive normal value, 2^(MIN_EXP-1). */
178 /* The greatest positive subnormal value. */
180 /* The least positive subnormal value, 2^(MIN_EXP-MANT_DIG). */
184 /* List of floating-point formats, in the same order as the fp_format
186 static fp_format_desc fp_formats
[fp_num_formats
] =
188 { "flt-32", "f", NULL
, 24, 128, -125, {}, {}, {}, {}, {} },
189 { "dbl-64", "", NULL
, 53, 1024, -1021, {}, {}, {}, {}, {} },
190 { "ldbl-96-intel", "L", NULL
, 64, 16384, -16381, {}, {}, {}, {}, {} },
191 { "ldbl-96-m68k", "L", NULL
, 64, 16384, -16382, {}, {}, {}, {}, {} },
192 { "ldbl-128", "L", NULL
, 113, 16384, -16381, {}, {}, {}, {}, {} },
193 { "ldbl-128ibm", "L", "0x1.fffffffffffff7ffffffffffff8p+1023",
194 106, 1024, -968, {}, {}, {}, {}, {} },
197 /* The supported rounding modes. */
208 /* Structure describing a single rounding mode. */
211 /* The name of the rounding mode. */
213 /* The MPFR rounding mode. */
214 mpfr_rnd_t mpfr_mode
;
215 /* The MPC rounding mode. */
217 } rounding_mode_desc
;
219 /* List of rounding modes, in the same order as the rounding_mode
221 static const rounding_mode_desc rounding_modes
[rm_num_modes
] =
223 { "downward", MPFR_RNDD
, MPC_RNDDD
},
224 { "tonearest", MPFR_RNDN
, MPC_RNDNN
},
225 { "towardzero", MPFR_RNDZ
, MPC_RNDZZ
},
226 { "upward", MPFR_RNDU
, MPC_RNDUU
},
229 /* The supported exceptions. */
238 exc_first_exception
= 0
241 /* List of exceptions, in the same order as the fp_exception
243 static const char *const exceptions
[exc_num_exceptions
] =
252 /* The internal precision to use for most MPFR calculations, which
253 must be at least 2 more than the greatest precision of any
254 supported floating-point format. */
255 static int internal_precision
;
257 /* A value that overflows all supported floating-point formats. */
258 static mpfr_t global_max
;
260 /* A value that is at most half the least subnormal in any
261 floating-point format and so is rounded the same way as all
262 sufficiently small positive values. */
263 static mpfr_t global_min
;
265 /* The maximum number of (real or integer) arguments to a function
266 handled by this program (complex arguments count as two real
270 /* The maximum number of (real or integer) return values from a
271 function handled by this program. */
274 /* A type of a function argument or return value. */
277 /* No type (not a valid argument or return value). */
279 /* A floating-point value with the type corresponding to that of
282 /* An integer value of type int. */
284 /* An integer value of type long. */
286 /* An integer value of type long long. */
290 /* A type of a generic real or integer value. */
295 /* Floating-point (represented with MPFR). */
297 /* Integer (represented with GMP). */
299 } generic_value_type
;
301 /* A generic value (argument or result). */
304 /* The type of this value. */
305 generic_value_type type
;
314 /* A type of input flag. */
320 /* The "spurious" and "missing" flags must be in the same order as
321 the fp_exception enumeration. */
322 flag_spurious_divbyzero
,
323 flag_spurious_inexact
,
324 flag_spurious_invalid
,
325 flag_spurious_overflow
,
326 flag_spurious_underflow
,
328 flag_missing_divbyzero
,
329 flag_missing_inexact
,
330 flag_missing_invalid
,
331 flag_missing_overflow
,
332 flag_missing_underflow
,
334 num_input_flag_types
,
336 flag_spurious_first
= flag_spurious_divbyzero
,
337 flag_missing_first
= flag_missing_divbyzero
340 /* List of flags, in the same order as the input_flag_type
342 static const char *const input_flags
[num_input_flag_types
] =
347 "spurious-divbyzero",
351 "spurious-underflow",
361 /* An input flag, possibly conditional. */
364 /* The type of this flag. */
365 input_flag_type type
;
366 /* The conditions on this flag, as a string ":cond1:cond2..." or
371 /* Structure describing a single test from the input file (which may
372 expand into many tests in the output). The choice of function,
373 which implies the numbers and types of arguments and results, is
374 implicit rather than stored in this structure (except as part of
378 /* The text of the input line describing the test, including the
381 /* The number of combinations of interpretations of input values for
382 different floating-point formats and rounding modes. */
383 size_t num_input_cases
;
384 /* The corresponding lists of inputs. */
385 generic_value
**inputs
;
386 /* The number of flags for this test. */
388 /* The corresponding list of flags. */
390 /* The old output for this test. */
391 const char *old_output
;
394 /* Ways to calculate a function. */
397 /* MPFR function with a single argument and result. */
399 /* MPFR function with two arguments and one result. */
401 /* MPFR function with three arguments and one result. */
403 /* MPFR function with a single argument and floating-point and
406 /* MPFR function with integer and floating-point arguments and one
409 /* MPFR function with a single argument and two floating-point
412 /* MPC function with a single complex argument and one real
415 /* MPC function with a single complex argument and one complex
418 /* MPC function with two complex arguments and one complex
423 /* Description of how to calculate a function. */
426 /* Which method is used to calculate the function. */
427 func_calc_method method
;
428 /* The specific function called. */
431 int (*mpfr_f_f
) (mpfr_t
, const mpfr_t
, mpfr_rnd_t
);
432 int (*mpfr_ff_f
) (mpfr_t
, const mpfr_t
, const mpfr_t
, mpfr_rnd_t
);
433 int (*mpfr_fff_f
) (mpfr_t
, const mpfr_t
, const mpfr_t
, const mpfr_t
,
435 int (*mpfr_f_f1
) (mpfr_t
, int *, const mpfr_t
, mpfr_rnd_t
);
436 int (*mpfr_if_f
) (mpfr_t
, long, const mpfr_t
, mpfr_rnd_t
);
437 int (*mpfr_f_11
) (mpfr_t
, mpfr_t
, const mpfr_t
, mpfr_rnd_t
);
438 int (*mpc_c_f
) (mpfr_t
, const mpc_t
, mpfr_rnd_t
);
439 int (*mpc_c_c
) (mpc_t
, const mpc_t
, mpc_rnd_t
);
440 int (*mpc_cc_c
) (mpc_t
, const mpc_t
, const mpc_t
, mpc_rnd_t
);
444 /* Structure describing a function handled by this program. */
447 /* The name of the function. */
449 /* The number of arguments. */
451 /* The types of the arguments. */
452 arg_ret_type arg_types
[MAX_NARGS
];
453 /* The number of return values. */
455 /* The types of the return values. */
456 arg_ret_type ret_types
[MAX_NRET
];
457 /* Whether the function has exactly determined results and
460 /* Whether the function is a complex function, so errno setting is
463 /* Whether to treat arguments given as floating-point constants as
464 exact only, rather than rounding them up and down to all
467 /* How to calculate this function. */
469 /* The number of tests allocated for this function. */
470 size_t num_tests_alloc
;
471 /* The number of tests for this function. */
473 /* The tests themselves. */
477 #define ARGS1(T1) 1, { T1 }
478 #define ARGS2(T1, T2) 2, { T1, T2 }
479 #define ARGS3(T1, T2, T3) 3, { T1, T2, T3 }
480 #define ARGS4(T1, T2, T3, T4) 4, { T1, T2, T3, T4 }
481 #define RET1(T1) 1, { T1 }
482 #define RET2(T1, T2) 2, { T1, T2 }
483 #define CALC(TYPE, FN) { TYPE, { .TYPE = FN } }
484 #define FUNC(NAME, ARGS, RET, EXACT, COMPLEX_FN, EXACT_ARGS, CALC) \
486 NAME, ARGS, RET, EXACT, COMPLEX_FN, EXACT_ARGS, CALC, 0, 0, NULL \
489 #define FUNC_mpfr_f_f(NAME, MPFR_FUNC, EXACT) \
490 FUNC (NAME, ARGS1 (type_fp), RET1 (type_fp), EXACT, false, false, \
491 CALC (mpfr_f_f, MPFR_FUNC))
492 #define FUNC_mpfr_ff_f(NAME, MPFR_FUNC, EXACT) \
493 FUNC (NAME, ARGS2 (type_fp, type_fp), RET1 (type_fp), EXACT, false, \
494 false, CALC (mpfr_ff_f, MPFR_FUNC))
495 #define FUNC_mpfr_if_f(NAME, MPFR_FUNC, EXACT) \
496 FUNC (NAME, ARGS2 (type_int, type_fp), RET1 (type_fp), EXACT, false, \
497 false, CALC (mpfr_if_f, MPFR_FUNC))
498 #define FUNC_mpc_c_f(NAME, MPFR_FUNC, EXACT) \
499 FUNC (NAME, ARGS2 (type_fp, type_fp), RET1 (type_fp), EXACT, true, \
500 false, CALC (mpc_c_f, MPFR_FUNC))
501 #define FUNC_mpc_c_c(NAME, MPFR_FUNC, EXACT) \
502 FUNC (NAME, ARGS2 (type_fp, type_fp), RET2 (type_fp, type_fp), EXACT, \
503 true, false, CALC (mpc_c_c, MPFR_FUNC))
505 /* List of functions handled by this program. */
506 static test_function test_functions
[] =
508 FUNC_mpfr_f_f ("acos", mpfr_acos
, false),
509 FUNC_mpfr_f_f ("acosh", mpfr_acosh
, false),
510 FUNC_mpfr_f_f ("asin", mpfr_asin
, false),
511 FUNC_mpfr_f_f ("asinh", mpfr_asinh
, false),
512 FUNC_mpfr_f_f ("atan", mpfr_atan
, false),
513 FUNC_mpfr_ff_f ("atan2", mpfr_atan2
, false),
514 FUNC_mpfr_f_f ("atanh", mpfr_atanh
, false),
515 FUNC_mpc_c_f ("cabs", mpc_abs
, false),
516 FUNC_mpc_c_c ("cacos", mpc_acos
, false),
517 FUNC_mpc_c_c ("cacosh", mpc_acosh
, false),
518 FUNC_mpc_c_f ("carg", mpc_arg
, false),
519 FUNC_mpc_c_c ("casin", mpc_asin
, false),
520 FUNC_mpc_c_c ("casinh", mpc_asinh
, false),
521 FUNC_mpc_c_c ("catan", mpc_atan
, false),
522 FUNC_mpc_c_c ("catanh", mpc_atanh
, false),
523 FUNC_mpfr_f_f ("cbrt", mpfr_cbrt
, false),
524 FUNC_mpc_c_c ("ccos", mpc_cos
, false),
525 FUNC_mpc_c_c ("ccosh", mpc_cosh
, false),
526 FUNC_mpc_c_c ("cexp", mpc_exp
, false),
527 FUNC_mpc_c_c ("clog", mpc_log
, false),
528 FUNC_mpc_c_c ("clog10", mpc_log10
, false),
529 FUNC_mpfr_f_f ("cos", mpfr_cos
, false),
530 FUNC_mpfr_f_f ("cosh", mpfr_cosh
, false),
531 FUNC ("cpow", ARGS4 (type_fp
, type_fp
, type_fp
, type_fp
),
532 RET2 (type_fp
, type_fp
), false, true, false,
533 CALC (mpc_cc_c
, mpc_pow
)),
534 FUNC_mpc_c_c ("csin", mpc_sin
, false),
535 FUNC_mpc_c_c ("csinh", mpc_sinh
, false),
536 FUNC_mpc_c_c ("csqrt", mpc_sqrt
, false),
537 FUNC_mpc_c_c ("ctan", mpc_tan
, false),
538 FUNC_mpc_c_c ("ctanh", mpc_tanh
, false),
539 FUNC_mpfr_f_f ("erf", mpfr_erf
, false),
540 FUNC_mpfr_f_f ("erfc", mpfr_erfc
, false),
541 FUNC_mpfr_f_f ("exp", mpfr_exp
, false),
542 FUNC_mpfr_f_f ("exp10", mpfr_exp10
, false),
543 FUNC_mpfr_f_f ("exp2", mpfr_exp2
, false),
544 FUNC_mpfr_f_f ("expm1", mpfr_expm1
, false),
545 FUNC ("fma", ARGS3 (type_fp
, type_fp
, type_fp
), RET1 (type_fp
),
546 true, false, true, CALC (mpfr_fff_f
, mpfr_fma
)),
547 FUNC_mpfr_ff_f ("hypot", mpfr_hypot
, false),
548 FUNC_mpfr_f_f ("j0", mpfr_j0
, false),
549 FUNC_mpfr_f_f ("j1", mpfr_j1
, false),
550 FUNC_mpfr_if_f ("jn", mpfr_jn
, false),
551 FUNC ("lgamma", ARGS1 (type_fp
), RET2 (type_fp
, type_int
), false, false,
552 false, CALC (mpfr_f_f1
, mpfr_lgamma
)),
553 FUNC_mpfr_f_f ("log", mpfr_log
, false),
554 FUNC_mpfr_f_f ("log10", mpfr_log10
, false),
555 FUNC_mpfr_f_f ("log1p", mpfr_log1p
, false),
556 FUNC_mpfr_f_f ("log2", mpfr_log2
, false),
557 FUNC_mpfr_ff_f ("pow", mpfr_pow
, false),
558 FUNC_mpfr_f_f ("sin", mpfr_sin
, false),
559 FUNC ("sincos", ARGS1 (type_fp
), RET2 (type_fp
, type_fp
), false, false,
560 false, CALC (mpfr_f_11
, mpfr_sin_cos
)),
561 FUNC_mpfr_f_f ("sinh", mpfr_sinh
, false),
562 FUNC_mpfr_f_f ("sqrt", mpfr_sqrt
, true),
563 FUNC_mpfr_f_f ("tan", mpfr_tan
, false),
564 FUNC_mpfr_f_f ("tanh", mpfr_tanh
, false),
565 FUNC_mpfr_f_f ("tgamma", mpfr_gamma
, false),
566 FUNC_mpfr_f_f ("y0", mpfr_y0
, false),
567 FUNC_mpfr_f_f ("y1", mpfr_y1
, false),
568 FUNC_mpfr_if_f ("yn", mpfr_yn
, false),
571 /* Allocate memory, with error checking. */
576 void *p
= malloc (n
);
578 error (EXIT_FAILURE
, errno
, "xmalloc failed");
583 xrealloc (void *p
, size_t n
)
587 error (EXIT_FAILURE
, errno
, "xrealloc failed");
592 xstrdup (const char *s
)
594 char *p
= strdup (s
);
596 error (EXIT_FAILURE
, errno
, "xstrdup failed");
600 /* Assert that the result of an MPFR operation was exact; that is,
601 that the returned ternary value was 0. */
609 /* Return the generic type of an argument or return value type T. */
611 static generic_value_type
612 generic_arg_ret_type (arg_ret_type t
)
629 /* Free a generic_value *V. */
632 generic_value_free (generic_value
*v
)
637 mpfr_clear (v
->value
.f
);
641 mpz_clear (v
->value
.i
);
649 /* Copy a generic_value *SRC to *DEST. */
652 generic_value_copy (generic_value
*dest
, const generic_value
*src
)
654 dest
->type
= src
->type
;
658 mpfr_init (dest
->value
.f
);
659 assert_exact (mpfr_set (dest
->value
.f
, src
->value
.f
, MPFR_RNDN
));
663 mpz_init (dest
->value
.i
);
664 mpz_set (dest
->value
.i
, src
->value
.i
);
672 /* Initialize data for floating-point formats. */
677 int global_max_exp
= 0, global_min_subnorm_exp
= 0;
678 for (fp_format f
= fp_first_format
; f
< fp_num_formats
; f
++)
680 if (fp_formats
[f
].mant_dig
+ 2 > internal_precision
)
681 internal_precision
= fp_formats
[f
].mant_dig
+ 2;
682 if (fp_formats
[f
].max_exp
> global_max_exp
)
683 global_max_exp
= fp_formats
[f
].max_exp
;
684 int min_subnorm_exp
= fp_formats
[f
].min_exp
- fp_formats
[f
].mant_dig
;
685 if (min_subnorm_exp
< global_min_subnorm_exp
)
686 global_min_subnorm_exp
= min_subnorm_exp
;
687 mpfr_init2 (fp_formats
[f
].max
, fp_formats
[f
].mant_dig
);
688 if (fp_formats
[f
].max_string
!= NULL
)
691 assert_exact (mpfr_strtofr (fp_formats
[f
].max
,
692 fp_formats
[f
].max_string
,
698 assert_exact (mpfr_set_ui_2exp (fp_formats
[f
].max
, 1,
699 fp_formats
[f
].max_exp
,
701 mpfr_nextbelow (fp_formats
[f
].max
);
703 mpfr_init2 (fp_formats
[f
].min
, fp_formats
[f
].mant_dig
);
704 assert_exact (mpfr_set_ui_2exp (fp_formats
[f
].min
, 1,
705 fp_formats
[f
].min_exp
- 1,
707 mpfr_init2 (fp_formats
[f
].min_plus_half
, fp_formats
[f
].mant_dig
+ 1);
708 assert_exact (mpfr_set (fp_formats
[f
].min_plus_half
,
709 fp_formats
[f
].min
, MPFR_RNDN
));
710 mpfr_nextabove (fp_formats
[f
].min_plus_half
);
711 mpfr_init2 (fp_formats
[f
].subnorm_max
, fp_formats
[f
].mant_dig
);
712 assert_exact (mpfr_set (fp_formats
[f
].subnorm_max
, fp_formats
[f
].min
,
714 mpfr_nextbelow (fp_formats
[f
].subnorm_max
);
715 mpfr_nextbelow (fp_formats
[f
].subnorm_max
);
716 mpfr_init2 (fp_formats
[f
].subnorm_min
, fp_formats
[f
].mant_dig
);
717 assert_exact (mpfr_set_ui_2exp (fp_formats
[f
].subnorm_min
, 1,
718 min_subnorm_exp
, MPFR_RNDN
));
720 mpfr_set_default_prec (internal_precision
);
721 mpfr_init (global_max
);
722 assert_exact (mpfr_set_ui_2exp (global_max
, 1, global_max_exp
, MPFR_RNDN
));
723 mpfr_init (global_min
);
724 assert_exact (mpfr_set_ui_2exp (global_min
, 1, global_min_subnorm_exp
- 1,
728 /* Fill in mpfr_t values for special strings in input arguments. */
731 special_fill_max (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
734 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
735 assert_exact (mpfr_set (res0
, fp_formats
[format
].max
, MPFR_RNDN
));
740 special_fill_minus_max (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
743 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
744 assert_exact (mpfr_neg (res0
, fp_formats
[format
].max
, MPFR_RNDN
));
749 special_fill_min (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
752 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
753 assert_exact (mpfr_set (res0
, fp_formats
[format
].min
, MPFR_RNDN
));
758 special_fill_minus_min (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
761 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
762 assert_exact (mpfr_neg (res0
, fp_formats
[format
].min
, MPFR_RNDN
));
767 special_fill_min_subnorm (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
770 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
771 assert_exact (mpfr_set (res0
, fp_formats
[format
].subnorm_min
, MPFR_RNDN
));
776 special_fill_minus_min_subnorm (mpfr_t res0
,
777 mpfr_t res1
__attribute__ ((unused
)),
780 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
781 assert_exact (mpfr_neg (res0
, fp_formats
[format
].subnorm_min
, MPFR_RNDN
));
786 special_fill_min_subnorm_p120 (mpfr_t res0
,
787 mpfr_t res1
__attribute__ ((unused
)),
790 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
791 assert_exact (mpfr_mul_2ui (res0
, fp_formats
[format
].subnorm_min
,
797 special_fill_pi (mpfr_t res0
, mpfr_t res1
, fp_format format
)
799 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
800 mpfr_const_pi (res0
, MPFR_RNDU
);
801 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
802 mpfr_const_pi (res1
, MPFR_RNDD
);
807 special_fill_minus_pi (mpfr_t res0
, mpfr_t res1
, fp_format format
)
809 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
810 mpfr_const_pi (res0
, MPFR_RNDU
);
811 assert_exact (mpfr_neg (res0
, res0
, MPFR_RNDN
));
812 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
813 mpfr_const_pi (res1
, MPFR_RNDD
);
814 assert_exact (mpfr_neg (res1
, res1
, MPFR_RNDN
));
819 special_fill_pi_2 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
821 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
822 mpfr_const_pi (res0
, MPFR_RNDU
);
823 assert_exact (mpfr_div_ui (res0
, res0
, 2, MPFR_RNDN
));
824 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
825 mpfr_const_pi (res1
, MPFR_RNDD
);
826 assert_exact (mpfr_div_ui (res1
, res1
, 2, MPFR_RNDN
));
831 special_fill_minus_pi_2 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
833 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
834 mpfr_const_pi (res0
, MPFR_RNDU
);
835 assert_exact (mpfr_div_ui (res0
, res0
, 2, MPFR_RNDN
));
836 assert_exact (mpfr_neg (res0
, res0
, MPFR_RNDN
));
837 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
838 mpfr_const_pi (res1
, MPFR_RNDD
);
839 assert_exact (mpfr_div_ui (res1
, res1
, 2, MPFR_RNDN
));
840 assert_exact (mpfr_neg (res1
, res1
, MPFR_RNDN
));
845 special_fill_pi_4 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
847 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
848 assert_exact (mpfr_set_si (res0
, 1, MPFR_RNDN
));
849 mpfr_atan (res0
, res0
, MPFR_RNDU
);
850 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
851 assert_exact (mpfr_set_si (res1
, 1, MPFR_RNDN
));
852 mpfr_atan (res1
, res1
, MPFR_RNDD
);
857 special_fill_pi_6 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
859 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
860 assert_exact (mpfr_set_si_2exp (res0
, 1, -1, MPFR_RNDN
));
861 mpfr_asin (res0
, res0
, MPFR_RNDU
);
862 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
863 assert_exact (mpfr_set_si_2exp (res1
, 1, -1, MPFR_RNDN
));
864 mpfr_asin (res1
, res1
, MPFR_RNDD
);
869 special_fill_minus_pi_6 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
871 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
872 assert_exact (mpfr_set_si_2exp (res0
, -1, -1, MPFR_RNDN
));
873 mpfr_asin (res0
, res0
, MPFR_RNDU
);
874 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
875 assert_exact (mpfr_set_si_2exp (res1
, -1, -1, MPFR_RNDN
));
876 mpfr_asin (res1
, res1
, MPFR_RNDD
);
881 special_fill_pi_3 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
883 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
884 assert_exact (mpfr_set_si_2exp (res0
, 1, -1, MPFR_RNDN
));
885 mpfr_acos (res0
, res0
, MPFR_RNDU
);
886 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
887 assert_exact (mpfr_set_si_2exp (res1
, 1, -1, MPFR_RNDN
));
888 mpfr_acos (res1
, res1
, MPFR_RNDD
);
893 special_fill_2pi_3 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
895 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
896 assert_exact (mpfr_set_si_2exp (res0
, -1, -1, MPFR_RNDN
));
897 mpfr_acos (res0
, res0
, MPFR_RNDU
);
898 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
899 assert_exact (mpfr_set_si_2exp (res1
, -1, -1, MPFR_RNDN
));
900 mpfr_acos (res1
, res1
, MPFR_RNDD
);
905 special_fill_2pi (mpfr_t res0
, mpfr_t res1
, fp_format format
)
907 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
908 mpfr_const_pi (res0
, MPFR_RNDU
);
909 assert_exact (mpfr_mul_ui (res0
, res0
, 2, MPFR_RNDN
));
910 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
911 mpfr_const_pi (res1
, MPFR_RNDD
);
912 assert_exact (mpfr_mul_ui (res1
, res1
, 2, MPFR_RNDN
));
917 special_fill_e (mpfr_t res0
, mpfr_t res1
, fp_format format
)
919 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
920 assert_exact (mpfr_set_si (res0
, 1, MPFR_RNDN
));
921 mpfr_exp (res0
, res0
, MPFR_RNDU
);
922 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
923 assert_exact (mpfr_set_si (res1
, 1, MPFR_RNDN
));
924 mpfr_exp (res1
, res1
, MPFR_RNDD
);
929 special_fill_1_e (mpfr_t res0
, mpfr_t res1
, fp_format format
)
931 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
932 assert_exact (mpfr_set_si (res0
, -1, MPFR_RNDN
));
933 mpfr_exp (res0
, res0
, MPFR_RNDU
);
934 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
935 assert_exact (mpfr_set_si (res1
, -1, MPFR_RNDN
));
936 mpfr_exp (res1
, res1
, MPFR_RNDD
);
941 special_fill_e_minus_1 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
943 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
944 assert_exact (mpfr_set_si (res0
, 1, MPFR_RNDN
));
945 mpfr_expm1 (res0
, res0
, MPFR_RNDU
);
946 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
947 assert_exact (mpfr_set_si (res1
, 1, MPFR_RNDN
));
948 mpfr_expm1 (res1
, res1
, MPFR_RNDD
);
952 /* A special string accepted in input arguments. */
957 /* The function that interprets it for a given floating-point
958 format, filling in up to two mpfr_t values and returning the
959 number of values filled. */
960 size_t (*func
) (mpfr_t
, mpfr_t
, fp_format
);
961 } special_real_input
;
963 /* List of special strings accepted in input arguments. */
965 static const special_real_input special_real_inputs
[] =
967 { "max", special_fill_max
},
968 { "-max", special_fill_minus_max
},
969 { "min", special_fill_min
},
970 { "-min", special_fill_minus_min
},
971 { "min_subnorm", special_fill_min_subnorm
},
972 { "-min_subnorm", special_fill_minus_min_subnorm
},
973 { "min_subnorm_p120", special_fill_min_subnorm_p120
},
974 { "pi", special_fill_pi
},
975 { "-pi", special_fill_minus_pi
},
976 { "pi/2", special_fill_pi_2
},
977 { "-pi/2", special_fill_minus_pi_2
},
978 { "pi/4", special_fill_pi_4
},
979 { "pi/6", special_fill_pi_6
},
980 { "-pi/6", special_fill_minus_pi_6
},
981 { "pi/3", special_fill_pi_3
},
982 { "2pi/3", special_fill_2pi_3
},
983 { "2pi", special_fill_2pi
},
984 { "e", special_fill_e
},
985 { "1/e", special_fill_1_e
},
986 { "e-1", special_fill_e_minus_1
},
989 /* Given a real number R computed in round-to-zero mode, set the
990 lowest bit as a sticky bit if INEXACT, and saturate the exponent
991 range for very large or small values. */
994 adjust_real (mpfr_t r
, bool inexact
)
998 /* NaNs are exact, as are infinities in round-to-zero mode. */
999 assert (mpfr_number_p (r
));
1000 if (mpfr_cmpabs (r
, global_min
) < 0)
1001 assert_exact (mpfr_copysign (r
, global_min
, r
, MPFR_RNDN
));
1002 else if (mpfr_cmpabs (r
, global_max
) > 0)
1003 assert_exact (mpfr_copysign (r
, global_max
, r
, MPFR_RNDN
));
1008 mpfr_exp_t e
= mpfr_get_z_2exp (tmp
, r
);
1009 if (mpz_sgn (tmp
) < 0)
1012 mpz_setbit (tmp
, 0);
1016 mpz_setbit (tmp
, 0);
1017 assert_exact (mpfr_set_z_2exp (r
, tmp
, e
, MPFR_RNDN
));
1022 /* Given a finite real number R with sticky bit, compute the roundings
1023 to FORMAT in each rounding mode, storing the results in RES, the
1024 before-rounding exceptions in EXC_BEFORE and the after-rounding
1025 exceptions in EXC_AFTER. */
1028 round_real (mpfr_t res
[rm_num_modes
],
1029 unsigned int exc_before
[rm_num_modes
],
1030 unsigned int exc_after
[rm_num_modes
],
1031 mpfr_t r
, fp_format format
)
1033 assert (mpfr_number_p (r
));
1034 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1036 mpfr_init2 (res
[m
], fp_formats
[format
].mant_dig
);
1037 exc_before
[m
] = exc_after
[m
] = 0;
1038 bool inexact
= mpfr_set (res
[m
], r
, rounding_modes
[m
].mpfr_mode
);
1039 if (mpfr_cmpabs (res
[m
], fp_formats
[format
].max
) > 0)
1042 exc_before
[m
] |= 1U << exc_overflow
;
1043 exc_after
[m
] |= 1U << exc_overflow
;
1048 overflow_inf
= true;
1051 overflow_inf
= false;
1054 overflow_inf
= mpfr_signbit (res
[m
]);
1057 overflow_inf
= !mpfr_signbit (res
[m
]);
1063 mpfr_set_inf (res
[m
], mpfr_signbit (res
[m
]) ? -1 : 1);
1065 assert_exact (mpfr_copysign (res
[m
], fp_formats
[format
].max
,
1066 res
[m
], MPFR_RNDN
));
1068 if (mpfr_cmpabs (r
, fp_formats
[format
].min
) < 0)
1070 /* Tiny before rounding; may or may not be tiny after
1071 rounding, and underflow applies only if also inexact
1072 around rounding to a possibly subnormal value. */
1073 bool tiny_after_rounding
1074 = mpfr_cmpabs (res
[m
], fp_formats
[format
].min
) < 0;
1075 /* To round to a possibly subnormal value, and determine
1076 inexactness as a subnormal in the process, scale up and
1077 round to integer, then scale back down. */
1080 assert_exact (mpfr_mul_2si (tmp
, r
, (fp_formats
[format
].mant_dig
1081 - fp_formats
[format
].min_exp
),
1083 int rint_res
= mpfr_rint (tmp
, tmp
, rounding_modes
[m
].mpfr_mode
);
1084 /* The integer must be representable. */
1085 assert (rint_res
== 0 || rint_res
== 2 || rint_res
== -2);
1086 /* If rounding to full precision was inexact, so must
1087 rounding to subnormal precision be inexact. */
1089 assert (rint_res
!= 0);
1091 inexact
= rint_res
!= 0;
1092 assert_exact (mpfr_mul_2si (res
[m
], tmp
,
1093 (fp_formats
[format
].min_exp
1094 - fp_formats
[format
].mant_dig
),
1099 exc_before
[m
] |= 1U << exc_underflow
;
1100 if (tiny_after_rounding
)
1101 exc_after
[m
] |= 1U << exc_underflow
;
1106 exc_before
[m
] |= 1U << exc_inexact
;
1107 exc_after
[m
] |= 1U << exc_inexact
;
1112 /* Handle the input argument at ARG (NUL-terminated), updating the
1113 lists of test inputs in IT accordingly. NUM_PREV_ARGS arguments
1114 are already in those lists. If EXACT_ARGS, interpret a value given
1115 as a floating-point constant exactly (it must be exact for some
1116 supported format) rather than rounding up and down. The argument,
1117 of type GTYPE, comes from file FILENAME, line LINENO. */
1120 handle_input_arg (const char *arg
, input_test
*it
, size_t num_prev_args
,
1121 generic_value_type gtype
, bool exact_args
,
1122 const char *filename
, unsigned int lineno
)
1124 size_t num_values
= 0;
1125 generic_value values
[2 * fp_num_formats
];
1126 bool check_empty_list
= false;
1130 for (fp_format f
= fp_first_format
; f
< fp_num_formats
; f
++)
1132 mpfr_t extra_values
[2];
1133 size_t num_extra_values
= 0;
1134 for (size_t i
= 0; i
< ARRAY_SIZE (special_real_inputs
); i
++)
1136 if (strcmp (arg
, special_real_inputs
[i
].str
) == 0)
1139 = special_real_inputs
[i
].func (extra_values
[0],
1140 extra_values
[1], f
);
1141 assert (num_extra_values
> 0
1142 && num_extra_values
<= ARRAY_SIZE (extra_values
));
1146 if (num_extra_values
== 0)
1151 check_empty_list
= true;
1153 bool inexact
= mpfr_strtofr (tmp
, arg
, &ep
, 0, MPFR_RNDZ
);
1154 if (*ep
!= 0 || !mpfr_number_p (tmp
))
1155 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1156 "bad floating-point argument: '%s'", arg
);
1157 adjust_real (tmp
, inexact
);
1158 mpfr_t rounded
[rm_num_modes
];
1159 unsigned int exc_before
[rm_num_modes
];
1160 unsigned int exc_after
[rm_num_modes
];
1161 round_real (rounded
, exc_before
, exc_after
, tmp
, f
);
1163 if (mpfr_number_p (rounded
[rm_upward
])
1164 && (!exact_args
|| mpfr_equal_p (rounded
[rm_upward
],
1165 rounded
[rm_downward
])))
1167 mpfr_init2 (extra_values
[num_extra_values
],
1168 fp_formats
[f
].mant_dig
);
1169 assert_exact (mpfr_set (extra_values
[num_extra_values
],
1170 rounded
[rm_upward
], MPFR_RNDN
));
1173 if (mpfr_number_p (rounded
[rm_downward
]) && !exact_args
)
1175 mpfr_init2 (extra_values
[num_extra_values
],
1176 fp_formats
[f
].mant_dig
);
1177 assert_exact (mpfr_set (extra_values
[num_extra_values
],
1178 rounded
[rm_downward
], MPFR_RNDN
));
1181 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1182 mpfr_clear (rounded
[m
]);
1184 for (size_t i
= 0; i
< num_extra_values
; i
++)
1187 for (size_t j
= 0; j
< num_values
; j
++)
1189 if (mpfr_equal_p (values
[j
].value
.f
, extra_values
[i
])
1190 && ((mpfr_signbit (values
[j
].value
.f
) != 0)
1191 == (mpfr_signbit (extra_values
[i
]) != 0)))
1199 assert (num_values
< ARRAY_SIZE (values
));
1200 values
[num_values
].type
= gtype_fp
;
1201 mpfr_init2 (values
[num_values
].value
.f
,
1202 fp_formats
[f
].mant_dig
);
1203 assert_exact (mpfr_set (values
[num_values
].value
.f
,
1204 extra_values
[i
], MPFR_RNDN
));
1207 mpfr_clear (extra_values
[i
]);
1214 values
[0].type
= gtype_int
;
1215 int ret
= mpz_init_set_str (values
[0].value
.i
, arg
, 0);
1217 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1218 "bad integer argument: '%s'", arg
);
1224 if (check_empty_list
&& num_values
== 0)
1225 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1226 "floating-point argument not exact for any format: '%s'",
1228 assert (num_values
> 0 && num_values
<= ARRAY_SIZE (values
));
1229 if (it
->num_input_cases
>= SIZE_MAX
/ num_values
)
1230 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
, "too many input cases");
1231 generic_value
**old_inputs
= it
->inputs
;
1232 size_t new_num_input_cases
= it
->num_input_cases
* num_values
;
1233 generic_value
**new_inputs
= xmalloc (new_num_input_cases
1234 * sizeof (new_inputs
[0]));
1235 for (size_t i
= 0; i
< it
->num_input_cases
; i
++)
1237 for (size_t j
= 0; j
< num_values
; j
++)
1239 size_t idx
= i
* num_values
+ j
;
1240 new_inputs
[idx
] = xmalloc ((num_prev_args
+ 1)
1241 * sizeof (new_inputs
[idx
][0]));
1242 for (size_t k
= 0; k
< num_prev_args
; k
++)
1243 generic_value_copy (&new_inputs
[idx
][k
], &old_inputs
[i
][k
]);
1244 generic_value_copy (&new_inputs
[idx
][num_prev_args
], &values
[j
]);
1246 for (size_t j
= 0; j
< num_prev_args
; j
++)
1247 generic_value_free (&old_inputs
[i
][j
]);
1248 free (old_inputs
[i
]);
1251 for (size_t i
= 0; i
< num_values
; i
++)
1252 generic_value_free (&values
[i
]);
1253 it
->inputs
= new_inputs
;
1254 it
->num_input_cases
= new_num_input_cases
;
1257 /* Handle the input flag ARG (NUL-terminated), storing it in *FLAG.
1258 The flag comes from file FILENAME, line LINENO. */
1261 handle_input_flag (char *arg
, input_flag
*flag
,
1262 const char *filename
, unsigned int lineno
)
1264 char *ep
= strchr (arg
, ':');
1267 ep
= strchr (arg
, 0);
1268 assert (ep
!= NULL
);
1273 for (input_flag_type i
= flag_first_flag
; i
<= num_input_flag_types
; i
++)
1275 if (strcmp (arg
, input_flags
[i
]) == 0)
1283 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
, "unknown flag: '%s'",
1289 flag
->cond
= xstrdup (ep
);
1292 /* Add the test LINE (file FILENAME, line LINENO) to the test
1296 add_test (char *line
, const char *filename
, unsigned int lineno
)
1298 size_t num_tokens
= 1;
1300 while ((p
= strchr (p
, ' ')) != NULL
)
1306 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1307 "line too short: '%s'", line
);
1308 p
= strchr (line
, ' ');
1309 size_t func_name_len
= p
- line
;
1310 for (size_t i
= 0; i
< ARRAY_SIZE (test_functions
); i
++)
1312 if (func_name_len
== strlen (test_functions
[i
].name
)
1313 && strncmp (line
, test_functions
[i
].name
, func_name_len
) == 0)
1315 test_function
*tf
= &test_functions
[i
];
1316 if (num_tokens
< 1 + tf
->num_args
)
1317 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1318 "line too short: '%s'", line
);
1319 if (tf
->num_tests
== tf
->num_tests_alloc
)
1321 tf
->num_tests_alloc
= 2 * tf
->num_tests_alloc
+ 16;
1323 = xrealloc (tf
->tests
,
1324 tf
->num_tests_alloc
* sizeof (tf
->tests
[0]));
1326 input_test
*it
= &tf
->tests
[tf
->num_tests
];
1328 it
->num_input_cases
= 1;
1329 it
->inputs
= xmalloc (sizeof (it
->inputs
[0]));
1330 it
->inputs
[0] = NULL
;
1331 it
->old_output
= NULL
;
1333 for (size_t j
= 0; j
< tf
->num_args
; j
++)
1335 char *ep
= strchr (p
, ' ');
1338 ep
= strchr (p
, '\n');
1339 assert (ep
!= NULL
);
1342 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1343 "empty token in line: '%s'", line
);
1344 for (char *t
= p
; t
< ep
; t
++)
1345 if (isspace ((unsigned char) *t
))
1346 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1347 "whitespace in token in line: '%s'", line
);
1350 handle_input_arg (p
, it
, j
,
1351 generic_arg_ret_type (tf
->arg_types
[j
]),
1352 tf
->exact_args
, filename
, lineno
);
1356 it
->num_flags
= num_tokens
- 1 - tf
->num_args
;
1357 it
->flags
= xmalloc (it
->num_flags
* sizeof (it
->flags
[0]));
1358 for (size_t j
= 0; j
< it
->num_flags
; j
++)
1360 char *ep
= strchr (p
, ' ');
1363 ep
= strchr (p
, '\n');
1364 assert (ep
!= NULL
);
1367 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1368 "empty token in line: '%s'", line
);
1369 for (char *t
= p
; t
< ep
; t
++)
1370 if (isspace ((unsigned char) *t
))
1371 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1372 "whitespace in token in line: '%s'", line
);
1375 handle_input_flag (p
, &it
->flags
[j
], filename
, lineno
);
1384 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1385 "unknown function in line: '%s'", line
);
1388 /* Read in the test input data from FILENAME. */
1391 read_input (const char *filename
)
1393 FILE *fp
= fopen (filename
, "r");
1395 error (EXIT_FAILURE
, errno
, "open '%s'", filename
);
1396 unsigned int lineno
= 0;
1401 ssize_t ret
= getline (&line
, &size
, fp
);
1405 if (line
[0] == '#' || line
[0] == '\n')
1407 add_test (line
, filename
, lineno
);
1410 error (EXIT_FAILURE
, errno
, "read from '%s'", filename
);
1411 if (fclose (fp
) != 0)
1412 error (EXIT_FAILURE
, errno
, "close '%s'", filename
);
1415 /* Calculate the generic results (round-to-zero with sticky bit) for
1416 the function described by CALC, with inputs INPUTS, if MODE is
1417 rm_towardzero; for other modes, calculate results in that mode,
1418 which must be exact zero results. */
1421 calc_generic_results (generic_value
*outputs
, generic_value
*inputs
,
1422 const func_calc_desc
*calc
, rounding_mode mode
)
1427 mpfr_rnd_t mode_mpfr
= rounding_modes
[mode
].mpfr_mode
;
1428 mpc_rnd_t mode_mpc
= rounding_modes
[mode
].mpc_mode
;
1430 switch (calc
->method
)
1433 assert (inputs
[0].type
== gtype_fp
);
1434 outputs
[0].type
= gtype_fp
;
1435 mpfr_init (outputs
[0].value
.f
);
1436 inexact
= calc
->func
.mpfr_f_f (outputs
[0].value
.f
, inputs
[0].value
.f
,
1438 if (mode
!= rm_towardzero
)
1439 assert (!inexact
&& mpfr_zero_p (outputs
[0].value
.f
));
1440 adjust_real (outputs
[0].value
.f
, inexact
);
1444 assert (inputs
[0].type
== gtype_fp
);
1445 assert (inputs
[1].type
== gtype_fp
);
1446 outputs
[0].type
= gtype_fp
;
1447 mpfr_init (outputs
[0].value
.f
);
1448 inexact
= calc
->func
.mpfr_ff_f (outputs
[0].value
.f
, inputs
[0].value
.f
,
1449 inputs
[1].value
.f
, mode_mpfr
);
1450 if (mode
!= rm_towardzero
)
1451 assert (!inexact
&& mpfr_zero_p (outputs
[0].value
.f
));
1452 adjust_real (outputs
[0].value
.f
, inexact
);
1456 assert (inputs
[0].type
== gtype_fp
);
1457 assert (inputs
[1].type
== gtype_fp
);
1458 assert (inputs
[2].type
== gtype_fp
);
1459 outputs
[0].type
= gtype_fp
;
1460 mpfr_init (outputs
[0].value
.f
);
1461 inexact
= calc
->func
.mpfr_fff_f (outputs
[0].value
.f
, inputs
[0].value
.f
,
1462 inputs
[1].value
.f
, inputs
[2].value
.f
,
1464 if (mode
!= rm_towardzero
)
1465 assert (!inexact
&& mpfr_zero_p (outputs
[0].value
.f
));
1466 adjust_real (outputs
[0].value
.f
, inexact
);
1470 assert (inputs
[0].type
== gtype_fp
);
1471 outputs
[0].type
= gtype_fp
;
1472 outputs
[1].type
= gtype_int
;
1473 mpfr_init (outputs
[0].value
.f
);
1475 inexact
= calc
->func
.mpfr_f_f1 (outputs
[0].value
.f
, &i
,
1476 inputs
[0].value
.f
, mode_mpfr
);
1477 if (mode
!= rm_towardzero
)
1478 assert (!inexact
&& mpfr_zero_p (outputs
[0].value
.f
));
1479 adjust_real (outputs
[0].value
.f
, inexact
);
1480 mpz_init_set_si (outputs
[1].value
.i
, i
);
1484 assert (inputs
[0].type
== gtype_int
);
1485 assert (inputs
[1].type
== gtype_fp
);
1486 outputs
[0].type
= gtype_fp
;
1487 mpfr_init (outputs
[0].value
.f
);
1488 assert (mpz_fits_slong_p (inputs
[0].value
.i
));
1489 long l
= mpz_get_si (inputs
[0].value
.i
);
1490 inexact
= calc
->func
.mpfr_if_f (outputs
[0].value
.f
, l
,
1491 inputs
[1].value
.f
, mode_mpfr
);
1492 if (mode
!= rm_towardzero
)
1493 assert (!inexact
&& mpfr_zero_p (outputs
[0].value
.f
));
1494 adjust_real (outputs
[0].value
.f
, inexact
);
1498 assert (inputs
[0].type
== gtype_fp
);
1499 outputs
[0].type
= gtype_fp
;
1500 mpfr_init (outputs
[0].value
.f
);
1501 outputs
[1].type
= gtype_fp
;
1502 mpfr_init (outputs
[1].value
.f
);
1503 int comb_ternary
= calc
->func
.mpfr_f_11 (outputs
[0].value
.f
,
1507 if (mode
!= rm_towardzero
)
1508 assert (((comb_ternary
& 0x3) == 0
1509 && mpfr_zero_p (outputs
[0].value
.f
))
1510 || ((comb_ternary
& 0xc) == 0
1511 && mpfr_zero_p (outputs
[1].value
.f
)));
1512 adjust_real (outputs
[0].value
.f
, (comb_ternary
& 0x3) != 0);
1513 adjust_real (outputs
[1].value
.f
, (comb_ternary
& 0xc) != 0);
1517 assert (inputs
[0].type
== gtype_fp
);
1518 assert (inputs
[1].type
== gtype_fp
);
1519 outputs
[0].type
= gtype_fp
;
1520 mpfr_init (outputs
[0].value
.f
);
1521 mpc_init2 (ci1
, internal_precision
);
1522 assert_exact (mpc_set_fr_fr (ci1
, inputs
[0].value
.f
, inputs
[1].value
.f
,
1524 inexact
= calc
->func
.mpc_c_f (outputs
[0].value
.f
, ci1
, mode_mpfr
);
1525 if (mode
!= rm_towardzero
)
1526 assert (!inexact
&& mpfr_zero_p (outputs
[0].value
.f
));
1527 adjust_real (outputs
[0].value
.f
, inexact
);
1532 assert (inputs
[0].type
== gtype_fp
);
1533 assert (inputs
[1].type
== gtype_fp
);
1534 outputs
[0].type
= gtype_fp
;
1535 mpfr_init (outputs
[0].value
.f
);
1536 outputs
[1].type
= gtype_fp
;
1537 mpfr_init (outputs
[1].value
.f
);
1538 mpc_init2 (ci1
, internal_precision
);
1539 mpc_init2 (co
, internal_precision
);
1540 assert_exact (mpc_set_fr_fr (ci1
, inputs
[0].value
.f
, inputs
[1].value
.f
,
1542 mpc_ternary
= calc
->func
.mpc_c_c (co
, ci1
, mode_mpc
);
1543 if (mode
!= rm_towardzero
)
1544 assert ((!MPC_INEX_RE (mpc_ternary
)
1545 && mpfr_zero_p (mpc_realref (co
)))
1546 || (!MPC_INEX_IM (mpc_ternary
)
1547 && mpfr_zero_p (mpc_imagref (co
))));
1548 assert_exact (mpfr_set (outputs
[0].value
.f
, mpc_realref (co
),
1550 assert_exact (mpfr_set (outputs
[1].value
.f
, mpc_imagref (co
),
1552 adjust_real (outputs
[0].value
.f
, MPC_INEX_RE (mpc_ternary
));
1553 adjust_real (outputs
[1].value
.f
, MPC_INEX_IM (mpc_ternary
));
1559 assert (inputs
[0].type
== gtype_fp
);
1560 assert (inputs
[1].type
== gtype_fp
);
1561 assert (inputs
[2].type
== gtype_fp
);
1562 assert (inputs
[3].type
== gtype_fp
);
1563 outputs
[0].type
= gtype_fp
;
1564 mpfr_init (outputs
[0].value
.f
);
1565 outputs
[1].type
= gtype_fp
;
1566 mpfr_init (outputs
[1].value
.f
);
1567 mpc_init2 (ci1
, internal_precision
);
1568 mpc_init2 (ci2
, internal_precision
);
1569 mpc_init2 (co
, internal_precision
);
1570 assert_exact (mpc_set_fr_fr (ci1
, inputs
[0].value
.f
, inputs
[1].value
.f
,
1572 assert_exact (mpc_set_fr_fr (ci2
, inputs
[2].value
.f
, inputs
[3].value
.f
,
1574 mpc_ternary
= calc
->func
.mpc_cc_c (co
, ci1
, ci2
, mode_mpc
);
1575 if (mode
!= rm_towardzero
)
1576 assert ((!MPC_INEX_RE (mpc_ternary
)
1577 && mpfr_zero_p (mpc_realref (co
)))
1578 || (!MPC_INEX_IM (mpc_ternary
)
1579 && mpfr_zero_p (mpc_imagref (co
))));
1580 assert_exact (mpfr_set (outputs
[0].value
.f
, mpc_realref (co
),
1582 assert_exact (mpfr_set (outputs
[1].value
.f
, mpc_imagref (co
),
1584 adjust_real (outputs
[0].value
.f
, MPC_INEX_RE (mpc_ternary
));
1585 adjust_real (outputs
[1].value
.f
, MPC_INEX_IM (mpc_ternary
));
1596 /* Return the number of bits for integer type TYPE, where "long" has
1597 LONG_BITS bits (32 or 64). */
1600 int_type_bits (arg_ret_type type
, int long_bits
)
1602 assert (long_bits
== 32 || long_bits
== 64);
1613 case type_long_long
:
1622 /* Check whether an integer Z fits a given type TYPE, where "long" has
1623 LONG_BITS bits (32 or 64). */
1626 int_fits_type (mpz_t z
, arg_ret_type type
, int long_bits
)
1628 int bits
= int_type_bits (type
, long_bits
);
1632 mpz_ui_pow_ui (t
, 2, bits
- 1);
1633 if (mpz_cmp (z
, t
) >= 0)
1636 if (mpz_cmp (z
, t
) < 0)
1642 /* Print a generic value V to FP (name FILENAME), preceded by a space,
1643 for type TYPE, floating-point format FORMAT, LONG_BITS bits per
1644 long, printing " IGNORE" instead if IGNORE. */
1647 output_generic_value (FILE *fp
, const char *filename
, const generic_value
*v
,
1648 bool ignore
, arg_ret_type type
, fp_format format
,
1653 if (fputs (" IGNORE", fp
) < 0)
1654 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1657 assert (v
->type
== generic_arg_ret_type (type
));
1662 suffix
= fp_formats
[format
].suffix
;
1673 case type_long_long
:
1683 if (mpfr_inf_p (v
->value
.f
))
1685 if (fputs ((mpfr_signbit (v
->value
.f
)
1686 ? " minus_infty" : " plus_infty"), fp
) < 0)
1687 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1691 assert (mpfr_number_p (v
->value
.f
));
1692 if (mpfr_fprintf (fp
, " %Ra%s", v
->value
.f
, suffix
) < 0)
1693 error (EXIT_FAILURE
, errno
, "mpfr_fprintf to '%s'", filename
);
1698 int bits
= int_type_bits (type
, long_bits
);
1701 mpz_ui_pow_ui (tmp
, 2, bits
- 1);
1703 if (mpz_cmp (v
->value
.i
, tmp
) == 0)
1705 mpz_add_ui (tmp
, tmp
, 1);
1706 if (mpfr_fprintf (fp
, " (%Zd%s-1)", tmp
, suffix
) < 0)
1707 error (EXIT_FAILURE
, errno
, "mpfr_fprintf to '%s'", filename
);
1711 if (mpfr_fprintf (fp
, " %Zd%s", v
->value
.i
, suffix
) < 0)
1712 error (EXIT_FAILURE
, errno
, "mpfr_fprintf to '%s'", filename
);
1722 /* Generate test output to FP (name FILENAME) for test function TF,
1723 input test IT, choice of input values INPUTS. */
1726 output_for_one_input_case (FILE *fp
, const char *filename
, test_function
*tf
,
1727 input_test
*it
, generic_value
*inputs
)
1729 bool long_bits_matters
= false;
1730 bool fits_long32
= true;
1731 for (size_t i
= 0; i
< tf
->num_args
; i
++)
1733 generic_value_type gtype
= generic_arg_ret_type (tf
->arg_types
[i
]);
1734 assert (inputs
[i
].type
== gtype
);
1735 if (gtype
== gtype_int
)
1737 bool fits_64
= int_fits_type (inputs
[i
].value
.i
, tf
->arg_types
[i
],
1741 if (tf
->arg_types
[i
] == type_long
1742 && !int_fits_type (inputs
[i
].value
.i
, tf
->arg_types
[i
], 32))
1744 long_bits_matters
= true;
1745 fits_long32
= false;
1749 generic_value generic_outputs
[MAX_NRET
];
1750 calc_generic_results (generic_outputs
, inputs
, &tf
->calc
, rm_towardzero
);
1751 bool ignore_output_long32
[MAX_NRET
] = { false };
1752 bool ignore_output_long64
[MAX_NRET
] = { false };
1753 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
1755 assert (generic_outputs
[i
].type
1756 == generic_arg_ret_type (tf
->ret_types
[i
]));
1757 switch (generic_outputs
[i
].type
)
1760 if (!mpfr_number_p (generic_outputs
[i
].value
.f
))
1761 goto out
; /* Result is NaN or exact infinity. */
1765 ignore_output_long32
[i
] = !int_fits_type (generic_outputs
[i
].value
.i
,
1766 tf
->ret_types
[i
], 32);
1767 ignore_output_long64
[i
] = !int_fits_type (generic_outputs
[i
].value
.i
,
1768 tf
->ret_types
[i
], 64);
1769 if (ignore_output_long32
[i
] != ignore_output_long64
[i
])
1770 long_bits_matters
= true;
1777 /* Iterate over relevant sizes of long and floating-point formats. */
1778 for (int long_bits
= 32; long_bits
<= 64; long_bits
+= 32)
1780 if (long_bits
== 32 && !fits_long32
)
1782 if (long_bits
== 64 && !long_bits_matters
)
1784 const char *long_cond
;
1785 if (long_bits_matters
)
1786 long_cond
= (long_bits
== 32 ? ":long32" : ":long64");
1789 bool *ignore_output
= (long_bits
== 32
1790 ? ignore_output_long32
1791 : ignore_output_long64
);
1792 for (fp_format f
= fp_first_format
; f
< fp_num_formats
; f
++)
1795 mpfr_t res
[rm_num_modes
];
1796 unsigned int exc_before
[rm_num_modes
];
1797 unsigned int exc_after
[rm_num_modes
];
1798 for (size_t i
= 0; i
< tf
->num_args
; i
++)
1800 if (inputs
[i
].type
== gtype_fp
)
1802 round_real (res
, exc_before
, exc_after
, inputs
[i
].value
.f
,
1804 if (!mpfr_equal_p (res
[rm_tonearest
], inputs
[i
].value
.f
))
1806 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1807 mpfr_clear (res
[m
]);
1814 /* The inputs fit this type, so compute the ideal outputs
1816 mpfr_t all_res
[MAX_NRET
][rm_num_modes
];
1817 unsigned int all_exc_before
[MAX_NRET
][rm_num_modes
];
1818 unsigned int all_exc_after
[MAX_NRET
][rm_num_modes
];
1819 unsigned int merged_exc_before
[rm_num_modes
] = { 0 };
1820 unsigned int merged_exc_after
[rm_num_modes
] = { 0 };
1821 /* For functions not exactly determined, track whether
1822 underflow is required (some result is inexact, and
1823 magnitude does not exceed the greatest magnitude
1824 subnormal), and permitted (not an exact zero, and
1825 magnitude does not exceed the least magnitude
1827 bool must_underflow
= false;
1828 bool may_underflow
= false;
1829 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
1831 switch (generic_outputs
[i
].type
)
1834 round_real (all_res
[i
], all_exc_before
[i
], all_exc_after
[i
],
1835 generic_outputs
[i
].value
.f
, f
);
1836 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1838 merged_exc_before
[m
] |= all_exc_before
[i
][m
];
1839 merged_exc_after
[m
] |= all_exc_after
[i
][m
];
1843 |= ((all_exc_before
[i
][m
]
1844 & (1U << exc_inexact
)) != 0
1845 && (mpfr_cmpabs (generic_outputs
[i
].value
.f
,
1846 fp_formats
[f
].subnorm_max
)
1849 |= (!mpfr_zero_p (generic_outputs
[i
].value
.f
)
1850 && (mpfr_cmpabs (generic_outputs
[i
].value
.f
,
1851 fp_formats
[f
].min_plus_half
)
1854 /* If the result is an exact zero, the sign may
1855 depend on the rounding mode, so recompute it
1856 directly in that mode. */
1857 if (mpfr_zero_p (all_res
[i
][m
])
1858 && (all_exc_before
[i
][m
] & (1U << exc_inexact
)) == 0)
1860 generic_value outputs_rm
[MAX_NRET
];
1861 calc_generic_results (outputs_rm
, inputs
,
1863 assert_exact (mpfr_set (all_res
[i
][m
],
1864 outputs_rm
[i
].value
.f
,
1866 for (size_t j
= 0; j
< tf
->num_ret
; j
++)
1867 generic_value_free (&outputs_rm
[j
]);
1873 if (ignore_output
[i
])
1874 for (rounding_mode m
= rm_first_mode
;
1878 merged_exc_before
[m
] |= 1U << exc_invalid
;
1879 merged_exc_after
[m
] |= 1U << exc_invalid
;
1887 assert (may_underflow
|| !must_underflow
);
1888 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1890 bool before_after_matters
1891 = tf
->exact
&& merged_exc_before
[m
] != merged_exc_after
[m
];
1892 if (before_after_matters
)
1894 assert ((merged_exc_before
[m
] ^ merged_exc_after
[m
])
1895 == (1U << exc_underflow
));
1896 assert ((merged_exc_before
[m
] & (1U << exc_underflow
)) != 0);
1898 unsigned int merged_exc
= merged_exc_before
[m
];
1899 if (fprintf (fp
, "= %s %s %s%s", tf
->name
,
1900 rounding_modes
[m
].name
, fp_formats
[f
].name
,
1902 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1904 for (size_t i
= 0; i
< tf
->num_args
; i
++)
1905 output_generic_value (fp
, filename
, &inputs
[i
], false,
1906 tf
->arg_types
[i
], f
, long_bits
);
1907 if (fputs (" :", fp
) < 0)
1908 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1909 /* Print outputs. */
1910 bool must_erange
= false;
1911 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
1914 g
.type
= generic_outputs
[i
].type
;
1918 if (mpfr_inf_p (all_res
[i
][m
])
1919 && (all_exc_before
[i
][m
]
1920 & (1U << exc_overflow
)) != 0)
1922 if (mpfr_zero_p (all_res
[i
][m
])
1924 || mpfr_zero_p (all_res
[i
][rm_tonearest
]))
1925 && (all_exc_before
[i
][m
]
1926 & (1U << exc_underflow
)) != 0)
1928 mpfr_init2 (g
.value
.f
, fp_formats
[f
].mant_dig
);
1929 assert_exact (mpfr_set (g
.value
.f
, all_res
[i
][m
],
1934 mpz_init (g
.value
.i
);
1935 mpz_set (g
.value
.i
, generic_outputs
[i
].value
.i
);
1941 output_generic_value (fp
, filename
, &g
, ignore_output
[i
],
1942 tf
->ret_types
[i
], f
, long_bits
);
1943 generic_value_free (&g
);
1945 if (fputs (" :", fp
) < 0)
1946 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1947 /* Print miscellaneous flags (passed through from
1949 for (size_t i
= 0; i
< it
->num_flags
; i
++)
1950 switch (it
->flags
[i
].type
)
1952 case flag_no_test_inline
:
1954 if (fprintf (fp
, " %s%s",
1955 input_flags
[it
->flags
[i
].type
],
1959 error (EXIT_FAILURE
, errno
, "write to '%s'",
1962 case flag_xfail_rounding
:
1963 if (m
!= rm_tonearest
)
1964 if (fprintf (fp
, " xfail%s",
1968 error (EXIT_FAILURE
, errno
, "write to '%s'",
1974 /* Print exception flags and compute errno
1975 expectations where not already computed. */
1976 bool may_edom
= false;
1977 bool must_edom
= false;
1978 bool may_erange
= must_erange
|| may_underflow
;
1979 for (fp_exception e
= exc_first_exception
;
1980 e
< exc_num_exceptions
;
1983 bool expect_e
= (merged_exc
& (1U << e
)) != 0;
1984 bool e_optional
= false;
1989 may_erange
= must_erange
= true;
1999 may_edom
= must_edom
= true;
2012 if (may_underflow
&& !must_underflow
)
2021 assert (!before_after_matters
);
2022 if (fprintf (fp
, " %s-ok", exceptions
[e
]) < 0)
2023 error (EXIT_FAILURE
, errno
, "write to '%s'",
2029 if (fprintf (fp
, " %s", exceptions
[e
]) < 0)
2030 error (EXIT_FAILURE
, errno
, "write to '%s'",
2032 if (before_after_matters
&& e
== exc_underflow
)
2033 if (fputs (":before-rounding", fp
) < 0)
2034 error (EXIT_FAILURE
, errno
, "write to '%s'",
2036 for (int after
= 0; after
<= 1; after
++)
2038 bool expect_e_here
= expect_e
;
2039 if (after
== 1 && (!before_after_matters
2040 || e
!= exc_underflow
))
2042 const char *after_cond
;
2043 if (before_after_matters
&& e
== exc_underflow
)
2047 : ":before-rounding");
2048 expect_e_here
= !after
;
2052 input_flag_type okflag
;
2053 okflag
= (expect_e_here
2054 ? flag_missing_first
2055 : flag_spurious_first
) + e
;
2056 for (size_t i
= 0; i
< it
->num_flags
; i
++)
2057 if (it
->flags
[i
].type
== okflag
)
2058 if (fprintf (fp
, " %s-ok%s%s",
2062 : ""), after_cond
) < 0)
2063 error (EXIT_FAILURE
, errno
, "write to '%s'",
2068 /* Print errno expectations. */
2072 must_erange
= false;
2074 if (may_edom
&& !must_edom
)
2076 if (fputs (" errno-edom-ok", fp
) < 0)
2077 error (EXIT_FAILURE
, errno
, "write to '%s'",
2083 if (fputs (" errno-edom", fp
) < 0)
2084 error (EXIT_FAILURE
, errno
, "write to '%s'",
2086 input_flag_type okflag
= (must_edom
2087 ? flag_missing_errno
2088 : flag_spurious_errno
);
2089 for (size_t i
= 0; i
< it
->num_flags
; i
++)
2090 if (it
->flags
[i
].type
== okflag
)
2091 if (fprintf (fp
, " errno-edom-ok%s",
2095 error (EXIT_FAILURE
, errno
, "write to '%s'",
2098 if (before_after_matters
)
2099 assert (may_erange
&& !must_erange
);
2100 if (may_erange
&& !must_erange
)
2102 if (fprintf (fp
, " errno-erange-ok%s",
2103 (before_after_matters
2104 ? ":before-rounding"
2106 error (EXIT_FAILURE
, errno
, "write to '%s'",
2109 if (before_after_matters
|| !(may_erange
&& !must_erange
))
2112 if (fputs (" errno-erange", fp
) < 0)
2113 error (EXIT_FAILURE
, errno
, "write to '%s'",
2115 input_flag_type okflag
= (must_erange
2116 ? flag_missing_errno
2117 : flag_spurious_errno
);
2118 for (size_t i
= 0; i
< it
->num_flags
; i
++)
2119 if (it
->flags
[i
].type
== okflag
)
2120 if (fprintf (fp
, " errno-erange-ok%s%s",
2124 (before_after_matters
2127 error (EXIT_FAILURE
, errno
, "write to '%s'",
2130 if (putc ('\n', fp
) < 0)
2131 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
2133 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
2135 if (generic_outputs
[i
].type
== gtype_fp
)
2136 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
2137 mpfr_clear (all_res
[i
][m
]);
2142 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
2143 generic_value_free (&generic_outputs
[i
]);
2146 /* Generate test output data to FILENAME. */
2149 generate_output (const char *filename
)
2151 FILE *fp
= fopen (filename
, "w");
2153 error (EXIT_FAILURE
, errno
, "open '%s'", filename
);
2154 for (size_t i
= 0; i
< ARRAY_SIZE (test_functions
); i
++)
2156 test_function
*tf
= &test_functions
[i
];
2157 for (size_t j
= 0; j
< tf
->num_tests
; j
++)
2159 input_test
*it
= &tf
->tests
[j
];
2160 if (fputs (it
->line
, fp
) < 0)
2161 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
2162 for (size_t k
= 0; k
< it
->num_input_cases
; k
++)
2163 output_for_one_input_case (fp
, filename
, tf
, it
, it
->inputs
[k
]);
2166 if (fclose (fp
) != 0)
2167 error (EXIT_FAILURE
, errno
, "close '%s'", filename
);
2171 main (int argc
, char **argv
)
2174 error (EXIT_FAILURE
, 0, "usage: gen-auto-libm-tests <input> <output>");
2175 const char *input_filename
= argv
[1];
2176 const char *output_filename
= argv
[2];
2178 read_input (input_filename
);
2179 generate_output (output_filename
);
2180 exit (EXIT_SUCCESS
);