1 /* Generate expected output for libm tests with MPFR and MPC.
2 Copyright (C) 2013 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
19 /* Compile this program as:
21 gcc -std=gnu99 -O2 -Wall -Wextra gen-auto-libm-tests.c -lmpc -lmpfr -lgmp \
22 -o gen-auto-libm-tests
24 (use of current MPC and MPFR versions recommended) and run it as:
26 gen-auto-libm-tests auto-libm-test-in auto-libm-test-out
28 The input file auto-libm-test-in contains three kinds of lines:
30 Lines beginning with "#" are comments, and are ignored, as are
33 Other lines are test lines, of the form "function input1 input2
34 ... [flag1 flag2 ...]". Inputs are either finite real numbers or
35 integers, depending on the function under test. Real numbers may
36 be in any form acceptable to mpfr_strtofr (base 0); integers in any
37 form acceptable to mpz_set_str (base 0). In addition, real numbers
38 may be certain special strings such as "pi", as listed in the
39 special_real_inputs array.
41 Each flag is a flag name possibly followed by a series of
42 ":condition". Conditions may be any of the names of floating-point
43 formats in the floating_point_formats array, "long32" and "long64"
44 to indicate the number of bits in the "long" type, or other strings
45 for which libm-test.inc defines a TEST_COND_<condition> macro (with
46 "-"- changed to "_" in the condition name) evaluating to nonzero
47 when the condition is true and zero when the condition is false.
48 The meaning is that the flag applies to the test if all the listed
49 conditions are true. "flag:cond1:cond2 flag:cond3:cond4" means the
50 flag applies if ((cond1 && cond2) || (cond3 && cond4)).
52 A real number specified as an input is considered to represent the
53 set of real numbers arising from rounding the given number in any
54 direction for any supported floating-point format; any roundings
55 that give infinity are ignored. Each input on a test line has all
56 the possible roundings considered independently. Each resulting
57 choice of the tuple of inputs to the function is ignored if the
58 mathematical result of the function involves a NaN or an exact
59 infinity, and is otherwise considered for each floating-point
60 format for which all those inputs are exactly representable. Thus
61 tests may result in "overflow", "underflow" and "inexact"
62 exceptions; "invalid" may arise only when the final result type is
63 an integer type and it is the conversion of a mathematically
64 defined finite result to integer type that results in that
67 By default, it is assumed that "overflow" and "underflow"
68 exceptions should be correct, but that "inexact" exceptions should
69 only be correct for functions listed as exactly determined. For
70 such functions, "underflow" exceptions should respect whether the
71 machine has before-rounding or after-rounding tininess detection.
72 For other functions, it is considered that if the exact result is
73 somewhere between the greatest magnitude subnormal of a given sign
74 (exclusive) and the least magnitude normal of that sign
75 (inclusive), underflow exceptions are permitted but optional on all
76 machines, and they are also permitted but optional for smaller
77 subnormal exact results for functions that are not exactly
78 determined. errno setting is expected for overflow to infinity and
79 underflow to zero (for real functions), and for out-of-range
80 conversion of a finite result to integer type, and is considered
81 permitted but optional for all other cases where overflow
82 exceptions occur, and where underflow exceptions occur or are
83 permitted. In other cases (where no overflow or underflow is
84 permitted), errno is expected to be left unchanged.
86 The flag "no-test-inline" indicates a test is disabled for inline
87 function testing; "xfail" indicates the test is disabled as
88 expected to produce incorrect results, "xfail-rounding" indicates
89 the test is disabled only in rounding modes other than
90 round-to-nearest. Otherwise, test flags are of the form
91 "spurious-<exception>" and "missing-<exception>", for any exception
92 ("overflow", "underflow", "inexact", "invalid", "divbyzero"),
93 "spurious-errno" and "missing-errno", to indicate when tests are
94 expected to deviate from the exception and errno settings
95 corresponding to the mathematical results. "xfail",
96 "xfail-rounding", "spurious-" and "missing-" flags should be
97 accompanied by a comment referring to an open bug in glibc
100 The output file auto-libm-test-out contains the test lines from
101 auto-libm-test-in, and, after the line for a given test, some
102 number of output test lines. An output test line is of the form "=
103 function rounding-mode format input1 input2 ... : output1 output2
104 ... : flags". rounding-mode is "tonearest", "towardzero", "upward"
105 or "downward". format is a name from the floating_point_formats
106 array, possibly followed by a sequence of ":flag" for flags from
107 "long32", "long64", "before-rounding" and "after-rounding" (the
108 last two indicating tests where expectations for underflow
109 exceptions depend on how the architecture detects tininess).
110 Inputs and outputs are specified as hex floats with the required
111 suffix for the floating-point type, or plus_infty or minus_infty
112 for infinite expected results, or as integer constant expressions
113 (not necessarily with the right type) or IGNORE for integer inputs
114 and outputs. Flags are "no-test-inline", "xfail", "<exception>",
115 "<exception>-ok", "errno-<value>", "errno-<value>-ok", where
116 "<exception>" and "errno-<value>" are unconditional, indicating
117 that a correct result means the given exception should be raised or
118 errno should be set to the given value, and other settings may be
119 conditional or unconditional; "-ok" means not to test for the given
120 exception or errno value (whether because it was marked as possibly
121 missing or spurious, or because the calculation of correct results
122 indicated it was optional). */
140 #define ARRAY_SIZE(A) (sizeof (A) / sizeof ((A)[0]))
142 /* The supported floating-point formats. */
155 /* Structure describing a single floating-point format. */
158 /* The name of the format. */
160 /* The suffix to use on floating-point constants with this
163 /* A string for the largest normal value, or NULL for IEEE formats
164 where this can be determined automatically. */
165 const char *max_string
;
166 /* The number of mantissa bits. */
168 /* The least N such that 2^N overflows. */
170 /* One more than the least N such that 2^N is normal. */
172 /* The largest normal value. */
174 /* The least positive normal value, 2^(MIN_EXP-1). */
176 /* The greatest positive subnormal value. */
178 /* The least positive subnormal value, 2^(MIN_EXP-MANT_DIG). */
182 /* List of floating-point formats, in the same order as the fp_format
184 static fp_format_desc fp_formats
[fp_num_formats
] =
186 { "flt-32", "f", NULL
, 24, 128, -125, {}, {}, {}, {} },
187 { "dbl-64", "", NULL
, 53, 1024, -1021, {}, {}, {}, {} },
188 { "ldbl-96-intel", "L", NULL
, 64, 16384, -16381, {}, {}, {}, {} },
189 { "ldbl-96-m68k", "L", NULL
, 64, 16384, -16382, {}, {}, {}, {} },
190 { "ldbl-128", "L", NULL
, 113, 16384, -16381, {}, {}, {}, {} },
191 { "ldbl-128ibm", "L", "0x1.fffffffffffff7ffffffffffff8p+1023",
192 106, 1024, -968, {}, {}, {}, {} },
195 /* The supported rounding modes. */
206 /* Structure describing a single rounding mode. */
209 /* The name of the rounding mode. */
211 /* The MPFR rounding mode. */
212 mpfr_rnd_t mpfr_mode
;
213 } rounding_mode_desc
;
215 /* List of rounding modes, in the same order as the rounding_mode
217 static const rounding_mode_desc rounding_modes
[rm_num_modes
] =
219 { "downward", MPFR_RNDD
},
220 { "tonearest", MPFR_RNDN
},
221 { "towardzero", MPFR_RNDZ
},
222 { "upward", MPFR_RNDU
},
225 /* The supported exceptions. */
234 exc_first_exception
= 0
237 /* List of exceptions, in the same order as the fp_exception
239 static const char *const exceptions
[exc_num_exceptions
] =
248 /* The internal precision to use for most MPFR calculations, which
249 must be at least 2 more than the greatest precision of any
250 supported floating-point format. */
251 static int internal_precision
;
253 /* A value that overflows all supported floating-point formats. */
254 static mpfr_t global_max
;
256 /* A value that is at most half the least subnormal in any
257 floating-point format and so is rounded the same way as all
258 sufficiently small positive values. */
259 static mpfr_t global_min
;
261 /* The maximum number of (real or integer) arguments to a function
262 handled by this program (complex arguments count as two real
266 /* The maximum number of (real or integer) return values from a
267 function handled by this program. */
270 /* A type of a function argument or return value. */
273 /* No type (not a valid argument or return value). */
275 /* A floating-point value with the type corresponding to that of
278 /* An integer value of type int. */
280 /* An integer value of type long. */
282 /* An integer value of type long long. */
286 /* A type of a generic real or integer value. */
291 /* Floating-point (represented with MPFR). */
293 /* Integer (represented with GMP). */
295 } generic_value_type
;
297 /* A generic value (argument or result). */
300 /* The type of this value. */
301 generic_value_type type
;
310 /* A type of input flag. */
316 /* The "spurious" and "missing" flags must be in the same order as
317 the fp_exception enumeration. */
318 flag_spurious_divbyzero
,
319 flag_spurious_inexact
,
320 flag_spurious_invalid
,
321 flag_spurious_overflow
,
322 flag_spurious_underflow
,
324 flag_missing_divbyzero
,
325 flag_missing_inexact
,
326 flag_missing_invalid
,
327 flag_missing_overflow
,
328 flag_missing_underflow
,
330 num_input_flag_types
,
332 flag_spurious_first
= flag_spurious_divbyzero
,
333 flag_missing_first
= flag_missing_divbyzero
336 /* List of flags, in the same order as the input_flag_type
338 static const char *const input_flags
[num_input_flag_types
] =
343 "spurious-divbyzero",
347 "spurious-underflow",
357 /* An input flag, possibly conditional. */
360 /* The type of this flag. */
361 input_flag_type type
;
362 /* The conditions on this flag, as a string ":cond1:cond2..." or
367 /* Structure describing a single test from the input file (which may
368 expand into many tests in the output). The choice of function,
369 which implies the numbers and types of arguments and results, is
370 implicit rather than stored in this structure (except as part of
374 /* The text of the input line describing the test, including the
377 /* The number of combinations of interpretations of input values for
378 different floating-point formats and rounding modes. */
379 size_t num_input_cases
;
380 /* The corresponding lists of inputs. */
381 generic_value
**inputs
;
382 /* The number of flags for this test. */
384 /* The corresponding list of flags. */
386 /* The old output for this test. */
387 const char *old_output
;
390 /* Ways to calculate a function. */
393 /* MPFR function with a single argument and result. */
395 /* MPFR function with two arguments and one result. */
397 /* MPFR function with a single argument and floating-point and
400 /* MPFR function with integer and floating-point arguments and one
403 /* MPFR function with a single argument and two floating-point
406 /* MPC function with a single complex argument and one real
409 /* MPC function with a single complex argument and one complex
412 /* MPC function with two complex arguments and one complex
417 /* Description of how to calculate a function. */
420 /* Which method is used to calculate the function. */
421 func_calc_method method
;
422 /* The specific function called. */
425 int (*mpfr_f_f
) (mpfr_t
, const mpfr_t
, mpfr_rnd_t
);
426 int (*mpfr_ff_f
) (mpfr_t
, const mpfr_t
, const mpfr_t
, mpfr_rnd_t
);
427 int (*mpfr_f_f1
) (mpfr_t
, int *, const mpfr_t
, mpfr_rnd_t
);
428 int (*mpfr_if_f
) (mpfr_t
, long, const mpfr_t
, mpfr_rnd_t
);
429 int (*mpfr_f_11
) (mpfr_t
, mpfr_t
, const mpfr_t
, mpfr_rnd_t
);
430 int (*mpc_c_f
) (mpfr_t
, const mpc_t
, mpfr_rnd_t
);
431 int (*mpc_c_c
) (mpc_t
, const mpc_t
, mpc_rnd_t
);
432 int (*mpc_cc_c
) (mpc_t
, const mpc_t
, const mpc_t
, mpc_rnd_t
);
436 /* Structure describing a function handled by this program. */
439 /* The name of the function. */
441 /* The number of arguments. */
443 /* The types of the arguments. */
444 arg_ret_type arg_types
[MAX_NARGS
];
445 /* The number of return values. */
447 /* The types of the return values. */
448 arg_ret_type ret_types
[MAX_NRET
];
449 /* Whether the function has exactly determined results and
452 /* Whether the function is a complex function, so errno setting is
455 /* How to calculate this function. */
457 /* The number of tests allocated for this function. */
458 size_t num_tests_alloc
;
459 /* The number of tests for this function. */
461 /* The tests themselves. */
465 #define ARGS1(T1) 1, { T1 }
466 #define ARGS2(T1, T2) 2, { T1, T2 }
467 #define ARGS3(T1, T2, T3) 3, { T1, T2, T3 }
468 #define ARGS4(T1, T2, T3, T4) 4, { T1, T2, T3, T4 }
469 #define RET1(T1) 1, { T1 }
470 #define RET2(T1, T2) 2, { T1, T2 }
471 #define CALC(TYPE, FN) { TYPE, { .TYPE = FN } }
472 #define FUNC(NAME, ARGS, RET, EXACT, COMPLEX_FN, CALC) \
474 NAME, ARGS, RET, EXACT, COMPLEX_FN, CALC, 0, 0, NULL \
477 #define FUNC_mpfr_f_f(NAME, MPFR_FUNC, EXACT) \
478 FUNC (NAME, ARGS1 (type_fp), RET1 (type_fp), EXACT, false, \
479 CALC (mpfr_f_f, MPFR_FUNC))
480 #define FUNC_mpfr_ff_f(NAME, MPFR_FUNC, EXACT) \
481 FUNC (NAME, ARGS2 (type_fp, type_fp), RET1 (type_fp), EXACT, false, \
482 CALC (mpfr_ff_f, MPFR_FUNC))
483 #define FUNC_mpfr_if_f(NAME, MPFR_FUNC, EXACT) \
484 FUNC (NAME, ARGS2 (type_int, type_fp), RET1 (type_fp), EXACT, false, \
485 CALC (mpfr_if_f, MPFR_FUNC))
486 #define FUNC_mpc_c_f(NAME, MPFR_FUNC, EXACT) \
487 FUNC (NAME, ARGS2 (type_fp, type_fp), RET1 (type_fp), EXACT, true, \
488 CALC (mpc_c_f, MPFR_FUNC))
489 #define FUNC_mpc_c_c(NAME, MPFR_FUNC, EXACT) \
490 FUNC (NAME, ARGS2 (type_fp, type_fp), RET2 (type_fp, type_fp), EXACT, \
491 true, CALC (mpc_c_c, MPFR_FUNC))
493 /* List of functions handled by this program. */
494 static test_function test_functions
[] =
496 FUNC_mpfr_f_f ("acos", mpfr_acos
, false),
497 FUNC_mpfr_f_f ("acosh", mpfr_acosh
, false),
498 FUNC_mpfr_f_f ("asin", mpfr_asin
, false),
499 FUNC_mpfr_f_f ("asinh", mpfr_asinh
, false),
500 FUNC_mpfr_f_f ("atan", mpfr_atan
, false),
501 FUNC_mpfr_ff_f ("atan2", mpfr_atan2
, false),
502 FUNC_mpfr_f_f ("atanh", mpfr_atanh
, false),
503 FUNC_mpc_c_f ("cabs", mpc_abs
, false),
504 FUNC_mpc_c_c ("cacos", mpc_acos
, false),
505 FUNC_mpc_c_c ("cacosh", mpc_acosh
, false),
506 FUNC_mpc_c_f ("carg", mpc_arg
, false),
507 FUNC_mpc_c_c ("casin", mpc_asin
, false),
508 FUNC_mpc_c_c ("casinh", mpc_asinh
, false),
509 FUNC_mpc_c_c ("catan", mpc_atan
, false),
510 FUNC_mpc_c_c ("catanh", mpc_atanh
, false),
511 FUNC_mpfr_f_f ("cbrt", mpfr_cbrt
, false),
512 FUNC_mpc_c_c ("ccos", mpc_cos
, false),
513 FUNC_mpc_c_c ("ccosh", mpc_cosh
, false),
514 FUNC_mpc_c_c ("cexp", mpc_exp
, false),
515 FUNC_mpc_c_c ("clog", mpc_log
, false),
516 FUNC_mpc_c_c ("clog10", mpc_log10
, false),
517 FUNC_mpfr_f_f ("cos", mpfr_cos
, false),
518 FUNC_mpfr_f_f ("cosh", mpfr_cosh
, false),
519 FUNC ("cpow", ARGS4 (type_fp
, type_fp
, type_fp
, type_fp
),
520 RET2 (type_fp
, type_fp
), false, true, CALC (mpc_cc_c
, mpc_pow
)),
521 FUNC_mpc_c_c ("csin", mpc_sin
, false),
522 FUNC_mpc_c_c ("csinh", mpc_sinh
, false),
523 FUNC_mpc_c_c ("csqrt", mpc_sqrt
, false),
524 FUNC_mpc_c_c ("ctan", mpc_tan
, false),
525 FUNC_mpc_c_c ("ctanh", mpc_tanh
, false),
526 FUNC_mpfr_f_f ("erf", mpfr_erf
, false),
527 FUNC_mpfr_f_f ("erfc", mpfr_erfc
, false),
528 FUNC_mpfr_f_f ("exp", mpfr_exp
, false),
529 FUNC_mpfr_f_f ("exp10", mpfr_exp10
, false),
530 FUNC_mpfr_f_f ("exp2", mpfr_exp2
, false),
531 FUNC_mpfr_f_f ("expm1", mpfr_expm1
, false),
532 FUNC_mpfr_ff_f ("hypot", mpfr_hypot
, false),
533 FUNC_mpfr_f_f ("j0", mpfr_j0
, false),
534 FUNC_mpfr_f_f ("j1", mpfr_j1
, false),
535 FUNC_mpfr_if_f ("jn", mpfr_jn
, false),
536 FUNC ("lgamma", ARGS1 (type_fp
), RET2 (type_fp
, type_int
), false, false,
537 CALC (mpfr_f_f1
, mpfr_lgamma
)),
538 FUNC_mpfr_f_f ("log", mpfr_log
, false),
539 FUNC_mpfr_f_f ("log10", mpfr_log10
, false),
540 FUNC_mpfr_f_f ("log1p", mpfr_log1p
, false),
541 FUNC_mpfr_f_f ("log2", mpfr_log2
, false),
542 FUNC_mpfr_ff_f ("pow", mpfr_pow
, false),
543 FUNC_mpfr_f_f ("sin", mpfr_sin
, false),
544 FUNC ("sincos", ARGS1 (type_fp
), RET2 (type_fp
, type_fp
), false, false,
545 CALC (mpfr_f_11
, mpfr_sin_cos
)),
546 FUNC_mpfr_f_f ("sinh", mpfr_sinh
, false),
547 FUNC_mpfr_f_f ("sqrt", mpfr_sqrt
, true),
548 FUNC_mpfr_f_f ("tan", mpfr_tan
, false),
549 FUNC_mpfr_f_f ("tanh", mpfr_tanh
, false),
550 FUNC_mpfr_f_f ("tgamma", mpfr_gamma
, false),
551 FUNC_mpfr_f_f ("y0", mpfr_y0
, false),
552 FUNC_mpfr_f_f ("y1", mpfr_y1
, false),
553 FUNC_mpfr_if_f ("yn", mpfr_yn
, false),
556 /* Allocate memory, with error checking. */
561 void *p
= malloc (n
);
563 error (EXIT_FAILURE
, errno
, "xmalloc failed");
568 xrealloc (void *p
, size_t n
)
572 error (EXIT_FAILURE
, errno
, "xrealloc failed");
577 xstrdup (const char *s
)
579 char *p
= strdup (s
);
581 error (EXIT_FAILURE
, errno
, "xstrdup failed");
585 /* Assert that the result of an MPFR operation was exact; that is,
586 that the returned ternary value was 0. */
594 /* Return the generic type of an argument or return value type T. */
596 static generic_value_type
597 generic_arg_ret_type (arg_ret_type t
)
614 /* Free a generic_value *V. */
617 generic_value_free (generic_value
*v
)
622 mpfr_clear (v
->value
.f
);
626 mpz_clear (v
->value
.i
);
634 /* Copy a generic_value *SRC to *DEST. */
637 generic_value_copy (generic_value
*dest
, const generic_value
*src
)
639 dest
->type
= src
->type
;
643 mpfr_init (dest
->value
.f
);
644 assert_exact (mpfr_set (dest
->value
.f
, src
->value
.f
, MPFR_RNDN
));
648 mpz_init (dest
->value
.i
);
649 mpz_set (dest
->value
.i
, src
->value
.i
);
657 /* Initialize data for floating-point formats. */
662 int global_max_exp
= 0, global_min_subnorm_exp
= 0;
663 for (fp_format f
= fp_first_format
; f
< fp_num_formats
; f
++)
665 if (fp_formats
[f
].mant_dig
+ 2 > internal_precision
)
666 internal_precision
= fp_formats
[f
].mant_dig
+ 2;
667 if (fp_formats
[f
].max_exp
> global_max_exp
)
668 global_max_exp
= fp_formats
[f
].max_exp
;
669 int min_subnorm_exp
= fp_formats
[f
].min_exp
- fp_formats
[f
].mant_dig
;
670 if (min_subnorm_exp
< global_min_subnorm_exp
)
671 global_min_subnorm_exp
= min_subnorm_exp
;
672 mpfr_init2 (fp_formats
[f
].max
, fp_formats
[f
].mant_dig
);
673 if (fp_formats
[f
].max_string
!= NULL
)
676 assert_exact (mpfr_strtofr (fp_formats
[f
].max
,
677 fp_formats
[f
].max_string
,
683 assert_exact (mpfr_set_ui_2exp (fp_formats
[f
].max
, 1,
684 fp_formats
[f
].max_exp
,
686 mpfr_nextbelow (fp_formats
[f
].max
);
688 mpfr_init2 (fp_formats
[f
].min
, fp_formats
[f
].mant_dig
);
689 assert_exact (mpfr_set_ui_2exp (fp_formats
[f
].min
, 1,
690 fp_formats
[f
].min_exp
- 1,
692 mpfr_init2 (fp_formats
[f
].subnorm_max
, fp_formats
[f
].mant_dig
);
693 assert_exact (mpfr_set (fp_formats
[f
].subnorm_max
, fp_formats
[f
].min
,
695 mpfr_nextbelow (fp_formats
[f
].subnorm_max
);
696 mpfr_nextbelow (fp_formats
[f
].subnorm_max
);
697 mpfr_init2 (fp_formats
[f
].subnorm_min
, fp_formats
[f
].mant_dig
);
698 assert_exact (mpfr_set_ui_2exp (fp_formats
[f
].subnorm_min
, 1,
699 min_subnorm_exp
, MPFR_RNDN
));
701 mpfr_set_default_prec (internal_precision
);
702 mpfr_init (global_max
);
703 assert_exact (mpfr_set_ui_2exp (global_max
, 1, global_max_exp
, MPFR_RNDN
));
704 mpfr_init (global_min
);
705 assert_exact (mpfr_set_ui_2exp (global_min
, 1, global_min_subnorm_exp
- 1,
709 /* Fill in mpfr_t values for special strings in input arguments. */
712 special_fill_max (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
715 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
716 assert_exact (mpfr_set (res0
, fp_formats
[format
].max
, MPFR_RNDN
));
721 special_fill_minus_max (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
724 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
725 assert_exact (mpfr_neg (res0
, fp_formats
[format
].max
, MPFR_RNDN
));
730 special_fill_min (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
733 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
734 assert_exact (mpfr_set (res0
, fp_formats
[format
].min
, MPFR_RNDN
));
739 special_fill_minus_min (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
742 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
743 assert_exact (mpfr_neg (res0
, fp_formats
[format
].min
, MPFR_RNDN
));
748 special_fill_min_subnorm (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
751 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
752 assert_exact (mpfr_set (res0
, fp_formats
[format
].subnorm_min
, MPFR_RNDN
));
757 special_fill_minus_min_subnorm (mpfr_t res0
,
758 mpfr_t res1
__attribute__ ((unused
)),
761 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
762 assert_exact (mpfr_neg (res0
, fp_formats
[format
].subnorm_min
, MPFR_RNDN
));
767 special_fill_min_subnorm_p120 (mpfr_t res0
,
768 mpfr_t res1
__attribute__ ((unused
)),
771 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
772 assert_exact (mpfr_mul_2ui (res0
, fp_formats
[format
].subnorm_min
,
778 special_fill_pi (mpfr_t res0
, mpfr_t res1
, fp_format format
)
780 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
781 mpfr_const_pi (res0
, MPFR_RNDU
);
782 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
783 mpfr_const_pi (res1
, MPFR_RNDD
);
788 special_fill_minus_pi (mpfr_t res0
, mpfr_t res1
, fp_format format
)
790 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
791 mpfr_const_pi (res0
, MPFR_RNDU
);
792 assert_exact (mpfr_neg (res0
, res0
, MPFR_RNDN
));
793 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
794 mpfr_const_pi (res1
, MPFR_RNDD
);
795 assert_exact (mpfr_neg (res1
, res1
, MPFR_RNDN
));
800 special_fill_pi_2 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
802 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
803 mpfr_const_pi (res0
, MPFR_RNDU
);
804 assert_exact (mpfr_div_ui (res0
, res0
, 2, MPFR_RNDN
));
805 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
806 mpfr_const_pi (res1
, MPFR_RNDD
);
807 assert_exact (mpfr_div_ui (res1
, res1
, 2, MPFR_RNDN
));
812 special_fill_minus_pi_2 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
814 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
815 mpfr_const_pi (res0
, MPFR_RNDU
);
816 assert_exact (mpfr_div_ui (res0
, res0
, 2, MPFR_RNDN
));
817 assert_exact (mpfr_neg (res0
, res0
, MPFR_RNDN
));
818 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
819 mpfr_const_pi (res1
, MPFR_RNDD
);
820 assert_exact (mpfr_div_ui (res1
, res1
, 2, MPFR_RNDN
));
821 assert_exact (mpfr_neg (res1
, res1
, MPFR_RNDN
));
826 special_fill_pi_4 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
828 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
829 assert_exact (mpfr_set_si (res0
, 1, MPFR_RNDN
));
830 mpfr_atan (res0
, res0
, MPFR_RNDU
);
831 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
832 assert_exact (mpfr_set_si (res1
, 1, MPFR_RNDN
));
833 mpfr_atan (res1
, res1
, MPFR_RNDD
);
838 special_fill_pi_6 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
840 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
841 assert_exact (mpfr_set_si_2exp (res0
, 1, -1, MPFR_RNDN
));
842 mpfr_asin (res0
, res0
, MPFR_RNDU
);
843 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
844 assert_exact (mpfr_set_si_2exp (res1
, 1, -1, MPFR_RNDN
));
845 mpfr_asin (res1
, res1
, MPFR_RNDD
);
850 special_fill_minus_pi_6 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
852 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
853 assert_exact (mpfr_set_si_2exp (res0
, -1, -1, MPFR_RNDN
));
854 mpfr_asin (res0
, res0
, MPFR_RNDU
);
855 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
856 assert_exact (mpfr_set_si_2exp (res1
, -1, -1, MPFR_RNDN
));
857 mpfr_asin (res1
, res1
, MPFR_RNDD
);
862 special_fill_pi_3 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
864 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
865 assert_exact (mpfr_set_si_2exp (res0
, 1, -1, MPFR_RNDN
));
866 mpfr_acos (res0
, res0
, MPFR_RNDU
);
867 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
868 assert_exact (mpfr_set_si_2exp (res1
, 1, -1, MPFR_RNDN
));
869 mpfr_acos (res1
, res1
, MPFR_RNDD
);
874 special_fill_2pi_3 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
876 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
877 assert_exact (mpfr_set_si_2exp (res0
, -1, -1, MPFR_RNDN
));
878 mpfr_acos (res0
, res0
, MPFR_RNDU
);
879 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
880 assert_exact (mpfr_set_si_2exp (res1
, -1, -1, MPFR_RNDN
));
881 mpfr_acos (res1
, res1
, MPFR_RNDD
);
886 special_fill_2pi (mpfr_t res0
, mpfr_t res1
, fp_format format
)
888 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
889 mpfr_const_pi (res0
, MPFR_RNDU
);
890 assert_exact (mpfr_mul_ui (res0
, res0
, 2, MPFR_RNDN
));
891 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
892 mpfr_const_pi (res1
, MPFR_RNDD
);
893 assert_exact (mpfr_mul_ui (res1
, res1
, 2, MPFR_RNDN
));
898 special_fill_e (mpfr_t res0
, mpfr_t res1
, fp_format format
)
900 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
901 assert_exact (mpfr_set_si (res0
, 1, MPFR_RNDN
));
902 mpfr_exp (res0
, res0
, MPFR_RNDU
);
903 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
904 assert_exact (mpfr_set_si (res1
, 1, MPFR_RNDN
));
905 mpfr_exp (res1
, res1
, MPFR_RNDD
);
910 special_fill_1_e (mpfr_t res0
, mpfr_t res1
, fp_format format
)
912 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
913 assert_exact (mpfr_set_si (res0
, -1, MPFR_RNDN
));
914 mpfr_exp (res0
, res0
, MPFR_RNDU
);
915 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
916 assert_exact (mpfr_set_si (res1
, -1, MPFR_RNDN
));
917 mpfr_exp (res1
, res1
, MPFR_RNDD
);
922 special_fill_e_minus_1 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
924 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
925 assert_exact (mpfr_set_si (res0
, 1, MPFR_RNDN
));
926 mpfr_expm1 (res0
, res0
, MPFR_RNDU
);
927 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
928 assert_exact (mpfr_set_si (res1
, 1, MPFR_RNDN
));
929 mpfr_expm1 (res1
, res1
, MPFR_RNDD
);
933 /* A special string accepted in input arguments. */
938 /* The function that interprets it for a given floating-point
939 format, filling in up to two mpfr_t values and returning the
940 number of values filled. */
941 size_t (*func
) (mpfr_t
, mpfr_t
, fp_format
);
942 } special_real_input
;
944 /* List of special strings accepted in input arguments. */
946 static const special_real_input special_real_inputs
[] =
948 { "max", special_fill_max
},
949 { "-max", special_fill_minus_max
},
950 { "min", special_fill_min
},
951 { "-min", special_fill_minus_min
},
952 { "min_subnorm", special_fill_min_subnorm
},
953 { "-min_subnorm", special_fill_minus_min_subnorm
},
954 { "min_subnorm_p120", special_fill_min_subnorm_p120
},
955 { "pi", special_fill_pi
},
956 { "-pi", special_fill_minus_pi
},
957 { "pi/2", special_fill_pi_2
},
958 { "-pi/2", special_fill_minus_pi_2
},
959 { "pi/4", special_fill_pi_4
},
960 { "pi/6", special_fill_pi_6
},
961 { "-pi/6", special_fill_minus_pi_6
},
962 { "pi/3", special_fill_pi_3
},
963 { "2pi/3", special_fill_2pi_3
},
964 { "2pi", special_fill_2pi
},
965 { "e", special_fill_e
},
966 { "1/e", special_fill_1_e
},
967 { "e-1", special_fill_e_minus_1
},
970 /* Given a real number R computed in round-to-zero mode, set the
971 lowest bit as a sticky bit if INEXACT, and saturate the exponent
972 range for very large or small values. */
975 adjust_real (mpfr_t r
, bool inexact
)
979 /* NaNs are exact, as are infinities in round-to-zero mode. */
980 assert (mpfr_number_p (r
));
981 if (mpfr_cmpabs (r
, global_min
) < 0)
982 assert_exact (mpfr_copysign (r
, global_min
, r
, MPFR_RNDN
));
983 else if (mpfr_cmpabs (r
, global_max
) > 0)
984 assert_exact (mpfr_copysign (r
, global_max
, r
, MPFR_RNDN
));
989 mpfr_exp_t e
= mpfr_get_z_2exp (tmp
, r
);
991 assert_exact (mpfr_set_z_2exp (r
, tmp
, e
, MPFR_RNDN
));
996 /* Given a finite real number R with sticky bit, compute the roundings
997 to FORMAT in each rounding mode, storing the results in RES, the
998 before-rounding exceptions in EXC_BEFORE and the after-rounding
999 exceptions in EXC_AFTER. */
1002 round_real (mpfr_t res
[rm_num_modes
],
1003 unsigned int exc_before
[rm_num_modes
],
1004 unsigned int exc_after
[rm_num_modes
],
1005 mpfr_t r
, fp_format format
)
1007 assert (mpfr_number_p (r
));
1008 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1010 mpfr_init2 (res
[m
], fp_formats
[format
].mant_dig
);
1011 exc_before
[m
] = exc_after
[m
] = 0;
1012 bool inexact
= mpfr_set (res
[m
], r
, rounding_modes
[m
].mpfr_mode
);
1013 if (mpfr_cmpabs (res
[m
], fp_formats
[format
].max
) > 0)
1016 exc_before
[m
] |= 1U << exc_overflow
;
1017 exc_after
[m
] |= 1U << exc_overflow
;
1022 overflow_inf
= true;
1025 overflow_inf
= false;
1028 overflow_inf
= mpfr_signbit (res
[m
]);
1031 overflow_inf
= !mpfr_signbit (res
[m
]);
1037 mpfr_set_inf (res
[m
], mpfr_signbit (res
[m
]) ? -1 : 1);
1039 assert_exact (mpfr_copysign (res
[m
], fp_formats
[format
].max
,
1040 res
[m
], MPFR_RNDN
));
1042 if (mpfr_cmpabs (r
, fp_formats
[format
].min
) < 0)
1044 /* Tiny before rounding; may or may not be tiny after
1045 rounding, and underflow applies only if also inexact
1046 around rounding to a possibly subnormal value. */
1047 bool tiny_after_rounding
1048 = mpfr_cmpabs (res
[m
], fp_formats
[format
].min
) < 0;
1049 /* To round to a possibly subnormal value, and determine
1050 inexactness as a subnormal in the process, scale up and
1051 round to integer, then scale back down. */
1054 assert_exact (mpfr_mul_2si (tmp
, r
, (fp_formats
[format
].mant_dig
1055 - fp_formats
[format
].min_exp
),
1057 int rint_res
= mpfr_rint (tmp
, tmp
, rounding_modes
[m
].mpfr_mode
);
1058 /* The integer must be representable. */
1059 assert (rint_res
== 0 || rint_res
== 2 || rint_res
== -2);
1060 /* If rounding to full precision was inexact, so must
1061 rounding to subnormal precision be inexact. */
1063 assert (rint_res
!= 0);
1065 inexact
= rint_res
!= 0;
1066 assert_exact (mpfr_mul_2si (res
[m
], tmp
,
1067 (fp_formats
[format
].min_exp
1068 - fp_formats
[format
].mant_dig
),
1073 exc_before
[m
] |= 1U << exc_underflow
;
1074 if (tiny_after_rounding
)
1075 exc_after
[m
] |= 1U << exc_underflow
;
1080 exc_before
[m
] |= 1U << exc_inexact
;
1081 exc_after
[m
] |= 1U << exc_inexact
;
1086 /* Handle the input argument at ARG (NUL-terminated), updating the
1087 lists of test inputs in IT accordingly. NUM_PREV_ARGS arguments
1088 are already in those lists. The argument, of type GTYPE, comes
1089 from file FILENAME, line LINENO. */
1092 handle_input_arg (const char *arg
, input_test
*it
, size_t num_prev_args
,
1093 generic_value_type gtype
,
1094 const char *filename
, unsigned int lineno
)
1096 size_t num_values
= 0;
1097 generic_value values
[2 * fp_num_formats
];
1101 for (fp_format f
= fp_first_format
; f
< fp_num_formats
; f
++)
1103 mpfr_t extra_values
[2];
1104 size_t num_extra_values
= 0;
1105 for (size_t i
= 0; i
< ARRAY_SIZE (special_real_inputs
); i
++)
1107 if (strcmp (arg
, special_real_inputs
[i
].str
) == 0)
1110 = special_real_inputs
[i
].func (extra_values
[0],
1111 extra_values
[1], f
);
1112 assert (num_extra_values
> 0
1113 && num_extra_values
<= ARRAY_SIZE (extra_values
));
1117 if (num_extra_values
== 0)
1122 bool inexact
= mpfr_strtofr (tmp
, arg
, &ep
, 0, MPFR_RNDZ
);
1123 if (*ep
!= 0 || !mpfr_number_p (tmp
))
1124 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1125 "bad floating-point argument: '%s'", arg
);
1126 adjust_real (tmp
, inexact
);
1127 mpfr_t rounded
[rm_num_modes
];
1128 unsigned int exc_before
[rm_num_modes
];
1129 unsigned int exc_after
[rm_num_modes
];
1130 round_real (rounded
, exc_before
, exc_after
, tmp
, f
);
1132 if (mpfr_number_p (rounded
[rm_upward
]))
1134 mpfr_init2 (extra_values
[num_extra_values
],
1135 fp_formats
[f
].mant_dig
);
1136 assert_exact (mpfr_set (extra_values
[num_extra_values
],
1137 rounded
[rm_upward
], MPFR_RNDN
));
1140 if (mpfr_number_p (rounded
[rm_downward
]))
1142 mpfr_init2 (extra_values
[num_extra_values
],
1143 fp_formats
[f
].mant_dig
);
1144 assert_exact (mpfr_set (extra_values
[num_extra_values
],
1145 rounded
[rm_downward
], MPFR_RNDN
));
1148 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1149 mpfr_clear (rounded
[m
]);
1151 for (size_t i
= 0; i
< num_extra_values
; i
++)
1154 for (size_t j
= 0; j
< num_values
; j
++)
1156 if (mpfr_equal_p (values
[j
].value
.f
, extra_values
[i
])
1157 && ((mpfr_signbit (values
[j
].value
.f
) != 0)
1158 == (mpfr_signbit (extra_values
[i
]) != 0)))
1166 assert (num_values
< ARRAY_SIZE (values
));
1167 values
[num_values
].type
= gtype_fp
;
1168 mpfr_init2 (values
[num_values
].value
.f
,
1169 fp_formats
[f
].mant_dig
);
1170 assert_exact (mpfr_set (values
[num_values
].value
.f
,
1171 extra_values
[i
], MPFR_RNDN
));
1174 mpfr_clear (extra_values
[i
]);
1181 values
[0].type
= gtype_int
;
1182 int ret
= mpz_init_set_str (values
[0].value
.i
, arg
, 0);
1184 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1185 "bad integer argument: '%s'", arg
);
1191 assert (num_values
> 0 && num_values
<= ARRAY_SIZE (values
));
1192 if (it
->num_input_cases
>= SIZE_MAX
/ num_values
)
1193 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
, "too many input cases");
1194 generic_value
**old_inputs
= it
->inputs
;
1195 size_t new_num_input_cases
= it
->num_input_cases
* num_values
;
1196 generic_value
**new_inputs
= xmalloc (new_num_input_cases
1197 * sizeof (new_inputs
[0]));
1198 for (size_t i
= 0; i
< it
->num_input_cases
; i
++)
1200 for (size_t j
= 0; j
< num_values
; j
++)
1202 size_t idx
= i
* num_values
+ j
;
1203 new_inputs
[idx
] = xmalloc ((num_prev_args
+ 1)
1204 * sizeof (new_inputs
[idx
][0]));
1205 for (size_t k
= 0; k
< num_prev_args
; k
++)
1206 generic_value_copy (&new_inputs
[idx
][k
], &old_inputs
[i
][k
]);
1207 generic_value_copy (&new_inputs
[idx
][num_prev_args
], &values
[j
]);
1209 for (size_t j
= 0; j
< num_prev_args
; j
++)
1210 generic_value_free (&old_inputs
[i
][j
]);
1211 free (old_inputs
[i
]);
1214 for (size_t i
= 0; i
< num_values
; i
++)
1215 generic_value_free (&values
[i
]);
1216 it
->inputs
= new_inputs
;
1217 it
->num_input_cases
= new_num_input_cases
;
1220 /* Handle the input flag ARG (NUL-terminated), storing it in *FLAG.
1221 The flag comes from file FILENAME, line LINENO. */
1224 handle_input_flag (char *arg
, input_flag
*flag
,
1225 const char *filename
, unsigned int lineno
)
1227 char *ep
= strchr (arg
, ':');
1230 ep
= strchr (arg
, 0);
1231 assert (ep
!= NULL
);
1236 for (input_flag_type i
= flag_first_flag
; i
<= num_input_flag_types
; i
++)
1238 if (strcmp (arg
, input_flags
[i
]) == 0)
1246 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
, "unknown flag: '%s'",
1252 flag
->cond
= xstrdup (ep
);
1255 /* Add the test LINE (file FILENAME, line LINENO) to the test
1259 add_test (char *line
, const char *filename
, unsigned int lineno
)
1261 size_t num_tokens
= 1;
1263 while ((p
= strchr (p
, ' ')) != NULL
)
1269 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1270 "line too short: '%s'", line
);
1271 p
= strchr (line
, ' ');
1272 size_t func_name_len
= p
- line
;
1273 for (size_t i
= 0; i
< ARRAY_SIZE (test_functions
); i
++)
1275 if (func_name_len
== strlen (test_functions
[i
].name
)
1276 && strncmp (line
, test_functions
[i
].name
, func_name_len
) == 0)
1278 test_function
*tf
= &test_functions
[i
];
1279 if (num_tokens
< 1 + tf
->num_args
)
1280 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1281 "line too short: '%s'", line
);
1282 if (tf
->num_tests
== tf
->num_tests_alloc
)
1284 tf
->num_tests_alloc
= 2 * tf
->num_tests_alloc
+ 16;
1286 = xrealloc (tf
->tests
,
1287 tf
->num_tests_alloc
* sizeof (tf
->tests
[0]));
1289 input_test
*it
= &tf
->tests
[tf
->num_tests
];
1291 it
->num_input_cases
= 1;
1292 it
->inputs
= xmalloc (sizeof (it
->inputs
[0]));
1293 it
->inputs
[0] = NULL
;
1294 it
->old_output
= NULL
;
1296 for (size_t j
= 0; j
< tf
->num_args
; j
++)
1298 char *ep
= strchr (p
, ' ');
1301 ep
= strchr (p
, '\n');
1302 assert (ep
!= NULL
);
1305 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1306 "empty token in line: '%s'", line
);
1307 for (char *t
= p
; t
< ep
; t
++)
1308 if (isspace ((unsigned char) *t
))
1309 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1310 "whitespace in token in line: '%s'", line
);
1313 handle_input_arg (p
, it
, j
,
1314 generic_arg_ret_type (tf
->arg_types
[j
]),
1319 it
->num_flags
= num_tokens
- 1 - tf
->num_args
;
1320 it
->flags
= xmalloc (it
->num_flags
* sizeof (it
->flags
[0]));
1321 for (size_t j
= 0; j
< it
->num_flags
; j
++)
1323 char *ep
= strchr (p
, ' ');
1326 ep
= strchr (p
, '\n');
1327 assert (ep
!= NULL
);
1330 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1331 "empty token in line: '%s'", line
);
1332 for (char *t
= p
; t
< ep
; t
++)
1333 if (isspace ((unsigned char) *t
))
1334 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1335 "whitespace in token in line: '%s'", line
);
1338 handle_input_flag (p
, &it
->flags
[j
], filename
, lineno
);
1347 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1348 "unknown function in line: '%s'", line
);
1351 /* Read in the test input data from FILENAME. */
1354 read_input (const char *filename
)
1356 FILE *fp
= fopen (filename
, "r");
1358 error (EXIT_FAILURE
, errno
, "open '%s'", filename
);
1359 unsigned int lineno
= 0;
1364 ssize_t ret
= getline (&line
, &size
, fp
);
1368 if (line
[0] == '#' || line
[0] == '\n')
1370 add_test (line
, filename
, lineno
);
1373 error (EXIT_FAILURE
, errno
, "read from '%s'", filename
);
1374 if (fclose (fp
) != 0)
1375 error (EXIT_FAILURE
, errno
, "close '%s'", filename
);
1378 /* Calculate the generic results (round-to-zero with sticky bit) for
1379 the function described by CALC, with inputs INPUTS. */
1382 calc_generic_results (generic_value
*outputs
, generic_value
*inputs
,
1383 const func_calc_desc
*calc
)
1389 switch (calc
->method
)
1392 assert (inputs
[0].type
== gtype_fp
);
1393 outputs
[0].type
= gtype_fp
;
1394 mpfr_init (outputs
[0].value
.f
);
1395 inexact
= calc
->func
.mpfr_f_f (outputs
[0].value
.f
, inputs
[0].value
.f
,
1397 adjust_real (outputs
[0].value
.f
, inexact
);
1401 assert (inputs
[0].type
== gtype_fp
);
1402 assert (inputs
[1].type
== gtype_fp
);
1403 outputs
[0].type
= gtype_fp
;
1404 mpfr_init (outputs
[0].value
.f
);
1405 inexact
= calc
->func
.mpfr_ff_f (outputs
[0].value
.f
, inputs
[0].value
.f
,
1406 inputs
[1].value
.f
, MPFR_RNDZ
);
1407 adjust_real (outputs
[0].value
.f
, inexact
);
1411 assert (inputs
[0].type
== gtype_fp
);
1412 outputs
[0].type
= gtype_fp
;
1413 outputs
[1].type
= gtype_int
;
1414 mpfr_init (outputs
[0].value
.f
);
1416 inexact
= calc
->func
.mpfr_f_f1 (outputs
[0].value
.f
, &i
,
1417 inputs
[0].value
.f
, MPFR_RNDZ
);
1418 adjust_real (outputs
[0].value
.f
, inexact
);
1419 mpz_init_set_si (outputs
[1].value
.i
, i
);
1423 assert (inputs
[0].type
== gtype_int
);
1424 assert (inputs
[1].type
== gtype_fp
);
1425 outputs
[0].type
= gtype_fp
;
1426 mpfr_init (outputs
[0].value
.f
);
1427 assert (mpz_fits_slong_p (inputs
[0].value
.i
));
1428 long l
= mpz_get_si (inputs
[0].value
.i
);
1429 inexact
= calc
->func
.mpfr_if_f (outputs
[0].value
.f
, l
,
1430 inputs
[1].value
.f
, MPFR_RNDZ
);
1431 adjust_real (outputs
[0].value
.f
, inexact
);
1435 assert (inputs
[0].type
== gtype_fp
);
1436 outputs
[0].type
= gtype_fp
;
1437 mpfr_init (outputs
[0].value
.f
);
1438 outputs
[1].type
= gtype_fp
;
1439 mpfr_init (outputs
[1].value
.f
);
1440 int comb_ternary
= calc
->func
.mpfr_f_11 (outputs
[0].value
.f
,
1444 adjust_real (outputs
[0].value
.f
, (comb_ternary
& 0x3) != 0);
1445 adjust_real (outputs
[1].value
.f
, (comb_ternary
& 0xc) != 0);
1449 assert (inputs
[0].type
== gtype_fp
);
1450 assert (inputs
[1].type
== gtype_fp
);
1451 outputs
[0].type
= gtype_fp
;
1452 mpfr_init (outputs
[0].value
.f
);
1453 mpc_init2 (ci1
, internal_precision
);
1454 assert_exact (mpc_set_fr_fr (ci1
, inputs
[0].value
.f
, inputs
[1].value
.f
,
1456 inexact
= calc
->func
.mpc_c_f (outputs
[0].value
.f
, ci1
, MPFR_RNDZ
);
1457 adjust_real (outputs
[0].value
.f
, inexact
);
1462 assert (inputs
[0].type
== gtype_fp
);
1463 assert (inputs
[1].type
== gtype_fp
);
1464 outputs
[0].type
= gtype_fp
;
1465 mpfr_init (outputs
[0].value
.f
);
1466 outputs
[1].type
= gtype_fp
;
1467 mpfr_init (outputs
[1].value
.f
);
1468 mpc_init2 (ci1
, internal_precision
);
1469 mpc_init2 (co
, internal_precision
);
1470 assert_exact (mpc_set_fr_fr (ci1
, inputs
[0].value
.f
, inputs
[1].value
.f
,
1472 mpc_ternary
= calc
->func
.mpc_c_c (co
, ci1
, MPC_RNDZZ
);
1473 assert_exact (mpfr_set (outputs
[0].value
.f
, mpc_realref (co
),
1475 assert_exact (mpfr_set (outputs
[1].value
.f
, mpc_imagref (co
),
1477 adjust_real (outputs
[0].value
.f
, MPC_INEX_RE (mpc_ternary
));
1478 adjust_real (outputs
[1].value
.f
, MPC_INEX_IM (mpc_ternary
));
1484 assert (inputs
[0].type
== gtype_fp
);
1485 assert (inputs
[1].type
== gtype_fp
);
1486 assert (inputs
[2].type
== gtype_fp
);
1487 assert (inputs
[3].type
== gtype_fp
);
1488 outputs
[0].type
= gtype_fp
;
1489 mpfr_init (outputs
[0].value
.f
);
1490 outputs
[1].type
= gtype_fp
;
1491 mpfr_init (outputs
[1].value
.f
);
1492 mpc_init2 (ci1
, internal_precision
);
1493 mpc_init2 (ci2
, internal_precision
);
1494 mpc_init2 (co
, internal_precision
);
1495 assert_exact (mpc_set_fr_fr (ci1
, inputs
[0].value
.f
, inputs
[1].value
.f
,
1497 assert_exact (mpc_set_fr_fr (ci2
, inputs
[2].value
.f
, inputs
[3].value
.f
,
1499 mpc_ternary
= calc
->func
.mpc_cc_c (co
, ci1
, ci2
, MPC_RNDZZ
);
1500 assert_exact (mpfr_set (outputs
[0].value
.f
, mpc_realref (co
),
1502 assert_exact (mpfr_set (outputs
[1].value
.f
, mpc_imagref (co
),
1504 adjust_real (outputs
[0].value
.f
, MPC_INEX_RE (mpc_ternary
));
1505 adjust_real (outputs
[1].value
.f
, MPC_INEX_IM (mpc_ternary
));
1516 /* Return the number of bits for integer type TYPE, where "long" has
1517 LONG_BITS bits (32 or 64). */
1520 int_type_bits (arg_ret_type type
, int long_bits
)
1522 assert (long_bits
== 32 || long_bits
== 64);
1533 case type_long_long
:
1542 /* Check whether an integer Z fits a given type TYPE, where "long" has
1543 LONG_BITS bits (32 or 64). */
1546 int_fits_type (mpz_t z
, arg_ret_type type
, int long_bits
)
1548 int bits
= int_type_bits (type
, long_bits
);
1552 mpz_ui_pow_ui (t
, 2, bits
- 1);
1553 if (mpz_cmp (z
, t
) >= 0)
1556 if (mpz_cmp (z
, t
) < 0)
1562 /* Print a generic value V to FP (name FILENAME), preceded by a space,
1563 for type TYPE, floating-point format FORMAT, LONG_BITS bits per
1564 long, printing " IGNORE" instead if IGNORE. */
1567 output_generic_value (FILE *fp
, const char *filename
, const generic_value
*v
,
1568 bool ignore
, arg_ret_type type
, fp_format format
,
1573 if (fputs (" IGNORE", fp
) < 0)
1574 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1577 assert (v
->type
== generic_arg_ret_type (type
));
1582 suffix
= fp_formats
[format
].suffix
;
1593 case type_long_long
:
1603 if (mpfr_inf_p (v
->value
.f
))
1605 if (fputs ((mpfr_signbit (v
->value
.f
)
1606 ? " minus_infty" : " plus_infty"), fp
) < 0)
1607 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1611 assert (mpfr_number_p (v
->value
.f
));
1612 if (mpfr_fprintf (fp
, " %Ra%s", v
->value
.f
, suffix
) < 0)
1613 error (EXIT_FAILURE
, errno
, "mpfr_fprintf to '%s'", filename
);
1618 int bits
= int_type_bits (type
, long_bits
);
1621 mpz_ui_pow_ui (tmp
, 2, bits
- 1);
1623 if (mpz_cmp (v
->value
.i
, tmp
) == 0)
1625 mpz_add_ui (tmp
, tmp
, 1);
1626 if (mpfr_fprintf (fp
, " (%Zd%s-1)", tmp
, suffix
) < 0)
1627 error (EXIT_FAILURE
, errno
, "mpfr_fprintf to '%s'", filename
);
1631 if (mpfr_fprintf (fp
, " %Zd%s", v
->value
.i
, suffix
) < 0)
1632 error (EXIT_FAILURE
, errno
, "mpfr_fprintf to '%s'", filename
);
1642 /* Generate test output to FP (name FILENAME) for test function TF,
1643 input test IT, choice of input values INPUTS. */
1646 output_for_one_input_case (FILE *fp
, const char *filename
, test_function
*tf
,
1647 input_test
*it
, generic_value
*inputs
)
1649 bool long_bits_matters
= false;
1650 bool fits_long32
= true;
1651 for (size_t i
= 0; i
< tf
->num_args
; i
++)
1653 generic_value_type gtype
= generic_arg_ret_type (tf
->arg_types
[i
]);
1654 assert (inputs
[i
].type
== gtype
);
1655 if (gtype
== gtype_int
)
1657 bool fits_64
= int_fits_type (inputs
[i
].value
.i
, tf
->arg_types
[i
],
1661 if (tf
->arg_types
[i
] == type_long
1662 && !int_fits_type (inputs
[i
].value
.i
, tf
->arg_types
[i
], 32))
1664 long_bits_matters
= true;
1665 fits_long32
= false;
1669 generic_value generic_outputs
[MAX_NRET
];
1670 calc_generic_results (generic_outputs
, inputs
, &tf
->calc
);
1671 bool ignore_output_long32
[MAX_NRET
] = { false };
1672 bool ignore_output_long64
[MAX_NRET
] = { false };
1673 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
1675 assert (generic_outputs
[i
].type
1676 == generic_arg_ret_type (tf
->ret_types
[i
]));
1677 switch (generic_outputs
[i
].type
)
1680 if (!mpfr_number_p (generic_outputs
[i
].value
.f
))
1681 goto out
; /* Result is NaN or exact infinity. */
1685 ignore_output_long32
[i
] = !int_fits_type (generic_outputs
[i
].value
.i
,
1686 tf
->ret_types
[i
], 32);
1687 ignore_output_long64
[i
] = !int_fits_type (generic_outputs
[i
].value
.i
,
1688 tf
->ret_types
[i
], 64);
1689 if (ignore_output_long32
[i
] != ignore_output_long64
[i
])
1690 long_bits_matters
= true;
1697 /* Iterate over relevant sizes of long and floating-point formats. */
1698 for (int long_bits
= 32; long_bits
<= 64; long_bits
+= 32)
1700 if (long_bits
== 32 && !fits_long32
)
1702 if (long_bits
== 64 && !long_bits_matters
)
1704 const char *long_cond
;
1705 if (long_bits_matters
)
1706 long_cond
= (long_bits
== 32 ? ":long32" : ":long64");
1709 bool *ignore_output
= (long_bits
== 32
1710 ? ignore_output_long32
1711 : ignore_output_long64
);
1712 for (fp_format f
= fp_first_format
; f
< fp_num_formats
; f
++)
1715 mpfr_t res
[rm_num_modes
];
1716 unsigned int exc_before
[rm_num_modes
];
1717 unsigned int exc_after
[rm_num_modes
];
1718 for (size_t i
= 0; i
< tf
->num_args
; i
++)
1720 if (inputs
[i
].type
== gtype_fp
)
1722 round_real (res
, exc_before
, exc_after
, inputs
[i
].value
.f
,
1724 if (!mpfr_equal_p (res
[rm_tonearest
], inputs
[i
].value
.f
))
1726 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1727 mpfr_clear (res
[m
]);
1734 /* The inputs fit this type, so compute the ideal outputs
1736 mpfr_t all_res
[MAX_NRET
][rm_num_modes
];
1737 unsigned int all_exc_before
[MAX_NRET
][rm_num_modes
];
1738 unsigned int all_exc_after
[MAX_NRET
][rm_num_modes
];
1739 unsigned int merged_exc_before
[rm_num_modes
] = { 0 };
1740 unsigned int merged_exc_after
[rm_num_modes
] = { 0 };
1741 /* For functions not exactly determined, track whether
1742 underflow is required (some result is inexact, and
1743 magnitude does not exceed the greatest magnitude
1744 subnormal), and permitted (not an exact zero, and
1745 magnitude does not exceed the least magnitude
1747 bool must_underflow
= false;
1748 bool may_underflow
= false;
1749 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
1751 switch (generic_outputs
[i
].type
)
1754 round_real (all_res
[i
], all_exc_before
[i
], all_exc_after
[i
],
1755 generic_outputs
[i
].value
.f
, f
);
1756 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1758 merged_exc_before
[m
] |= all_exc_before
[i
][m
];
1759 merged_exc_after
[m
] |= all_exc_after
[i
][m
];
1763 |= ((all_exc_before
[i
][m
]
1764 & (1U << exc_inexact
)) != 0
1765 && (mpfr_cmpabs (generic_outputs
[i
].value
.f
,
1766 fp_formats
[f
].subnorm_max
)
1769 |= (!mpfr_zero_p (generic_outputs
[i
].value
.f
)
1770 && mpfr_cmpabs (generic_outputs
[i
].value
.f
,
1771 fp_formats
[f
].min
) <= 0);
1777 if (ignore_output
[i
])
1778 for (rounding_mode m
= rm_first_mode
;
1782 merged_exc_before
[m
] |= 1U << exc_invalid
;
1783 merged_exc_after
[m
] |= 1U << exc_invalid
;
1791 assert (may_underflow
|| !must_underflow
);
1792 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1794 bool before_after_matters
1795 = tf
->exact
&& merged_exc_before
[m
] != merged_exc_after
[m
];
1796 for (int after
= 0; after
<= 1; after
++)
1798 if (after
== 1 && !before_after_matters
)
1800 const char *after_cond
;
1801 if (before_after_matters
)
1804 : ":before-rounding");
1807 unsigned int merged_exc
= (after
1808 ? merged_exc_after
[m
]
1809 : merged_exc_before
[m
]);
1810 if (fprintf (fp
, "= %s %s %s%s%s", tf
->name
,
1811 rounding_modes
[m
].name
, fp_formats
[f
].name
,
1812 long_cond
, after_cond
) < 0)
1813 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1815 for (size_t i
= 0; i
< tf
->num_args
; i
++)
1816 output_generic_value (fp
, filename
, &inputs
[i
], false,
1817 tf
->arg_types
[i
], f
, long_bits
);
1818 if (fputs (" :", fp
) < 0)
1819 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1820 /* Print outputs. */
1821 bool must_erange
= false;
1822 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
1825 g
.type
= generic_outputs
[i
].type
;
1829 if (mpfr_inf_p (all_res
[i
][m
])
1830 && (all_exc_before
[i
][m
]
1831 & (1U << exc_overflow
)) != 0)
1833 if (mpfr_zero_p (all_res
[i
][m
])
1835 || mpfr_zero_p (all_res
[i
][rm_tonearest
]))
1836 && (all_exc_before
[i
][m
]
1837 & (1U << exc_underflow
)) != 0)
1839 mpfr_init2 (g
.value
.f
, fp_formats
[f
].mant_dig
);
1840 assert_exact (mpfr_set (g
.value
.f
, all_res
[i
][m
],
1845 mpz_init (g
.value
.i
);
1846 mpz_set (g
.value
.i
, generic_outputs
[i
].value
.i
);
1852 output_generic_value (fp
, filename
, &g
, ignore_output
[i
],
1853 tf
->ret_types
[i
], f
, long_bits
);
1854 generic_value_free (&g
);
1856 if (fputs (" :", fp
) < 0)
1857 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1858 /* Print miscellaneous flags (passed through from
1860 for (size_t i
= 0; i
< it
->num_flags
; i
++)
1861 switch (it
->flags
[i
].type
)
1863 case flag_no_test_inline
:
1865 if (fprintf (fp
, " %s%s",
1866 input_flags
[it
->flags
[i
].type
],
1870 error (EXIT_FAILURE
, errno
, "write to '%s'",
1873 case flag_xfail_rounding
:
1874 if (m
!= rm_tonearest
)
1875 if (fprintf (fp
, " xfail%s",
1879 error (EXIT_FAILURE
, errno
, "write to '%s'",
1885 /* Print exception flags and compute errno
1886 expectations where not already computed. */
1887 bool may_edom
= false;
1888 bool must_edom
= false;
1889 bool may_erange
= must_erange
|| may_underflow
;
1890 for (fp_exception e
= exc_first_exception
;
1891 e
< exc_num_exceptions
;
1894 bool expect_e
= (merged_exc
& (1U << e
)) != 0;
1895 bool e_optional
= false;
1900 may_erange
= must_erange
= true;
1910 may_edom
= must_edom
= true;
1923 if (may_underflow
&& !must_underflow
)
1932 if (fprintf (fp
, " %s-ok", exceptions
[e
]) < 0)
1933 error (EXIT_FAILURE
, errno
, "write to '%s'",
1939 if (fprintf (fp
, " %s", exceptions
[e
]) < 0)
1940 error (EXIT_FAILURE
, errno
, "write to '%s'",
1942 input_flag_type okflag
;
1944 ? flag_missing_first
1945 : flag_spurious_first
) + e
;
1946 for (size_t i
= 0; i
< it
->num_flags
; i
++)
1947 if (it
->flags
[i
].type
== okflag
)
1948 if (fprintf (fp
, " %s-ok%s",
1953 error (EXIT_FAILURE
, errno
, "write to '%s'",
1957 /* Print errno expectations. */
1961 must_erange
= false;
1963 if (may_edom
&& !must_edom
)
1965 if (fputs (" errno-edom-ok", fp
) < 0)
1966 error (EXIT_FAILURE
, errno
, "write to '%s'",
1972 if (fputs (" errno-edom", fp
) < 0)
1973 error (EXIT_FAILURE
, errno
, "write to '%s'",
1975 input_flag_type okflag
= (must_edom
1976 ? flag_missing_errno
1977 : flag_spurious_errno
);
1978 for (size_t i
= 0; i
< it
->num_flags
; i
++)
1979 if (it
->flags
[i
].type
== okflag
)
1980 if (fprintf (fp
, " errno-edom-ok%s",
1984 error (EXIT_FAILURE
, errno
, "write to '%s'",
1987 if (may_erange
&& !must_erange
)
1989 if (fputs (" errno-erange-ok", fp
) < 0)
1990 error (EXIT_FAILURE
, errno
, "write to '%s'",
1996 if (fputs (" errno-erange", fp
) < 0)
1997 error (EXIT_FAILURE
, errno
, "write to '%s'",
1999 input_flag_type okflag
= (must_erange
2000 ? flag_missing_errno
2001 : flag_spurious_errno
);
2002 for (size_t i
= 0; i
< it
->num_flags
; i
++)
2003 if (it
->flags
[i
].type
== okflag
)
2004 if (fprintf (fp
, " errno-erange-ok%s",
2008 error (EXIT_FAILURE
, errno
, "write to '%s'",
2011 if (putc ('\n', fp
) < 0)
2012 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
2015 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
2017 if (generic_outputs
[i
].type
== gtype_fp
)
2018 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
2019 mpfr_clear (all_res
[i
][m
]);
2024 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
2025 generic_value_free (&generic_outputs
[i
]);
2028 /* Generate test output data to FILENAME. */
2031 generate_output (const char *filename
)
2033 FILE *fp
= fopen (filename
, "w");
2035 error (EXIT_FAILURE
, errno
, "open '%s'", filename
);
2036 for (size_t i
= 0; i
< ARRAY_SIZE (test_functions
); i
++)
2038 test_function
*tf
= &test_functions
[i
];
2039 for (size_t j
= 0; j
< tf
->num_tests
; j
++)
2041 input_test
*it
= &tf
->tests
[j
];
2042 if (fputs (it
->line
, fp
) < 0)
2043 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
2044 for (size_t k
= 0; k
< it
->num_input_cases
; k
++)
2045 output_for_one_input_case (fp
, filename
, tf
, it
, it
->inputs
[k
]);
2048 if (fclose (fp
) != 0)
2049 error (EXIT_FAILURE
, errno
, "close '%s'", filename
);
2053 main (int argc
, char **argv
)
2056 error (EXIT_FAILURE
, 0, "usage: gen-auto-libm-tests <input> <output>");
2057 const char *input_filename
= argv
[1];
2058 const char *output_filename
= argv
[2];
2060 read_input (input_filename
);
2061 generate_output (output_filename
);
2062 exit (EXIT_SUCCESS
);