1 /* Generate expected output for libm tests with MPFR and MPC.
2 Copyright (C) 2013-2023 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 <https://www.gnu.org/licenses/>. */
19 /* Compile this program as:
21 gcc -std=gnu11 -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 <func> auto-libm-test-out-<func>
28 to generate results for normal libm functions, or
30 gen-auto-libm-tests --narrow auto-libm-test-in <func> \
31 auto-libm-test-out-narrow-<func>
33 to generate results for a function rounding results to a narrower
34 type (in the case of fma and sqrt, both output files are generated
35 from the same test inputs).
37 The input file auto-libm-test-in contains three kinds of lines:
39 Lines beginning with "#" are comments, and are ignored, as are
42 Other lines are test lines, of the form "function input1 input2
43 ... [flag1 flag2 ...]". Inputs are either finite real numbers or
44 integers, depending on the function under test. Real numbers may
45 be in any form acceptable to mpfr_strtofr (base 0); integers in any
46 form acceptable to mpz_set_str (base 0). In addition, real numbers
47 may be certain special strings such as "pi", as listed in the
48 special_real_inputs array.
50 Each flag is a flag name possibly followed by a series of
51 ":condition". Conditions may be any of the names of floating-point
52 formats in the floating_point_formats array, "long32" and "long64"
53 to indicate the number of bits in the "long" type, or other strings
54 for which libm-test.inc defines a TEST_COND_<condition> macro (with
55 "-"- changed to "_" in the condition name) evaluating to nonzero
56 when the condition is true and zero when the condition is false.
57 The meaning is that the flag applies to the test if all the listed
58 conditions are true. "flag:cond1:cond2 flag:cond3:cond4" means the
59 flag applies if ((cond1 && cond2) || (cond3 && cond4)).
61 A real number specified as an input is considered to represent the
62 set of real numbers arising from rounding the given number in any
63 direction for any supported floating-point format; any roundings
64 that give infinity are ignored. Each input on a test line has all
65 the possible roundings considered independently. Each resulting
66 choice of the tuple of inputs to the function is ignored if the
67 mathematical result of the function involves a NaN or an exact
68 infinity, and is otherwise considered for each floating-point
69 format for which all those inputs are exactly representable. Thus
70 tests may result in "overflow", "underflow" and "inexact"
71 exceptions; "invalid" may arise only when the final result type is
72 an integer type and it is the conversion of a mathematically
73 defined finite result to integer type that results in that
76 By default, it is assumed that "overflow" and "underflow"
77 exceptions should be correct, but that "inexact" exceptions should
78 only be correct for functions listed as exactly determined. For
79 such functions, "underflow" exceptions should respect whether the
80 machine has before-rounding or after-rounding tininess detection.
81 For other functions, it is considered that if the exact result is
82 somewhere between the greatest magnitude subnormal of a given sign
83 (exclusive) and the least magnitude normal of that sign
84 (inclusive), underflow exceptions are permitted but optional on all
85 machines, and they are also permitted but optional for smaller
86 subnormal exact results for functions that are not exactly
87 determined. errno setting is expected for overflow to infinity and
88 underflow to zero (for real functions), and for out-of-range
89 conversion of a finite result to integer type, and is considered
90 permitted but optional for all other cases where overflow
91 exceptions occur, and where underflow exceptions occur or are
92 permitted. In other cases (where no overflow or underflow is
93 permitted), errno is expected to be left unchanged.
95 The flag "ignore-zero-inf-sign" indicates the the signs of
96 zero and infinite results should be ignored; "xfail" indicates the
97 test is disabled as expected to produce incorrect results,
98 "xfail-rounding" indicates the test is disabled only in rounding
99 modes other than round-to-nearest. Otherwise, test flags are of
100 the form "spurious-<exception>" and "missing-<exception>", for any
101 exception ("overflow", "underflow", "inexact", "invalid",
102 "divbyzero"), "spurious-errno" and "missing-errno", to indicate
103 when tests are expected to deviate from the exception and errno
104 settings corresponding to the mathematical results. "xfail",
105 "xfail-rounding", "spurious-" and "missing-" flags should be
106 accompanied by a comment referring to an open bug in glibc
109 The output file auto-libm-test-out-<func> contains the test lines from
110 auto-libm-test-in, and, after the line for a given test, some
111 number of output test lines. An output test line is of the form "=
112 function rounding-mode format input1 input2 ... : output1 output2
113 ... : flags". rounding-mode is "tonearest", "towardzero", "upward"
114 or "downward". format is a name from the floating_point_formats
115 array, possibly followed by a sequence of ":flag" for flags from
116 "long32" and "long64". Inputs and outputs are specified as hex
117 floats with the required suffix for the floating-point type, or
118 plus_infty or minus_infty for infinite expected results, or as
119 integer constant expressions (not necessarily with the right type)
120 or IGNORE for integer inputs and outputs. Flags are
121 "ignore-zero-info-sign", "xfail", "<exception>",
122 "<exception>-ok", "errno-<value>", "errno-<value>-ok", which may be
123 unconditional or conditional. "<exception>" indicates that a
124 correct result means the given exception should be raised.
125 "errno-<value>" indicates that a correct result means errno should
126 be set to the given value. "-ok" means not to test for the given
127 exception or errno value (whether because it was marked as possibly
128 missing or spurious, or because the calculation of correct results
129 indicated it was optional). Conditions "before-rounding" and
130 "after-rounding" indicate tests where expectations for underflow
131 exceptions depend on how the architecture detects tininess.
133 For functions rounding their results to a narrower type, the format
134 given on an output test line is the result format followed by
135 information about the requirements on the argument format to be
136 able to represent the argument values, in the form
137 "format:arg_fmt(MAX_EXP,NUM_ONES,MIN_EXP,MAX_PREC)". Instead of
138 separate lines for separate argument formats, an output test line
139 relates to all argument formats that can represent the values.
140 MAX_EXP is the maximum exponent of a nonzero bit in any argument,
141 or 0 if all arguments are zero; NUM_ONES is the maximum number of
142 leading bits with value 1 in an argument with exponent MAX_EXP, or
143 0 if all arguments are zero; MIN_EXP is the minimum exponent of a
144 nonzero bit in any argument, or 0 if all arguments are zero;
145 MAX_PREC is the maximum precision required to represent all
146 arguments, or 0 if all arguments are zero. */
164 #define ARRAY_SIZE(A) (sizeof (A) / sizeof ((A)[0]))
166 /* The supported floating-point formats. */
179 /* Structure describing a single floating-point format. */
182 /* The name of the format. */
184 /* A string for the largest normal value, or NULL for IEEE formats
185 where this can be determined automatically. */
186 const char *max_string
;
187 /* The number of mantissa bits. */
189 /* The least N such that 2^N overflows. */
191 /* One more than the least N such that 2^N is normal. */
193 /* The largest normal value. */
195 /* The value 0.5ulp above the least positive normal value. */
196 mpfr_t min_plus_half
;
197 /* The least positive normal value, 2^(MIN_EXP-1). */
199 /* The greatest positive subnormal value. */
201 /* The least positive subnormal value, 2^(MIN_EXP-MANT_DIG). */
205 /* List of floating-point formats, in the same order as the fp_format
207 static fp_format_desc fp_formats
[fp_num_formats
] =
209 { "binary32", NULL
, 24, 128, -125, {}, {}, {}, {}, {} },
210 { "binary64", NULL
, 53, 1024, -1021, {}, {}, {}, {}, {} },
211 { "intel96", NULL
, 64, 16384, -16381, {}, {}, {}, {}, {} },
212 { "m68k96", NULL
, 64, 16384, -16382, {}, {}, {}, {}, {} },
213 { "binary128", NULL
, 113, 16384, -16381, {}, {}, {}, {}, {} },
214 { "ibm128", "0x1.fffffffffffff7ffffffffffff8p+1023",
215 106, 1024, -968, {}, {}, {}, {}, {} },
218 /* The supported rounding modes. */
229 /* Structure describing a single rounding mode. */
232 /* The name of the rounding mode. */
234 /* The MPFR rounding mode. */
235 mpfr_rnd_t mpfr_mode
;
236 /* The MPC rounding mode. */
238 } rounding_mode_desc
;
240 /* List of rounding modes, in the same order as the rounding_mode
242 static const rounding_mode_desc rounding_modes
[rm_num_modes
] =
244 { "downward", MPFR_RNDD
, MPC_RNDDD
},
245 { "tonearest", MPFR_RNDN
, MPC_RNDNN
},
246 { "towardzero", MPFR_RNDZ
, MPC_RNDZZ
},
247 { "upward", MPFR_RNDU
, MPC_RNDUU
},
250 /* The supported exceptions. */
259 exc_first_exception
= 0
262 /* List of exceptions, in the same order as the fp_exception
264 static const char *const exceptions
[exc_num_exceptions
] =
273 /* The internal precision to use for most MPFR calculations, which
274 must be at least 2 more than the greatest precision of any
275 supported floating-point format. */
276 static int internal_precision
;
278 /* A value that overflows all supported floating-point formats. */
279 static mpfr_t global_max
;
281 /* A value that is at most half the least subnormal in any
282 floating-point format and so is rounded the same way as all
283 sufficiently small positive values. */
284 static mpfr_t global_min
;
286 /* The maximum number of (real or integer) arguments to a function
287 handled by this program (complex arguments count as two real
291 /* The maximum number of (real or integer) return values from a
292 function handled by this program. */
295 /* A type of a function argument or return value. */
298 /* No type (not a valid argument or return value). */
300 /* A floating-point value with the type corresponding to that of
303 /* An integer value of type int. */
305 /* An integer value of type long. */
307 /* An integer value of type long long. */
311 /* A type of a generic real or integer value. */
316 /* Floating-point (represented with MPFR). */
318 /* Integer (represented with GMP). */
320 } generic_value_type
;
322 /* A generic value (argument or result). */
325 /* The type of this value. */
326 generic_value_type type
;
335 /* A type of input flag. */
338 flag_ignore_zero_inf_sign
,
341 /* The "spurious" and "missing" flags must be in the same order as
342 the fp_exception enumeration. */
343 flag_spurious_divbyzero
,
344 flag_spurious_inexact
,
345 flag_spurious_invalid
,
346 flag_spurious_overflow
,
347 flag_spurious_underflow
,
349 flag_missing_divbyzero
,
350 flag_missing_inexact
,
351 flag_missing_invalid
,
352 flag_missing_overflow
,
353 flag_missing_underflow
,
355 num_input_flag_types
,
357 flag_spurious_first
= flag_spurious_divbyzero
,
358 flag_missing_first
= flag_missing_divbyzero
361 /* List of flags, in the same order as the input_flag_type
363 static const char *const input_flags
[num_input_flag_types
] =
365 "ignore-zero-inf-sign",
368 "spurious-divbyzero",
372 "spurious-underflow",
382 /* An input flag, possibly conditional. */
385 /* The type of this flag. */
386 input_flag_type type
;
387 /* The conditions on this flag, as a string ":cond1:cond2..." or
392 /* Structure describing a single test from the input file (which may
393 expand into many tests in the output). The choice of function,
394 which implies the numbers and types of arguments and results, is
395 implicit rather than stored in this structure (except as part of
399 /* The text of the input line describing the test, including the
402 /* The number of combinations of interpretations of input values for
403 different floating-point formats and rounding modes. */
404 size_t num_input_cases
;
405 /* The corresponding lists of inputs. */
406 generic_value
**inputs
;
407 /* The number of flags for this test. */
409 /* The corresponding list of flags. */
411 /* The old output for this test. */
412 const char *old_output
;
415 /* Ways to calculate a function. */
418 /* MPFR function with a single argument and result. */
420 /* MPFR function with two arguments and one result. */
422 /* MPFR function with three arguments and one result. */
424 /* MPFR function with a single argument and floating-point and
427 /* MPFR function with integer and floating-point arguments and one
430 /* MPFR function with a single argument and two floating-point
433 /* MPC function with a single complex argument and one real
436 /* MPC function with a single complex argument and one complex
439 /* MPC function with two complex arguments and one complex
444 /* Description of how to calculate a function. */
447 /* Which method is used to calculate the function. */
448 func_calc_method method
;
449 /* The specific function called. */
452 int (*mpfr_f_f
) (mpfr_t
, const mpfr_t
, mpfr_rnd_t
);
453 int (*mpfr_ff_f
) (mpfr_t
, const mpfr_t
, const mpfr_t
, mpfr_rnd_t
);
454 int (*mpfr_fff_f
) (mpfr_t
, const mpfr_t
, const mpfr_t
, const mpfr_t
,
456 int (*mpfr_f_f1
) (mpfr_t
, int *, const mpfr_t
, mpfr_rnd_t
);
457 int (*mpfr_if_f
) (mpfr_t
, long, const mpfr_t
, mpfr_rnd_t
);
458 int (*mpfr_f_11
) (mpfr_t
, mpfr_t
, const mpfr_t
, mpfr_rnd_t
);
459 int (*mpc_c_f
) (mpfr_t
, const mpc_t
, mpfr_rnd_t
);
460 int (*mpc_c_c
) (mpc_t
, const mpc_t
, mpc_rnd_t
);
461 int (*mpc_cc_c
) (mpc_t
, const mpc_t
, const mpc_t
, mpc_rnd_t
);
465 /* Structure describing a function handled by this program. */
468 /* The name of the function. */
470 /* The number of arguments. */
472 /* The types of the arguments. */
473 arg_ret_type arg_types
[MAX_NARGS
];
474 /* The number of return values. */
476 /* The types of the return values. */
477 arg_ret_type ret_types
[MAX_NRET
];
478 /* Whether the function has exactly determined results and
481 /* Whether the function is a complex function, so errno setting is
484 /* Whether to treat arguments given as floating-point constants as
485 exact only, rather than rounding them up and down to all
488 /* How to calculate this function. */
490 /* The number of tests allocated for this function. */
491 size_t num_tests_alloc
;
492 /* The number of tests for this function. */
494 /* The tests themselves. */
498 #define ARGS1(T1) 1, { T1 }
499 #define ARGS2(T1, T2) 2, { T1, T2 }
500 #define ARGS3(T1, T2, T3) 3, { T1, T2, T3 }
501 #define ARGS4(T1, T2, T3, T4) 4, { T1, T2, T3, T4 }
502 #define RET1(T1) 1, { T1 }
503 #define RET2(T1, T2) 2, { T1, T2 }
504 #define CALC(TYPE, FN) { TYPE, { .TYPE = FN } }
505 #define FUNC(NAME, ARGS, RET, EXACT, COMPLEX_FN, EXACT_ARGS, CALC) \
507 NAME, ARGS, RET, EXACT, COMPLEX_FN, EXACT_ARGS, CALC, 0, 0, NULL \
510 #define FUNC_mpfr_f_f(NAME, MPFR_FUNC, EXACT) \
511 FUNC (NAME, ARGS1 (type_fp), RET1 (type_fp), EXACT, false, false, \
512 CALC (mpfr_f_f, MPFR_FUNC))
513 #define FUNC_mpfr_ff_f(NAME, MPFR_FUNC, EXACT) \
514 FUNC (NAME, ARGS2 (type_fp, type_fp), RET1 (type_fp), EXACT, false, \
515 false, CALC (mpfr_ff_f, MPFR_FUNC))
516 #define FUNC_mpfr_if_f(NAME, MPFR_FUNC, EXACT) \
517 FUNC (NAME, ARGS2 (type_int, type_fp), RET1 (type_fp), EXACT, false, \
518 false, CALC (mpfr_if_f, MPFR_FUNC))
519 #define FUNC_mpc_c_f(NAME, MPFR_FUNC, EXACT) \
520 FUNC (NAME, ARGS2 (type_fp, type_fp), RET1 (type_fp), EXACT, true, \
521 false, CALC (mpc_c_f, MPFR_FUNC))
522 #define FUNC_mpc_c_c(NAME, MPFR_FUNC, EXACT) \
523 FUNC (NAME, ARGS2 (type_fp, type_fp), RET2 (type_fp, type_fp), EXACT, \
524 true, false, CALC (mpc_c_c, MPFR_FUNC))
526 /* List of functions handled by this program. */
527 static test_function test_functions
[] =
529 FUNC_mpfr_f_f ("acos", mpfr_acos
, false),
530 FUNC_mpfr_f_f ("acosh", mpfr_acosh
, false),
531 FUNC_mpfr_ff_f ("add", mpfr_add
, true),
532 FUNC_mpfr_f_f ("asin", mpfr_asin
, false),
533 FUNC_mpfr_f_f ("asinh", mpfr_asinh
, false),
534 FUNC_mpfr_f_f ("atan", mpfr_atan
, false),
535 FUNC_mpfr_ff_f ("atan2", mpfr_atan2
, false),
536 FUNC_mpfr_f_f ("atanh", mpfr_atanh
, false),
537 FUNC_mpc_c_f ("cabs", mpc_abs
, false),
538 FUNC_mpc_c_c ("cacos", mpc_acos
, false),
539 FUNC_mpc_c_c ("cacosh", mpc_acosh
, false),
540 FUNC_mpc_c_f ("carg", mpc_arg
, false),
541 FUNC_mpc_c_c ("casin", mpc_asin
, false),
542 FUNC_mpc_c_c ("casinh", mpc_asinh
, false),
543 FUNC_mpc_c_c ("catan", mpc_atan
, false),
544 FUNC_mpc_c_c ("catanh", mpc_atanh
, false),
545 FUNC_mpfr_f_f ("cbrt", mpfr_cbrt
, false),
546 FUNC_mpc_c_c ("ccos", mpc_cos
, false),
547 FUNC_mpc_c_c ("ccosh", mpc_cosh
, false),
548 FUNC_mpc_c_c ("cexp", mpc_exp
, false),
549 FUNC_mpc_c_c ("clog", mpc_log
, false),
550 FUNC_mpc_c_c ("clog10", mpc_log10
, false),
551 FUNC_mpfr_f_f ("cos", mpfr_cos
, false),
552 FUNC_mpfr_f_f ("cosh", mpfr_cosh
, false),
553 FUNC ("cpow", ARGS4 (type_fp
, type_fp
, type_fp
, type_fp
),
554 RET2 (type_fp
, type_fp
), false, true, false,
555 CALC (mpc_cc_c
, mpc_pow
)),
556 FUNC_mpc_c_c ("csin", mpc_sin
, false),
557 FUNC_mpc_c_c ("csinh", mpc_sinh
, false),
558 FUNC_mpc_c_c ("csqrt", mpc_sqrt
, false),
559 FUNC_mpc_c_c ("ctan", mpc_tan
, false),
560 FUNC_mpc_c_c ("ctanh", mpc_tanh
, false),
561 FUNC_mpfr_ff_f ("div", mpfr_div
, true),
562 FUNC_mpfr_f_f ("erf", mpfr_erf
, false),
563 FUNC_mpfr_f_f ("erfc", mpfr_erfc
, false),
564 FUNC_mpfr_f_f ("exp", mpfr_exp
, false),
565 FUNC_mpfr_f_f ("exp10", mpfr_exp10
, false),
566 FUNC_mpfr_f_f ("exp2", mpfr_exp2
, false),
567 FUNC_mpfr_f_f ("expm1", mpfr_expm1
, false),
568 FUNC ("fma", ARGS3 (type_fp
, type_fp
, type_fp
), RET1 (type_fp
),
569 true, false, true, CALC (mpfr_fff_f
, mpfr_fma
)),
570 FUNC_mpfr_ff_f ("hypot", mpfr_hypot
, false),
571 FUNC_mpfr_f_f ("j0", mpfr_j0
, false),
572 FUNC_mpfr_f_f ("j1", mpfr_j1
, false),
573 FUNC_mpfr_if_f ("jn", mpfr_jn
, false),
574 FUNC ("lgamma", ARGS1 (type_fp
), RET2 (type_fp
, type_int
), false, false,
575 false, CALC (mpfr_f_f1
, mpfr_lgamma
)),
576 FUNC_mpfr_f_f ("log", mpfr_log
, false),
577 FUNC_mpfr_f_f ("log10", mpfr_log10
, false),
578 FUNC_mpfr_f_f ("log1p", mpfr_log1p
, false),
579 FUNC_mpfr_f_f ("log2", mpfr_log2
, false),
580 FUNC_mpfr_ff_f ("mul", mpfr_mul
, true),
581 FUNC_mpfr_ff_f ("pow", mpfr_pow
, false),
582 FUNC_mpfr_f_f ("sin", mpfr_sin
, false),
583 FUNC ("sincos", ARGS1 (type_fp
), RET2 (type_fp
, type_fp
), false, false,
584 false, CALC (mpfr_f_11
, mpfr_sin_cos
)),
585 FUNC_mpfr_f_f ("sinh", mpfr_sinh
, false),
586 FUNC_mpfr_ff_f ("sub", mpfr_sub
, true),
587 FUNC_mpfr_f_f ("sqrt", mpfr_sqrt
, true),
588 FUNC_mpfr_f_f ("tan", mpfr_tan
, false),
589 FUNC_mpfr_f_f ("tanh", mpfr_tanh
, false),
590 FUNC_mpfr_f_f ("tgamma", mpfr_gamma
, false),
591 FUNC_mpfr_f_f ("y0", mpfr_y0
, false),
592 FUNC_mpfr_f_f ("y1", mpfr_y1
, false),
593 FUNC_mpfr_if_f ("yn", mpfr_yn
, false),
596 /* Allocate memory, with error checking. */
601 void *p
= malloc (n
);
603 error (EXIT_FAILURE
, errno
, "xmalloc failed");
608 xrealloc (void *p
, size_t n
)
612 error (EXIT_FAILURE
, errno
, "xrealloc failed");
617 xstrdup (const char *s
)
619 char *p
= strdup (s
);
621 error (EXIT_FAILURE
, errno
, "xstrdup failed");
625 /* Assert that the result of an MPFR operation was exact; that is,
626 that the returned ternary value was 0. */
634 /* Return the generic type of an argument or return value type T. */
636 static generic_value_type
637 generic_arg_ret_type (arg_ret_type t
)
654 /* Free a generic_value *V. */
657 generic_value_free (generic_value
*v
)
662 mpfr_clear (v
->value
.f
);
666 mpz_clear (v
->value
.i
);
674 /* Copy a generic_value *SRC to *DEST. */
677 generic_value_copy (generic_value
*dest
, const generic_value
*src
)
679 dest
->type
= src
->type
;
683 mpfr_init (dest
->value
.f
);
684 assert_exact (mpfr_set (dest
->value
.f
, src
->value
.f
, MPFR_RNDN
));
688 mpz_init (dest
->value
.i
);
689 mpz_set (dest
->value
.i
, src
->value
.i
);
697 /* Initialize data for floating-point formats. */
700 init_fp_formats (void)
702 int global_max_exp
= 0, global_min_subnorm_exp
= 0;
703 for (fp_format f
= fp_first_format
; f
< fp_num_formats
; f
++)
705 if (fp_formats
[f
].mant_dig
+ 2 > internal_precision
)
706 internal_precision
= fp_formats
[f
].mant_dig
+ 2;
707 if (fp_formats
[f
].max_exp
> global_max_exp
)
708 global_max_exp
= fp_formats
[f
].max_exp
;
709 int min_subnorm_exp
= fp_formats
[f
].min_exp
- fp_formats
[f
].mant_dig
;
710 if (min_subnorm_exp
< global_min_subnorm_exp
)
711 global_min_subnorm_exp
= min_subnorm_exp
;
712 mpfr_init2 (fp_formats
[f
].max
, fp_formats
[f
].mant_dig
);
713 if (fp_formats
[f
].max_string
!= NULL
)
716 assert_exact (mpfr_strtofr (fp_formats
[f
].max
,
717 fp_formats
[f
].max_string
,
723 assert_exact (mpfr_set_ui_2exp (fp_formats
[f
].max
, 1,
724 fp_formats
[f
].max_exp
,
726 mpfr_nextbelow (fp_formats
[f
].max
);
728 mpfr_init2 (fp_formats
[f
].min
, fp_formats
[f
].mant_dig
);
729 assert_exact (mpfr_set_ui_2exp (fp_formats
[f
].min
, 1,
730 fp_formats
[f
].min_exp
- 1,
732 mpfr_init2 (fp_formats
[f
].min_plus_half
, fp_formats
[f
].mant_dig
+ 1);
733 assert_exact (mpfr_set (fp_formats
[f
].min_plus_half
,
734 fp_formats
[f
].min
, MPFR_RNDN
));
735 mpfr_nextabove (fp_formats
[f
].min_plus_half
);
736 mpfr_init2 (fp_formats
[f
].subnorm_max
, fp_formats
[f
].mant_dig
);
737 assert_exact (mpfr_set (fp_formats
[f
].subnorm_max
, fp_formats
[f
].min
,
739 mpfr_nextbelow (fp_formats
[f
].subnorm_max
);
740 mpfr_nextbelow (fp_formats
[f
].subnorm_max
);
741 mpfr_init2 (fp_formats
[f
].subnorm_min
, fp_formats
[f
].mant_dig
);
742 assert_exact (mpfr_set_ui_2exp (fp_formats
[f
].subnorm_min
, 1,
743 min_subnorm_exp
, MPFR_RNDN
));
745 mpfr_set_default_prec (internal_precision
);
746 mpfr_init (global_max
);
747 assert_exact (mpfr_set_ui_2exp (global_max
, 1, global_max_exp
, MPFR_RNDN
));
748 mpfr_init (global_min
);
749 assert_exact (mpfr_set_ui_2exp (global_min
, 1, global_min_subnorm_exp
- 1,
753 /* Fill in mpfr_t values for special strings in input arguments. */
756 special_fill_max (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
759 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
760 assert_exact (mpfr_set (res0
, fp_formats
[format
].max
, MPFR_RNDN
));
765 special_fill_minus_max (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
768 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
769 assert_exact (mpfr_neg (res0
, fp_formats
[format
].max
, MPFR_RNDN
));
774 special_fill_min (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
777 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
778 assert_exact (mpfr_set (res0
, fp_formats
[format
].min
, MPFR_RNDN
));
783 special_fill_minus_min (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
786 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
787 assert_exact (mpfr_neg (res0
, fp_formats
[format
].min
, MPFR_RNDN
));
792 special_fill_min_subnorm (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
795 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
796 assert_exact (mpfr_set (res0
, fp_formats
[format
].subnorm_min
, MPFR_RNDN
));
801 special_fill_minus_min_subnorm (mpfr_t res0
,
802 mpfr_t res1
__attribute__ ((unused
)),
805 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
806 assert_exact (mpfr_neg (res0
, fp_formats
[format
].subnorm_min
, MPFR_RNDN
));
811 special_fill_min_subnorm_p120 (mpfr_t res0
,
812 mpfr_t res1
__attribute__ ((unused
)),
815 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
816 assert_exact (mpfr_mul_2ui (res0
, fp_formats
[format
].subnorm_min
,
822 special_fill_pi (mpfr_t res0
, mpfr_t res1
, fp_format format
)
824 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
825 mpfr_const_pi (res0
, MPFR_RNDU
);
826 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
827 mpfr_const_pi (res1
, MPFR_RNDD
);
832 special_fill_minus_pi (mpfr_t res0
, mpfr_t res1
, fp_format format
)
834 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
835 mpfr_const_pi (res0
, MPFR_RNDU
);
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_neg (res1
, res1
, MPFR_RNDN
));
844 special_fill_pi_2 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
846 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
847 mpfr_const_pi (res0
, MPFR_RNDU
);
848 assert_exact (mpfr_div_ui (res0
, res0
, 2, MPFR_RNDN
));
849 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
850 mpfr_const_pi (res1
, MPFR_RNDD
);
851 assert_exact (mpfr_div_ui (res1
, res1
, 2, MPFR_RNDN
));
856 special_fill_minus_pi_2 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
858 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
859 mpfr_const_pi (res0
, MPFR_RNDU
);
860 assert_exact (mpfr_div_ui (res0
, res0
, 2, MPFR_RNDN
));
861 assert_exact (mpfr_neg (res0
, res0
, MPFR_RNDN
));
862 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
863 mpfr_const_pi (res1
, MPFR_RNDD
);
864 assert_exact (mpfr_div_ui (res1
, res1
, 2, MPFR_RNDN
));
865 assert_exact (mpfr_neg (res1
, res1
, MPFR_RNDN
));
870 special_fill_pi_4 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
872 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
873 assert_exact (mpfr_set_si (res0
, 1, MPFR_RNDN
));
874 mpfr_atan (res0
, res0
, MPFR_RNDU
);
875 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
876 assert_exact (mpfr_set_si (res1
, 1, MPFR_RNDN
));
877 mpfr_atan (res1
, res1
, MPFR_RNDD
);
882 special_fill_pi_6 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
884 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
885 assert_exact (mpfr_set_si_2exp (res0
, 1, -1, MPFR_RNDN
));
886 mpfr_asin (res0
, res0
, MPFR_RNDU
);
887 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
888 assert_exact (mpfr_set_si_2exp (res1
, 1, -1, MPFR_RNDN
));
889 mpfr_asin (res1
, res1
, MPFR_RNDD
);
894 special_fill_minus_pi_6 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
896 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
897 assert_exact (mpfr_set_si_2exp (res0
, -1, -1, MPFR_RNDN
));
898 mpfr_asin (res0
, res0
, MPFR_RNDU
);
899 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
900 assert_exact (mpfr_set_si_2exp (res1
, -1, -1, MPFR_RNDN
));
901 mpfr_asin (res1
, res1
, MPFR_RNDD
);
906 special_fill_pi_3 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
908 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
909 assert_exact (mpfr_set_si_2exp (res0
, 1, -1, MPFR_RNDN
));
910 mpfr_acos (res0
, res0
, MPFR_RNDU
);
911 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
912 assert_exact (mpfr_set_si_2exp (res1
, 1, -1, MPFR_RNDN
));
913 mpfr_acos (res1
, res1
, MPFR_RNDD
);
918 special_fill_2pi_3 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
920 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
921 assert_exact (mpfr_set_si_2exp (res0
, -1, -1, MPFR_RNDN
));
922 mpfr_acos (res0
, res0
, MPFR_RNDU
);
923 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
924 assert_exact (mpfr_set_si_2exp (res1
, -1, -1, MPFR_RNDN
));
925 mpfr_acos (res1
, res1
, MPFR_RNDD
);
930 special_fill_2pi (mpfr_t res0
, mpfr_t res1
, fp_format format
)
932 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
933 mpfr_const_pi (res0
, MPFR_RNDU
);
934 assert_exact (mpfr_mul_ui (res0
, res0
, 2, MPFR_RNDN
));
935 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
936 mpfr_const_pi (res1
, MPFR_RNDD
);
937 assert_exact (mpfr_mul_ui (res1
, res1
, 2, MPFR_RNDN
));
942 special_fill_e (mpfr_t res0
, mpfr_t res1
, fp_format format
)
944 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
945 assert_exact (mpfr_set_si (res0
, 1, MPFR_RNDN
));
946 mpfr_exp (res0
, res0
, MPFR_RNDU
);
947 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
948 assert_exact (mpfr_set_si (res1
, 1, MPFR_RNDN
));
949 mpfr_exp (res1
, res1
, MPFR_RNDD
);
954 special_fill_1_e (mpfr_t res0
, mpfr_t res1
, fp_format format
)
956 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
957 assert_exact (mpfr_set_si (res0
, -1, MPFR_RNDN
));
958 mpfr_exp (res0
, res0
, MPFR_RNDU
);
959 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
960 assert_exact (mpfr_set_si (res1
, -1, MPFR_RNDN
));
961 mpfr_exp (res1
, res1
, MPFR_RNDD
);
966 special_fill_e_minus_1 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
968 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
969 assert_exact (mpfr_set_si (res0
, 1, MPFR_RNDN
));
970 mpfr_expm1 (res0
, res0
, MPFR_RNDU
);
971 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
972 assert_exact (mpfr_set_si (res1
, 1, MPFR_RNDN
));
973 mpfr_expm1 (res1
, res1
, MPFR_RNDD
);
977 /* A special string accepted in input arguments. */
982 /* The function that interprets it for a given floating-point
983 format, filling in up to two mpfr_t values and returning the
984 number of values filled. */
985 size_t (*func
) (mpfr_t
, mpfr_t
, fp_format
);
986 } special_real_input
;
988 /* List of special strings accepted in input arguments. */
990 static const special_real_input special_real_inputs
[] =
992 { "max", special_fill_max
},
993 { "-max", special_fill_minus_max
},
994 { "min", special_fill_min
},
995 { "-min", special_fill_minus_min
},
996 { "min_subnorm", special_fill_min_subnorm
},
997 { "-min_subnorm", special_fill_minus_min_subnorm
},
998 { "min_subnorm_p120", special_fill_min_subnorm_p120
},
999 { "pi", special_fill_pi
},
1000 { "-pi", special_fill_minus_pi
},
1001 { "pi/2", special_fill_pi_2
},
1002 { "-pi/2", special_fill_minus_pi_2
},
1003 { "pi/4", special_fill_pi_4
},
1004 { "pi/6", special_fill_pi_6
},
1005 { "-pi/6", special_fill_minus_pi_6
},
1006 { "pi/3", special_fill_pi_3
},
1007 { "2pi/3", special_fill_2pi_3
},
1008 { "2pi", special_fill_2pi
},
1009 { "e", special_fill_e
},
1010 { "1/e", special_fill_1_e
},
1011 { "e-1", special_fill_e_minus_1
},
1014 /* Given a real number R computed in round-to-zero mode, set the
1015 lowest bit as a sticky bit if INEXACT, and saturate the exponent
1016 range for very large or small values. */
1019 adjust_real (mpfr_t r
, bool inexact
)
1023 /* NaNs are exact, as are infinities in round-to-zero mode. */
1024 assert (mpfr_number_p (r
));
1025 if (mpfr_cmpabs (r
, global_min
) < 0)
1026 assert_exact (mpfr_copysign (r
, global_min
, r
, MPFR_RNDN
));
1027 else if (mpfr_cmpabs (r
, global_max
) > 0)
1028 assert_exact (mpfr_copysign (r
, global_max
, r
, MPFR_RNDN
));
1033 mpfr_exp_t e
= mpfr_get_z_2exp (tmp
, r
);
1034 if (mpz_sgn (tmp
) < 0)
1037 mpz_setbit (tmp
, 0);
1041 mpz_setbit (tmp
, 0);
1042 assert_exact (mpfr_set_z_2exp (r
, tmp
, e
, MPFR_RNDN
));
1047 /* Given a finite real number R with sticky bit, compute the roundings
1048 to FORMAT in each rounding mode, storing the results in RES, the
1049 before-rounding exceptions in EXC_BEFORE and the after-rounding
1050 exceptions in EXC_AFTER. */
1053 round_real (mpfr_t res
[rm_num_modes
],
1054 unsigned int exc_before
[rm_num_modes
],
1055 unsigned int exc_after
[rm_num_modes
],
1056 mpfr_t r
, fp_format format
)
1058 assert (mpfr_number_p (r
));
1059 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1061 mpfr_init2 (res
[m
], fp_formats
[format
].mant_dig
);
1062 exc_before
[m
] = exc_after
[m
] = 0;
1063 bool inexact
= mpfr_set (res
[m
], r
, rounding_modes
[m
].mpfr_mode
);
1064 if (mpfr_cmpabs (res
[m
], fp_formats
[format
].max
) > 0)
1067 exc_before
[m
] |= 1U << exc_overflow
;
1068 exc_after
[m
] |= 1U << exc_overflow
;
1073 overflow_inf
= true;
1076 overflow_inf
= false;
1079 overflow_inf
= mpfr_signbit (res
[m
]);
1082 overflow_inf
= !mpfr_signbit (res
[m
]);
1088 mpfr_set_inf (res
[m
], mpfr_signbit (res
[m
]) ? -1 : 1);
1090 assert_exact (mpfr_copysign (res
[m
], fp_formats
[format
].max
,
1091 res
[m
], MPFR_RNDN
));
1093 if (mpfr_cmpabs (r
, fp_formats
[format
].min
) < 0)
1095 /* Tiny before rounding; may or may not be tiny after
1096 rounding, and underflow applies only if also inexact
1097 around rounding to a possibly subnormal value. */
1098 bool tiny_after_rounding
1099 = mpfr_cmpabs (res
[m
], fp_formats
[format
].min
) < 0;
1100 /* To round to a possibly subnormal value, and determine
1101 inexactness as a subnormal in the process, scale up and
1102 round to integer, then scale back down. */
1105 assert_exact (mpfr_mul_2si (tmp
, r
, (fp_formats
[format
].mant_dig
1106 - fp_formats
[format
].min_exp
),
1108 int rint_res
= mpfr_rint (tmp
, tmp
, rounding_modes
[m
].mpfr_mode
);
1109 /* The integer must be representable. */
1110 assert (rint_res
== 0 || rint_res
== 2 || rint_res
== -2);
1111 /* If rounding to full precision was inexact, so must
1112 rounding to subnormal precision be inexact. */
1114 assert (rint_res
!= 0);
1116 inexact
= rint_res
!= 0;
1117 assert_exact (mpfr_mul_2si (res
[m
], tmp
,
1118 (fp_formats
[format
].min_exp
1119 - fp_formats
[format
].mant_dig
),
1124 exc_before
[m
] |= 1U << exc_underflow
;
1125 if (tiny_after_rounding
)
1126 exc_after
[m
] |= 1U << exc_underflow
;
1131 exc_before
[m
] |= 1U << exc_inexact
;
1132 exc_after
[m
] |= 1U << exc_inexact
;
1137 /* Handle the input argument at ARG (NUL-terminated), updating the
1138 lists of test inputs in IT accordingly. NUM_PREV_ARGS arguments
1139 are already in those lists. If EXACT_ARGS, interpret a value given
1140 as a floating-point constant exactly (it must be exact for some
1141 supported format) rather than rounding up and down. The argument,
1142 of type GTYPE, comes from file FILENAME, line LINENO. */
1145 handle_input_arg (const char *arg
, input_test
*it
, size_t num_prev_args
,
1146 generic_value_type gtype
, bool exact_args
,
1147 const char *filename
, unsigned int lineno
)
1149 size_t num_values
= 0;
1150 generic_value values
[2 * fp_num_formats
];
1151 bool check_empty_list
= false;
1155 for (fp_format f
= fp_first_format
; f
< fp_num_formats
; f
++)
1157 mpfr_t extra_values
[2];
1158 size_t num_extra_values
= 0;
1159 for (size_t i
= 0; i
< ARRAY_SIZE (special_real_inputs
); i
++)
1161 if (strcmp (arg
, special_real_inputs
[i
].str
) == 0)
1164 = special_real_inputs
[i
].func (extra_values
[0],
1165 extra_values
[1], f
);
1166 assert (num_extra_values
> 0
1167 && num_extra_values
<= ARRAY_SIZE (extra_values
));
1171 if (num_extra_values
== 0)
1176 check_empty_list
= true;
1178 bool inexact
= mpfr_strtofr (tmp
, arg
, &ep
, 0, MPFR_RNDZ
);
1179 if (*ep
!= 0 || !mpfr_number_p (tmp
))
1180 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1181 "bad floating-point argument: '%s'", arg
);
1182 adjust_real (tmp
, inexact
);
1183 mpfr_t rounded
[rm_num_modes
];
1184 unsigned int exc_before
[rm_num_modes
];
1185 unsigned int exc_after
[rm_num_modes
];
1186 round_real (rounded
, exc_before
, exc_after
, tmp
, f
);
1188 if (mpfr_number_p (rounded
[rm_upward
])
1189 && (!exact_args
|| mpfr_equal_p (rounded
[rm_upward
],
1190 rounded
[rm_downward
])))
1192 mpfr_init2 (extra_values
[num_extra_values
],
1193 fp_formats
[f
].mant_dig
);
1194 assert_exact (mpfr_set (extra_values
[num_extra_values
],
1195 rounded
[rm_upward
], MPFR_RNDN
));
1198 if (mpfr_number_p (rounded
[rm_downward
]) && !exact_args
)
1200 mpfr_init2 (extra_values
[num_extra_values
],
1201 fp_formats
[f
].mant_dig
);
1202 assert_exact (mpfr_set (extra_values
[num_extra_values
],
1203 rounded
[rm_downward
], MPFR_RNDN
));
1206 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1207 mpfr_clear (rounded
[m
]);
1209 for (size_t i
= 0; i
< num_extra_values
; i
++)
1212 for (size_t j
= 0; j
< num_values
; j
++)
1214 if (mpfr_equal_p (values
[j
].value
.f
, extra_values
[i
])
1215 && ((mpfr_signbit (values
[j
].value
.f
) != 0)
1216 == (mpfr_signbit (extra_values
[i
]) != 0)))
1224 assert (num_values
< ARRAY_SIZE (values
));
1225 values
[num_values
].type
= gtype_fp
;
1226 mpfr_init2 (values
[num_values
].value
.f
,
1227 fp_formats
[f
].mant_dig
);
1228 assert_exact (mpfr_set (values
[num_values
].value
.f
,
1229 extra_values
[i
], MPFR_RNDN
));
1232 mpfr_clear (extra_values
[i
]);
1239 values
[0].type
= gtype_int
;
1240 int ret
= mpz_init_set_str (values
[0].value
.i
, arg
, 0);
1242 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1243 "bad integer argument: '%s'", arg
);
1249 if (check_empty_list
&& num_values
== 0)
1250 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1251 "floating-point argument not exact for any format: '%s'",
1253 assert (num_values
> 0 && num_values
<= ARRAY_SIZE (values
));
1254 if (it
->num_input_cases
>= SIZE_MAX
/ num_values
)
1255 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
, "too many input cases");
1256 generic_value
**old_inputs
= it
->inputs
;
1257 size_t new_num_input_cases
= it
->num_input_cases
* num_values
;
1258 generic_value
**new_inputs
= xmalloc (new_num_input_cases
1259 * sizeof (new_inputs
[0]));
1260 for (size_t i
= 0; i
< it
->num_input_cases
; i
++)
1262 for (size_t j
= 0; j
< num_values
; j
++)
1264 size_t idx
= i
* num_values
+ j
;
1265 new_inputs
[idx
] = xmalloc ((num_prev_args
+ 1)
1266 * sizeof (new_inputs
[idx
][0]));
1267 for (size_t k
= 0; k
< num_prev_args
; k
++)
1268 generic_value_copy (&new_inputs
[idx
][k
], &old_inputs
[i
][k
]);
1269 generic_value_copy (&new_inputs
[idx
][num_prev_args
], &values
[j
]);
1271 for (size_t j
= 0; j
< num_prev_args
; j
++)
1272 generic_value_free (&old_inputs
[i
][j
]);
1273 free (old_inputs
[i
]);
1276 for (size_t i
= 0; i
< num_values
; i
++)
1277 generic_value_free (&values
[i
]);
1278 it
->inputs
= new_inputs
;
1279 it
->num_input_cases
= new_num_input_cases
;
1282 /* Handle the input flag ARG (NUL-terminated), storing it in *FLAG.
1283 The flag comes from file FILENAME, line LINENO. */
1286 handle_input_flag (char *arg
, input_flag
*flag
,
1287 const char *filename
, unsigned int lineno
)
1289 char *ep
= strchr (arg
, ':');
1292 ep
= strchr (arg
, 0);
1293 assert (ep
!= NULL
);
1298 for (input_flag_type i
= flag_first_flag
; i
< num_input_flag_types
; i
++)
1300 if (strcmp (arg
, input_flags
[i
]) == 0)
1308 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
, "unknown flag: '%s'",
1314 flag
->cond
= xstrdup (ep
);
1317 /* Add the test LINE (file FILENAME, line LINENO) to the test
1321 add_test (char *line
, const char *filename
, unsigned int lineno
)
1323 size_t num_tokens
= 1;
1325 while ((p
= strchr (p
, ' ')) != NULL
)
1331 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1332 "line too short: '%s'", line
);
1333 p
= strchr (line
, ' ');
1334 size_t func_name_len
= p
- line
;
1335 for (size_t i
= 0; i
< ARRAY_SIZE (test_functions
); i
++)
1337 if (func_name_len
== strlen (test_functions
[i
].name
)
1338 && strncmp (line
, test_functions
[i
].name
, func_name_len
) == 0)
1340 test_function
*tf
= &test_functions
[i
];
1341 if (num_tokens
< 1 + tf
->num_args
)
1342 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1343 "line too short: '%s'", line
);
1344 if (tf
->num_tests
== tf
->num_tests_alloc
)
1346 tf
->num_tests_alloc
= 2 * tf
->num_tests_alloc
+ 16;
1348 = xrealloc (tf
->tests
,
1349 tf
->num_tests_alloc
* sizeof (tf
->tests
[0]));
1351 input_test
*it
= &tf
->tests
[tf
->num_tests
];
1353 it
->num_input_cases
= 1;
1354 it
->inputs
= xmalloc (sizeof (it
->inputs
[0]));
1355 it
->inputs
[0] = NULL
;
1356 it
->old_output
= NULL
;
1358 for (size_t j
= 0; j
< tf
->num_args
; 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_arg (p
, it
, j
,
1376 generic_arg_ret_type (tf
->arg_types
[j
]),
1377 tf
->exact_args
, filename
, lineno
);
1381 it
->num_flags
= num_tokens
- 1 - tf
->num_args
;
1382 it
->flags
= xmalloc (it
->num_flags
* sizeof (it
->flags
[0]));
1383 for (size_t j
= 0; j
< it
->num_flags
; j
++)
1385 char *ep
= strchr (p
, ' ');
1388 ep
= strchr (p
, '\n');
1389 assert (ep
!= NULL
);
1392 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1393 "empty token in line: '%s'", line
);
1394 for (char *t
= p
; t
< ep
; t
++)
1395 if (isspace ((unsigned char) *t
))
1396 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1397 "whitespace in token in line: '%s'", line
);
1400 handle_input_flag (p
, &it
->flags
[j
], filename
, lineno
);
1409 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1410 "unknown function in line: '%s'", line
);
1413 /* Read in the test input data from FILENAME. */
1416 read_input (const char *filename
)
1418 FILE *fp
= fopen (filename
, "r");
1420 error (EXIT_FAILURE
, errno
, "open '%s'", filename
);
1421 unsigned int lineno
= 0;
1426 ssize_t ret
= getline (&line
, &size
, fp
);
1430 if (line
[0] == '#' || line
[0] == '\n')
1432 add_test (line
, filename
, lineno
);
1435 error (EXIT_FAILURE
, errno
, "read from '%s'", filename
);
1436 if (fclose (fp
) != 0)
1437 error (EXIT_FAILURE
, errno
, "close '%s'", filename
);
1440 /* Calculate the generic results (round-to-zero with sticky bit) for
1441 the function described by CALC, with inputs INPUTS, if MODE is
1442 rm_towardzero; for other modes, calculate results in that mode,
1443 which must be exact zero results. */
1446 calc_generic_results (generic_value
*outputs
, generic_value
*inputs
,
1447 const func_calc_desc
*calc
, rounding_mode mode
)
1452 mpfr_rnd_t mode_mpfr
= rounding_modes
[mode
].mpfr_mode
;
1453 mpc_rnd_t mode_mpc
= rounding_modes
[mode
].mpc_mode
;
1455 switch (calc
->method
)
1458 assert (inputs
[0].type
== gtype_fp
);
1459 outputs
[0].type
= gtype_fp
;
1460 mpfr_init (outputs
[0].value
.f
);
1461 inexact
= calc
->func
.mpfr_f_f (outputs
[0].value
.f
, inputs
[0].value
.f
,
1463 if (mode
!= rm_towardzero
)
1464 assert (!inexact
&& mpfr_zero_p (outputs
[0].value
.f
));
1465 adjust_real (outputs
[0].value
.f
, inexact
);
1469 assert (inputs
[0].type
== gtype_fp
);
1470 assert (inputs
[1].type
== gtype_fp
);
1471 outputs
[0].type
= gtype_fp
;
1472 mpfr_init (outputs
[0].value
.f
);
1473 inexact
= calc
->func
.mpfr_ff_f (outputs
[0].value
.f
, inputs
[0].value
.f
,
1474 inputs
[1].value
.f
, mode_mpfr
);
1475 if (mode
!= rm_towardzero
)
1476 assert (!inexact
&& mpfr_zero_p (outputs
[0].value
.f
));
1477 adjust_real (outputs
[0].value
.f
, inexact
);
1481 assert (inputs
[0].type
== gtype_fp
);
1482 assert (inputs
[1].type
== gtype_fp
);
1483 assert (inputs
[2].type
== gtype_fp
);
1484 outputs
[0].type
= gtype_fp
;
1485 mpfr_init (outputs
[0].value
.f
);
1486 inexact
= calc
->func
.mpfr_fff_f (outputs
[0].value
.f
, inputs
[0].value
.f
,
1487 inputs
[1].value
.f
, inputs
[2].value
.f
,
1489 if (mode
!= rm_towardzero
)
1490 assert (!inexact
&& mpfr_zero_p (outputs
[0].value
.f
));
1491 adjust_real (outputs
[0].value
.f
, inexact
);
1495 assert (inputs
[0].type
== gtype_fp
);
1496 outputs
[0].type
= gtype_fp
;
1497 outputs
[1].type
= gtype_int
;
1498 mpfr_init (outputs
[0].value
.f
);
1500 inexact
= calc
->func
.mpfr_f_f1 (outputs
[0].value
.f
, &i
,
1501 inputs
[0].value
.f
, mode_mpfr
);
1502 if (mode
!= rm_towardzero
)
1503 assert (!inexact
&& mpfr_zero_p (outputs
[0].value
.f
));
1504 adjust_real (outputs
[0].value
.f
, inexact
);
1505 mpz_init_set_si (outputs
[1].value
.i
, i
);
1509 assert (inputs
[0].type
== gtype_int
);
1510 assert (inputs
[1].type
== gtype_fp
);
1511 outputs
[0].type
= gtype_fp
;
1512 mpfr_init (outputs
[0].value
.f
);
1513 assert (mpz_fits_slong_p (inputs
[0].value
.i
));
1514 long l
= mpz_get_si (inputs
[0].value
.i
);
1515 inexact
= calc
->func
.mpfr_if_f (outputs
[0].value
.f
, l
,
1516 inputs
[1].value
.f
, mode_mpfr
);
1517 if (mode
!= rm_towardzero
)
1518 assert (!inexact
&& mpfr_zero_p (outputs
[0].value
.f
));
1519 adjust_real (outputs
[0].value
.f
, inexact
);
1523 assert (inputs
[0].type
== gtype_fp
);
1524 outputs
[0].type
= gtype_fp
;
1525 mpfr_init (outputs
[0].value
.f
);
1526 outputs
[1].type
= gtype_fp
;
1527 mpfr_init (outputs
[1].value
.f
);
1528 int comb_ternary
= calc
->func
.mpfr_f_11 (outputs
[0].value
.f
,
1532 if (mode
!= rm_towardzero
)
1533 assert (((comb_ternary
& 0x3) == 0
1534 && mpfr_zero_p (outputs
[0].value
.f
))
1535 || ((comb_ternary
& 0xc) == 0
1536 && mpfr_zero_p (outputs
[1].value
.f
)));
1537 adjust_real (outputs
[0].value
.f
, (comb_ternary
& 0x3) != 0);
1538 adjust_real (outputs
[1].value
.f
, (comb_ternary
& 0xc) != 0);
1542 assert (inputs
[0].type
== gtype_fp
);
1543 assert (inputs
[1].type
== gtype_fp
);
1544 outputs
[0].type
= gtype_fp
;
1545 mpfr_init (outputs
[0].value
.f
);
1546 mpc_init2 (ci1
, internal_precision
);
1547 assert_exact (mpc_set_fr_fr (ci1
, inputs
[0].value
.f
, inputs
[1].value
.f
,
1549 inexact
= calc
->func
.mpc_c_f (outputs
[0].value
.f
, ci1
, mode_mpfr
);
1550 if (mode
!= rm_towardzero
)
1551 assert (!inexact
&& mpfr_zero_p (outputs
[0].value
.f
));
1552 adjust_real (outputs
[0].value
.f
, inexact
);
1557 assert (inputs
[0].type
== gtype_fp
);
1558 assert (inputs
[1].type
== gtype_fp
);
1559 outputs
[0].type
= gtype_fp
;
1560 mpfr_init (outputs
[0].value
.f
);
1561 outputs
[1].type
= gtype_fp
;
1562 mpfr_init (outputs
[1].value
.f
);
1563 mpc_init2 (ci1
, internal_precision
);
1564 mpc_init2 (co
, internal_precision
);
1565 assert_exact (mpc_set_fr_fr (ci1
, inputs
[0].value
.f
, inputs
[1].value
.f
,
1567 mpc_ternary
= calc
->func
.mpc_c_c (co
, ci1
, mode_mpc
);
1568 if (mode
!= rm_towardzero
)
1569 assert ((!MPC_INEX_RE (mpc_ternary
)
1570 && mpfr_zero_p (mpc_realref (co
)))
1571 || (!MPC_INEX_IM (mpc_ternary
)
1572 && mpfr_zero_p (mpc_imagref (co
))));
1573 assert_exact (mpfr_set (outputs
[0].value
.f
, mpc_realref (co
),
1575 assert_exact (mpfr_set (outputs
[1].value
.f
, mpc_imagref (co
),
1577 adjust_real (outputs
[0].value
.f
, MPC_INEX_RE (mpc_ternary
));
1578 adjust_real (outputs
[1].value
.f
, MPC_INEX_IM (mpc_ternary
));
1584 assert (inputs
[0].type
== gtype_fp
);
1585 assert (inputs
[1].type
== gtype_fp
);
1586 assert (inputs
[2].type
== gtype_fp
);
1587 assert (inputs
[3].type
== gtype_fp
);
1588 outputs
[0].type
= gtype_fp
;
1589 mpfr_init (outputs
[0].value
.f
);
1590 outputs
[1].type
= gtype_fp
;
1591 mpfr_init (outputs
[1].value
.f
);
1592 mpc_init2 (ci1
, internal_precision
);
1593 mpc_init2 (ci2
, internal_precision
);
1594 mpc_init2 (co
, internal_precision
);
1595 assert_exact (mpc_set_fr_fr (ci1
, inputs
[0].value
.f
, inputs
[1].value
.f
,
1597 assert_exact (mpc_set_fr_fr (ci2
, inputs
[2].value
.f
, inputs
[3].value
.f
,
1599 mpc_ternary
= calc
->func
.mpc_cc_c (co
, ci1
, ci2
, mode_mpc
);
1600 if (mode
!= rm_towardzero
)
1601 assert ((!MPC_INEX_RE (mpc_ternary
)
1602 && mpfr_zero_p (mpc_realref (co
)))
1603 || (!MPC_INEX_IM (mpc_ternary
)
1604 && mpfr_zero_p (mpc_imagref (co
))));
1605 assert_exact (mpfr_set (outputs
[0].value
.f
, mpc_realref (co
),
1607 assert_exact (mpfr_set (outputs
[1].value
.f
, mpc_imagref (co
),
1609 adjust_real (outputs
[0].value
.f
, MPC_INEX_RE (mpc_ternary
));
1610 adjust_real (outputs
[1].value
.f
, MPC_INEX_IM (mpc_ternary
));
1621 /* Return the number of bits for integer type TYPE, where "long" has
1622 LONG_BITS bits (32 or 64). */
1625 int_type_bits (arg_ret_type type
, int long_bits
)
1627 assert (long_bits
== 32 || long_bits
== 64);
1638 case type_long_long
:
1647 /* Check whether an integer Z fits a given type TYPE, where "long" has
1648 LONG_BITS bits (32 or 64). */
1651 int_fits_type (mpz_t z
, arg_ret_type type
, int long_bits
)
1653 int bits
= int_type_bits (type
, long_bits
);
1657 mpz_ui_pow_ui (t
, 2, bits
- 1);
1658 if (mpz_cmp (z
, t
) >= 0)
1661 if (mpz_cmp (z
, t
) < 0)
1667 /* Print a generic value V to FP (name FILENAME), preceded by a space,
1668 for type TYPE, LONG_BITS bits per long, printing " IGNORE" instead
1672 output_generic_value (FILE *fp
, const char *filename
, const generic_value
*v
,
1673 bool ignore
, arg_ret_type type
, int long_bits
)
1677 if (fputs (" IGNORE", fp
) < 0)
1678 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1681 assert (v
->type
== generic_arg_ret_type (type
));
1697 case type_long_long
:
1707 if (mpfr_inf_p (v
->value
.f
))
1709 if (fputs ((mpfr_signbit (v
->value
.f
)
1710 ? " minus_infty" : " plus_infty"), fp
) < 0)
1711 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1715 assert (mpfr_number_p (v
->value
.f
));
1716 if (mpfr_fprintf (fp
, " %Ra%s", v
->value
.f
, suffix
) < 0)
1717 error (EXIT_FAILURE
, errno
, "mpfr_fprintf to '%s'", filename
);
1722 int bits
= int_type_bits (type
, long_bits
);
1725 mpz_ui_pow_ui (tmp
, 2, bits
- 1);
1727 if (mpz_cmp (v
->value
.i
, tmp
) == 0)
1729 mpz_add_ui (tmp
, tmp
, 1);
1730 if (mpfr_fprintf (fp
, " (%Zd%s-1)", tmp
, suffix
) < 0)
1731 error (EXIT_FAILURE
, errno
, "mpfr_fprintf to '%s'", filename
);
1735 if (mpfr_fprintf (fp
, " %Zd%s", v
->value
.i
, suffix
) < 0)
1736 error (EXIT_FAILURE
, errno
, "mpfr_fprintf to '%s'", filename
);
1746 /* Generate test output to FP (name FILENAME) for test function TF
1747 (rounding results to a narrower type if NARROW), input test IT,
1748 choice of input values INPUTS. */
1751 output_for_one_input_case (FILE *fp
, const char *filename
, test_function
*tf
,
1752 bool narrow
, input_test
*it
, generic_value
*inputs
)
1754 bool long_bits_matters
= false;
1755 bool fits_long32
= true;
1756 for (size_t i
= 0; i
< tf
->num_args
; i
++)
1758 generic_value_type gtype
= generic_arg_ret_type (tf
->arg_types
[i
]);
1759 assert (inputs
[i
].type
== gtype
);
1760 if (gtype
== gtype_int
)
1762 bool fits_64
= int_fits_type (inputs
[i
].value
.i
, tf
->arg_types
[i
],
1766 if (tf
->arg_types
[i
] == type_long
1767 && !int_fits_type (inputs
[i
].value
.i
, tf
->arg_types
[i
], 32))
1769 long_bits_matters
= true;
1770 fits_long32
= false;
1774 generic_value generic_outputs
[MAX_NRET
];
1775 calc_generic_results (generic_outputs
, inputs
, &tf
->calc
, rm_towardzero
);
1776 bool ignore_output_long32
[MAX_NRET
] = { false };
1777 bool ignore_output_long64
[MAX_NRET
] = { false };
1778 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
1780 assert (generic_outputs
[i
].type
1781 == generic_arg_ret_type (tf
->ret_types
[i
]));
1782 switch (generic_outputs
[i
].type
)
1785 if (!mpfr_number_p (generic_outputs
[i
].value
.f
))
1786 goto out
; /* Result is NaN or exact infinity. */
1790 ignore_output_long32
[i
] = !int_fits_type (generic_outputs
[i
].value
.i
,
1791 tf
->ret_types
[i
], 32);
1792 ignore_output_long64
[i
] = !int_fits_type (generic_outputs
[i
].value
.i
,
1793 tf
->ret_types
[i
], 64);
1794 if (ignore_output_long32
[i
] != ignore_output_long64
[i
])
1795 long_bits_matters
= true;
1802 /* Iterate over relevant sizes of long and floating-point formats. */
1803 for (int long_bits
= 32; long_bits
<= 64; long_bits
+= 32)
1805 if (long_bits
== 32 && !fits_long32
)
1807 if (long_bits
== 64 && !long_bits_matters
)
1809 const char *long_cond
;
1810 if (long_bits_matters
)
1811 long_cond
= (long_bits
== 32 ? ":long32" : ":long64");
1814 bool *ignore_output
= (long_bits
== 32
1815 ? ignore_output_long32
1816 : ignore_output_long64
);
1817 for (fp_format f
= fp_first_format
; f
< fp_num_formats
; f
++)
1820 mpfr_t res
[rm_num_modes
];
1821 unsigned int exc_before
[rm_num_modes
];
1822 unsigned int exc_after
[rm_num_modes
];
1823 bool have_fp_arg
= false;
1828 for (size_t i
= 0; i
< tf
->num_args
; i
++)
1830 if (inputs
[i
].type
== gtype_fp
)
1834 if (mpfr_zero_p (inputs
[i
].value
.f
))
1836 assert (mpfr_regular_p (inputs
[i
].value
.f
));
1837 int this_exp
, this_num_ones
, this_min_exp
, this_prec
;
1840 mpfr_exp_t e
= mpfr_get_z_2exp (tmp
, inputs
[i
].value
.f
);
1841 if (mpz_sgn (tmp
) < 0)
1843 size_t bits
= mpz_sizeinbase (tmp
, 2);
1844 mp_bitcnt_t tz
= mpz_scan1 (tmp
, 0);
1845 this_min_exp
= e
+ tz
;
1846 this_prec
= bits
- tz
;
1847 assert (this_prec
> 0);
1848 this_exp
= this_min_exp
+ this_prec
- 1;
1850 == mpfr_get_exp (inputs
[i
].value
.f
) - 1);
1852 while ((size_t) this_num_ones
< bits
1853 && mpz_tstbit (tmp
, bits
- 1 - this_num_ones
))
1858 if (this_exp
> max_exp
1859 || (this_exp
== max_exp
1860 && this_num_ones
> num_ones
))
1863 num_ones
= this_num_ones
;
1865 if (this_min_exp
< min_exp
)
1866 min_exp
= this_min_exp
;
1867 if (this_prec
> max_prec
)
1868 max_prec
= this_prec
;
1873 num_ones
= this_num_ones
;
1874 min_exp
= this_min_exp
;
1875 max_prec
= this_prec
;
1881 round_real (res
, exc_before
, exc_after
,
1882 inputs
[i
].value
.f
, f
);
1883 if (!mpfr_equal_p (res
[rm_tonearest
], inputs
[i
].value
.f
))
1885 for (rounding_mode m
= rm_first_mode
;
1888 mpfr_clear (res
[m
]);
1896 /* The inputs fit this type if required to do so, so compute
1897 the ideal outputs and exceptions. */
1898 mpfr_t all_res
[MAX_NRET
][rm_num_modes
];
1899 unsigned int all_exc_before
[MAX_NRET
][rm_num_modes
];
1900 unsigned int all_exc_after
[MAX_NRET
][rm_num_modes
];
1901 unsigned int merged_exc_before
[rm_num_modes
] = { 0 };
1902 unsigned int merged_exc_after
[rm_num_modes
] = { 0 };
1903 /* For functions not exactly determined, track whether
1904 underflow is required (some result is inexact, and
1905 magnitude does not exceed the greatest magnitude
1906 subnormal), and permitted (not an exact zero, and
1907 magnitude does not exceed the least magnitude
1909 bool must_underflow
= false;
1910 bool may_underflow
= false;
1911 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
1913 switch (generic_outputs
[i
].type
)
1916 round_real (all_res
[i
], all_exc_before
[i
], all_exc_after
[i
],
1917 generic_outputs
[i
].value
.f
, f
);
1918 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1920 merged_exc_before
[m
] |= all_exc_before
[i
][m
];
1921 merged_exc_after
[m
] |= all_exc_after
[i
][m
];
1925 |= ((all_exc_before
[i
][m
]
1926 & (1U << exc_inexact
)) != 0
1927 && (mpfr_cmpabs (generic_outputs
[i
].value
.f
,
1928 fp_formats
[f
].subnorm_max
)
1931 |= (!mpfr_zero_p (generic_outputs
[i
].value
.f
)
1932 && (mpfr_cmpabs (generic_outputs
[i
].value
.f
,
1933 fp_formats
[f
].min_plus_half
)
1936 /* If the result is an exact zero, the sign may
1937 depend on the rounding mode, so recompute it
1938 directly in that mode. */
1939 if (mpfr_zero_p (all_res
[i
][m
])
1940 && (all_exc_before
[i
][m
] & (1U << exc_inexact
)) == 0)
1942 generic_value outputs_rm
[MAX_NRET
];
1943 calc_generic_results (outputs_rm
, inputs
,
1945 assert_exact (mpfr_set (all_res
[i
][m
],
1946 outputs_rm
[i
].value
.f
,
1948 for (size_t j
= 0; j
< tf
->num_ret
; j
++)
1949 generic_value_free (&outputs_rm
[j
]);
1955 if (ignore_output
[i
])
1956 for (rounding_mode m
= rm_first_mode
;
1960 merged_exc_before
[m
] |= 1U << exc_invalid
;
1961 merged_exc_after
[m
] |= 1U << exc_invalid
;
1969 assert (may_underflow
|| !must_underflow
);
1970 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1972 bool before_after_matters
1973 = tf
->exact
&& merged_exc_before
[m
] != merged_exc_after
[m
];
1974 if (before_after_matters
)
1976 assert ((merged_exc_before
[m
] ^ merged_exc_after
[m
])
1977 == (1U << exc_underflow
));
1978 assert ((merged_exc_before
[m
] & (1U << exc_underflow
)) != 0);
1980 unsigned int merged_exc
= merged_exc_before
[m
];
1983 if (fprintf (fp
, "= %s %s %s%s:arg_fmt(%d,%d,%d,%d)",
1984 tf
->name
, rounding_modes
[m
].name
,
1985 fp_formats
[f
].name
, long_cond
, max_exp
,
1986 num_ones
, min_exp
, max_prec
) < 0)
1987 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1991 if (fprintf (fp
, "= %s %s %s%s", tf
->name
,
1992 rounding_modes
[m
].name
, fp_formats
[f
].name
,
1994 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1997 for (size_t i
= 0; i
< tf
->num_args
; i
++)
1998 output_generic_value (fp
, filename
, &inputs
[i
], false,
1999 tf
->arg_types
[i
], long_bits
);
2000 if (fputs (" :", fp
) < 0)
2001 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
2002 /* Print outputs. */
2003 bool must_erange
= false;
2004 bool some_underflow_zero
= false;
2005 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
2008 g
.type
= generic_outputs
[i
].type
;
2012 if (mpfr_inf_p (all_res
[i
][m
])
2013 && (all_exc_before
[i
][m
]
2014 & (1U << exc_overflow
)) != 0)
2016 if (mpfr_zero_p (all_res
[i
][m
])
2018 || mpfr_zero_p (all_res
[i
][rm_tonearest
]))
2019 && (all_exc_before
[i
][m
]
2020 & (1U << exc_underflow
)) != 0)
2022 if (mpfr_zero_p (all_res
[i
][rm_towardzero
])
2023 && (all_exc_before
[i
][m
]
2024 & (1U << exc_underflow
)) != 0)
2025 some_underflow_zero
= true;
2026 mpfr_init2 (g
.value
.f
, fp_formats
[f
].mant_dig
);
2027 assert_exact (mpfr_set (g
.value
.f
, all_res
[i
][m
],
2032 mpz_init (g
.value
.i
);
2033 mpz_set (g
.value
.i
, generic_outputs
[i
].value
.i
);
2039 output_generic_value (fp
, filename
, &g
, ignore_output
[i
],
2040 tf
->ret_types
[i
], long_bits
);
2041 generic_value_free (&g
);
2043 if (fputs (" :", fp
) < 0)
2044 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
2045 /* Print miscellaneous flags (passed through from
2047 for (size_t i
= 0; i
< it
->num_flags
; i
++)
2048 switch (it
->flags
[i
].type
)
2050 case flag_ignore_zero_inf_sign
:
2052 if (fprintf (fp
, " %s%s",
2053 input_flags
[it
->flags
[i
].type
],
2057 error (EXIT_FAILURE
, errno
, "write to '%s'",
2060 case flag_xfail_rounding
:
2061 if (m
!= rm_tonearest
)
2062 if (fprintf (fp
, " xfail%s",
2066 error (EXIT_FAILURE
, errno
, "write to '%s'",
2072 /* For the ibm128 format, expect incorrect overflowing
2073 results in rounding modes other than to nearest;
2074 likewise incorrect results where the result may
2076 if (f
== fp_ldbl_128ibm
2077 && m
!= rm_tonearest
2078 && (some_underflow_zero
2079 || (merged_exc_before
[m
] & (1U << exc_overflow
)) != 0))
2080 if (fputs (" xfail:ibm128-libgcc", fp
) < 0)
2081 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
2082 /* Print exception flags and compute errno
2083 expectations where not already computed. */
2084 bool may_edom
= false;
2085 bool must_edom
= false;
2086 bool may_erange
= must_erange
|| may_underflow
;
2087 for (fp_exception e
= exc_first_exception
;
2088 e
< exc_num_exceptions
;
2091 bool expect_e
= (merged_exc
& (1U << e
)) != 0;
2092 bool e_optional
= false;
2097 may_erange
= must_erange
= true;
2107 may_edom
= must_edom
= true;
2120 if (may_underflow
&& !must_underflow
)
2129 assert (!before_after_matters
);
2130 if (fprintf (fp
, " %s-ok", exceptions
[e
]) < 0)
2131 error (EXIT_FAILURE
, errno
, "write to '%s'",
2137 if (fprintf (fp
, " %s", exceptions
[e
]) < 0)
2138 error (EXIT_FAILURE
, errno
, "write to '%s'",
2140 if (before_after_matters
&& e
== exc_underflow
)
2141 if (fputs (":before-rounding", fp
) < 0)
2142 error (EXIT_FAILURE
, errno
, "write to '%s'",
2144 for (int after
= 0; after
<= 1; after
++)
2146 bool expect_e_here
= expect_e
;
2147 if (after
== 1 && (!before_after_matters
2148 || e
!= exc_underflow
))
2150 const char *after_cond
;
2151 if (before_after_matters
&& e
== exc_underflow
)
2155 : ":before-rounding");
2156 expect_e_here
= !after
;
2160 input_flag_type okflag
;
2161 okflag
= (expect_e_here
2162 ? flag_missing_first
2163 : flag_spurious_first
) + e
;
2164 for (size_t i
= 0; i
< it
->num_flags
; i
++)
2165 if (it
->flags
[i
].type
== okflag
)
2166 if (fprintf (fp
, " %s-ok%s%s",
2170 : ""), after_cond
) < 0)
2171 error (EXIT_FAILURE
, errno
, "write to '%s'",
2176 /* Print errno expectations. */
2180 must_erange
= false;
2182 if (may_edom
&& !must_edom
)
2184 if (fputs (" errno-edom-ok", fp
) < 0)
2185 error (EXIT_FAILURE
, errno
, "write to '%s'",
2191 if (fputs (" errno-edom", fp
) < 0)
2192 error (EXIT_FAILURE
, errno
, "write to '%s'",
2194 input_flag_type okflag
= (must_edom
2195 ? flag_missing_errno
2196 : flag_spurious_errno
);
2197 for (size_t i
= 0; i
< it
->num_flags
; i
++)
2198 if (it
->flags
[i
].type
== okflag
)
2199 if (fprintf (fp
, " errno-edom-ok%s",
2203 error (EXIT_FAILURE
, errno
, "write to '%s'",
2206 if (before_after_matters
)
2207 assert (may_erange
&& !must_erange
);
2208 if (may_erange
&& !must_erange
)
2210 if (fprintf (fp
, " errno-erange-ok%s",
2211 (before_after_matters
2212 ? ":before-rounding"
2214 error (EXIT_FAILURE
, errno
, "write to '%s'",
2217 if (before_after_matters
|| !(may_erange
&& !must_erange
))
2220 if (fputs (" errno-erange", fp
) < 0)
2221 error (EXIT_FAILURE
, errno
, "write to '%s'",
2223 input_flag_type okflag
= (must_erange
2224 ? flag_missing_errno
2225 : flag_spurious_errno
);
2226 for (size_t i
= 0; i
< it
->num_flags
; i
++)
2227 if (it
->flags
[i
].type
== okflag
)
2228 if (fprintf (fp
, " errno-erange-ok%s%s",
2232 (before_after_matters
2235 error (EXIT_FAILURE
, errno
, "write to '%s'",
2238 if (putc ('\n', fp
) < 0)
2239 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
2241 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
2243 if (generic_outputs
[i
].type
== gtype_fp
)
2244 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
2245 mpfr_clear (all_res
[i
][m
]);
2250 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
2251 generic_value_free (&generic_outputs
[i
]);
2254 /* Generate test output data for FUNCTION to FILENAME. The function
2255 is interpreted as rounding its results to a narrower type if
2259 generate_output (const char *function
, bool narrow
, const char *filename
)
2261 FILE *fp
= fopen (filename
, "w");
2263 error (EXIT_FAILURE
, errno
, "open '%s'", filename
);
2264 for (size_t i
= 0; i
< ARRAY_SIZE (test_functions
); i
++)
2266 test_function
*tf
= &test_functions
[i
];
2267 if (strcmp (tf
->name
, function
) != 0)
2269 for (size_t j
= 0; j
< tf
->num_tests
; j
++)
2271 input_test
*it
= &tf
->tests
[j
];
2272 if (fputs (it
->line
, fp
) < 0)
2273 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
2274 for (size_t k
= 0; k
< it
->num_input_cases
; k
++)
2275 output_for_one_input_case (fp
, filename
, tf
, narrow
,
2279 if (fclose (fp
) != 0)
2280 error (EXIT_FAILURE
, errno
, "close '%s'", filename
);
2284 main (int argc
, char **argv
)
2287 && !(argc
== 5 && strcmp (argv
[1], "--narrow") == 0))
2288 error (EXIT_FAILURE
, 0,
2289 "usage: gen-auto-libm-tests [--narrow] <input> <func> <output>");
2291 const char *input_filename
= argv
[1];
2292 const char *function
= argv
[2];
2293 const char *output_filename
= argv
[3];
2297 input_filename
= argv
[1];
2299 output_filename
= argv
[3];
2304 input_filename
= argv
[2];
2306 output_filename
= argv
[4];
2309 read_input (input_filename
);
2310 generate_output (function
, narrow
, output_filename
);
2311 exit (EXIT_SUCCESS
);