1 /* Generate expected output for libm tests with MPFR and MPC.
2 Copyright (C) 2013-2018 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=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 "no-test-inline" indicates a test is disabled for inline
96 function testing; "ignore-zero-inf-sign" indicates the the signs of
97 zero and infinite results should be ignored; "xfail" indicates the
98 test is disabled as expected to produce incorrect results,
99 "xfail-rounding" indicates the test is disabled only in rounding
100 modes other than round-to-nearest. Otherwise, test flags are of
101 the form "spurious-<exception>" and "missing-<exception>", for any
102 exception ("overflow", "underflow", "inexact", "invalid",
103 "divbyzero"), "spurious-errno" and "missing-errno", to indicate
104 when tests are expected to deviate from the exception and errno
105 settings corresponding to the mathematical results. "xfail",
106 "xfail-rounding", "spurious-" and "missing-" flags should be
107 accompanied by a comment referring to an open bug in glibc
110 The output file auto-libm-test-out-<func> contains the test lines from
111 auto-libm-test-in, and, after the line for a given test, some
112 number of output test lines. An output test line is of the form "=
113 function rounding-mode format input1 input2 ... : output1 output2
114 ... : flags". rounding-mode is "tonearest", "towardzero", "upward"
115 or "downward". format is a name from the floating_point_formats
116 array, possibly followed by a sequence of ":flag" for flags from
117 "long32" and "long64". Inputs and outputs are specified as hex
118 floats with the required suffix for the floating-point type, or
119 plus_infty or minus_infty for infinite expected results, or as
120 integer constant expressions (not necessarily with the right type)
121 or IGNORE for integer inputs and outputs. Flags are
122 "no-test-inline", "ignore-zero-info-sign", "xfail", "<exception>",
123 "<exception>-ok", "errno-<value>", "errno-<value>-ok", which may be
124 unconditional or conditional. "<exception>" indicates that a
125 correct result means the given exception should be raised.
126 "errno-<value>" indicates that a correct result means errno should
127 be set to the given value. "-ok" means not to test for the given
128 exception or errno value (whether because it was marked as possibly
129 missing or spurious, or because the calculation of correct results
130 indicated it was optional). Conditions "before-rounding" and
131 "after-rounding" indicate tests where expectations for underflow
132 exceptions depend on how the architecture detects tininess.
134 For functions rounding their results to a narrower type, the format
135 given on an output test line is the result format followed by
136 information about the requirements on the argument format to be
137 able to represent the argument values, in the form
138 "format:arg_fmt(MAX_EXP,NUM_ONES,MIN_EXP,MAX_PREC)". Instead of
139 separate lines for separate argument formats, an output test line
140 relates to all argument formats that can represent the values.
141 MAX_EXP is the maximum exponent of a nonzero bit in any argument,
142 or 0 if all arguments are zero; NUM_ONES is the maximum number of
143 leading bits with value 1 in an argument with exponent MAX_EXP, or
144 0 if all arguments are zero; MIN_EXP is the minimum exponent of a
145 nonzero bit in any argument, or 0 if all arguments are zero;
146 MAX_PREC is the maximum precision required to represent all
147 arguments, or 0 if all arguments are zero. */
165 #define ARRAY_SIZE(A) (sizeof (A) / sizeof ((A)[0]))
167 /* The supported floating-point formats. */
180 /* Structure describing a single floating-point format. */
183 /* The name of the format. */
185 /* A string for the largest normal value, or NULL for IEEE formats
186 where this can be determined automatically. */
187 const char *max_string
;
188 /* The number of mantissa bits. */
190 /* The least N such that 2^N overflows. */
192 /* One more than the least N such that 2^N is normal. */
194 /* The largest normal value. */
196 /* The value 0.5ulp above the least positive normal value. */
197 mpfr_t min_plus_half
;
198 /* The least positive normal value, 2^(MIN_EXP-1). */
200 /* The greatest positive subnormal value. */
202 /* The least positive subnormal value, 2^(MIN_EXP-MANT_DIG). */
206 /* List of floating-point formats, in the same order as the fp_format
208 static fp_format_desc fp_formats
[fp_num_formats
] =
210 { "binary32", NULL
, 24, 128, -125, {}, {}, {}, {}, {} },
211 { "binary64", NULL
, 53, 1024, -1021, {}, {}, {}, {}, {} },
212 { "intel96", NULL
, 64, 16384, -16381, {}, {}, {}, {}, {} },
213 { "m68k96", NULL
, 64, 16384, -16382, {}, {}, {}, {}, {} },
214 { "binary128", NULL
, 113, 16384, -16381, {}, {}, {}, {}, {} },
215 { "ibm128", "0x1.fffffffffffff7ffffffffffff8p+1023",
216 106, 1024, -968, {}, {}, {}, {}, {} },
219 /* The supported rounding modes. */
230 /* Structure describing a single rounding mode. */
233 /* The name of the rounding mode. */
235 /* The MPFR rounding mode. */
236 mpfr_rnd_t mpfr_mode
;
237 /* The MPC rounding mode. */
239 } rounding_mode_desc
;
241 /* List of rounding modes, in the same order as the rounding_mode
243 static const rounding_mode_desc rounding_modes
[rm_num_modes
] =
245 { "downward", MPFR_RNDD
, MPC_RNDDD
},
246 { "tonearest", MPFR_RNDN
, MPC_RNDNN
},
247 { "towardzero", MPFR_RNDZ
, MPC_RNDZZ
},
248 { "upward", MPFR_RNDU
, MPC_RNDUU
},
251 /* The supported exceptions. */
260 exc_first_exception
= 0
263 /* List of exceptions, in the same order as the fp_exception
265 static const char *const exceptions
[exc_num_exceptions
] =
274 /* The internal precision to use for most MPFR calculations, which
275 must be at least 2 more than the greatest precision of any
276 supported floating-point format. */
277 static int internal_precision
;
279 /* A value that overflows all supported floating-point formats. */
280 static mpfr_t global_max
;
282 /* A value that is at most half the least subnormal in any
283 floating-point format and so is rounded the same way as all
284 sufficiently small positive values. */
285 static mpfr_t global_min
;
287 /* The maximum number of (real or integer) arguments to a function
288 handled by this program (complex arguments count as two real
292 /* The maximum number of (real or integer) return values from a
293 function handled by this program. */
296 /* A type of a function argument or return value. */
299 /* No type (not a valid argument or return value). */
301 /* A floating-point value with the type corresponding to that of
304 /* An integer value of type int. */
306 /* An integer value of type long. */
308 /* An integer value of type long long. */
312 /* A type of a generic real or integer value. */
317 /* Floating-point (represented with MPFR). */
319 /* Integer (represented with GMP). */
321 } generic_value_type
;
323 /* A generic value (argument or result). */
326 /* The type of this value. */
327 generic_value_type type
;
336 /* A type of input flag. */
340 flag_ignore_zero_inf_sign
,
343 /* The "spurious" and "missing" flags must be in the same order as
344 the fp_exception enumeration. */
345 flag_spurious_divbyzero
,
346 flag_spurious_inexact
,
347 flag_spurious_invalid
,
348 flag_spurious_overflow
,
349 flag_spurious_underflow
,
351 flag_missing_divbyzero
,
352 flag_missing_inexact
,
353 flag_missing_invalid
,
354 flag_missing_overflow
,
355 flag_missing_underflow
,
357 num_input_flag_types
,
359 flag_spurious_first
= flag_spurious_divbyzero
,
360 flag_missing_first
= flag_missing_divbyzero
363 /* List of flags, in the same order as the input_flag_type
365 static const char *const input_flags
[num_input_flag_types
] =
368 "ignore-zero-inf-sign",
371 "spurious-divbyzero",
375 "spurious-underflow",
385 /* An input flag, possibly conditional. */
388 /* The type of this flag. */
389 input_flag_type type
;
390 /* The conditions on this flag, as a string ":cond1:cond2..." or
395 /* Structure describing a single test from the input file (which may
396 expand into many tests in the output). The choice of function,
397 which implies the numbers and types of arguments and results, is
398 implicit rather than stored in this structure (except as part of
402 /* The text of the input line describing the test, including the
405 /* The number of combinations of interpretations of input values for
406 different floating-point formats and rounding modes. */
407 size_t num_input_cases
;
408 /* The corresponding lists of inputs. */
409 generic_value
**inputs
;
410 /* The number of flags for this test. */
412 /* The corresponding list of flags. */
414 /* The old output for this test. */
415 const char *old_output
;
418 /* Ways to calculate a function. */
421 /* MPFR function with a single argument and result. */
423 /* MPFR function with two arguments and one result. */
425 /* MPFR function with three arguments and one result. */
427 /* MPFR function with a single argument and floating-point and
430 /* MPFR function with integer and floating-point arguments and one
433 /* MPFR function with a single argument and two floating-point
436 /* MPC function with a single complex argument and one real
439 /* MPC function with a single complex argument and one complex
442 /* MPC function with two complex arguments and one complex
447 /* Description of how to calculate a function. */
450 /* Which method is used to calculate the function. */
451 func_calc_method method
;
452 /* The specific function called. */
455 int (*mpfr_f_f
) (mpfr_t
, const mpfr_t
, mpfr_rnd_t
);
456 int (*mpfr_ff_f
) (mpfr_t
, const mpfr_t
, const mpfr_t
, mpfr_rnd_t
);
457 int (*mpfr_fff_f
) (mpfr_t
, const mpfr_t
, const mpfr_t
, const mpfr_t
,
459 int (*mpfr_f_f1
) (mpfr_t
, int *, const mpfr_t
, mpfr_rnd_t
);
460 int (*mpfr_if_f
) (mpfr_t
, long, const mpfr_t
, mpfr_rnd_t
);
461 int (*mpfr_f_11
) (mpfr_t
, mpfr_t
, const mpfr_t
, mpfr_rnd_t
);
462 int (*mpc_c_f
) (mpfr_t
, const mpc_t
, mpfr_rnd_t
);
463 int (*mpc_c_c
) (mpc_t
, const mpc_t
, mpc_rnd_t
);
464 int (*mpc_cc_c
) (mpc_t
, const mpc_t
, const mpc_t
, mpc_rnd_t
);
468 /* Structure describing a function handled by this program. */
471 /* The name of the function. */
473 /* The number of arguments. */
475 /* The types of the arguments. */
476 arg_ret_type arg_types
[MAX_NARGS
];
477 /* The number of return values. */
479 /* The types of the return values. */
480 arg_ret_type ret_types
[MAX_NRET
];
481 /* Whether the function has exactly determined results and
484 /* Whether the function is a complex function, so errno setting is
487 /* Whether to treat arguments given as floating-point constants as
488 exact only, rather than rounding them up and down to all
491 /* How to calculate this function. */
493 /* The number of tests allocated for this function. */
494 size_t num_tests_alloc
;
495 /* The number of tests for this function. */
497 /* The tests themselves. */
501 #define ARGS1(T1) 1, { T1 }
502 #define ARGS2(T1, T2) 2, { T1, T2 }
503 #define ARGS3(T1, T2, T3) 3, { T1, T2, T3 }
504 #define ARGS4(T1, T2, T3, T4) 4, { T1, T2, T3, T4 }
505 #define RET1(T1) 1, { T1 }
506 #define RET2(T1, T2) 2, { T1, T2 }
507 #define CALC(TYPE, FN) { TYPE, { .TYPE = FN } }
508 #define FUNC(NAME, ARGS, RET, EXACT, COMPLEX_FN, EXACT_ARGS, CALC) \
510 NAME, ARGS, RET, EXACT, COMPLEX_FN, EXACT_ARGS, CALC, 0, 0, NULL \
513 #define FUNC_mpfr_f_f(NAME, MPFR_FUNC, EXACT) \
514 FUNC (NAME, ARGS1 (type_fp), RET1 (type_fp), EXACT, false, false, \
515 CALC (mpfr_f_f, MPFR_FUNC))
516 #define FUNC_mpfr_ff_f(NAME, MPFR_FUNC, EXACT) \
517 FUNC (NAME, ARGS2 (type_fp, type_fp), RET1 (type_fp), EXACT, false, \
518 false, CALC (mpfr_ff_f, MPFR_FUNC))
519 #define FUNC_mpfr_if_f(NAME, MPFR_FUNC, EXACT) \
520 FUNC (NAME, ARGS2 (type_int, type_fp), RET1 (type_fp), EXACT, false, \
521 false, CALC (mpfr_if_f, MPFR_FUNC))
522 #define FUNC_mpc_c_f(NAME, MPFR_FUNC, EXACT) \
523 FUNC (NAME, ARGS2 (type_fp, type_fp), RET1 (type_fp), EXACT, true, \
524 false, CALC (mpc_c_f, MPFR_FUNC))
525 #define FUNC_mpc_c_c(NAME, MPFR_FUNC, EXACT) \
526 FUNC (NAME, ARGS2 (type_fp, type_fp), RET2 (type_fp, type_fp), EXACT, \
527 true, false, CALC (mpc_c_c, MPFR_FUNC))
529 /* List of functions handled by this program. */
530 static test_function test_functions
[] =
532 FUNC_mpfr_f_f ("acos", mpfr_acos
, false),
533 FUNC_mpfr_f_f ("acosh", mpfr_acosh
, false),
534 FUNC_mpfr_ff_f ("add", mpfr_add
, true),
535 FUNC_mpfr_f_f ("asin", mpfr_asin
, false),
536 FUNC_mpfr_f_f ("asinh", mpfr_asinh
, false),
537 FUNC_mpfr_f_f ("atan", mpfr_atan
, false),
538 FUNC_mpfr_ff_f ("atan2", mpfr_atan2
, false),
539 FUNC_mpfr_f_f ("atanh", mpfr_atanh
, false),
540 FUNC_mpc_c_f ("cabs", mpc_abs
, false),
541 FUNC_mpc_c_c ("cacos", mpc_acos
, false),
542 FUNC_mpc_c_c ("cacosh", mpc_acosh
, false),
543 FUNC_mpc_c_f ("carg", mpc_arg
, false),
544 FUNC_mpc_c_c ("casin", mpc_asin
, false),
545 FUNC_mpc_c_c ("casinh", mpc_asinh
, false),
546 FUNC_mpc_c_c ("catan", mpc_atan
, false),
547 FUNC_mpc_c_c ("catanh", mpc_atanh
, false),
548 FUNC_mpfr_f_f ("cbrt", mpfr_cbrt
, false),
549 FUNC_mpc_c_c ("ccos", mpc_cos
, false),
550 FUNC_mpc_c_c ("ccosh", mpc_cosh
, false),
551 FUNC_mpc_c_c ("cexp", mpc_exp
, false),
552 FUNC_mpc_c_c ("clog", mpc_log
, false),
553 FUNC_mpc_c_c ("clog10", mpc_log10
, false),
554 FUNC_mpfr_f_f ("cos", mpfr_cos
, false),
555 FUNC_mpfr_f_f ("cosh", mpfr_cosh
, false),
556 FUNC ("cpow", ARGS4 (type_fp
, type_fp
, type_fp
, type_fp
),
557 RET2 (type_fp
, type_fp
), false, true, false,
558 CALC (mpc_cc_c
, mpc_pow
)),
559 FUNC_mpc_c_c ("csin", mpc_sin
, false),
560 FUNC_mpc_c_c ("csinh", mpc_sinh
, false),
561 FUNC_mpc_c_c ("csqrt", mpc_sqrt
, false),
562 FUNC_mpc_c_c ("ctan", mpc_tan
, false),
563 FUNC_mpc_c_c ("ctanh", mpc_tanh
, false),
564 FUNC_mpfr_f_f ("erf", mpfr_erf
, false),
565 FUNC_mpfr_f_f ("erfc", mpfr_erfc
, false),
566 FUNC_mpfr_f_f ("exp", mpfr_exp
, false),
567 FUNC_mpfr_f_f ("exp10", mpfr_exp10
, false),
568 FUNC_mpfr_f_f ("exp2", mpfr_exp2
, false),
569 FUNC_mpfr_f_f ("expm1", mpfr_expm1
, false),
570 FUNC ("fma", ARGS3 (type_fp
, type_fp
, type_fp
), RET1 (type_fp
),
571 true, false, true, CALC (mpfr_fff_f
, mpfr_fma
)),
572 FUNC_mpfr_ff_f ("hypot", mpfr_hypot
, false),
573 FUNC_mpfr_f_f ("j0", mpfr_j0
, false),
574 FUNC_mpfr_f_f ("j1", mpfr_j1
, false),
575 FUNC_mpfr_if_f ("jn", mpfr_jn
, false),
576 FUNC ("lgamma", ARGS1 (type_fp
), RET2 (type_fp
, type_int
), false, false,
577 false, CALC (mpfr_f_f1
, mpfr_lgamma
)),
578 FUNC_mpfr_f_f ("log", mpfr_log
, false),
579 FUNC_mpfr_f_f ("log10", mpfr_log10
, false),
580 FUNC_mpfr_f_f ("log1p", mpfr_log1p
, false),
581 FUNC_mpfr_f_f ("log2", mpfr_log2
, false),
582 FUNC_mpfr_ff_f ("mul", mpfr_mul
, true),
583 FUNC_mpfr_ff_f ("pow", mpfr_pow
, false),
584 FUNC_mpfr_f_f ("sin", mpfr_sin
, false),
585 FUNC ("sincos", ARGS1 (type_fp
), RET2 (type_fp
, type_fp
), false, false,
586 false, CALC (mpfr_f_11
, mpfr_sin_cos
)),
587 FUNC_mpfr_f_f ("sinh", mpfr_sinh
, false),
588 FUNC_mpfr_ff_f ("sub", mpfr_sub
, true),
589 FUNC_mpfr_f_f ("sqrt", mpfr_sqrt
, true),
590 FUNC_mpfr_f_f ("tan", mpfr_tan
, false),
591 FUNC_mpfr_f_f ("tanh", mpfr_tanh
, false),
592 FUNC_mpfr_f_f ("tgamma", mpfr_gamma
, false),
593 FUNC_mpfr_f_f ("y0", mpfr_y0
, false),
594 FUNC_mpfr_f_f ("y1", mpfr_y1
, false),
595 FUNC_mpfr_if_f ("yn", mpfr_yn
, false),
598 /* Allocate memory, with error checking. */
603 void *p
= malloc (n
);
605 error (EXIT_FAILURE
, errno
, "xmalloc failed");
610 xrealloc (void *p
, size_t n
)
614 error (EXIT_FAILURE
, errno
, "xrealloc failed");
619 xstrdup (const char *s
)
621 char *p
= strdup (s
);
623 error (EXIT_FAILURE
, errno
, "xstrdup failed");
627 /* Assert that the result of an MPFR operation was exact; that is,
628 that the returned ternary value was 0. */
636 /* Return the generic type of an argument or return value type T. */
638 static generic_value_type
639 generic_arg_ret_type (arg_ret_type t
)
656 /* Free a generic_value *V. */
659 generic_value_free (generic_value
*v
)
664 mpfr_clear (v
->value
.f
);
668 mpz_clear (v
->value
.i
);
676 /* Copy a generic_value *SRC to *DEST. */
679 generic_value_copy (generic_value
*dest
, const generic_value
*src
)
681 dest
->type
= src
->type
;
685 mpfr_init (dest
->value
.f
);
686 assert_exact (mpfr_set (dest
->value
.f
, src
->value
.f
, MPFR_RNDN
));
690 mpz_init (dest
->value
.i
);
691 mpz_set (dest
->value
.i
, src
->value
.i
);
699 /* Initialize data for floating-point formats. */
702 init_fp_formats (void)
704 int global_max_exp
= 0, global_min_subnorm_exp
= 0;
705 for (fp_format f
= fp_first_format
; f
< fp_num_formats
; f
++)
707 if (fp_formats
[f
].mant_dig
+ 2 > internal_precision
)
708 internal_precision
= fp_formats
[f
].mant_dig
+ 2;
709 if (fp_formats
[f
].max_exp
> global_max_exp
)
710 global_max_exp
= fp_formats
[f
].max_exp
;
711 int min_subnorm_exp
= fp_formats
[f
].min_exp
- fp_formats
[f
].mant_dig
;
712 if (min_subnorm_exp
< global_min_subnorm_exp
)
713 global_min_subnorm_exp
= min_subnorm_exp
;
714 mpfr_init2 (fp_formats
[f
].max
, fp_formats
[f
].mant_dig
);
715 if (fp_formats
[f
].max_string
!= NULL
)
718 assert_exact (mpfr_strtofr (fp_formats
[f
].max
,
719 fp_formats
[f
].max_string
,
725 assert_exact (mpfr_set_ui_2exp (fp_formats
[f
].max
, 1,
726 fp_formats
[f
].max_exp
,
728 mpfr_nextbelow (fp_formats
[f
].max
);
730 mpfr_init2 (fp_formats
[f
].min
, fp_formats
[f
].mant_dig
);
731 assert_exact (mpfr_set_ui_2exp (fp_formats
[f
].min
, 1,
732 fp_formats
[f
].min_exp
- 1,
734 mpfr_init2 (fp_formats
[f
].min_plus_half
, fp_formats
[f
].mant_dig
+ 1);
735 assert_exact (mpfr_set (fp_formats
[f
].min_plus_half
,
736 fp_formats
[f
].min
, MPFR_RNDN
));
737 mpfr_nextabove (fp_formats
[f
].min_plus_half
);
738 mpfr_init2 (fp_formats
[f
].subnorm_max
, fp_formats
[f
].mant_dig
);
739 assert_exact (mpfr_set (fp_formats
[f
].subnorm_max
, fp_formats
[f
].min
,
741 mpfr_nextbelow (fp_formats
[f
].subnorm_max
);
742 mpfr_nextbelow (fp_formats
[f
].subnorm_max
);
743 mpfr_init2 (fp_formats
[f
].subnorm_min
, fp_formats
[f
].mant_dig
);
744 assert_exact (mpfr_set_ui_2exp (fp_formats
[f
].subnorm_min
, 1,
745 min_subnorm_exp
, MPFR_RNDN
));
747 mpfr_set_default_prec (internal_precision
);
748 mpfr_init (global_max
);
749 assert_exact (mpfr_set_ui_2exp (global_max
, 1, global_max_exp
, MPFR_RNDN
));
750 mpfr_init (global_min
);
751 assert_exact (mpfr_set_ui_2exp (global_min
, 1, global_min_subnorm_exp
- 1,
755 /* Fill in mpfr_t values for special strings in input arguments. */
758 special_fill_max (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
761 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
762 assert_exact (mpfr_set (res0
, fp_formats
[format
].max
, MPFR_RNDN
));
767 special_fill_minus_max (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
770 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
771 assert_exact (mpfr_neg (res0
, fp_formats
[format
].max
, MPFR_RNDN
));
776 special_fill_min (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
779 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
780 assert_exact (mpfr_set (res0
, fp_formats
[format
].min
, MPFR_RNDN
));
785 special_fill_minus_min (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
788 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
789 assert_exact (mpfr_neg (res0
, fp_formats
[format
].min
, MPFR_RNDN
));
794 special_fill_min_subnorm (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
797 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
798 assert_exact (mpfr_set (res0
, fp_formats
[format
].subnorm_min
, MPFR_RNDN
));
803 special_fill_minus_min_subnorm (mpfr_t res0
,
804 mpfr_t res1
__attribute__ ((unused
)),
807 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
808 assert_exact (mpfr_neg (res0
, fp_formats
[format
].subnorm_min
, MPFR_RNDN
));
813 special_fill_min_subnorm_p120 (mpfr_t res0
,
814 mpfr_t res1
__attribute__ ((unused
)),
817 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
818 assert_exact (mpfr_mul_2ui (res0
, fp_formats
[format
].subnorm_min
,
824 special_fill_pi (mpfr_t res0
, mpfr_t res1
, fp_format format
)
826 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
827 mpfr_const_pi (res0
, MPFR_RNDU
);
828 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
829 mpfr_const_pi (res1
, MPFR_RNDD
);
834 special_fill_minus_pi (mpfr_t res0
, mpfr_t res1
, fp_format format
)
836 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
837 mpfr_const_pi (res0
, MPFR_RNDU
);
838 assert_exact (mpfr_neg (res0
, res0
, MPFR_RNDN
));
839 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
840 mpfr_const_pi (res1
, MPFR_RNDD
);
841 assert_exact (mpfr_neg (res1
, res1
, MPFR_RNDN
));
846 special_fill_pi_2 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
848 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
849 mpfr_const_pi (res0
, MPFR_RNDU
);
850 assert_exact (mpfr_div_ui (res0
, res0
, 2, MPFR_RNDN
));
851 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
852 mpfr_const_pi (res1
, MPFR_RNDD
);
853 assert_exact (mpfr_div_ui (res1
, res1
, 2, MPFR_RNDN
));
858 special_fill_minus_pi_2 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
860 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
861 mpfr_const_pi (res0
, MPFR_RNDU
);
862 assert_exact (mpfr_div_ui (res0
, res0
, 2, MPFR_RNDN
));
863 assert_exact (mpfr_neg (res0
, res0
, MPFR_RNDN
));
864 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
865 mpfr_const_pi (res1
, MPFR_RNDD
);
866 assert_exact (mpfr_div_ui (res1
, res1
, 2, MPFR_RNDN
));
867 assert_exact (mpfr_neg (res1
, res1
, MPFR_RNDN
));
872 special_fill_pi_4 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
874 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
875 assert_exact (mpfr_set_si (res0
, 1, MPFR_RNDN
));
876 mpfr_atan (res0
, res0
, MPFR_RNDU
);
877 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
878 assert_exact (mpfr_set_si (res1
, 1, MPFR_RNDN
));
879 mpfr_atan (res1
, res1
, MPFR_RNDD
);
884 special_fill_pi_6 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
886 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
887 assert_exact (mpfr_set_si_2exp (res0
, 1, -1, MPFR_RNDN
));
888 mpfr_asin (res0
, res0
, MPFR_RNDU
);
889 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
890 assert_exact (mpfr_set_si_2exp (res1
, 1, -1, MPFR_RNDN
));
891 mpfr_asin (res1
, res1
, MPFR_RNDD
);
896 special_fill_minus_pi_6 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
898 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
899 assert_exact (mpfr_set_si_2exp (res0
, -1, -1, MPFR_RNDN
));
900 mpfr_asin (res0
, res0
, MPFR_RNDU
);
901 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
902 assert_exact (mpfr_set_si_2exp (res1
, -1, -1, MPFR_RNDN
));
903 mpfr_asin (res1
, res1
, MPFR_RNDD
);
908 special_fill_pi_3 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
910 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
911 assert_exact (mpfr_set_si_2exp (res0
, 1, -1, MPFR_RNDN
));
912 mpfr_acos (res0
, res0
, MPFR_RNDU
);
913 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
914 assert_exact (mpfr_set_si_2exp (res1
, 1, -1, MPFR_RNDN
));
915 mpfr_acos (res1
, res1
, MPFR_RNDD
);
920 special_fill_2pi_3 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
922 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
923 assert_exact (mpfr_set_si_2exp (res0
, -1, -1, MPFR_RNDN
));
924 mpfr_acos (res0
, res0
, MPFR_RNDU
);
925 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
926 assert_exact (mpfr_set_si_2exp (res1
, -1, -1, MPFR_RNDN
));
927 mpfr_acos (res1
, res1
, MPFR_RNDD
);
932 special_fill_2pi (mpfr_t res0
, mpfr_t res1
, fp_format format
)
934 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
935 mpfr_const_pi (res0
, MPFR_RNDU
);
936 assert_exact (mpfr_mul_ui (res0
, res0
, 2, MPFR_RNDN
));
937 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
938 mpfr_const_pi (res1
, MPFR_RNDD
);
939 assert_exact (mpfr_mul_ui (res1
, res1
, 2, MPFR_RNDN
));
944 special_fill_e (mpfr_t res0
, mpfr_t res1
, fp_format format
)
946 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
947 assert_exact (mpfr_set_si (res0
, 1, MPFR_RNDN
));
948 mpfr_exp (res0
, res0
, MPFR_RNDU
);
949 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
950 assert_exact (mpfr_set_si (res1
, 1, MPFR_RNDN
));
951 mpfr_exp (res1
, res1
, MPFR_RNDD
);
956 special_fill_1_e (mpfr_t res0
, mpfr_t res1
, fp_format format
)
958 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
959 assert_exact (mpfr_set_si (res0
, -1, MPFR_RNDN
));
960 mpfr_exp (res0
, res0
, MPFR_RNDU
);
961 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
962 assert_exact (mpfr_set_si (res1
, -1, MPFR_RNDN
));
963 mpfr_exp (res1
, res1
, MPFR_RNDD
);
968 special_fill_e_minus_1 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
970 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
971 assert_exact (mpfr_set_si (res0
, 1, MPFR_RNDN
));
972 mpfr_expm1 (res0
, res0
, MPFR_RNDU
);
973 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
974 assert_exact (mpfr_set_si (res1
, 1, MPFR_RNDN
));
975 mpfr_expm1 (res1
, res1
, MPFR_RNDD
);
979 /* A special string accepted in input arguments. */
984 /* The function that interprets it for a given floating-point
985 format, filling in up to two mpfr_t values and returning the
986 number of values filled. */
987 size_t (*func
) (mpfr_t
, mpfr_t
, fp_format
);
988 } special_real_input
;
990 /* List of special strings accepted in input arguments. */
992 static const special_real_input special_real_inputs
[] =
994 { "max", special_fill_max
},
995 { "-max", special_fill_minus_max
},
996 { "min", special_fill_min
},
997 { "-min", special_fill_minus_min
},
998 { "min_subnorm", special_fill_min_subnorm
},
999 { "-min_subnorm", special_fill_minus_min_subnorm
},
1000 { "min_subnorm_p120", special_fill_min_subnorm_p120
},
1001 { "pi", special_fill_pi
},
1002 { "-pi", special_fill_minus_pi
},
1003 { "pi/2", special_fill_pi_2
},
1004 { "-pi/2", special_fill_minus_pi_2
},
1005 { "pi/4", special_fill_pi_4
},
1006 { "pi/6", special_fill_pi_6
},
1007 { "-pi/6", special_fill_minus_pi_6
},
1008 { "pi/3", special_fill_pi_3
},
1009 { "2pi/3", special_fill_2pi_3
},
1010 { "2pi", special_fill_2pi
},
1011 { "e", special_fill_e
},
1012 { "1/e", special_fill_1_e
},
1013 { "e-1", special_fill_e_minus_1
},
1016 /* Given a real number R computed in round-to-zero mode, set the
1017 lowest bit as a sticky bit if INEXACT, and saturate the exponent
1018 range for very large or small values. */
1021 adjust_real (mpfr_t r
, bool inexact
)
1025 /* NaNs are exact, as are infinities in round-to-zero mode. */
1026 assert (mpfr_number_p (r
));
1027 if (mpfr_cmpabs (r
, global_min
) < 0)
1028 assert_exact (mpfr_copysign (r
, global_min
, r
, MPFR_RNDN
));
1029 else if (mpfr_cmpabs (r
, global_max
) > 0)
1030 assert_exact (mpfr_copysign (r
, global_max
, r
, MPFR_RNDN
));
1035 mpfr_exp_t e
= mpfr_get_z_2exp (tmp
, r
);
1036 if (mpz_sgn (tmp
) < 0)
1039 mpz_setbit (tmp
, 0);
1043 mpz_setbit (tmp
, 0);
1044 assert_exact (mpfr_set_z_2exp (r
, tmp
, e
, MPFR_RNDN
));
1049 /* Given a finite real number R with sticky bit, compute the roundings
1050 to FORMAT in each rounding mode, storing the results in RES, the
1051 before-rounding exceptions in EXC_BEFORE and the after-rounding
1052 exceptions in EXC_AFTER. */
1055 round_real (mpfr_t res
[rm_num_modes
],
1056 unsigned int exc_before
[rm_num_modes
],
1057 unsigned int exc_after
[rm_num_modes
],
1058 mpfr_t r
, fp_format format
)
1060 assert (mpfr_number_p (r
));
1061 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1063 mpfr_init2 (res
[m
], fp_formats
[format
].mant_dig
);
1064 exc_before
[m
] = exc_after
[m
] = 0;
1065 bool inexact
= mpfr_set (res
[m
], r
, rounding_modes
[m
].mpfr_mode
);
1066 if (mpfr_cmpabs (res
[m
], fp_formats
[format
].max
) > 0)
1069 exc_before
[m
] |= 1U << exc_overflow
;
1070 exc_after
[m
] |= 1U << exc_overflow
;
1075 overflow_inf
= true;
1078 overflow_inf
= false;
1081 overflow_inf
= mpfr_signbit (res
[m
]);
1084 overflow_inf
= !mpfr_signbit (res
[m
]);
1090 mpfr_set_inf (res
[m
], mpfr_signbit (res
[m
]) ? -1 : 1);
1092 assert_exact (mpfr_copysign (res
[m
], fp_formats
[format
].max
,
1093 res
[m
], MPFR_RNDN
));
1095 if (mpfr_cmpabs (r
, fp_formats
[format
].min
) < 0)
1097 /* Tiny before rounding; may or may not be tiny after
1098 rounding, and underflow applies only if also inexact
1099 around rounding to a possibly subnormal value. */
1100 bool tiny_after_rounding
1101 = mpfr_cmpabs (res
[m
], fp_formats
[format
].min
) < 0;
1102 /* To round to a possibly subnormal value, and determine
1103 inexactness as a subnormal in the process, scale up and
1104 round to integer, then scale back down. */
1107 assert_exact (mpfr_mul_2si (tmp
, r
, (fp_formats
[format
].mant_dig
1108 - fp_formats
[format
].min_exp
),
1110 int rint_res
= mpfr_rint (tmp
, tmp
, rounding_modes
[m
].mpfr_mode
);
1111 /* The integer must be representable. */
1112 assert (rint_res
== 0 || rint_res
== 2 || rint_res
== -2);
1113 /* If rounding to full precision was inexact, so must
1114 rounding to subnormal precision be inexact. */
1116 assert (rint_res
!= 0);
1118 inexact
= rint_res
!= 0;
1119 assert_exact (mpfr_mul_2si (res
[m
], tmp
,
1120 (fp_formats
[format
].min_exp
1121 - fp_formats
[format
].mant_dig
),
1126 exc_before
[m
] |= 1U << exc_underflow
;
1127 if (tiny_after_rounding
)
1128 exc_after
[m
] |= 1U << exc_underflow
;
1133 exc_before
[m
] |= 1U << exc_inexact
;
1134 exc_after
[m
] |= 1U << exc_inexact
;
1139 /* Handle the input argument at ARG (NUL-terminated), updating the
1140 lists of test inputs in IT accordingly. NUM_PREV_ARGS arguments
1141 are already in those lists. If EXACT_ARGS, interpret a value given
1142 as a floating-point constant exactly (it must be exact for some
1143 supported format) rather than rounding up and down. The argument,
1144 of type GTYPE, comes from file FILENAME, line LINENO. */
1147 handle_input_arg (const char *arg
, input_test
*it
, size_t num_prev_args
,
1148 generic_value_type gtype
, bool exact_args
,
1149 const char *filename
, unsigned int lineno
)
1151 size_t num_values
= 0;
1152 generic_value values
[2 * fp_num_formats
];
1153 bool check_empty_list
= false;
1157 for (fp_format f
= fp_first_format
; f
< fp_num_formats
; f
++)
1159 mpfr_t extra_values
[2];
1160 size_t num_extra_values
= 0;
1161 for (size_t i
= 0; i
< ARRAY_SIZE (special_real_inputs
); i
++)
1163 if (strcmp (arg
, special_real_inputs
[i
].str
) == 0)
1166 = special_real_inputs
[i
].func (extra_values
[0],
1167 extra_values
[1], f
);
1168 assert (num_extra_values
> 0
1169 && num_extra_values
<= ARRAY_SIZE (extra_values
));
1173 if (num_extra_values
== 0)
1178 check_empty_list
= true;
1180 bool inexact
= mpfr_strtofr (tmp
, arg
, &ep
, 0, MPFR_RNDZ
);
1181 if (*ep
!= 0 || !mpfr_number_p (tmp
))
1182 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1183 "bad floating-point argument: '%s'", arg
);
1184 adjust_real (tmp
, inexact
);
1185 mpfr_t rounded
[rm_num_modes
];
1186 unsigned int exc_before
[rm_num_modes
];
1187 unsigned int exc_after
[rm_num_modes
];
1188 round_real (rounded
, exc_before
, exc_after
, tmp
, f
);
1190 if (mpfr_number_p (rounded
[rm_upward
])
1191 && (!exact_args
|| mpfr_equal_p (rounded
[rm_upward
],
1192 rounded
[rm_downward
])))
1194 mpfr_init2 (extra_values
[num_extra_values
],
1195 fp_formats
[f
].mant_dig
);
1196 assert_exact (mpfr_set (extra_values
[num_extra_values
],
1197 rounded
[rm_upward
], MPFR_RNDN
));
1200 if (mpfr_number_p (rounded
[rm_downward
]) && !exact_args
)
1202 mpfr_init2 (extra_values
[num_extra_values
],
1203 fp_formats
[f
].mant_dig
);
1204 assert_exact (mpfr_set (extra_values
[num_extra_values
],
1205 rounded
[rm_downward
], MPFR_RNDN
));
1208 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1209 mpfr_clear (rounded
[m
]);
1211 for (size_t i
= 0; i
< num_extra_values
; i
++)
1214 for (size_t j
= 0; j
< num_values
; j
++)
1216 if (mpfr_equal_p (values
[j
].value
.f
, extra_values
[i
])
1217 && ((mpfr_signbit (values
[j
].value
.f
) != 0)
1218 == (mpfr_signbit (extra_values
[i
]) != 0)))
1226 assert (num_values
< ARRAY_SIZE (values
));
1227 values
[num_values
].type
= gtype_fp
;
1228 mpfr_init2 (values
[num_values
].value
.f
,
1229 fp_formats
[f
].mant_dig
);
1230 assert_exact (mpfr_set (values
[num_values
].value
.f
,
1231 extra_values
[i
], MPFR_RNDN
));
1234 mpfr_clear (extra_values
[i
]);
1241 values
[0].type
= gtype_int
;
1242 int ret
= mpz_init_set_str (values
[0].value
.i
, arg
, 0);
1244 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1245 "bad integer argument: '%s'", arg
);
1251 if (check_empty_list
&& num_values
== 0)
1252 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1253 "floating-point argument not exact for any format: '%s'",
1255 assert (num_values
> 0 && num_values
<= ARRAY_SIZE (values
));
1256 if (it
->num_input_cases
>= SIZE_MAX
/ num_values
)
1257 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
, "too many input cases");
1258 generic_value
**old_inputs
= it
->inputs
;
1259 size_t new_num_input_cases
= it
->num_input_cases
* num_values
;
1260 generic_value
**new_inputs
= xmalloc (new_num_input_cases
1261 * sizeof (new_inputs
[0]));
1262 for (size_t i
= 0; i
< it
->num_input_cases
; i
++)
1264 for (size_t j
= 0; j
< num_values
; j
++)
1266 size_t idx
= i
* num_values
+ j
;
1267 new_inputs
[idx
] = xmalloc ((num_prev_args
+ 1)
1268 * sizeof (new_inputs
[idx
][0]));
1269 for (size_t k
= 0; k
< num_prev_args
; k
++)
1270 generic_value_copy (&new_inputs
[idx
][k
], &old_inputs
[i
][k
]);
1271 generic_value_copy (&new_inputs
[idx
][num_prev_args
], &values
[j
]);
1273 for (size_t j
= 0; j
< num_prev_args
; j
++)
1274 generic_value_free (&old_inputs
[i
][j
]);
1275 free (old_inputs
[i
]);
1278 for (size_t i
= 0; i
< num_values
; i
++)
1279 generic_value_free (&values
[i
]);
1280 it
->inputs
= new_inputs
;
1281 it
->num_input_cases
= new_num_input_cases
;
1284 /* Handle the input flag ARG (NUL-terminated), storing it in *FLAG.
1285 The flag comes from file FILENAME, line LINENO. */
1288 handle_input_flag (char *arg
, input_flag
*flag
,
1289 const char *filename
, unsigned int lineno
)
1291 char *ep
= strchr (arg
, ':');
1294 ep
= strchr (arg
, 0);
1295 assert (ep
!= NULL
);
1300 for (input_flag_type i
= flag_first_flag
; i
<= num_input_flag_types
; i
++)
1302 if (strcmp (arg
, input_flags
[i
]) == 0)
1310 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
, "unknown flag: '%s'",
1316 flag
->cond
= xstrdup (ep
);
1319 /* Add the test LINE (file FILENAME, line LINENO) to the test
1323 add_test (char *line
, const char *filename
, unsigned int lineno
)
1325 size_t num_tokens
= 1;
1327 while ((p
= strchr (p
, ' ')) != NULL
)
1333 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1334 "line too short: '%s'", line
);
1335 p
= strchr (line
, ' ');
1336 size_t func_name_len
= p
- line
;
1337 for (size_t i
= 0; i
< ARRAY_SIZE (test_functions
); i
++)
1339 if (func_name_len
== strlen (test_functions
[i
].name
)
1340 && strncmp (line
, test_functions
[i
].name
, func_name_len
) == 0)
1342 test_function
*tf
= &test_functions
[i
];
1343 if (num_tokens
< 1 + tf
->num_args
)
1344 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1345 "line too short: '%s'", line
);
1346 if (tf
->num_tests
== tf
->num_tests_alloc
)
1348 tf
->num_tests_alloc
= 2 * tf
->num_tests_alloc
+ 16;
1350 = xrealloc (tf
->tests
,
1351 tf
->num_tests_alloc
* sizeof (tf
->tests
[0]));
1353 input_test
*it
= &tf
->tests
[tf
->num_tests
];
1355 it
->num_input_cases
= 1;
1356 it
->inputs
= xmalloc (sizeof (it
->inputs
[0]));
1357 it
->inputs
[0] = NULL
;
1358 it
->old_output
= NULL
;
1360 for (size_t j
= 0; j
< tf
->num_args
; j
++)
1362 char *ep
= strchr (p
, ' ');
1365 ep
= strchr (p
, '\n');
1366 assert (ep
!= NULL
);
1369 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1370 "empty token in line: '%s'", line
);
1371 for (char *t
= p
; t
< ep
; t
++)
1372 if (isspace ((unsigned char) *t
))
1373 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1374 "whitespace in token in line: '%s'", line
);
1377 handle_input_arg (p
, it
, j
,
1378 generic_arg_ret_type (tf
->arg_types
[j
]),
1379 tf
->exact_args
, filename
, lineno
);
1383 it
->num_flags
= num_tokens
- 1 - tf
->num_args
;
1384 it
->flags
= xmalloc (it
->num_flags
* sizeof (it
->flags
[0]));
1385 for (size_t j
= 0; j
< it
->num_flags
; j
++)
1387 char *ep
= strchr (p
, ' ');
1390 ep
= strchr (p
, '\n');
1391 assert (ep
!= NULL
);
1394 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1395 "empty token in line: '%s'", line
);
1396 for (char *t
= p
; t
< ep
; t
++)
1397 if (isspace ((unsigned char) *t
))
1398 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1399 "whitespace in token in line: '%s'", line
);
1402 handle_input_flag (p
, &it
->flags
[j
], filename
, lineno
);
1411 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1412 "unknown function in line: '%s'", line
);
1415 /* Read in the test input data from FILENAME. */
1418 read_input (const char *filename
)
1420 FILE *fp
= fopen (filename
, "r");
1422 error (EXIT_FAILURE
, errno
, "open '%s'", filename
);
1423 unsigned int lineno
= 0;
1428 ssize_t ret
= getline (&line
, &size
, fp
);
1432 if (line
[0] == '#' || line
[0] == '\n')
1434 add_test (line
, filename
, lineno
);
1437 error (EXIT_FAILURE
, errno
, "read from '%s'", filename
);
1438 if (fclose (fp
) != 0)
1439 error (EXIT_FAILURE
, errno
, "close '%s'", filename
);
1442 /* Calculate the generic results (round-to-zero with sticky bit) for
1443 the function described by CALC, with inputs INPUTS, if MODE is
1444 rm_towardzero; for other modes, calculate results in that mode,
1445 which must be exact zero results. */
1448 calc_generic_results (generic_value
*outputs
, generic_value
*inputs
,
1449 const func_calc_desc
*calc
, rounding_mode mode
)
1454 mpfr_rnd_t mode_mpfr
= rounding_modes
[mode
].mpfr_mode
;
1455 mpc_rnd_t mode_mpc
= rounding_modes
[mode
].mpc_mode
;
1457 switch (calc
->method
)
1460 assert (inputs
[0].type
== gtype_fp
);
1461 outputs
[0].type
= gtype_fp
;
1462 mpfr_init (outputs
[0].value
.f
);
1463 inexact
= calc
->func
.mpfr_f_f (outputs
[0].value
.f
, inputs
[0].value
.f
,
1465 if (mode
!= rm_towardzero
)
1466 assert (!inexact
&& mpfr_zero_p (outputs
[0].value
.f
));
1467 adjust_real (outputs
[0].value
.f
, inexact
);
1471 assert (inputs
[0].type
== gtype_fp
);
1472 assert (inputs
[1].type
== gtype_fp
);
1473 outputs
[0].type
= gtype_fp
;
1474 mpfr_init (outputs
[0].value
.f
);
1475 inexact
= calc
->func
.mpfr_ff_f (outputs
[0].value
.f
, inputs
[0].value
.f
,
1476 inputs
[1].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
);
1483 assert (inputs
[0].type
== gtype_fp
);
1484 assert (inputs
[1].type
== gtype_fp
);
1485 assert (inputs
[2].type
== gtype_fp
);
1486 outputs
[0].type
= gtype_fp
;
1487 mpfr_init (outputs
[0].value
.f
);
1488 inexact
= calc
->func
.mpfr_fff_f (outputs
[0].value
.f
, inputs
[0].value
.f
,
1489 inputs
[1].value
.f
, inputs
[2].value
.f
,
1491 if (mode
!= rm_towardzero
)
1492 assert (!inexact
&& mpfr_zero_p (outputs
[0].value
.f
));
1493 adjust_real (outputs
[0].value
.f
, inexact
);
1497 assert (inputs
[0].type
== gtype_fp
);
1498 outputs
[0].type
= gtype_fp
;
1499 outputs
[1].type
= gtype_int
;
1500 mpfr_init (outputs
[0].value
.f
);
1502 inexact
= calc
->func
.mpfr_f_f1 (outputs
[0].value
.f
, &i
,
1503 inputs
[0].value
.f
, mode_mpfr
);
1504 if (mode
!= rm_towardzero
)
1505 assert (!inexact
&& mpfr_zero_p (outputs
[0].value
.f
));
1506 adjust_real (outputs
[0].value
.f
, inexact
);
1507 mpz_init_set_si (outputs
[1].value
.i
, i
);
1511 assert (inputs
[0].type
== gtype_int
);
1512 assert (inputs
[1].type
== gtype_fp
);
1513 outputs
[0].type
= gtype_fp
;
1514 mpfr_init (outputs
[0].value
.f
);
1515 assert (mpz_fits_slong_p (inputs
[0].value
.i
));
1516 long l
= mpz_get_si (inputs
[0].value
.i
);
1517 inexact
= calc
->func
.mpfr_if_f (outputs
[0].value
.f
, l
,
1518 inputs
[1].value
.f
, mode_mpfr
);
1519 if (mode
!= rm_towardzero
)
1520 assert (!inexact
&& mpfr_zero_p (outputs
[0].value
.f
));
1521 adjust_real (outputs
[0].value
.f
, inexact
);
1525 assert (inputs
[0].type
== gtype_fp
);
1526 outputs
[0].type
= gtype_fp
;
1527 mpfr_init (outputs
[0].value
.f
);
1528 outputs
[1].type
= gtype_fp
;
1529 mpfr_init (outputs
[1].value
.f
);
1530 int comb_ternary
= calc
->func
.mpfr_f_11 (outputs
[0].value
.f
,
1534 if (mode
!= rm_towardzero
)
1535 assert (((comb_ternary
& 0x3) == 0
1536 && mpfr_zero_p (outputs
[0].value
.f
))
1537 || ((comb_ternary
& 0xc) == 0
1538 && mpfr_zero_p (outputs
[1].value
.f
)));
1539 adjust_real (outputs
[0].value
.f
, (comb_ternary
& 0x3) != 0);
1540 adjust_real (outputs
[1].value
.f
, (comb_ternary
& 0xc) != 0);
1544 assert (inputs
[0].type
== gtype_fp
);
1545 assert (inputs
[1].type
== gtype_fp
);
1546 outputs
[0].type
= gtype_fp
;
1547 mpfr_init (outputs
[0].value
.f
);
1548 mpc_init2 (ci1
, internal_precision
);
1549 assert_exact (mpc_set_fr_fr (ci1
, inputs
[0].value
.f
, inputs
[1].value
.f
,
1551 inexact
= calc
->func
.mpc_c_f (outputs
[0].value
.f
, ci1
, mode_mpfr
);
1552 if (mode
!= rm_towardzero
)
1553 assert (!inexact
&& mpfr_zero_p (outputs
[0].value
.f
));
1554 adjust_real (outputs
[0].value
.f
, inexact
);
1559 assert (inputs
[0].type
== gtype_fp
);
1560 assert (inputs
[1].type
== gtype_fp
);
1561 outputs
[0].type
= gtype_fp
;
1562 mpfr_init (outputs
[0].value
.f
);
1563 outputs
[1].type
= gtype_fp
;
1564 mpfr_init (outputs
[1].value
.f
);
1565 mpc_init2 (ci1
, internal_precision
);
1566 mpc_init2 (co
, internal_precision
);
1567 assert_exact (mpc_set_fr_fr (ci1
, inputs
[0].value
.f
, inputs
[1].value
.f
,
1569 mpc_ternary
= calc
->func
.mpc_c_c (co
, ci1
, mode_mpc
);
1570 if (mode
!= rm_towardzero
)
1571 assert ((!MPC_INEX_RE (mpc_ternary
)
1572 && mpfr_zero_p (mpc_realref (co
)))
1573 || (!MPC_INEX_IM (mpc_ternary
)
1574 && mpfr_zero_p (mpc_imagref (co
))));
1575 assert_exact (mpfr_set (outputs
[0].value
.f
, mpc_realref (co
),
1577 assert_exact (mpfr_set (outputs
[1].value
.f
, mpc_imagref (co
),
1579 adjust_real (outputs
[0].value
.f
, MPC_INEX_RE (mpc_ternary
));
1580 adjust_real (outputs
[1].value
.f
, MPC_INEX_IM (mpc_ternary
));
1586 assert (inputs
[0].type
== gtype_fp
);
1587 assert (inputs
[1].type
== gtype_fp
);
1588 assert (inputs
[2].type
== gtype_fp
);
1589 assert (inputs
[3].type
== gtype_fp
);
1590 outputs
[0].type
= gtype_fp
;
1591 mpfr_init (outputs
[0].value
.f
);
1592 outputs
[1].type
= gtype_fp
;
1593 mpfr_init (outputs
[1].value
.f
);
1594 mpc_init2 (ci1
, internal_precision
);
1595 mpc_init2 (ci2
, internal_precision
);
1596 mpc_init2 (co
, internal_precision
);
1597 assert_exact (mpc_set_fr_fr (ci1
, inputs
[0].value
.f
, inputs
[1].value
.f
,
1599 assert_exact (mpc_set_fr_fr (ci2
, inputs
[2].value
.f
, inputs
[3].value
.f
,
1601 mpc_ternary
= calc
->func
.mpc_cc_c (co
, ci1
, ci2
, mode_mpc
);
1602 if (mode
!= rm_towardzero
)
1603 assert ((!MPC_INEX_RE (mpc_ternary
)
1604 && mpfr_zero_p (mpc_realref (co
)))
1605 || (!MPC_INEX_IM (mpc_ternary
)
1606 && mpfr_zero_p (mpc_imagref (co
))));
1607 assert_exact (mpfr_set (outputs
[0].value
.f
, mpc_realref (co
),
1609 assert_exact (mpfr_set (outputs
[1].value
.f
, mpc_imagref (co
),
1611 adjust_real (outputs
[0].value
.f
, MPC_INEX_RE (mpc_ternary
));
1612 adjust_real (outputs
[1].value
.f
, MPC_INEX_IM (mpc_ternary
));
1623 /* Return the number of bits for integer type TYPE, where "long" has
1624 LONG_BITS bits (32 or 64). */
1627 int_type_bits (arg_ret_type type
, int long_bits
)
1629 assert (long_bits
== 32 || long_bits
== 64);
1640 case type_long_long
:
1649 /* Check whether an integer Z fits a given type TYPE, where "long" has
1650 LONG_BITS bits (32 or 64). */
1653 int_fits_type (mpz_t z
, arg_ret_type type
, int long_bits
)
1655 int bits
= int_type_bits (type
, long_bits
);
1659 mpz_ui_pow_ui (t
, 2, bits
- 1);
1660 if (mpz_cmp (z
, t
) >= 0)
1663 if (mpz_cmp (z
, t
) < 0)
1669 /* Print a generic value V to FP (name FILENAME), preceded by a space,
1670 for type TYPE, LONG_BITS bits per long, printing " IGNORE" instead
1674 output_generic_value (FILE *fp
, const char *filename
, const generic_value
*v
,
1675 bool ignore
, arg_ret_type type
, int long_bits
)
1679 if (fputs (" IGNORE", fp
) < 0)
1680 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1683 assert (v
->type
== generic_arg_ret_type (type
));
1699 case type_long_long
:
1709 if (mpfr_inf_p (v
->value
.f
))
1711 if (fputs ((mpfr_signbit (v
->value
.f
)
1712 ? " minus_infty" : " plus_infty"), fp
) < 0)
1713 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1717 assert (mpfr_number_p (v
->value
.f
));
1718 if (mpfr_fprintf (fp
, " %Ra%s", v
->value
.f
, suffix
) < 0)
1719 error (EXIT_FAILURE
, errno
, "mpfr_fprintf to '%s'", filename
);
1724 int bits
= int_type_bits (type
, long_bits
);
1727 mpz_ui_pow_ui (tmp
, 2, bits
- 1);
1729 if (mpz_cmp (v
->value
.i
, tmp
) == 0)
1731 mpz_add_ui (tmp
, tmp
, 1);
1732 if (mpfr_fprintf (fp
, " (%Zd%s-1)", tmp
, suffix
) < 0)
1733 error (EXIT_FAILURE
, errno
, "mpfr_fprintf to '%s'", filename
);
1737 if (mpfr_fprintf (fp
, " %Zd%s", v
->value
.i
, suffix
) < 0)
1738 error (EXIT_FAILURE
, errno
, "mpfr_fprintf to '%s'", filename
);
1748 /* Generate test output to FP (name FILENAME) for test function TF
1749 (rounding results to a narrower type if NARROW), input test IT,
1750 choice of input values INPUTS. */
1753 output_for_one_input_case (FILE *fp
, const char *filename
, test_function
*tf
,
1754 bool narrow
, input_test
*it
, generic_value
*inputs
)
1756 bool long_bits_matters
= false;
1757 bool fits_long32
= true;
1758 for (size_t i
= 0; i
< tf
->num_args
; i
++)
1760 generic_value_type gtype
= generic_arg_ret_type (tf
->arg_types
[i
]);
1761 assert (inputs
[i
].type
== gtype
);
1762 if (gtype
== gtype_int
)
1764 bool fits_64
= int_fits_type (inputs
[i
].value
.i
, tf
->arg_types
[i
],
1768 if (tf
->arg_types
[i
] == type_long
1769 && !int_fits_type (inputs
[i
].value
.i
, tf
->arg_types
[i
], 32))
1771 long_bits_matters
= true;
1772 fits_long32
= false;
1776 generic_value generic_outputs
[MAX_NRET
];
1777 calc_generic_results (generic_outputs
, inputs
, &tf
->calc
, rm_towardzero
);
1778 bool ignore_output_long32
[MAX_NRET
] = { false };
1779 bool ignore_output_long64
[MAX_NRET
] = { false };
1780 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
1782 assert (generic_outputs
[i
].type
1783 == generic_arg_ret_type (tf
->ret_types
[i
]));
1784 switch (generic_outputs
[i
].type
)
1787 if (!mpfr_number_p (generic_outputs
[i
].value
.f
))
1788 goto out
; /* Result is NaN or exact infinity. */
1792 ignore_output_long32
[i
] = !int_fits_type (generic_outputs
[i
].value
.i
,
1793 tf
->ret_types
[i
], 32);
1794 ignore_output_long64
[i
] = !int_fits_type (generic_outputs
[i
].value
.i
,
1795 tf
->ret_types
[i
], 64);
1796 if (ignore_output_long32
[i
] != ignore_output_long64
[i
])
1797 long_bits_matters
= true;
1804 /* Iterate over relevant sizes of long and floating-point formats. */
1805 for (int long_bits
= 32; long_bits
<= 64; long_bits
+= 32)
1807 if (long_bits
== 32 && !fits_long32
)
1809 if (long_bits
== 64 && !long_bits_matters
)
1811 const char *long_cond
;
1812 if (long_bits_matters
)
1813 long_cond
= (long_bits
== 32 ? ":long32" : ":long64");
1816 bool *ignore_output
= (long_bits
== 32
1817 ? ignore_output_long32
1818 : ignore_output_long64
);
1819 for (fp_format f
= fp_first_format
; f
< fp_num_formats
; f
++)
1822 mpfr_t res
[rm_num_modes
];
1823 unsigned int exc_before
[rm_num_modes
];
1824 unsigned int exc_after
[rm_num_modes
];
1825 bool have_fp_arg
= false;
1830 for (size_t i
= 0; i
< tf
->num_args
; i
++)
1832 if (inputs
[i
].type
== gtype_fp
)
1836 if (mpfr_zero_p (inputs
[i
].value
.f
))
1838 assert (mpfr_regular_p (inputs
[i
].value
.f
));
1839 int this_exp
, this_num_ones
, this_min_exp
, this_prec
;
1842 mpfr_exp_t e
= mpfr_get_z_2exp (tmp
, inputs
[i
].value
.f
);
1843 if (mpz_sgn (tmp
) < 0)
1845 size_t bits
= mpz_sizeinbase (tmp
, 2);
1846 mp_bitcnt_t tz
= mpz_scan1 (tmp
, 0);
1847 this_min_exp
= e
+ tz
;
1848 this_prec
= bits
- tz
;
1849 assert (this_prec
> 0);
1850 this_exp
= this_min_exp
+ this_prec
- 1;
1852 == mpfr_get_exp (inputs
[i
].value
.f
) - 1);
1854 while ((size_t) this_num_ones
< bits
1855 && mpz_tstbit (tmp
, bits
- 1 - this_num_ones
))
1860 if (this_exp
> max_exp
1861 || (this_exp
== max_exp
1862 && this_num_ones
> num_ones
))
1865 num_ones
= this_num_ones
;
1867 if (this_min_exp
< min_exp
)
1868 min_exp
= this_min_exp
;
1869 if (this_prec
> max_prec
)
1870 max_prec
= this_prec
;
1875 num_ones
= this_num_ones
;
1876 min_exp
= this_min_exp
;
1877 max_prec
= this_prec
;
1883 round_real (res
, exc_before
, exc_after
,
1884 inputs
[i
].value
.f
, f
);
1885 if (!mpfr_equal_p (res
[rm_tonearest
], inputs
[i
].value
.f
))
1887 for (rounding_mode m
= rm_first_mode
;
1890 mpfr_clear (res
[m
]);
1898 /* The inputs fit this type if required to do so, so compute
1899 the ideal outputs and exceptions. */
1900 mpfr_t all_res
[MAX_NRET
][rm_num_modes
];
1901 unsigned int all_exc_before
[MAX_NRET
][rm_num_modes
];
1902 unsigned int all_exc_after
[MAX_NRET
][rm_num_modes
];
1903 unsigned int merged_exc_before
[rm_num_modes
] = { 0 };
1904 unsigned int merged_exc_after
[rm_num_modes
] = { 0 };
1905 /* For functions not exactly determined, track whether
1906 underflow is required (some result is inexact, and
1907 magnitude does not exceed the greatest magnitude
1908 subnormal), and permitted (not an exact zero, and
1909 magnitude does not exceed the least magnitude
1911 bool must_underflow
= false;
1912 bool may_underflow
= false;
1913 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
1915 switch (generic_outputs
[i
].type
)
1918 round_real (all_res
[i
], all_exc_before
[i
], all_exc_after
[i
],
1919 generic_outputs
[i
].value
.f
, f
);
1920 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1922 merged_exc_before
[m
] |= all_exc_before
[i
][m
];
1923 merged_exc_after
[m
] |= all_exc_after
[i
][m
];
1927 |= ((all_exc_before
[i
][m
]
1928 & (1U << exc_inexact
)) != 0
1929 && (mpfr_cmpabs (generic_outputs
[i
].value
.f
,
1930 fp_formats
[f
].subnorm_max
)
1933 |= (!mpfr_zero_p (generic_outputs
[i
].value
.f
)
1934 && (mpfr_cmpabs (generic_outputs
[i
].value
.f
,
1935 fp_formats
[f
].min_plus_half
)
1938 /* If the result is an exact zero, the sign may
1939 depend on the rounding mode, so recompute it
1940 directly in that mode. */
1941 if (mpfr_zero_p (all_res
[i
][m
])
1942 && (all_exc_before
[i
][m
] & (1U << exc_inexact
)) == 0)
1944 generic_value outputs_rm
[MAX_NRET
];
1945 calc_generic_results (outputs_rm
, inputs
,
1947 assert_exact (mpfr_set (all_res
[i
][m
],
1948 outputs_rm
[i
].value
.f
,
1950 for (size_t j
= 0; j
< tf
->num_ret
; j
++)
1951 generic_value_free (&outputs_rm
[j
]);
1957 if (ignore_output
[i
])
1958 for (rounding_mode m
= rm_first_mode
;
1962 merged_exc_before
[m
] |= 1U << exc_invalid
;
1963 merged_exc_after
[m
] |= 1U << exc_invalid
;
1971 assert (may_underflow
|| !must_underflow
);
1972 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1974 bool before_after_matters
1975 = tf
->exact
&& merged_exc_before
[m
] != merged_exc_after
[m
];
1976 if (before_after_matters
)
1978 assert ((merged_exc_before
[m
] ^ merged_exc_after
[m
])
1979 == (1U << exc_underflow
));
1980 assert ((merged_exc_before
[m
] & (1U << exc_underflow
)) != 0);
1982 unsigned int merged_exc
= merged_exc_before
[m
];
1985 if (fprintf (fp
, "= %s %s %s%s:arg_fmt(%d,%d,%d,%d)",
1986 tf
->name
, rounding_modes
[m
].name
,
1987 fp_formats
[f
].name
, long_cond
, max_exp
,
1988 num_ones
, min_exp
, max_prec
) < 0)
1989 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1993 if (fprintf (fp
, "= %s %s %s%s", tf
->name
,
1994 rounding_modes
[m
].name
, fp_formats
[f
].name
,
1996 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1999 for (size_t i
= 0; i
< tf
->num_args
; i
++)
2000 output_generic_value (fp
, filename
, &inputs
[i
], false,
2001 tf
->arg_types
[i
], long_bits
);
2002 if (fputs (" :", fp
) < 0)
2003 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
2004 /* Print outputs. */
2005 bool must_erange
= false;
2006 bool some_underflow_zero
= false;
2007 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
2010 g
.type
= generic_outputs
[i
].type
;
2014 if (mpfr_inf_p (all_res
[i
][m
])
2015 && (all_exc_before
[i
][m
]
2016 & (1U << exc_overflow
)) != 0)
2018 if (mpfr_zero_p (all_res
[i
][m
])
2020 || mpfr_zero_p (all_res
[i
][rm_tonearest
]))
2021 && (all_exc_before
[i
][m
]
2022 & (1U << exc_underflow
)) != 0)
2024 if (mpfr_zero_p (all_res
[i
][rm_towardzero
])
2025 && (all_exc_before
[i
][m
]
2026 & (1U << exc_underflow
)) != 0)
2027 some_underflow_zero
= true;
2028 mpfr_init2 (g
.value
.f
, fp_formats
[f
].mant_dig
);
2029 assert_exact (mpfr_set (g
.value
.f
, all_res
[i
][m
],
2034 mpz_init (g
.value
.i
);
2035 mpz_set (g
.value
.i
, generic_outputs
[i
].value
.i
);
2041 output_generic_value (fp
, filename
, &g
, ignore_output
[i
],
2042 tf
->ret_types
[i
], long_bits
);
2043 generic_value_free (&g
);
2045 if (fputs (" :", fp
) < 0)
2046 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
2047 /* Print miscellaneous flags (passed through from
2049 for (size_t i
= 0; i
< it
->num_flags
; i
++)
2050 switch (it
->flags
[i
].type
)
2052 case flag_no_test_inline
:
2053 case flag_ignore_zero_inf_sign
:
2055 if (fprintf (fp
, " %s%s",
2056 input_flags
[it
->flags
[i
].type
],
2060 error (EXIT_FAILURE
, errno
, "write to '%s'",
2063 case flag_xfail_rounding
:
2064 if (m
!= rm_tonearest
)
2065 if (fprintf (fp
, " xfail%s",
2069 error (EXIT_FAILURE
, errno
, "write to '%s'",
2075 /* For the ibm128 format, expect incorrect overflowing
2076 results in rounding modes other than to nearest;
2077 likewise incorrect results where the result may
2079 if (f
== fp_ldbl_128ibm
2080 && m
!= rm_tonearest
2081 && (some_underflow_zero
2082 || (merged_exc_before
[m
] & (1U << exc_overflow
)) != 0))
2083 if (fputs (" xfail:ibm128-libgcc", fp
) < 0)
2084 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
2085 /* Print exception flags and compute errno
2086 expectations where not already computed. */
2087 bool may_edom
= false;
2088 bool must_edom
= false;
2089 bool may_erange
= must_erange
|| may_underflow
;
2090 for (fp_exception e
= exc_first_exception
;
2091 e
< exc_num_exceptions
;
2094 bool expect_e
= (merged_exc
& (1U << e
)) != 0;
2095 bool e_optional
= false;
2100 may_erange
= must_erange
= true;
2110 may_edom
= must_edom
= true;
2123 if (may_underflow
&& !must_underflow
)
2132 assert (!before_after_matters
);
2133 if (fprintf (fp
, " %s-ok", exceptions
[e
]) < 0)
2134 error (EXIT_FAILURE
, errno
, "write to '%s'",
2140 if (fprintf (fp
, " %s", exceptions
[e
]) < 0)
2141 error (EXIT_FAILURE
, errno
, "write to '%s'",
2143 if (before_after_matters
&& e
== exc_underflow
)
2144 if (fputs (":before-rounding", fp
) < 0)
2145 error (EXIT_FAILURE
, errno
, "write to '%s'",
2147 for (int after
= 0; after
<= 1; after
++)
2149 bool expect_e_here
= expect_e
;
2150 if (after
== 1 && (!before_after_matters
2151 || e
!= exc_underflow
))
2153 const char *after_cond
;
2154 if (before_after_matters
&& e
== exc_underflow
)
2158 : ":before-rounding");
2159 expect_e_here
= !after
;
2163 input_flag_type okflag
;
2164 okflag
= (expect_e_here
2165 ? flag_missing_first
2166 : flag_spurious_first
) + e
;
2167 for (size_t i
= 0; i
< it
->num_flags
; i
++)
2168 if (it
->flags
[i
].type
== okflag
)
2169 if (fprintf (fp
, " %s-ok%s%s",
2173 : ""), after_cond
) < 0)
2174 error (EXIT_FAILURE
, errno
, "write to '%s'",
2179 /* Print errno expectations. */
2183 must_erange
= false;
2185 if (may_edom
&& !must_edom
)
2187 if (fputs (" errno-edom-ok", fp
) < 0)
2188 error (EXIT_FAILURE
, errno
, "write to '%s'",
2194 if (fputs (" errno-edom", fp
) < 0)
2195 error (EXIT_FAILURE
, errno
, "write to '%s'",
2197 input_flag_type okflag
= (must_edom
2198 ? flag_missing_errno
2199 : flag_spurious_errno
);
2200 for (size_t i
= 0; i
< it
->num_flags
; i
++)
2201 if (it
->flags
[i
].type
== okflag
)
2202 if (fprintf (fp
, " errno-edom-ok%s",
2206 error (EXIT_FAILURE
, errno
, "write to '%s'",
2209 if (before_after_matters
)
2210 assert (may_erange
&& !must_erange
);
2211 if (may_erange
&& !must_erange
)
2213 if (fprintf (fp
, " errno-erange-ok%s",
2214 (before_after_matters
2215 ? ":before-rounding"
2217 error (EXIT_FAILURE
, errno
, "write to '%s'",
2220 if (before_after_matters
|| !(may_erange
&& !must_erange
))
2223 if (fputs (" errno-erange", fp
) < 0)
2224 error (EXIT_FAILURE
, errno
, "write to '%s'",
2226 input_flag_type okflag
= (must_erange
2227 ? flag_missing_errno
2228 : flag_spurious_errno
);
2229 for (size_t i
= 0; i
< it
->num_flags
; i
++)
2230 if (it
->flags
[i
].type
== okflag
)
2231 if (fprintf (fp
, " errno-erange-ok%s%s",
2235 (before_after_matters
2238 error (EXIT_FAILURE
, errno
, "write to '%s'",
2241 if (putc ('\n', fp
) < 0)
2242 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
2244 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
2246 if (generic_outputs
[i
].type
== gtype_fp
)
2247 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
2248 mpfr_clear (all_res
[i
][m
]);
2253 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
2254 generic_value_free (&generic_outputs
[i
]);
2257 /* Generate test output data for FUNCTION to FILENAME. The function
2258 is interpreted as rounding its results to a narrower type if
2262 generate_output (const char *function
, bool narrow
, const char *filename
)
2264 FILE *fp
= fopen (filename
, "w");
2266 error (EXIT_FAILURE
, errno
, "open '%s'", filename
);
2267 for (size_t i
= 0; i
< ARRAY_SIZE (test_functions
); i
++)
2269 test_function
*tf
= &test_functions
[i
];
2270 if (strcmp (tf
->name
, function
) != 0)
2272 for (size_t j
= 0; j
< tf
->num_tests
; j
++)
2274 input_test
*it
= &tf
->tests
[j
];
2275 if (fputs (it
->line
, fp
) < 0)
2276 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
2277 for (size_t k
= 0; k
< it
->num_input_cases
; k
++)
2278 output_for_one_input_case (fp
, filename
, tf
, narrow
,
2282 if (fclose (fp
) != 0)
2283 error (EXIT_FAILURE
, errno
, "close '%s'", filename
);
2287 main (int argc
, char **argv
)
2290 && !(argc
== 5 && strcmp (argv
[1], "--narrow") == 0))
2291 error (EXIT_FAILURE
, 0,
2292 "usage: gen-auto-libm-tests [--narrow] <input> <func> <output>");
2294 const char *input_filename
= argv
[1];
2295 const char *function
= argv
[2];
2296 const char *output_filename
= argv
[3];
2300 input_filename
= argv
[1];
2302 output_filename
= argv
[3];
2307 input_filename
= argv
[2];
2309 output_filename
= argv
[4];
2312 read_input (input_filename
);
2313 generate_output (function
, narrow
, output_filename
);
2314 exit (EXIT_SUCCESS
);