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 ("pow", mpfr_pow
, false),
583 FUNC_mpfr_f_f ("sin", mpfr_sin
, false),
584 FUNC ("sincos", ARGS1 (type_fp
), RET2 (type_fp
, type_fp
), false, false,
585 false, CALC (mpfr_f_11
, mpfr_sin_cos
)),
586 FUNC_mpfr_f_f ("sinh", mpfr_sinh
, false),
587 FUNC_mpfr_ff_f ("sub", mpfr_sub
, true),
588 FUNC_mpfr_f_f ("sqrt", mpfr_sqrt
, true),
589 FUNC_mpfr_f_f ("tan", mpfr_tan
, false),
590 FUNC_mpfr_f_f ("tanh", mpfr_tanh
, false),
591 FUNC_mpfr_f_f ("tgamma", mpfr_gamma
, false),
592 FUNC_mpfr_f_f ("y0", mpfr_y0
, false),
593 FUNC_mpfr_f_f ("y1", mpfr_y1
, false),
594 FUNC_mpfr_if_f ("yn", mpfr_yn
, false),
597 /* Allocate memory, with error checking. */
602 void *p
= malloc (n
);
604 error (EXIT_FAILURE
, errno
, "xmalloc failed");
609 xrealloc (void *p
, size_t n
)
613 error (EXIT_FAILURE
, errno
, "xrealloc failed");
618 xstrdup (const char *s
)
620 char *p
= strdup (s
);
622 error (EXIT_FAILURE
, errno
, "xstrdup failed");
626 /* Assert that the result of an MPFR operation was exact; that is,
627 that the returned ternary value was 0. */
635 /* Return the generic type of an argument or return value type T. */
637 static generic_value_type
638 generic_arg_ret_type (arg_ret_type t
)
655 /* Free a generic_value *V. */
658 generic_value_free (generic_value
*v
)
663 mpfr_clear (v
->value
.f
);
667 mpz_clear (v
->value
.i
);
675 /* Copy a generic_value *SRC to *DEST. */
678 generic_value_copy (generic_value
*dest
, const generic_value
*src
)
680 dest
->type
= src
->type
;
684 mpfr_init (dest
->value
.f
);
685 assert_exact (mpfr_set (dest
->value
.f
, src
->value
.f
, MPFR_RNDN
));
689 mpz_init (dest
->value
.i
);
690 mpz_set (dest
->value
.i
, src
->value
.i
);
698 /* Initialize data for floating-point formats. */
701 init_fp_formats (void)
703 int global_max_exp
= 0, global_min_subnorm_exp
= 0;
704 for (fp_format f
= fp_first_format
; f
< fp_num_formats
; f
++)
706 if (fp_formats
[f
].mant_dig
+ 2 > internal_precision
)
707 internal_precision
= fp_formats
[f
].mant_dig
+ 2;
708 if (fp_formats
[f
].max_exp
> global_max_exp
)
709 global_max_exp
= fp_formats
[f
].max_exp
;
710 int min_subnorm_exp
= fp_formats
[f
].min_exp
- fp_formats
[f
].mant_dig
;
711 if (min_subnorm_exp
< global_min_subnorm_exp
)
712 global_min_subnorm_exp
= min_subnorm_exp
;
713 mpfr_init2 (fp_formats
[f
].max
, fp_formats
[f
].mant_dig
);
714 if (fp_formats
[f
].max_string
!= NULL
)
717 assert_exact (mpfr_strtofr (fp_formats
[f
].max
,
718 fp_formats
[f
].max_string
,
724 assert_exact (mpfr_set_ui_2exp (fp_formats
[f
].max
, 1,
725 fp_formats
[f
].max_exp
,
727 mpfr_nextbelow (fp_formats
[f
].max
);
729 mpfr_init2 (fp_formats
[f
].min
, fp_formats
[f
].mant_dig
);
730 assert_exact (mpfr_set_ui_2exp (fp_formats
[f
].min
, 1,
731 fp_formats
[f
].min_exp
- 1,
733 mpfr_init2 (fp_formats
[f
].min_plus_half
, fp_formats
[f
].mant_dig
+ 1);
734 assert_exact (mpfr_set (fp_formats
[f
].min_plus_half
,
735 fp_formats
[f
].min
, MPFR_RNDN
));
736 mpfr_nextabove (fp_formats
[f
].min_plus_half
);
737 mpfr_init2 (fp_formats
[f
].subnorm_max
, fp_formats
[f
].mant_dig
);
738 assert_exact (mpfr_set (fp_formats
[f
].subnorm_max
, fp_formats
[f
].min
,
740 mpfr_nextbelow (fp_formats
[f
].subnorm_max
);
741 mpfr_nextbelow (fp_formats
[f
].subnorm_max
);
742 mpfr_init2 (fp_formats
[f
].subnorm_min
, fp_formats
[f
].mant_dig
);
743 assert_exact (mpfr_set_ui_2exp (fp_formats
[f
].subnorm_min
, 1,
744 min_subnorm_exp
, MPFR_RNDN
));
746 mpfr_set_default_prec (internal_precision
);
747 mpfr_init (global_max
);
748 assert_exact (mpfr_set_ui_2exp (global_max
, 1, global_max_exp
, MPFR_RNDN
));
749 mpfr_init (global_min
);
750 assert_exact (mpfr_set_ui_2exp (global_min
, 1, global_min_subnorm_exp
- 1,
754 /* Fill in mpfr_t values for special strings in input arguments. */
757 special_fill_max (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
760 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
761 assert_exact (mpfr_set (res0
, fp_formats
[format
].max
, MPFR_RNDN
));
766 special_fill_minus_max (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
769 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
770 assert_exact (mpfr_neg (res0
, fp_formats
[format
].max
, MPFR_RNDN
));
775 special_fill_min (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
778 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
779 assert_exact (mpfr_set (res0
, fp_formats
[format
].min
, MPFR_RNDN
));
784 special_fill_minus_min (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
787 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
788 assert_exact (mpfr_neg (res0
, fp_formats
[format
].min
, MPFR_RNDN
));
793 special_fill_min_subnorm (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
796 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
797 assert_exact (mpfr_set (res0
, fp_formats
[format
].subnorm_min
, MPFR_RNDN
));
802 special_fill_minus_min_subnorm (mpfr_t res0
,
803 mpfr_t res1
__attribute__ ((unused
)),
806 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
807 assert_exact (mpfr_neg (res0
, fp_formats
[format
].subnorm_min
, MPFR_RNDN
));
812 special_fill_min_subnorm_p120 (mpfr_t res0
,
813 mpfr_t res1
__attribute__ ((unused
)),
816 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
817 assert_exact (mpfr_mul_2ui (res0
, fp_formats
[format
].subnorm_min
,
823 special_fill_pi (mpfr_t res0
, mpfr_t res1
, fp_format format
)
825 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
826 mpfr_const_pi (res0
, MPFR_RNDU
);
827 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
828 mpfr_const_pi (res1
, MPFR_RNDD
);
833 special_fill_minus_pi (mpfr_t res0
, mpfr_t res1
, fp_format format
)
835 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
836 mpfr_const_pi (res0
, MPFR_RNDU
);
837 assert_exact (mpfr_neg (res0
, res0
, MPFR_RNDN
));
838 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
839 mpfr_const_pi (res1
, MPFR_RNDD
);
840 assert_exact (mpfr_neg (res1
, res1
, MPFR_RNDN
));
845 special_fill_pi_2 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
847 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
848 mpfr_const_pi (res0
, MPFR_RNDU
);
849 assert_exact (mpfr_div_ui (res0
, res0
, 2, MPFR_RNDN
));
850 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
851 mpfr_const_pi (res1
, MPFR_RNDD
);
852 assert_exact (mpfr_div_ui (res1
, res1
, 2, MPFR_RNDN
));
857 special_fill_minus_pi_2 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
859 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
860 mpfr_const_pi (res0
, MPFR_RNDU
);
861 assert_exact (mpfr_div_ui (res0
, res0
, 2, MPFR_RNDN
));
862 assert_exact (mpfr_neg (res0
, res0
, MPFR_RNDN
));
863 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
864 mpfr_const_pi (res1
, MPFR_RNDD
);
865 assert_exact (mpfr_div_ui (res1
, res1
, 2, MPFR_RNDN
));
866 assert_exact (mpfr_neg (res1
, res1
, MPFR_RNDN
));
871 special_fill_pi_4 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
873 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
874 assert_exact (mpfr_set_si (res0
, 1, MPFR_RNDN
));
875 mpfr_atan (res0
, res0
, MPFR_RNDU
);
876 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
877 assert_exact (mpfr_set_si (res1
, 1, MPFR_RNDN
));
878 mpfr_atan (res1
, res1
, MPFR_RNDD
);
883 special_fill_pi_6 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
885 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
886 assert_exact (mpfr_set_si_2exp (res0
, 1, -1, MPFR_RNDN
));
887 mpfr_asin (res0
, res0
, MPFR_RNDU
);
888 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
889 assert_exact (mpfr_set_si_2exp (res1
, 1, -1, MPFR_RNDN
));
890 mpfr_asin (res1
, res1
, MPFR_RNDD
);
895 special_fill_minus_pi_6 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
897 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
898 assert_exact (mpfr_set_si_2exp (res0
, -1, -1, MPFR_RNDN
));
899 mpfr_asin (res0
, res0
, MPFR_RNDU
);
900 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
901 assert_exact (mpfr_set_si_2exp (res1
, -1, -1, MPFR_RNDN
));
902 mpfr_asin (res1
, res1
, MPFR_RNDD
);
907 special_fill_pi_3 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
909 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
910 assert_exact (mpfr_set_si_2exp (res0
, 1, -1, MPFR_RNDN
));
911 mpfr_acos (res0
, res0
, MPFR_RNDU
);
912 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
913 assert_exact (mpfr_set_si_2exp (res1
, 1, -1, MPFR_RNDN
));
914 mpfr_acos (res1
, res1
, MPFR_RNDD
);
919 special_fill_2pi_3 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
921 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
922 assert_exact (mpfr_set_si_2exp (res0
, -1, -1, MPFR_RNDN
));
923 mpfr_acos (res0
, res0
, MPFR_RNDU
);
924 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
925 assert_exact (mpfr_set_si_2exp (res1
, -1, -1, MPFR_RNDN
));
926 mpfr_acos (res1
, res1
, MPFR_RNDD
);
931 special_fill_2pi (mpfr_t res0
, mpfr_t res1
, fp_format format
)
933 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
934 mpfr_const_pi (res0
, MPFR_RNDU
);
935 assert_exact (mpfr_mul_ui (res0
, res0
, 2, MPFR_RNDN
));
936 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
937 mpfr_const_pi (res1
, MPFR_RNDD
);
938 assert_exact (mpfr_mul_ui (res1
, res1
, 2, MPFR_RNDN
));
943 special_fill_e (mpfr_t res0
, mpfr_t res1
, fp_format format
)
945 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
946 assert_exact (mpfr_set_si (res0
, 1, MPFR_RNDN
));
947 mpfr_exp (res0
, res0
, MPFR_RNDU
);
948 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
949 assert_exact (mpfr_set_si (res1
, 1, MPFR_RNDN
));
950 mpfr_exp (res1
, res1
, MPFR_RNDD
);
955 special_fill_1_e (mpfr_t res0
, mpfr_t res1
, fp_format format
)
957 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
958 assert_exact (mpfr_set_si (res0
, -1, MPFR_RNDN
));
959 mpfr_exp (res0
, res0
, MPFR_RNDU
);
960 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
961 assert_exact (mpfr_set_si (res1
, -1, MPFR_RNDN
));
962 mpfr_exp (res1
, res1
, MPFR_RNDD
);
967 special_fill_e_minus_1 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
969 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
970 assert_exact (mpfr_set_si (res0
, 1, MPFR_RNDN
));
971 mpfr_expm1 (res0
, res0
, MPFR_RNDU
);
972 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
973 assert_exact (mpfr_set_si (res1
, 1, MPFR_RNDN
));
974 mpfr_expm1 (res1
, res1
, MPFR_RNDD
);
978 /* A special string accepted in input arguments. */
983 /* The function that interprets it for a given floating-point
984 format, filling in up to two mpfr_t values and returning the
985 number of values filled. */
986 size_t (*func
) (mpfr_t
, mpfr_t
, fp_format
);
987 } special_real_input
;
989 /* List of special strings accepted in input arguments. */
991 static const special_real_input special_real_inputs
[] =
993 { "max", special_fill_max
},
994 { "-max", special_fill_minus_max
},
995 { "min", special_fill_min
},
996 { "-min", special_fill_minus_min
},
997 { "min_subnorm", special_fill_min_subnorm
},
998 { "-min_subnorm", special_fill_minus_min_subnorm
},
999 { "min_subnorm_p120", special_fill_min_subnorm_p120
},
1000 { "pi", special_fill_pi
},
1001 { "-pi", special_fill_minus_pi
},
1002 { "pi/2", special_fill_pi_2
},
1003 { "-pi/2", special_fill_minus_pi_2
},
1004 { "pi/4", special_fill_pi_4
},
1005 { "pi/6", special_fill_pi_6
},
1006 { "-pi/6", special_fill_minus_pi_6
},
1007 { "pi/3", special_fill_pi_3
},
1008 { "2pi/3", special_fill_2pi_3
},
1009 { "2pi", special_fill_2pi
},
1010 { "e", special_fill_e
},
1011 { "1/e", special_fill_1_e
},
1012 { "e-1", special_fill_e_minus_1
},
1015 /* Given a real number R computed in round-to-zero mode, set the
1016 lowest bit as a sticky bit if INEXACT, and saturate the exponent
1017 range for very large or small values. */
1020 adjust_real (mpfr_t r
, bool inexact
)
1024 /* NaNs are exact, as are infinities in round-to-zero mode. */
1025 assert (mpfr_number_p (r
));
1026 if (mpfr_cmpabs (r
, global_min
) < 0)
1027 assert_exact (mpfr_copysign (r
, global_min
, r
, MPFR_RNDN
));
1028 else if (mpfr_cmpabs (r
, global_max
) > 0)
1029 assert_exact (mpfr_copysign (r
, global_max
, r
, MPFR_RNDN
));
1034 mpfr_exp_t e
= mpfr_get_z_2exp (tmp
, r
);
1035 if (mpz_sgn (tmp
) < 0)
1038 mpz_setbit (tmp
, 0);
1042 mpz_setbit (tmp
, 0);
1043 assert_exact (mpfr_set_z_2exp (r
, tmp
, e
, MPFR_RNDN
));
1048 /* Given a finite real number R with sticky bit, compute the roundings
1049 to FORMAT in each rounding mode, storing the results in RES, the
1050 before-rounding exceptions in EXC_BEFORE and the after-rounding
1051 exceptions in EXC_AFTER. */
1054 round_real (mpfr_t res
[rm_num_modes
],
1055 unsigned int exc_before
[rm_num_modes
],
1056 unsigned int exc_after
[rm_num_modes
],
1057 mpfr_t r
, fp_format format
)
1059 assert (mpfr_number_p (r
));
1060 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1062 mpfr_init2 (res
[m
], fp_formats
[format
].mant_dig
);
1063 exc_before
[m
] = exc_after
[m
] = 0;
1064 bool inexact
= mpfr_set (res
[m
], r
, rounding_modes
[m
].mpfr_mode
);
1065 if (mpfr_cmpabs (res
[m
], fp_formats
[format
].max
) > 0)
1068 exc_before
[m
] |= 1U << exc_overflow
;
1069 exc_after
[m
] |= 1U << exc_overflow
;
1074 overflow_inf
= true;
1077 overflow_inf
= false;
1080 overflow_inf
= mpfr_signbit (res
[m
]);
1083 overflow_inf
= !mpfr_signbit (res
[m
]);
1089 mpfr_set_inf (res
[m
], mpfr_signbit (res
[m
]) ? -1 : 1);
1091 assert_exact (mpfr_copysign (res
[m
], fp_formats
[format
].max
,
1092 res
[m
], MPFR_RNDN
));
1094 if (mpfr_cmpabs (r
, fp_formats
[format
].min
) < 0)
1096 /* Tiny before rounding; may or may not be tiny after
1097 rounding, and underflow applies only if also inexact
1098 around rounding to a possibly subnormal value. */
1099 bool tiny_after_rounding
1100 = mpfr_cmpabs (res
[m
], fp_formats
[format
].min
) < 0;
1101 /* To round to a possibly subnormal value, and determine
1102 inexactness as a subnormal in the process, scale up and
1103 round to integer, then scale back down. */
1106 assert_exact (mpfr_mul_2si (tmp
, r
, (fp_formats
[format
].mant_dig
1107 - fp_formats
[format
].min_exp
),
1109 int rint_res
= mpfr_rint (tmp
, tmp
, rounding_modes
[m
].mpfr_mode
);
1110 /* The integer must be representable. */
1111 assert (rint_res
== 0 || rint_res
== 2 || rint_res
== -2);
1112 /* If rounding to full precision was inexact, so must
1113 rounding to subnormal precision be inexact. */
1115 assert (rint_res
!= 0);
1117 inexact
= rint_res
!= 0;
1118 assert_exact (mpfr_mul_2si (res
[m
], tmp
,
1119 (fp_formats
[format
].min_exp
1120 - fp_formats
[format
].mant_dig
),
1125 exc_before
[m
] |= 1U << exc_underflow
;
1126 if (tiny_after_rounding
)
1127 exc_after
[m
] |= 1U << exc_underflow
;
1132 exc_before
[m
] |= 1U << exc_inexact
;
1133 exc_after
[m
] |= 1U << exc_inexact
;
1138 /* Handle the input argument at ARG (NUL-terminated), updating the
1139 lists of test inputs in IT accordingly. NUM_PREV_ARGS arguments
1140 are already in those lists. If EXACT_ARGS, interpret a value given
1141 as a floating-point constant exactly (it must be exact for some
1142 supported format) rather than rounding up and down. The argument,
1143 of type GTYPE, comes from file FILENAME, line LINENO. */
1146 handle_input_arg (const char *arg
, input_test
*it
, size_t num_prev_args
,
1147 generic_value_type gtype
, bool exact_args
,
1148 const char *filename
, unsigned int lineno
)
1150 size_t num_values
= 0;
1151 generic_value values
[2 * fp_num_formats
];
1152 bool check_empty_list
= false;
1156 for (fp_format f
= fp_first_format
; f
< fp_num_formats
; f
++)
1158 mpfr_t extra_values
[2];
1159 size_t num_extra_values
= 0;
1160 for (size_t i
= 0; i
< ARRAY_SIZE (special_real_inputs
); i
++)
1162 if (strcmp (arg
, special_real_inputs
[i
].str
) == 0)
1165 = special_real_inputs
[i
].func (extra_values
[0],
1166 extra_values
[1], f
);
1167 assert (num_extra_values
> 0
1168 && num_extra_values
<= ARRAY_SIZE (extra_values
));
1172 if (num_extra_values
== 0)
1177 check_empty_list
= true;
1179 bool inexact
= mpfr_strtofr (tmp
, arg
, &ep
, 0, MPFR_RNDZ
);
1180 if (*ep
!= 0 || !mpfr_number_p (tmp
))
1181 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1182 "bad floating-point argument: '%s'", arg
);
1183 adjust_real (tmp
, inexact
);
1184 mpfr_t rounded
[rm_num_modes
];
1185 unsigned int exc_before
[rm_num_modes
];
1186 unsigned int exc_after
[rm_num_modes
];
1187 round_real (rounded
, exc_before
, exc_after
, tmp
, f
);
1189 if (mpfr_number_p (rounded
[rm_upward
])
1190 && (!exact_args
|| mpfr_equal_p (rounded
[rm_upward
],
1191 rounded
[rm_downward
])))
1193 mpfr_init2 (extra_values
[num_extra_values
],
1194 fp_formats
[f
].mant_dig
);
1195 assert_exact (mpfr_set (extra_values
[num_extra_values
],
1196 rounded
[rm_upward
], MPFR_RNDN
));
1199 if (mpfr_number_p (rounded
[rm_downward
]) && !exact_args
)
1201 mpfr_init2 (extra_values
[num_extra_values
],
1202 fp_formats
[f
].mant_dig
);
1203 assert_exact (mpfr_set (extra_values
[num_extra_values
],
1204 rounded
[rm_downward
], MPFR_RNDN
));
1207 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1208 mpfr_clear (rounded
[m
]);
1210 for (size_t i
= 0; i
< num_extra_values
; i
++)
1213 for (size_t j
= 0; j
< num_values
; j
++)
1215 if (mpfr_equal_p (values
[j
].value
.f
, extra_values
[i
])
1216 && ((mpfr_signbit (values
[j
].value
.f
) != 0)
1217 == (mpfr_signbit (extra_values
[i
]) != 0)))
1225 assert (num_values
< ARRAY_SIZE (values
));
1226 values
[num_values
].type
= gtype_fp
;
1227 mpfr_init2 (values
[num_values
].value
.f
,
1228 fp_formats
[f
].mant_dig
);
1229 assert_exact (mpfr_set (values
[num_values
].value
.f
,
1230 extra_values
[i
], MPFR_RNDN
));
1233 mpfr_clear (extra_values
[i
]);
1240 values
[0].type
= gtype_int
;
1241 int ret
= mpz_init_set_str (values
[0].value
.i
, arg
, 0);
1243 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1244 "bad integer argument: '%s'", arg
);
1250 if (check_empty_list
&& num_values
== 0)
1251 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1252 "floating-point argument not exact for any format: '%s'",
1254 assert (num_values
> 0 && num_values
<= ARRAY_SIZE (values
));
1255 if (it
->num_input_cases
>= SIZE_MAX
/ num_values
)
1256 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
, "too many input cases");
1257 generic_value
**old_inputs
= it
->inputs
;
1258 size_t new_num_input_cases
= it
->num_input_cases
* num_values
;
1259 generic_value
**new_inputs
= xmalloc (new_num_input_cases
1260 * sizeof (new_inputs
[0]));
1261 for (size_t i
= 0; i
< it
->num_input_cases
; i
++)
1263 for (size_t j
= 0; j
< num_values
; j
++)
1265 size_t idx
= i
* num_values
+ j
;
1266 new_inputs
[idx
] = xmalloc ((num_prev_args
+ 1)
1267 * sizeof (new_inputs
[idx
][0]));
1268 for (size_t k
= 0; k
< num_prev_args
; k
++)
1269 generic_value_copy (&new_inputs
[idx
][k
], &old_inputs
[i
][k
]);
1270 generic_value_copy (&new_inputs
[idx
][num_prev_args
], &values
[j
]);
1272 for (size_t j
= 0; j
< num_prev_args
; j
++)
1273 generic_value_free (&old_inputs
[i
][j
]);
1274 free (old_inputs
[i
]);
1277 for (size_t i
= 0; i
< num_values
; i
++)
1278 generic_value_free (&values
[i
]);
1279 it
->inputs
= new_inputs
;
1280 it
->num_input_cases
= new_num_input_cases
;
1283 /* Handle the input flag ARG (NUL-terminated), storing it in *FLAG.
1284 The flag comes from file FILENAME, line LINENO. */
1287 handle_input_flag (char *arg
, input_flag
*flag
,
1288 const char *filename
, unsigned int lineno
)
1290 char *ep
= strchr (arg
, ':');
1293 ep
= strchr (arg
, 0);
1294 assert (ep
!= NULL
);
1299 for (input_flag_type i
= flag_first_flag
; i
<= num_input_flag_types
; i
++)
1301 if (strcmp (arg
, input_flags
[i
]) == 0)
1309 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
, "unknown flag: '%s'",
1315 flag
->cond
= xstrdup (ep
);
1318 /* Add the test LINE (file FILENAME, line LINENO) to the test
1322 add_test (char *line
, const char *filename
, unsigned int lineno
)
1324 size_t num_tokens
= 1;
1326 while ((p
= strchr (p
, ' ')) != NULL
)
1332 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1333 "line too short: '%s'", line
);
1334 p
= strchr (line
, ' ');
1335 size_t func_name_len
= p
- line
;
1336 for (size_t i
= 0; i
< ARRAY_SIZE (test_functions
); i
++)
1338 if (func_name_len
== strlen (test_functions
[i
].name
)
1339 && strncmp (line
, test_functions
[i
].name
, func_name_len
) == 0)
1341 test_function
*tf
= &test_functions
[i
];
1342 if (num_tokens
< 1 + tf
->num_args
)
1343 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1344 "line too short: '%s'", line
);
1345 if (tf
->num_tests
== tf
->num_tests_alloc
)
1347 tf
->num_tests_alloc
= 2 * tf
->num_tests_alloc
+ 16;
1349 = xrealloc (tf
->tests
,
1350 tf
->num_tests_alloc
* sizeof (tf
->tests
[0]));
1352 input_test
*it
= &tf
->tests
[tf
->num_tests
];
1354 it
->num_input_cases
= 1;
1355 it
->inputs
= xmalloc (sizeof (it
->inputs
[0]));
1356 it
->inputs
[0] = NULL
;
1357 it
->old_output
= NULL
;
1359 for (size_t j
= 0; j
< tf
->num_args
; j
++)
1361 char *ep
= strchr (p
, ' ');
1364 ep
= strchr (p
, '\n');
1365 assert (ep
!= NULL
);
1368 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1369 "empty token in line: '%s'", line
);
1370 for (char *t
= p
; t
< ep
; t
++)
1371 if (isspace ((unsigned char) *t
))
1372 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1373 "whitespace in token in line: '%s'", line
);
1376 handle_input_arg (p
, it
, j
,
1377 generic_arg_ret_type (tf
->arg_types
[j
]),
1378 tf
->exact_args
, filename
, lineno
);
1382 it
->num_flags
= num_tokens
- 1 - tf
->num_args
;
1383 it
->flags
= xmalloc (it
->num_flags
* sizeof (it
->flags
[0]));
1384 for (size_t j
= 0; j
< it
->num_flags
; j
++)
1386 char *ep
= strchr (p
, ' ');
1389 ep
= strchr (p
, '\n');
1390 assert (ep
!= NULL
);
1393 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1394 "empty token in line: '%s'", line
);
1395 for (char *t
= p
; t
< ep
; t
++)
1396 if (isspace ((unsigned char) *t
))
1397 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1398 "whitespace in token in line: '%s'", line
);
1401 handle_input_flag (p
, &it
->flags
[j
], filename
, lineno
);
1410 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1411 "unknown function in line: '%s'", line
);
1414 /* Read in the test input data from FILENAME. */
1417 read_input (const char *filename
)
1419 FILE *fp
= fopen (filename
, "r");
1421 error (EXIT_FAILURE
, errno
, "open '%s'", filename
);
1422 unsigned int lineno
= 0;
1427 ssize_t ret
= getline (&line
, &size
, fp
);
1431 if (line
[0] == '#' || line
[0] == '\n')
1433 add_test (line
, filename
, lineno
);
1436 error (EXIT_FAILURE
, errno
, "read from '%s'", filename
);
1437 if (fclose (fp
) != 0)
1438 error (EXIT_FAILURE
, errno
, "close '%s'", filename
);
1441 /* Calculate the generic results (round-to-zero with sticky bit) for
1442 the function described by CALC, with inputs INPUTS, if MODE is
1443 rm_towardzero; for other modes, calculate results in that mode,
1444 which must be exact zero results. */
1447 calc_generic_results (generic_value
*outputs
, generic_value
*inputs
,
1448 const func_calc_desc
*calc
, rounding_mode mode
)
1453 mpfr_rnd_t mode_mpfr
= rounding_modes
[mode
].mpfr_mode
;
1454 mpc_rnd_t mode_mpc
= rounding_modes
[mode
].mpc_mode
;
1456 switch (calc
->method
)
1459 assert (inputs
[0].type
== gtype_fp
);
1460 outputs
[0].type
= gtype_fp
;
1461 mpfr_init (outputs
[0].value
.f
);
1462 inexact
= calc
->func
.mpfr_f_f (outputs
[0].value
.f
, inputs
[0].value
.f
,
1464 if (mode
!= rm_towardzero
)
1465 assert (!inexact
&& mpfr_zero_p (outputs
[0].value
.f
));
1466 adjust_real (outputs
[0].value
.f
, inexact
);
1470 assert (inputs
[0].type
== gtype_fp
);
1471 assert (inputs
[1].type
== gtype_fp
);
1472 outputs
[0].type
= gtype_fp
;
1473 mpfr_init (outputs
[0].value
.f
);
1474 inexact
= calc
->func
.mpfr_ff_f (outputs
[0].value
.f
, inputs
[0].value
.f
,
1475 inputs
[1].value
.f
, mode_mpfr
);
1476 if (mode
!= rm_towardzero
)
1477 assert (!inexact
&& mpfr_zero_p (outputs
[0].value
.f
));
1478 adjust_real (outputs
[0].value
.f
, inexact
);
1482 assert (inputs
[0].type
== gtype_fp
);
1483 assert (inputs
[1].type
== gtype_fp
);
1484 assert (inputs
[2].type
== gtype_fp
);
1485 outputs
[0].type
= gtype_fp
;
1486 mpfr_init (outputs
[0].value
.f
);
1487 inexact
= calc
->func
.mpfr_fff_f (outputs
[0].value
.f
, inputs
[0].value
.f
,
1488 inputs
[1].value
.f
, inputs
[2].value
.f
,
1490 if (mode
!= rm_towardzero
)
1491 assert (!inexact
&& mpfr_zero_p (outputs
[0].value
.f
));
1492 adjust_real (outputs
[0].value
.f
, inexact
);
1496 assert (inputs
[0].type
== gtype_fp
);
1497 outputs
[0].type
= gtype_fp
;
1498 outputs
[1].type
= gtype_int
;
1499 mpfr_init (outputs
[0].value
.f
);
1501 inexact
= calc
->func
.mpfr_f_f1 (outputs
[0].value
.f
, &i
,
1502 inputs
[0].value
.f
, mode_mpfr
);
1503 if (mode
!= rm_towardzero
)
1504 assert (!inexact
&& mpfr_zero_p (outputs
[0].value
.f
));
1505 adjust_real (outputs
[0].value
.f
, inexact
);
1506 mpz_init_set_si (outputs
[1].value
.i
, i
);
1510 assert (inputs
[0].type
== gtype_int
);
1511 assert (inputs
[1].type
== gtype_fp
);
1512 outputs
[0].type
= gtype_fp
;
1513 mpfr_init (outputs
[0].value
.f
);
1514 assert (mpz_fits_slong_p (inputs
[0].value
.i
));
1515 long l
= mpz_get_si (inputs
[0].value
.i
);
1516 inexact
= calc
->func
.mpfr_if_f (outputs
[0].value
.f
, l
,
1517 inputs
[1].value
.f
, mode_mpfr
);
1518 if (mode
!= rm_towardzero
)
1519 assert (!inexact
&& mpfr_zero_p (outputs
[0].value
.f
));
1520 adjust_real (outputs
[0].value
.f
, inexact
);
1524 assert (inputs
[0].type
== gtype_fp
);
1525 outputs
[0].type
= gtype_fp
;
1526 mpfr_init (outputs
[0].value
.f
);
1527 outputs
[1].type
= gtype_fp
;
1528 mpfr_init (outputs
[1].value
.f
);
1529 int comb_ternary
= calc
->func
.mpfr_f_11 (outputs
[0].value
.f
,
1533 if (mode
!= rm_towardzero
)
1534 assert (((comb_ternary
& 0x3) == 0
1535 && mpfr_zero_p (outputs
[0].value
.f
))
1536 || ((comb_ternary
& 0xc) == 0
1537 && mpfr_zero_p (outputs
[1].value
.f
)));
1538 adjust_real (outputs
[0].value
.f
, (comb_ternary
& 0x3) != 0);
1539 adjust_real (outputs
[1].value
.f
, (comb_ternary
& 0xc) != 0);
1543 assert (inputs
[0].type
== gtype_fp
);
1544 assert (inputs
[1].type
== gtype_fp
);
1545 outputs
[0].type
= gtype_fp
;
1546 mpfr_init (outputs
[0].value
.f
);
1547 mpc_init2 (ci1
, internal_precision
);
1548 assert_exact (mpc_set_fr_fr (ci1
, inputs
[0].value
.f
, inputs
[1].value
.f
,
1550 inexact
= calc
->func
.mpc_c_f (outputs
[0].value
.f
, ci1
, mode_mpfr
);
1551 if (mode
!= rm_towardzero
)
1552 assert (!inexact
&& mpfr_zero_p (outputs
[0].value
.f
));
1553 adjust_real (outputs
[0].value
.f
, inexact
);
1558 assert (inputs
[0].type
== gtype_fp
);
1559 assert (inputs
[1].type
== gtype_fp
);
1560 outputs
[0].type
= gtype_fp
;
1561 mpfr_init (outputs
[0].value
.f
);
1562 outputs
[1].type
= gtype_fp
;
1563 mpfr_init (outputs
[1].value
.f
);
1564 mpc_init2 (ci1
, internal_precision
);
1565 mpc_init2 (co
, internal_precision
);
1566 assert_exact (mpc_set_fr_fr (ci1
, inputs
[0].value
.f
, inputs
[1].value
.f
,
1568 mpc_ternary
= calc
->func
.mpc_c_c (co
, ci1
, mode_mpc
);
1569 if (mode
!= rm_towardzero
)
1570 assert ((!MPC_INEX_RE (mpc_ternary
)
1571 && mpfr_zero_p (mpc_realref (co
)))
1572 || (!MPC_INEX_IM (mpc_ternary
)
1573 && mpfr_zero_p (mpc_imagref (co
))));
1574 assert_exact (mpfr_set (outputs
[0].value
.f
, mpc_realref (co
),
1576 assert_exact (mpfr_set (outputs
[1].value
.f
, mpc_imagref (co
),
1578 adjust_real (outputs
[0].value
.f
, MPC_INEX_RE (mpc_ternary
));
1579 adjust_real (outputs
[1].value
.f
, MPC_INEX_IM (mpc_ternary
));
1585 assert (inputs
[0].type
== gtype_fp
);
1586 assert (inputs
[1].type
== gtype_fp
);
1587 assert (inputs
[2].type
== gtype_fp
);
1588 assert (inputs
[3].type
== gtype_fp
);
1589 outputs
[0].type
= gtype_fp
;
1590 mpfr_init (outputs
[0].value
.f
);
1591 outputs
[1].type
= gtype_fp
;
1592 mpfr_init (outputs
[1].value
.f
);
1593 mpc_init2 (ci1
, internal_precision
);
1594 mpc_init2 (ci2
, internal_precision
);
1595 mpc_init2 (co
, internal_precision
);
1596 assert_exact (mpc_set_fr_fr (ci1
, inputs
[0].value
.f
, inputs
[1].value
.f
,
1598 assert_exact (mpc_set_fr_fr (ci2
, inputs
[2].value
.f
, inputs
[3].value
.f
,
1600 mpc_ternary
= calc
->func
.mpc_cc_c (co
, ci1
, ci2
, mode_mpc
);
1601 if (mode
!= rm_towardzero
)
1602 assert ((!MPC_INEX_RE (mpc_ternary
)
1603 && mpfr_zero_p (mpc_realref (co
)))
1604 || (!MPC_INEX_IM (mpc_ternary
)
1605 && mpfr_zero_p (mpc_imagref (co
))));
1606 assert_exact (mpfr_set (outputs
[0].value
.f
, mpc_realref (co
),
1608 assert_exact (mpfr_set (outputs
[1].value
.f
, mpc_imagref (co
),
1610 adjust_real (outputs
[0].value
.f
, MPC_INEX_RE (mpc_ternary
));
1611 adjust_real (outputs
[1].value
.f
, MPC_INEX_IM (mpc_ternary
));
1622 /* Return the number of bits for integer type TYPE, where "long" has
1623 LONG_BITS bits (32 or 64). */
1626 int_type_bits (arg_ret_type type
, int long_bits
)
1628 assert (long_bits
== 32 || long_bits
== 64);
1639 case type_long_long
:
1648 /* Check whether an integer Z fits a given type TYPE, where "long" has
1649 LONG_BITS bits (32 or 64). */
1652 int_fits_type (mpz_t z
, arg_ret_type type
, int long_bits
)
1654 int bits
= int_type_bits (type
, long_bits
);
1658 mpz_ui_pow_ui (t
, 2, bits
- 1);
1659 if (mpz_cmp (z
, t
) >= 0)
1662 if (mpz_cmp (z
, t
) < 0)
1668 /* Print a generic value V to FP (name FILENAME), preceded by a space,
1669 for type TYPE, LONG_BITS bits per long, printing " IGNORE" instead
1673 output_generic_value (FILE *fp
, const char *filename
, const generic_value
*v
,
1674 bool ignore
, arg_ret_type type
, int long_bits
)
1678 if (fputs (" IGNORE", fp
) < 0)
1679 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1682 assert (v
->type
== generic_arg_ret_type (type
));
1698 case type_long_long
:
1708 if (mpfr_inf_p (v
->value
.f
))
1710 if (fputs ((mpfr_signbit (v
->value
.f
)
1711 ? " minus_infty" : " plus_infty"), fp
) < 0)
1712 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1716 assert (mpfr_number_p (v
->value
.f
));
1717 if (mpfr_fprintf (fp
, " %Ra%s", v
->value
.f
, suffix
) < 0)
1718 error (EXIT_FAILURE
, errno
, "mpfr_fprintf to '%s'", filename
);
1723 int bits
= int_type_bits (type
, long_bits
);
1726 mpz_ui_pow_ui (tmp
, 2, bits
- 1);
1728 if (mpz_cmp (v
->value
.i
, tmp
) == 0)
1730 mpz_add_ui (tmp
, tmp
, 1);
1731 if (mpfr_fprintf (fp
, " (%Zd%s-1)", tmp
, suffix
) < 0)
1732 error (EXIT_FAILURE
, errno
, "mpfr_fprintf to '%s'", filename
);
1736 if (mpfr_fprintf (fp
, " %Zd%s", v
->value
.i
, suffix
) < 0)
1737 error (EXIT_FAILURE
, errno
, "mpfr_fprintf to '%s'", filename
);
1747 /* Generate test output to FP (name FILENAME) for test function TF
1748 (rounding results to a narrower type if NARROW), input test IT,
1749 choice of input values INPUTS. */
1752 output_for_one_input_case (FILE *fp
, const char *filename
, test_function
*tf
,
1753 bool narrow
, input_test
*it
, generic_value
*inputs
)
1755 bool long_bits_matters
= false;
1756 bool fits_long32
= true;
1757 for (size_t i
= 0; i
< tf
->num_args
; i
++)
1759 generic_value_type gtype
= generic_arg_ret_type (tf
->arg_types
[i
]);
1760 assert (inputs
[i
].type
== gtype
);
1761 if (gtype
== gtype_int
)
1763 bool fits_64
= int_fits_type (inputs
[i
].value
.i
, tf
->arg_types
[i
],
1767 if (tf
->arg_types
[i
] == type_long
1768 && !int_fits_type (inputs
[i
].value
.i
, tf
->arg_types
[i
], 32))
1770 long_bits_matters
= true;
1771 fits_long32
= false;
1775 generic_value generic_outputs
[MAX_NRET
];
1776 calc_generic_results (generic_outputs
, inputs
, &tf
->calc
, rm_towardzero
);
1777 bool ignore_output_long32
[MAX_NRET
] = { false };
1778 bool ignore_output_long64
[MAX_NRET
] = { false };
1779 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
1781 assert (generic_outputs
[i
].type
1782 == generic_arg_ret_type (tf
->ret_types
[i
]));
1783 switch (generic_outputs
[i
].type
)
1786 if (!mpfr_number_p (generic_outputs
[i
].value
.f
))
1787 goto out
; /* Result is NaN or exact infinity. */
1791 ignore_output_long32
[i
] = !int_fits_type (generic_outputs
[i
].value
.i
,
1792 tf
->ret_types
[i
], 32);
1793 ignore_output_long64
[i
] = !int_fits_type (generic_outputs
[i
].value
.i
,
1794 tf
->ret_types
[i
], 64);
1795 if (ignore_output_long32
[i
] != ignore_output_long64
[i
])
1796 long_bits_matters
= true;
1803 /* Iterate over relevant sizes of long and floating-point formats. */
1804 for (int long_bits
= 32; long_bits
<= 64; long_bits
+= 32)
1806 if (long_bits
== 32 && !fits_long32
)
1808 if (long_bits
== 64 && !long_bits_matters
)
1810 const char *long_cond
;
1811 if (long_bits_matters
)
1812 long_cond
= (long_bits
== 32 ? ":long32" : ":long64");
1815 bool *ignore_output
= (long_bits
== 32
1816 ? ignore_output_long32
1817 : ignore_output_long64
);
1818 for (fp_format f
= fp_first_format
; f
< fp_num_formats
; f
++)
1821 mpfr_t res
[rm_num_modes
];
1822 unsigned int exc_before
[rm_num_modes
];
1823 unsigned int exc_after
[rm_num_modes
];
1824 bool have_fp_arg
= false;
1829 for (size_t i
= 0; i
< tf
->num_args
; i
++)
1831 if (inputs
[i
].type
== gtype_fp
)
1835 if (mpfr_zero_p (inputs
[i
].value
.f
))
1837 assert (mpfr_regular_p (inputs
[i
].value
.f
));
1838 int this_exp
, this_num_ones
, this_min_exp
, this_prec
;
1841 mpfr_exp_t e
= mpfr_get_z_2exp (tmp
, inputs
[i
].value
.f
);
1842 if (mpz_sgn (tmp
) < 0)
1844 size_t bits
= mpz_sizeinbase (tmp
, 2);
1845 mp_bitcnt_t tz
= mpz_scan1 (tmp
, 0);
1846 this_min_exp
= e
+ tz
;
1847 this_prec
= bits
- tz
;
1848 assert (this_prec
> 0);
1849 this_exp
= this_min_exp
+ this_prec
- 1;
1851 == mpfr_get_exp (inputs
[i
].value
.f
) - 1);
1853 while ((size_t) this_num_ones
< bits
1854 && mpz_tstbit (tmp
, bits
- 1 - this_num_ones
))
1859 if (this_exp
> max_exp
1860 || (this_exp
== max_exp
1861 && this_num_ones
> num_ones
))
1864 num_ones
= this_num_ones
;
1866 if (this_min_exp
< min_exp
)
1867 min_exp
= this_min_exp
;
1868 if (this_prec
> max_prec
)
1869 max_prec
= this_prec
;
1874 num_ones
= this_num_ones
;
1875 min_exp
= this_min_exp
;
1876 max_prec
= this_prec
;
1882 round_real (res
, exc_before
, exc_after
,
1883 inputs
[i
].value
.f
, f
);
1884 if (!mpfr_equal_p (res
[rm_tonearest
], inputs
[i
].value
.f
))
1886 for (rounding_mode m
= rm_first_mode
;
1889 mpfr_clear (res
[m
]);
1897 /* The inputs fit this type if required to do so, so compute
1898 the ideal outputs and exceptions. */
1899 mpfr_t all_res
[MAX_NRET
][rm_num_modes
];
1900 unsigned int all_exc_before
[MAX_NRET
][rm_num_modes
];
1901 unsigned int all_exc_after
[MAX_NRET
][rm_num_modes
];
1902 unsigned int merged_exc_before
[rm_num_modes
] = { 0 };
1903 unsigned int merged_exc_after
[rm_num_modes
] = { 0 };
1904 /* For functions not exactly determined, track whether
1905 underflow is required (some result is inexact, and
1906 magnitude does not exceed the greatest magnitude
1907 subnormal), and permitted (not an exact zero, and
1908 magnitude does not exceed the least magnitude
1910 bool must_underflow
= false;
1911 bool may_underflow
= false;
1912 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
1914 switch (generic_outputs
[i
].type
)
1917 round_real (all_res
[i
], all_exc_before
[i
], all_exc_after
[i
],
1918 generic_outputs
[i
].value
.f
, f
);
1919 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1921 merged_exc_before
[m
] |= all_exc_before
[i
][m
];
1922 merged_exc_after
[m
] |= all_exc_after
[i
][m
];
1926 |= ((all_exc_before
[i
][m
]
1927 & (1U << exc_inexact
)) != 0
1928 && (mpfr_cmpabs (generic_outputs
[i
].value
.f
,
1929 fp_formats
[f
].subnorm_max
)
1932 |= (!mpfr_zero_p (generic_outputs
[i
].value
.f
)
1933 && (mpfr_cmpabs (generic_outputs
[i
].value
.f
,
1934 fp_formats
[f
].min_plus_half
)
1937 /* If the result is an exact zero, the sign may
1938 depend on the rounding mode, so recompute it
1939 directly in that mode. */
1940 if (mpfr_zero_p (all_res
[i
][m
])
1941 && (all_exc_before
[i
][m
] & (1U << exc_inexact
)) == 0)
1943 generic_value outputs_rm
[MAX_NRET
];
1944 calc_generic_results (outputs_rm
, inputs
,
1946 assert_exact (mpfr_set (all_res
[i
][m
],
1947 outputs_rm
[i
].value
.f
,
1949 for (size_t j
= 0; j
< tf
->num_ret
; j
++)
1950 generic_value_free (&outputs_rm
[j
]);
1956 if (ignore_output
[i
])
1957 for (rounding_mode m
= rm_first_mode
;
1961 merged_exc_before
[m
] |= 1U << exc_invalid
;
1962 merged_exc_after
[m
] |= 1U << exc_invalid
;
1970 assert (may_underflow
|| !must_underflow
);
1971 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1973 bool before_after_matters
1974 = tf
->exact
&& merged_exc_before
[m
] != merged_exc_after
[m
];
1975 if (before_after_matters
)
1977 assert ((merged_exc_before
[m
] ^ merged_exc_after
[m
])
1978 == (1U << exc_underflow
));
1979 assert ((merged_exc_before
[m
] & (1U << exc_underflow
)) != 0);
1981 unsigned int merged_exc
= merged_exc_before
[m
];
1984 if (fprintf (fp
, "= %s %s %s%s:arg_fmt(%d,%d,%d,%d)",
1985 tf
->name
, rounding_modes
[m
].name
,
1986 fp_formats
[f
].name
, long_cond
, max_exp
,
1987 num_ones
, min_exp
, max_prec
) < 0)
1988 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1992 if (fprintf (fp
, "= %s %s %s%s", tf
->name
,
1993 rounding_modes
[m
].name
, fp_formats
[f
].name
,
1995 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1998 for (size_t i
= 0; i
< tf
->num_args
; i
++)
1999 output_generic_value (fp
, filename
, &inputs
[i
], false,
2000 tf
->arg_types
[i
], long_bits
);
2001 if (fputs (" :", fp
) < 0)
2002 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
2003 /* Print outputs. */
2004 bool must_erange
= false;
2005 bool some_underflow_zero
= false;
2006 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
2009 g
.type
= generic_outputs
[i
].type
;
2013 if (mpfr_inf_p (all_res
[i
][m
])
2014 && (all_exc_before
[i
][m
]
2015 & (1U << exc_overflow
)) != 0)
2017 if (mpfr_zero_p (all_res
[i
][m
])
2019 || mpfr_zero_p (all_res
[i
][rm_tonearest
]))
2020 && (all_exc_before
[i
][m
]
2021 & (1U << exc_underflow
)) != 0)
2023 if (mpfr_zero_p (all_res
[i
][rm_towardzero
])
2024 && (all_exc_before
[i
][m
]
2025 & (1U << exc_underflow
)) != 0)
2026 some_underflow_zero
= true;
2027 mpfr_init2 (g
.value
.f
, fp_formats
[f
].mant_dig
);
2028 assert_exact (mpfr_set (g
.value
.f
, all_res
[i
][m
],
2033 mpz_init (g
.value
.i
);
2034 mpz_set (g
.value
.i
, generic_outputs
[i
].value
.i
);
2040 output_generic_value (fp
, filename
, &g
, ignore_output
[i
],
2041 tf
->ret_types
[i
], long_bits
);
2042 generic_value_free (&g
);
2044 if (fputs (" :", fp
) < 0)
2045 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
2046 /* Print miscellaneous flags (passed through from
2048 for (size_t i
= 0; i
< it
->num_flags
; i
++)
2049 switch (it
->flags
[i
].type
)
2051 case flag_no_test_inline
:
2052 case flag_ignore_zero_inf_sign
:
2054 if (fprintf (fp
, " %s%s",
2055 input_flags
[it
->flags
[i
].type
],
2059 error (EXIT_FAILURE
, errno
, "write to '%s'",
2062 case flag_xfail_rounding
:
2063 if (m
!= rm_tonearest
)
2064 if (fprintf (fp
, " xfail%s",
2068 error (EXIT_FAILURE
, errno
, "write to '%s'",
2074 /* For the ibm128 format, expect incorrect overflowing
2075 results in rounding modes other than to nearest;
2076 likewise incorrect results where the result may
2078 if (f
== fp_ldbl_128ibm
2079 && m
!= rm_tonearest
2080 && (some_underflow_zero
2081 || (merged_exc_before
[m
] & (1U << exc_overflow
)) != 0))
2082 if (fputs (" xfail:ibm128-libgcc", fp
) < 0)
2083 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
2084 /* Print exception flags and compute errno
2085 expectations where not already computed. */
2086 bool may_edom
= false;
2087 bool must_edom
= false;
2088 bool may_erange
= must_erange
|| may_underflow
;
2089 for (fp_exception e
= exc_first_exception
;
2090 e
< exc_num_exceptions
;
2093 bool expect_e
= (merged_exc
& (1U << e
)) != 0;
2094 bool e_optional
= false;
2099 may_erange
= must_erange
= true;
2109 may_edom
= must_edom
= true;
2122 if (may_underflow
&& !must_underflow
)
2131 assert (!before_after_matters
);
2132 if (fprintf (fp
, " %s-ok", exceptions
[e
]) < 0)
2133 error (EXIT_FAILURE
, errno
, "write to '%s'",
2139 if (fprintf (fp
, " %s", exceptions
[e
]) < 0)
2140 error (EXIT_FAILURE
, errno
, "write to '%s'",
2142 if (before_after_matters
&& e
== exc_underflow
)
2143 if (fputs (":before-rounding", fp
) < 0)
2144 error (EXIT_FAILURE
, errno
, "write to '%s'",
2146 for (int after
= 0; after
<= 1; after
++)
2148 bool expect_e_here
= expect_e
;
2149 if (after
== 1 && (!before_after_matters
2150 || e
!= exc_underflow
))
2152 const char *after_cond
;
2153 if (before_after_matters
&& e
== exc_underflow
)
2157 : ":before-rounding");
2158 expect_e_here
= !after
;
2162 input_flag_type okflag
;
2163 okflag
= (expect_e_here
2164 ? flag_missing_first
2165 : flag_spurious_first
) + e
;
2166 for (size_t i
= 0; i
< it
->num_flags
; i
++)
2167 if (it
->flags
[i
].type
== okflag
)
2168 if (fprintf (fp
, " %s-ok%s%s",
2172 : ""), after_cond
) < 0)
2173 error (EXIT_FAILURE
, errno
, "write to '%s'",
2178 /* Print errno expectations. */
2182 must_erange
= false;
2184 if (may_edom
&& !must_edom
)
2186 if (fputs (" errno-edom-ok", fp
) < 0)
2187 error (EXIT_FAILURE
, errno
, "write to '%s'",
2193 if (fputs (" errno-edom", fp
) < 0)
2194 error (EXIT_FAILURE
, errno
, "write to '%s'",
2196 input_flag_type okflag
= (must_edom
2197 ? flag_missing_errno
2198 : flag_spurious_errno
);
2199 for (size_t i
= 0; i
< it
->num_flags
; i
++)
2200 if (it
->flags
[i
].type
== okflag
)
2201 if (fprintf (fp
, " errno-edom-ok%s",
2205 error (EXIT_FAILURE
, errno
, "write to '%s'",
2208 if (before_after_matters
)
2209 assert (may_erange
&& !must_erange
);
2210 if (may_erange
&& !must_erange
)
2212 if (fprintf (fp
, " errno-erange-ok%s",
2213 (before_after_matters
2214 ? ":before-rounding"
2216 error (EXIT_FAILURE
, errno
, "write to '%s'",
2219 if (before_after_matters
|| !(may_erange
&& !must_erange
))
2222 if (fputs (" errno-erange", fp
) < 0)
2223 error (EXIT_FAILURE
, errno
, "write to '%s'",
2225 input_flag_type okflag
= (must_erange
2226 ? flag_missing_errno
2227 : flag_spurious_errno
);
2228 for (size_t i
= 0; i
< it
->num_flags
; i
++)
2229 if (it
->flags
[i
].type
== okflag
)
2230 if (fprintf (fp
, " errno-erange-ok%s%s",
2234 (before_after_matters
2237 error (EXIT_FAILURE
, errno
, "write to '%s'",
2240 if (putc ('\n', fp
) < 0)
2241 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
2243 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
2245 if (generic_outputs
[i
].type
== gtype_fp
)
2246 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
2247 mpfr_clear (all_res
[i
][m
]);
2252 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
2253 generic_value_free (&generic_outputs
[i
]);
2256 /* Generate test output data for FUNCTION to FILENAME. The function
2257 is interpreted as rounding its results to a narrower type if
2261 generate_output (const char *function
, bool narrow
, const char *filename
)
2263 FILE *fp
= fopen (filename
, "w");
2265 error (EXIT_FAILURE
, errno
, "open '%s'", filename
);
2266 for (size_t i
= 0; i
< ARRAY_SIZE (test_functions
); i
++)
2268 test_function
*tf
= &test_functions
[i
];
2269 if (strcmp (tf
->name
, function
) != 0)
2271 for (size_t j
= 0; j
< tf
->num_tests
; j
++)
2273 input_test
*it
= &tf
->tests
[j
];
2274 if (fputs (it
->line
, fp
) < 0)
2275 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
2276 for (size_t k
= 0; k
< it
->num_input_cases
; k
++)
2277 output_for_one_input_case (fp
, filename
, tf
, narrow
,
2281 if (fclose (fp
) != 0)
2282 error (EXIT_FAILURE
, errno
, "close '%s'", filename
);
2286 main (int argc
, char **argv
)
2289 && !(argc
== 5 && strcmp (argv
[1], "--narrow") == 0))
2290 error (EXIT_FAILURE
, 0,
2291 "usage: gen-auto-libm-tests [--narrow] <input> <func> <output>");
2293 const char *input_filename
= argv
[1];
2294 const char *function
= argv
[2];
2295 const char *output_filename
= argv
[3];
2299 input_filename
= argv
[1];
2301 output_filename
= argv
[3];
2306 input_filename
= argv
[2];
2308 output_filename
= argv
[4];
2311 read_input (input_filename
);
2312 generate_output (function
, narrow
, output_filename
);
2313 exit (EXIT_SUCCESS
);