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
414 /* Description of how to calculate a function. */
417 /* Which method is used to calculate the function. */
418 func_calc_method method
;
419 /* The specific function called. */
422 int (*mpfr_f_f
) (mpfr_t
, const mpfr_t
, mpfr_rnd_t
);
423 int (*mpfr_ff_f
) (mpfr_t
, const mpfr_t
, const mpfr_t
, mpfr_rnd_t
);
424 int (*mpfr_f_f1
) (mpfr_t
, int *, const mpfr_t
, mpfr_rnd_t
);
425 int (*mpfr_if_f
) (mpfr_t
, long, const mpfr_t
, mpfr_rnd_t
);
426 int (*mpfr_f_11
) (mpfr_t
, mpfr_t
, const mpfr_t
, mpfr_rnd_t
);
427 int (*mpc_c_f
) (mpfr_t
, const mpc_t
, mpfr_rnd_t
);
428 int (*mpc_c_c
) (mpc_t
, const mpc_t
, mpc_rnd_t
);
432 /* Structure describing a function handled by this program. */
435 /* The name of the function. */
437 /* The number of arguments. */
439 /* The types of the arguments. */
440 arg_ret_type arg_types
[MAX_NARGS
];
441 /* The number of return values. */
443 /* The types of the return values. */
444 arg_ret_type ret_types
[MAX_NRET
];
445 /* Whether the function has exactly determined results and
448 /* Whether the function is a complex function, so errno setting is
451 /* How to calculate this function. */
453 /* The number of tests allocated for this function. */
454 size_t num_tests_alloc
;
455 /* The number of tests for this function. */
457 /* The tests themselves. */
461 #define ARGS1(T1) 1, { T1 }
462 #define ARGS2(T1, T2) 2, { T1, T2 }
463 #define ARGS3(T1, T2, T3) 3, { T1, T2, T3 }
464 #define ARGS4(T1, T2, T3, T4) 4, { T1, T2, T3, T4 }
465 #define RET1(T1) 1, { T1 }
466 #define RET2(T1, T2) 2, { T1, T2 }
467 #define CALC(TYPE, FN) { TYPE, { .TYPE = FN } }
468 #define FUNC(NAME, ARGS, RET, EXACT, COMPLEX_FN, CALC) \
470 NAME, ARGS, RET, EXACT, COMPLEX_FN, CALC, 0, 0, NULL \
473 #define FUNC_mpfr_f_f(NAME, MPFR_FUNC, EXACT) \
474 FUNC (NAME, ARGS1 (type_fp), RET1 (type_fp), EXACT, false, \
475 CALC (mpfr_f_f, MPFR_FUNC))
476 #define FUNC_mpfr_ff_f(NAME, MPFR_FUNC, EXACT) \
477 FUNC (NAME, ARGS2 (type_fp, type_fp), RET1 (type_fp), EXACT, false, \
478 CALC (mpfr_ff_f, MPFR_FUNC))
479 #define FUNC_mpfr_if_f(NAME, MPFR_FUNC, EXACT) \
480 FUNC (NAME, ARGS2 (type_int, type_fp), RET1 (type_fp), EXACT, false, \
481 CALC (mpfr_if_f, MPFR_FUNC))
482 #define FUNC_mpc_c_f(NAME, MPFR_FUNC, EXACT) \
483 FUNC (NAME, ARGS2 (type_fp, type_fp), RET1 (type_fp), EXACT, true, \
484 CALC (mpc_c_f, MPFR_FUNC))
485 #define FUNC_mpc_c_c(NAME, MPFR_FUNC, EXACT) \
486 FUNC (NAME, ARGS2 (type_fp, type_fp), RET2 (type_fp, type_fp), EXACT, \
487 true, CALC (mpc_c_c, MPFR_FUNC))
489 /* List of functions handled by this program. */
490 static test_function test_functions
[] =
492 FUNC_mpfr_f_f ("acos", mpfr_acos
, false),
493 FUNC_mpfr_f_f ("acosh", mpfr_acosh
, false),
494 FUNC_mpfr_f_f ("asin", mpfr_asin
, false),
495 FUNC_mpfr_f_f ("asinh", mpfr_asinh
, false),
496 FUNC_mpfr_f_f ("atan", mpfr_atan
, false),
497 FUNC_mpfr_ff_f ("atan2", mpfr_atan2
, false),
498 FUNC_mpfr_f_f ("atanh", mpfr_atanh
, false),
499 FUNC_mpc_c_f ("cabs", mpc_abs
, false),
500 FUNC_mpc_c_c ("cacos", mpc_acos
, false),
501 FUNC_mpc_c_c ("cacosh", mpc_acosh
, false),
502 FUNC_mpc_c_f ("carg", mpc_arg
, false),
503 FUNC_mpc_c_c ("casin", mpc_asin
, false),
504 FUNC_mpc_c_c ("casinh", mpc_asinh
, false),
505 FUNC_mpc_c_c ("catan", mpc_atan
, false),
506 FUNC_mpc_c_c ("catanh", mpc_atanh
, false),
507 FUNC_mpfr_f_f ("cbrt", mpfr_cbrt
, false),
508 FUNC_mpc_c_c ("ccos", mpc_cos
, false),
509 FUNC_mpc_c_c ("ccosh", mpc_cosh
, false),
510 FUNC_mpc_c_c ("cexp", mpc_exp
, false),
511 FUNC_mpc_c_c ("clog", mpc_log
, false),
512 FUNC_mpc_c_c ("clog10", mpc_log10
, false),
513 FUNC_mpfr_f_f ("cos", mpfr_cos
, false),
514 FUNC_mpfr_f_f ("cosh", mpfr_cosh
, false),
515 FUNC_mpc_c_c ("csin", mpc_sin
, false),
516 FUNC_mpc_c_c ("csinh", mpc_sinh
, false),
517 FUNC_mpc_c_c ("csqrt", mpc_sqrt
, false),
518 FUNC_mpc_c_c ("ctan", mpc_tan
, false),
519 FUNC_mpc_c_c ("ctanh", mpc_tanh
, false),
520 FUNC_mpfr_f_f ("erf", mpfr_erf
, false),
521 FUNC_mpfr_f_f ("erfc", mpfr_erfc
, false),
522 FUNC_mpfr_f_f ("exp", mpfr_exp
, false),
523 FUNC_mpfr_f_f ("exp10", mpfr_exp10
, false),
524 FUNC_mpfr_f_f ("exp2", mpfr_exp2
, false),
525 FUNC_mpfr_f_f ("expm1", mpfr_expm1
, false),
526 FUNC_mpfr_ff_f ("hypot", mpfr_hypot
, false),
527 FUNC_mpfr_f_f ("j0", mpfr_j0
, false),
528 FUNC_mpfr_f_f ("j1", mpfr_j1
, false),
529 FUNC_mpfr_if_f ("jn", mpfr_jn
, false),
530 FUNC ("lgamma", ARGS1 (type_fp
), RET2 (type_fp
, type_int
), false, false,
531 CALC (mpfr_f_f1
, mpfr_lgamma
)),
532 FUNC_mpfr_f_f ("log", mpfr_log
, false),
533 FUNC_mpfr_f_f ("log10", mpfr_log10
, false),
534 FUNC_mpfr_f_f ("log1p", mpfr_log1p
, false),
535 FUNC_mpfr_f_f ("log2", mpfr_log2
, false),
536 FUNC_mpfr_ff_f ("pow", mpfr_pow
, false),
537 FUNC_mpfr_f_f ("sin", mpfr_sin
, false),
538 FUNC ("sincos", ARGS1 (type_fp
), RET2 (type_fp
, type_fp
), false, false,
539 CALC (mpfr_f_11
, mpfr_sin_cos
)),
540 FUNC_mpfr_f_f ("sinh", mpfr_sinh
, false),
541 FUNC_mpfr_f_f ("sqrt", mpfr_sqrt
, true),
542 FUNC_mpfr_f_f ("tan", mpfr_tan
, false),
543 FUNC_mpfr_f_f ("tanh", mpfr_tanh
, false),
544 FUNC_mpfr_f_f ("tgamma", mpfr_gamma
, false),
545 FUNC_mpfr_f_f ("y0", mpfr_y0
, false),
546 FUNC_mpfr_f_f ("y1", mpfr_y1
, false),
547 FUNC_mpfr_if_f ("yn", mpfr_yn
, false),
550 /* Allocate memory, with error checking. */
555 void *p
= malloc (n
);
557 error (EXIT_FAILURE
, errno
, "xmalloc failed");
562 xrealloc (void *p
, size_t n
)
566 error (EXIT_FAILURE
, errno
, "xrealloc failed");
571 xstrdup (const char *s
)
573 char *p
= strdup (s
);
575 error (EXIT_FAILURE
, errno
, "xstrdup failed");
579 /* Assert that the result of an MPFR operation was exact; that is,
580 that the returned ternary value was 0. */
588 /* Return the generic type of an argument or return value type T. */
590 static generic_value_type
591 generic_arg_ret_type (arg_ret_type t
)
608 /* Free a generic_value *V. */
611 generic_value_free (generic_value
*v
)
616 mpfr_clear (v
->value
.f
);
620 mpz_clear (v
->value
.i
);
628 /* Copy a generic_value *SRC to *DEST. */
631 generic_value_copy (generic_value
*dest
, const generic_value
*src
)
633 dest
->type
= src
->type
;
637 mpfr_init (dest
->value
.f
);
638 assert_exact (mpfr_set (dest
->value
.f
, src
->value
.f
, MPFR_RNDN
));
642 mpz_init (dest
->value
.i
);
643 mpz_set (dest
->value
.i
, src
->value
.i
);
651 /* Initialize data for floating-point formats. */
656 int global_max_exp
= 0, global_min_subnorm_exp
= 0;
657 for (fp_format f
= fp_first_format
; f
< fp_num_formats
; f
++)
659 if (fp_formats
[f
].mant_dig
+ 2 > internal_precision
)
660 internal_precision
= fp_formats
[f
].mant_dig
+ 2;
661 if (fp_formats
[f
].max_exp
> global_max_exp
)
662 global_max_exp
= fp_formats
[f
].max_exp
;
663 int min_subnorm_exp
= fp_formats
[f
].min_exp
- fp_formats
[f
].mant_dig
;
664 if (min_subnorm_exp
< global_min_subnorm_exp
)
665 global_min_subnorm_exp
= min_subnorm_exp
;
666 mpfr_init2 (fp_formats
[f
].max
, fp_formats
[f
].mant_dig
);
667 if (fp_formats
[f
].max_string
!= NULL
)
670 assert_exact (mpfr_strtofr (fp_formats
[f
].max
,
671 fp_formats
[f
].max_string
,
677 assert_exact (mpfr_set_ui_2exp (fp_formats
[f
].max
, 1,
678 fp_formats
[f
].max_exp
,
680 mpfr_nextbelow (fp_formats
[f
].max
);
682 mpfr_init2 (fp_formats
[f
].min
, fp_formats
[f
].mant_dig
);
683 assert_exact (mpfr_set_ui_2exp (fp_formats
[f
].min
, 1,
684 fp_formats
[f
].min_exp
- 1,
686 mpfr_init2 (fp_formats
[f
].subnorm_max
, fp_formats
[f
].mant_dig
);
687 assert_exact (mpfr_set (fp_formats
[f
].subnorm_max
, fp_formats
[f
].min
,
689 mpfr_nextbelow (fp_formats
[f
].subnorm_max
);
690 mpfr_nextbelow (fp_formats
[f
].subnorm_max
);
691 mpfr_init2 (fp_formats
[f
].subnorm_min
, fp_formats
[f
].mant_dig
);
692 assert_exact (mpfr_set_ui_2exp (fp_formats
[f
].subnorm_min
, 1,
693 min_subnorm_exp
, MPFR_RNDN
));
695 mpfr_set_default_prec (internal_precision
);
696 mpfr_init (global_max
);
697 assert_exact (mpfr_set_ui_2exp (global_max
, 1, global_max_exp
, MPFR_RNDN
));
698 mpfr_init (global_min
);
699 assert_exact (mpfr_set_ui_2exp (global_min
, 1, global_min_subnorm_exp
- 1,
703 /* Fill in mpfr_t values for special strings in input arguments. */
706 special_fill_max (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
709 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
710 assert_exact (mpfr_set (res0
, fp_formats
[format
].max
, MPFR_RNDN
));
715 special_fill_minus_max (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
718 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
719 assert_exact (mpfr_neg (res0
, fp_formats
[format
].max
, MPFR_RNDN
));
724 special_fill_min (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
727 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
728 assert_exact (mpfr_set (res0
, fp_formats
[format
].min
, MPFR_RNDN
));
733 special_fill_minus_min (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
736 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
737 assert_exact (mpfr_neg (res0
, fp_formats
[format
].min
, MPFR_RNDN
));
742 special_fill_min_subnorm (mpfr_t res0
, mpfr_t res1
__attribute__ ((unused
)),
745 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
746 assert_exact (mpfr_set (res0
, fp_formats
[format
].subnorm_min
, MPFR_RNDN
));
751 special_fill_minus_min_subnorm (mpfr_t res0
,
752 mpfr_t res1
__attribute__ ((unused
)),
755 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
756 assert_exact (mpfr_neg (res0
, fp_formats
[format
].subnorm_min
, MPFR_RNDN
));
761 special_fill_min_subnorm_p120 (mpfr_t res0
,
762 mpfr_t res1
__attribute__ ((unused
)),
765 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
766 assert_exact (mpfr_mul_2ui (res0
, fp_formats
[format
].subnorm_min
,
772 special_fill_pi (mpfr_t res0
, mpfr_t res1
, fp_format format
)
774 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
775 mpfr_const_pi (res0
, MPFR_RNDU
);
776 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
777 mpfr_const_pi (res1
, MPFR_RNDD
);
782 special_fill_minus_pi (mpfr_t res0
, mpfr_t res1
, fp_format format
)
784 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
785 mpfr_const_pi (res0
, MPFR_RNDU
);
786 assert_exact (mpfr_neg (res0
, res0
, MPFR_RNDN
));
787 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
788 mpfr_const_pi (res1
, MPFR_RNDD
);
789 assert_exact (mpfr_neg (res1
, res1
, MPFR_RNDN
));
794 special_fill_pi_2 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
796 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
797 mpfr_const_pi (res0
, MPFR_RNDU
);
798 assert_exact (mpfr_div_ui (res0
, res0
, 2, MPFR_RNDN
));
799 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
800 mpfr_const_pi (res1
, MPFR_RNDD
);
801 assert_exact (mpfr_div_ui (res1
, res1
, 2, MPFR_RNDN
));
806 special_fill_minus_pi_2 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
808 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
809 mpfr_const_pi (res0
, MPFR_RNDU
);
810 assert_exact (mpfr_div_ui (res0
, res0
, 2, MPFR_RNDN
));
811 assert_exact (mpfr_neg (res0
, res0
, MPFR_RNDN
));
812 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
813 mpfr_const_pi (res1
, MPFR_RNDD
);
814 assert_exact (mpfr_div_ui (res1
, res1
, 2, MPFR_RNDN
));
815 assert_exact (mpfr_neg (res1
, res1
, MPFR_RNDN
));
820 special_fill_pi_4 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
822 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
823 assert_exact (mpfr_set_si (res0
, 1, MPFR_RNDN
));
824 mpfr_atan (res0
, res0
, MPFR_RNDU
);
825 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
826 assert_exact (mpfr_set_si (res1
, 1, MPFR_RNDN
));
827 mpfr_atan (res1
, res1
, MPFR_RNDD
);
832 special_fill_pi_6 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
834 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
835 assert_exact (mpfr_set_si_2exp (res0
, 1, -1, MPFR_RNDN
));
836 mpfr_asin (res0
, res0
, MPFR_RNDU
);
837 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
838 assert_exact (mpfr_set_si_2exp (res1
, 1, -1, MPFR_RNDN
));
839 mpfr_asin (res1
, res1
, MPFR_RNDD
);
844 special_fill_minus_pi_6 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
846 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
847 assert_exact (mpfr_set_si_2exp (res0
, -1, -1, MPFR_RNDN
));
848 mpfr_asin (res0
, res0
, MPFR_RNDU
);
849 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
850 assert_exact (mpfr_set_si_2exp (res1
, -1, -1, MPFR_RNDN
));
851 mpfr_asin (res1
, res1
, MPFR_RNDD
);
856 special_fill_pi_3 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
858 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
859 assert_exact (mpfr_set_si_2exp (res0
, 1, -1, MPFR_RNDN
));
860 mpfr_acos (res0
, res0
, MPFR_RNDU
);
861 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
862 assert_exact (mpfr_set_si_2exp (res1
, 1, -1, MPFR_RNDN
));
863 mpfr_acos (res1
, res1
, MPFR_RNDD
);
868 special_fill_2pi_3 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
870 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
871 assert_exact (mpfr_set_si_2exp (res0
, -1, -1, MPFR_RNDN
));
872 mpfr_acos (res0
, res0
, MPFR_RNDU
);
873 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
874 assert_exact (mpfr_set_si_2exp (res1
, -1, -1, MPFR_RNDN
));
875 mpfr_acos (res1
, res1
, MPFR_RNDD
);
880 special_fill_e (mpfr_t res0
, mpfr_t res1
, fp_format format
)
882 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
883 assert_exact (mpfr_set_si (res0
, 1, MPFR_RNDN
));
884 mpfr_exp (res0
, res0
, MPFR_RNDU
);
885 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
886 assert_exact (mpfr_set_si (res1
, 1, MPFR_RNDN
));
887 mpfr_exp (res1
, res1
, MPFR_RNDD
);
892 special_fill_1_e (mpfr_t res0
, mpfr_t res1
, fp_format format
)
894 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
895 assert_exact (mpfr_set_si (res0
, -1, MPFR_RNDN
));
896 mpfr_exp (res0
, res0
, MPFR_RNDU
);
897 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
898 assert_exact (mpfr_set_si (res1
, -1, MPFR_RNDN
));
899 mpfr_exp (res1
, res1
, MPFR_RNDD
);
904 special_fill_e_minus_1 (mpfr_t res0
, mpfr_t res1
, fp_format format
)
906 mpfr_init2 (res0
, fp_formats
[format
].mant_dig
);
907 assert_exact (mpfr_set_si (res0
, 1, MPFR_RNDN
));
908 mpfr_expm1 (res0
, res0
, MPFR_RNDU
);
909 mpfr_init2 (res1
, fp_formats
[format
].mant_dig
);
910 assert_exact (mpfr_set_si (res1
, 1, MPFR_RNDN
));
911 mpfr_expm1 (res1
, res1
, MPFR_RNDD
);
915 /* A special string accepted in input arguments. */
920 /* The function that interprets it for a given floating-point
921 format, filling in up to two mpfr_t values and returning the
922 number of values filled. */
923 size_t (*func
) (mpfr_t
, mpfr_t
, fp_format
);
924 } special_real_input
;
926 /* List of special strings accepted in input arguments. */
928 static const special_real_input special_real_inputs
[] =
930 { "max", special_fill_max
},
931 { "-max", special_fill_minus_max
},
932 { "min", special_fill_min
},
933 { "-min", special_fill_minus_min
},
934 { "min_subnorm", special_fill_min_subnorm
},
935 { "-min_subnorm", special_fill_minus_min_subnorm
},
936 { "min_subnorm_p120", special_fill_min_subnorm_p120
},
937 { "pi", special_fill_pi
},
938 { "-pi", special_fill_minus_pi
},
939 { "pi/2", special_fill_pi_2
},
940 { "-pi/2", special_fill_minus_pi_2
},
941 { "pi/4", special_fill_pi_4
},
942 { "pi/6", special_fill_pi_6
},
943 { "-pi/6", special_fill_minus_pi_6
},
944 { "pi/3", special_fill_pi_3
},
945 { "2pi/3", special_fill_2pi_3
},
946 { "e", special_fill_e
},
947 { "1/e", special_fill_1_e
},
948 { "e-1", special_fill_e_minus_1
},
951 /* Given a real number R computed in round-to-zero mode, set the
952 lowest bit as a sticky bit if INEXACT, and saturate the exponent
953 range for very large or small values. */
956 adjust_real (mpfr_t r
, bool inexact
)
960 /* NaNs are exact, as are infinities in round-to-zero mode. */
961 assert (mpfr_number_p (r
));
962 if (mpfr_cmpabs (r
, global_min
) < 0)
963 assert_exact (mpfr_copysign (r
, global_min
, r
, MPFR_RNDN
));
964 else if (mpfr_cmpabs (r
, global_max
) > 0)
965 assert_exact (mpfr_copysign (r
, global_max
, r
, MPFR_RNDN
));
970 mpfr_exp_t e
= mpfr_get_z_2exp (tmp
, r
);
972 assert_exact (mpfr_set_z_2exp (r
, tmp
, e
, MPFR_RNDN
));
977 /* Given a finite real number R with sticky bit, compute the roundings
978 to FORMAT in each rounding mode, storing the results in RES, the
979 before-rounding exceptions in EXC_BEFORE and the after-rounding
980 exceptions in EXC_AFTER. */
983 round_real (mpfr_t res
[rm_num_modes
],
984 unsigned int exc_before
[rm_num_modes
],
985 unsigned int exc_after
[rm_num_modes
],
986 mpfr_t r
, fp_format format
)
988 assert (mpfr_number_p (r
));
989 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
991 mpfr_init2 (res
[m
], fp_formats
[format
].mant_dig
);
992 exc_before
[m
] = exc_after
[m
] = 0;
993 bool inexact
= mpfr_set (res
[m
], r
, rounding_modes
[m
].mpfr_mode
);
994 if (mpfr_cmpabs (res
[m
], fp_formats
[format
].max
) > 0)
997 exc_before
[m
] |= 1U << exc_overflow
;
998 exc_after
[m
] |= 1U << exc_overflow
;
1003 overflow_inf
= true;
1006 overflow_inf
= false;
1009 overflow_inf
= mpfr_signbit (res
[m
]);
1012 overflow_inf
= !mpfr_signbit (res
[m
]);
1018 mpfr_set_inf (res
[m
], mpfr_signbit (res
[m
]) ? -1 : 1);
1020 assert_exact (mpfr_copysign (res
[m
], fp_formats
[format
].max
,
1021 res
[m
], MPFR_RNDN
));
1023 if (mpfr_cmpabs (r
, fp_formats
[format
].min
) < 0)
1025 /* Tiny before rounding; may or may not be tiny after
1026 rounding, and underflow applies only if also inexact
1027 around rounding to a possibly subnormal value. */
1028 bool tiny_after_rounding
1029 = mpfr_cmpabs (res
[m
], fp_formats
[format
].min
) < 0;
1030 /* To round to a possibly subnormal value, and determine
1031 inexactness as a subnormal in the process, scale up and
1032 round to integer, then scale back down. */
1035 assert_exact (mpfr_mul_2si (tmp
, r
, (fp_formats
[format
].mant_dig
1036 - fp_formats
[format
].min_exp
),
1038 int rint_res
= mpfr_rint (tmp
, tmp
, rounding_modes
[m
].mpfr_mode
);
1039 /* The integer must be representable. */
1040 assert (rint_res
== 0 || rint_res
== 2 || rint_res
== -2);
1041 /* If rounding to full precision was inexact, so must
1042 rounding to subnormal precision be inexact. */
1044 assert (rint_res
!= 0);
1046 inexact
= rint_res
!= 0;
1047 assert_exact (mpfr_mul_2si (res
[m
], tmp
,
1048 (fp_formats
[format
].min_exp
1049 - fp_formats
[format
].mant_dig
),
1054 exc_before
[m
] |= 1U << exc_underflow
;
1055 if (tiny_after_rounding
)
1056 exc_after
[m
] |= 1U << exc_underflow
;
1061 exc_before
[m
] |= 1U << exc_inexact
;
1062 exc_after
[m
] |= 1U << exc_inexact
;
1067 /* Handle the input argument at ARG (NUL-terminated), updating the
1068 lists of test inputs in IT accordingly. NUM_PREV_ARGS arguments
1069 are already in those lists. The argument, of type GTYPE, comes
1070 from file FILENAME, line LINENO. */
1073 handle_input_arg (const char *arg
, input_test
*it
, size_t num_prev_args
,
1074 generic_value_type gtype
,
1075 const char *filename
, unsigned int lineno
)
1077 size_t num_values
= 0;
1078 generic_value values
[2 * fp_num_formats
];
1082 for (fp_format f
= fp_first_format
; f
< fp_num_formats
; f
++)
1084 mpfr_t extra_values
[2];
1085 size_t num_extra_values
= 0;
1086 for (size_t i
= 0; i
< ARRAY_SIZE (special_real_inputs
); i
++)
1088 if (strcmp (arg
, special_real_inputs
[i
].str
) == 0)
1091 = special_real_inputs
[i
].func (extra_values
[0],
1092 extra_values
[1], f
);
1093 assert (num_extra_values
> 0
1094 && num_extra_values
<= ARRAY_SIZE (extra_values
));
1098 if (num_extra_values
== 0)
1103 bool inexact
= mpfr_strtofr (tmp
, arg
, &ep
, 0, MPFR_RNDZ
);
1104 if (*ep
!= 0 || !mpfr_number_p (tmp
))
1105 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1106 "bad floating-point argument: '%s'", arg
);
1107 adjust_real (tmp
, inexact
);
1108 mpfr_t rounded
[rm_num_modes
];
1109 unsigned int exc_before
[rm_num_modes
];
1110 unsigned int exc_after
[rm_num_modes
];
1111 round_real (rounded
, exc_before
, exc_after
, tmp
, f
);
1113 if (mpfr_number_p (rounded
[rm_upward
]))
1115 mpfr_init2 (extra_values
[num_extra_values
],
1116 fp_formats
[f
].mant_dig
);
1117 assert_exact (mpfr_set (extra_values
[num_extra_values
],
1118 rounded
[rm_upward
], MPFR_RNDN
));
1121 if (mpfr_number_p (rounded
[rm_downward
]))
1123 mpfr_init2 (extra_values
[num_extra_values
],
1124 fp_formats
[f
].mant_dig
);
1125 assert_exact (mpfr_set (extra_values
[num_extra_values
],
1126 rounded
[rm_downward
], MPFR_RNDN
));
1129 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1130 mpfr_clear (rounded
[m
]);
1132 for (size_t i
= 0; i
< num_extra_values
; i
++)
1135 for (size_t j
= 0; j
< num_values
; j
++)
1137 if (mpfr_equal_p (values
[j
].value
.f
, extra_values
[i
])
1138 && ((mpfr_signbit (values
[j
].value
.f
) != 0)
1139 == (mpfr_signbit (extra_values
[i
]) != 0)))
1147 assert (num_values
< ARRAY_SIZE (values
));
1148 values
[num_values
].type
= gtype_fp
;
1149 mpfr_init2 (values
[num_values
].value
.f
,
1150 fp_formats
[f
].mant_dig
);
1151 assert_exact (mpfr_set (values
[num_values
].value
.f
,
1152 extra_values
[i
], MPFR_RNDN
));
1155 mpfr_clear (extra_values
[i
]);
1162 values
[0].type
= gtype_int
;
1163 int ret
= mpz_init_set_str (values
[0].value
.i
, arg
, 0);
1165 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1166 "bad integer argument: '%s'", arg
);
1172 assert (num_values
> 0 && num_values
<= ARRAY_SIZE (values
));
1173 if (it
->num_input_cases
>= SIZE_MAX
/ num_values
)
1174 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
, "too many input cases");
1175 generic_value
**old_inputs
= it
->inputs
;
1176 size_t new_num_input_cases
= it
->num_input_cases
* num_values
;
1177 generic_value
**new_inputs
= xmalloc (new_num_input_cases
1178 * sizeof (new_inputs
[0]));
1179 for (size_t i
= 0; i
< it
->num_input_cases
; i
++)
1181 for (size_t j
= 0; j
< num_values
; j
++)
1183 size_t idx
= i
* num_values
+ j
;
1184 new_inputs
[idx
] = xmalloc ((num_prev_args
+ 1)
1185 * sizeof (new_inputs
[idx
][0]));
1186 for (size_t k
= 0; k
< num_prev_args
; k
++)
1187 generic_value_copy (&new_inputs
[idx
][k
], &old_inputs
[i
][k
]);
1188 generic_value_copy (&new_inputs
[idx
][num_prev_args
], &values
[j
]);
1190 for (size_t j
= 0; j
< num_prev_args
; j
++)
1191 generic_value_free (&old_inputs
[i
][j
]);
1192 free (old_inputs
[i
]);
1195 for (size_t i
= 0; i
< num_values
; i
++)
1196 generic_value_free (&values
[i
]);
1197 it
->inputs
= new_inputs
;
1198 it
->num_input_cases
= new_num_input_cases
;
1201 /* Handle the input flag ARG (NUL-terminated), storing it in *FLAG.
1202 The flag comes from file FILENAME, line LINENO. */
1205 handle_input_flag (char *arg
, input_flag
*flag
,
1206 const char *filename
, unsigned int lineno
)
1208 char *ep
= strchr (arg
, ':');
1211 ep
= strchr (arg
, 0);
1212 assert (ep
!= NULL
);
1217 for (input_flag_type i
= flag_first_flag
; i
<= num_input_flag_types
; i
++)
1219 if (strcmp (arg
, input_flags
[i
]) == 0)
1227 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
, "unknown flag: '%s'",
1233 flag
->cond
= xstrdup (ep
);
1236 /* Add the test LINE (file FILENAME, line LINENO) to the test
1240 add_test (char *line
, const char *filename
, unsigned int lineno
)
1242 size_t num_tokens
= 1;
1244 while ((p
= strchr (p
, ' ')) != NULL
)
1250 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1251 "line too short: '%s'", line
);
1252 p
= strchr (line
, ' ');
1253 size_t func_name_len
= p
- line
;
1254 for (size_t i
= 0; i
< ARRAY_SIZE (test_functions
); i
++)
1256 if (func_name_len
== strlen (test_functions
[i
].name
)
1257 && strncmp (line
, test_functions
[i
].name
, func_name_len
) == 0)
1259 test_function
*tf
= &test_functions
[i
];
1260 if (num_tokens
< 1 + tf
->num_args
)
1261 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1262 "line too short: '%s'", line
);
1263 if (tf
->num_tests
== tf
->num_tests_alloc
)
1265 tf
->num_tests_alloc
= 2 * tf
->num_tests_alloc
+ 16;
1267 = xrealloc (tf
->tests
,
1268 tf
->num_tests_alloc
* sizeof (tf
->tests
[0]));
1270 input_test
*it
= &tf
->tests
[tf
->num_tests
];
1272 it
->num_input_cases
= 1;
1273 it
->inputs
= xmalloc (sizeof (it
->inputs
[0]));
1274 it
->inputs
[0] = NULL
;
1275 it
->old_output
= NULL
;
1277 for (size_t j
= 0; j
< tf
->num_args
; j
++)
1279 char *ep
= strchr (p
, ' ');
1282 ep
= strchr (p
, '\n');
1283 assert (ep
!= NULL
);
1286 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1287 "empty token in line: '%s'", line
);
1288 for (char *t
= p
; t
< ep
; t
++)
1289 if (isspace ((unsigned char) *t
))
1290 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1291 "whitespace in token in line: '%s'", line
);
1294 handle_input_arg (p
, it
, j
,
1295 generic_arg_ret_type (tf
->arg_types
[j
]),
1300 it
->num_flags
= num_tokens
- 1 - tf
->num_args
;
1301 it
->flags
= xmalloc (it
->num_flags
* sizeof (it
->flags
[0]));
1302 for (size_t j
= 0; j
< it
->num_flags
; j
++)
1304 char *ep
= strchr (p
, ' ');
1307 ep
= strchr (p
, '\n');
1308 assert (ep
!= NULL
);
1311 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1312 "empty token in line: '%s'", line
);
1313 for (char *t
= p
; t
< ep
; t
++)
1314 if (isspace ((unsigned char) *t
))
1315 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1316 "whitespace in token in line: '%s'", line
);
1319 handle_input_flag (p
, &it
->flags
[j
], filename
, lineno
);
1328 error_at_line (EXIT_FAILURE
, 0, filename
, lineno
,
1329 "unknown function in line: '%s'", line
);
1332 /* Read in the test input data from FILENAME. */
1335 read_input (const char *filename
)
1337 FILE *fp
= fopen (filename
, "r");
1339 error (EXIT_FAILURE
, errno
, "open '%s'", filename
);
1340 unsigned int lineno
= 0;
1345 ssize_t ret
= getline (&line
, &size
, fp
);
1349 if (line
[0] == '#' || line
[0] == '\n')
1351 add_test (line
, filename
, lineno
);
1354 error (EXIT_FAILURE
, errno
, "read from '%s'", filename
);
1355 if (fclose (fp
) != 0)
1356 error (EXIT_FAILURE
, errno
, "close '%s'", filename
);
1359 /* Calculate the generic results (round-to-zero with sticky bit) for
1360 the function described by CALC, with inputs INPUTS. */
1363 calc_generic_results (generic_value
*outputs
, generic_value
*inputs
,
1364 const func_calc_desc
*calc
)
1367 switch (calc
->method
)
1370 assert (inputs
[0].type
== gtype_fp
);
1371 outputs
[0].type
= gtype_fp
;
1372 mpfr_init (outputs
[0].value
.f
);
1373 inexact
= calc
->func
.mpfr_f_f (outputs
[0].value
.f
, inputs
[0].value
.f
,
1375 adjust_real (outputs
[0].value
.f
, inexact
);
1379 assert (inputs
[0].type
== gtype_fp
);
1380 assert (inputs
[1].type
== gtype_fp
);
1381 outputs
[0].type
= gtype_fp
;
1382 mpfr_init (outputs
[0].value
.f
);
1383 inexact
= calc
->func
.mpfr_ff_f (outputs
[0].value
.f
, inputs
[0].value
.f
,
1384 inputs
[1].value
.f
, MPFR_RNDZ
);
1385 adjust_real (outputs
[0].value
.f
, inexact
);
1389 assert (inputs
[0].type
== gtype_fp
);
1390 outputs
[0].type
= gtype_fp
;
1391 outputs
[1].type
= gtype_int
;
1392 mpfr_init (outputs
[0].value
.f
);
1394 inexact
= calc
->func
.mpfr_f_f1 (outputs
[0].value
.f
, &i
,
1395 inputs
[0].value
.f
, MPFR_RNDZ
);
1396 adjust_real (outputs
[0].value
.f
, inexact
);
1397 mpz_init_set_si (outputs
[1].value
.i
, i
);
1401 assert (inputs
[0].type
== gtype_int
);
1402 assert (inputs
[1].type
== gtype_fp
);
1403 outputs
[0].type
= gtype_fp
;
1404 mpfr_init (outputs
[0].value
.f
);
1405 assert (mpz_fits_slong_p (inputs
[0].value
.i
));
1406 long l
= mpz_get_si (inputs
[0].value
.i
);
1407 inexact
= calc
->func
.mpfr_if_f (outputs
[0].value
.f
, l
,
1408 inputs
[1].value
.f
, MPFR_RNDZ
);
1409 adjust_real (outputs
[0].value
.f
, inexact
);
1413 assert (inputs
[0].type
== gtype_fp
);
1414 outputs
[0].type
= gtype_fp
;
1415 mpfr_init (outputs
[0].value
.f
);
1416 outputs
[1].type
= gtype_fp
;
1417 mpfr_init (outputs
[1].value
.f
);
1418 int comb_ternary
= calc
->func
.mpfr_f_11 (outputs
[0].value
.f
,
1422 adjust_real (outputs
[0].value
.f
, (comb_ternary
& 0x3) != 0);
1423 adjust_real (outputs
[1].value
.f
, (comb_ternary
& 0xc) != 0);
1427 assert (inputs
[0].type
== gtype_fp
);
1428 assert (inputs
[1].type
== gtype_fp
);
1429 outputs
[0].type
= gtype_fp
;
1430 mpfr_init (outputs
[0].value
.f
);
1432 mpc_init2 (ci
, internal_precision
);
1433 assert_exact (mpc_set_fr_fr (ci
, inputs
[0].value
.f
, inputs
[1].value
.f
,
1435 inexact
= calc
->func
.mpc_c_f (outputs
[0].value
.f
, ci
, MPFR_RNDZ
);
1436 adjust_real (outputs
[0].value
.f
, inexact
);
1441 assert (inputs
[0].type
== gtype_fp
);
1442 assert (inputs
[1].type
== gtype_fp
);
1443 outputs
[0].type
= gtype_fp
;
1444 mpfr_init (outputs
[0].value
.f
);
1445 outputs
[1].type
= gtype_fp
;
1446 mpfr_init (outputs
[1].value
.f
);
1448 mpc_init2 (ci
, internal_precision
);
1449 mpc_init2 (co
, internal_precision
);
1450 assert_exact (mpc_set_fr_fr (ci
, inputs
[0].value
.f
, inputs
[1].value
.f
,
1452 int mpc_ternary
= calc
->func
.mpc_c_c (co
, ci
, MPC_RNDZZ
);
1453 assert_exact (mpfr_set (outputs
[0].value
.f
, mpc_realref (co
),
1455 assert_exact (mpfr_set (outputs
[1].value
.f
, mpc_imagref (co
),
1457 adjust_real (outputs
[0].value
.f
, MPC_INEX_RE (mpc_ternary
));
1458 adjust_real (outputs
[1].value
.f
, MPC_INEX_IM (mpc_ternary
));
1468 /* Return the number of bits for integer type TYPE, where "long" has
1469 LONG_BITS bits (32 or 64). */
1472 int_type_bits (arg_ret_type type
, int long_bits
)
1474 assert (long_bits
== 32 || long_bits
== 64);
1485 case type_long_long
:
1494 /* Check whether an integer Z fits a given type TYPE, where "long" has
1495 LONG_BITS bits (32 or 64). */
1498 int_fits_type (mpz_t z
, arg_ret_type type
, int long_bits
)
1500 int bits
= int_type_bits (type
, long_bits
);
1504 mpz_ui_pow_ui (t
, 2, bits
- 1);
1505 if (mpz_cmp (z
, t
) >= 0)
1508 if (mpz_cmp (z
, t
) < 0)
1514 /* Print a generic value V to FP (name FILENAME), preceded by a space,
1515 for type TYPE, floating-point format FORMAT, LONG_BITS bits per
1516 long, printing " IGNORE" instead if IGNORE. */
1519 output_generic_value (FILE *fp
, const char *filename
, const generic_value
*v
,
1520 bool ignore
, arg_ret_type type
, fp_format format
,
1525 if (fputs (" IGNORE", fp
) < 0)
1526 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1529 assert (v
->type
== generic_arg_ret_type (type
));
1534 suffix
= fp_formats
[format
].suffix
;
1545 case type_long_long
:
1555 if (mpfr_inf_p (v
->value
.f
))
1557 if (fputs ((mpfr_signbit (v
->value
.f
)
1558 ? " minus_infty" : " plus_infty"), fp
) < 0)
1559 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1563 assert (mpfr_number_p (v
->value
.f
));
1564 if (mpfr_fprintf (fp
, " %Ra%s", v
->value
.f
, suffix
) < 0)
1565 error (EXIT_FAILURE
, errno
, "mpfr_fprintf to '%s'", filename
);
1570 int bits
= int_type_bits (type
, long_bits
);
1573 mpz_ui_pow_ui (tmp
, 2, bits
- 1);
1575 if (mpz_cmp (v
->value
.i
, tmp
) == 0)
1577 mpz_add_ui (tmp
, tmp
, 1);
1578 if (mpfr_fprintf (fp
, " (%Zd%s-1)", tmp
, suffix
) < 0)
1579 error (EXIT_FAILURE
, errno
, "mpfr_fprintf to '%s'", filename
);
1583 if (mpfr_fprintf (fp
, " %Zd%s", v
->value
.i
, suffix
) < 0)
1584 error (EXIT_FAILURE
, errno
, "mpfr_fprintf to '%s'", filename
);
1594 /* Generate test output to FP (name FILENAME) for test function TF,
1595 input test IT, choice of input values INPUTS. */
1598 output_for_one_input_case (FILE *fp
, const char *filename
, test_function
*tf
,
1599 input_test
*it
, generic_value
*inputs
)
1601 bool long_bits_matters
= false;
1602 bool fits_long32
= true;
1603 for (size_t i
= 0; i
< tf
->num_args
; i
++)
1605 generic_value_type gtype
= generic_arg_ret_type (tf
->arg_types
[i
]);
1606 assert (inputs
[i
].type
== gtype
);
1607 if (gtype
== gtype_int
)
1609 bool fits_64
= int_fits_type (inputs
[i
].value
.i
, tf
->arg_types
[i
],
1613 if (tf
->arg_types
[i
] == type_long
1614 && !int_fits_type (inputs
[i
].value
.i
, tf
->arg_types
[i
], 32))
1616 long_bits_matters
= true;
1617 fits_long32
= false;
1621 generic_value generic_outputs
[MAX_NRET
];
1622 calc_generic_results (generic_outputs
, inputs
, &tf
->calc
);
1623 bool ignore_output_long32
[MAX_NRET
] = { false };
1624 bool ignore_output_long64
[MAX_NRET
] = { false };
1625 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
1627 assert (generic_outputs
[i
].type
1628 == generic_arg_ret_type (tf
->ret_types
[i
]));
1629 switch (generic_outputs
[i
].type
)
1632 if (!mpfr_number_p (generic_outputs
[i
].value
.f
))
1633 goto out
; /* Result is NaN or exact infinity. */
1637 ignore_output_long32
[i
] = !int_fits_type (generic_outputs
[i
].value
.i
,
1638 tf
->ret_types
[i
], 32);
1639 ignore_output_long64
[i
] = !int_fits_type (generic_outputs
[i
].value
.i
,
1640 tf
->ret_types
[i
], 64);
1641 if (ignore_output_long32
[i
] != ignore_output_long64
[i
])
1642 long_bits_matters
= true;
1649 /* Iterate over relevant sizes of long and floating-point formats. */
1650 for (int long_bits
= 32; long_bits
<= 64; long_bits
+= 32)
1652 if (long_bits
== 32 && !fits_long32
)
1654 if (long_bits
== 64 && !long_bits_matters
)
1656 const char *long_cond
;
1657 if (long_bits_matters
)
1658 long_cond
= (long_bits
== 32 ? ":long32" : ":long64");
1661 bool *ignore_output
= (long_bits
== 32
1662 ? ignore_output_long32
1663 : ignore_output_long64
);
1664 for (fp_format f
= fp_first_format
; f
< fp_num_formats
; f
++)
1667 mpfr_t res
[rm_num_modes
];
1668 unsigned int exc_before
[rm_num_modes
];
1669 unsigned int exc_after
[rm_num_modes
];
1670 for (size_t i
= 0; i
< tf
->num_args
; i
++)
1672 if (inputs
[i
].type
== gtype_fp
)
1674 round_real (res
, exc_before
, exc_after
, inputs
[i
].value
.f
,
1676 if (!mpfr_equal_p (res
[rm_tonearest
], inputs
[i
].value
.f
))
1678 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1679 mpfr_clear (res
[m
]);
1686 /* The inputs fit this type, so compute the ideal outputs
1688 mpfr_t all_res
[MAX_NRET
][rm_num_modes
];
1689 unsigned int all_exc_before
[MAX_NRET
][rm_num_modes
];
1690 unsigned int all_exc_after
[MAX_NRET
][rm_num_modes
];
1691 unsigned int merged_exc_before
[rm_num_modes
] = { 0 };
1692 unsigned int merged_exc_after
[rm_num_modes
] = { 0 };
1693 /* For functions not exactly determined, track whether
1694 underflow is required (some result is inexact, and
1695 magnitude does not exceed the greatest magnitude
1696 subnormal), and permitted (not an exact zero, and
1697 magnitude does not exceed the least magnitude
1699 bool must_underflow
= false;
1700 bool may_underflow
= false;
1701 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
1703 switch (generic_outputs
[i
].type
)
1706 round_real (all_res
[i
], all_exc_before
[i
], all_exc_after
[i
],
1707 generic_outputs
[i
].value
.f
, f
);
1708 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1710 merged_exc_before
[m
] |= all_exc_before
[i
][m
];
1711 merged_exc_after
[m
] |= all_exc_after
[i
][m
];
1715 |= ((all_exc_before
[i
][m
]
1716 & (1U << exc_inexact
)) != 0
1717 && (mpfr_cmpabs (generic_outputs
[i
].value
.f
,
1718 fp_formats
[f
].subnorm_max
)
1721 |= (!mpfr_zero_p (generic_outputs
[i
].value
.f
)
1722 && mpfr_cmpabs (generic_outputs
[i
].value
.f
,
1723 fp_formats
[f
].min
) <= 0);
1729 if (ignore_output
[i
])
1730 for (rounding_mode m
= rm_first_mode
;
1734 merged_exc_before
[m
] |= 1U << exc_invalid
;
1735 merged_exc_after
[m
] |= 1U << exc_invalid
;
1743 assert (may_underflow
|| !must_underflow
);
1744 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1746 bool before_after_matters
1747 = tf
->exact
&& merged_exc_before
[m
] != merged_exc_after
[m
];
1748 for (int after
= 0; after
<= 1; after
++)
1750 if (after
== 1 && !before_after_matters
)
1752 const char *after_cond
;
1753 if (before_after_matters
)
1756 : ":before-rounding");
1759 unsigned int merged_exc
= (after
1760 ? merged_exc_after
[m
]
1761 : merged_exc_before
[m
]);
1762 if (fprintf (fp
, "= %s %s %s%s%s", tf
->name
,
1763 rounding_modes
[m
].name
, fp_formats
[f
].name
,
1764 long_cond
, after_cond
) < 0)
1765 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1767 for (size_t i
= 0; i
< tf
->num_args
; i
++)
1768 output_generic_value (fp
, filename
, &inputs
[i
], false,
1769 tf
->arg_types
[i
], f
, long_bits
);
1770 if (fputs (" :", fp
) < 0)
1771 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1772 /* Print outputs. */
1773 bool must_erange
= false;
1774 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
1777 g
.type
= generic_outputs
[i
].type
;
1781 if (mpfr_inf_p (all_res
[i
][m
])
1782 && (all_exc_before
[i
][m
]
1783 & (1U << exc_overflow
)) != 0)
1785 if (mpfr_zero_p (all_res
[i
][m
])
1787 || mpfr_zero_p (all_res
[i
][rm_tonearest
]))
1788 && (all_exc_before
[i
][m
]
1789 & (1U << exc_underflow
)) != 0)
1791 mpfr_init2 (g
.value
.f
, fp_formats
[f
].mant_dig
);
1792 assert_exact (mpfr_set (g
.value
.f
, all_res
[i
][m
],
1797 mpz_init (g
.value
.i
);
1798 mpz_set (g
.value
.i
, generic_outputs
[i
].value
.i
);
1804 output_generic_value (fp
, filename
, &g
, ignore_output
[i
],
1805 tf
->ret_types
[i
], f
, long_bits
);
1806 generic_value_free (&g
);
1808 if (fputs (" :", fp
) < 0)
1809 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1810 /* Print miscellaneous flags (passed through from
1812 for (size_t i
= 0; i
< it
->num_flags
; i
++)
1813 switch (it
->flags
[i
].type
)
1815 case flag_no_test_inline
:
1817 if (fprintf (fp
, " %s%s",
1818 input_flags
[it
->flags
[i
].type
],
1822 error (EXIT_FAILURE
, errno
, "write to '%s'",
1825 case flag_xfail_rounding
:
1826 if (m
!= rm_tonearest
)
1827 if (fprintf (fp
, " xfail%s",
1831 error (EXIT_FAILURE
, errno
, "write to '%s'",
1837 /* Print exception flags and compute errno
1838 expectations where not already computed. */
1839 bool may_edom
= false;
1840 bool must_edom
= false;
1841 bool may_erange
= must_erange
|| may_underflow
;
1842 for (fp_exception e
= exc_first_exception
;
1843 e
< exc_num_exceptions
;
1846 bool expect_e
= (merged_exc
& (1U << e
)) != 0;
1847 bool e_optional
= false;
1852 may_erange
= must_erange
= true;
1862 may_edom
= must_edom
= true;
1875 if (may_underflow
&& !must_underflow
)
1884 if (fprintf (fp
, " %s-ok", exceptions
[e
]) < 0)
1885 error (EXIT_FAILURE
, errno
, "write to '%s'",
1891 if (fprintf (fp
, " %s", exceptions
[e
]) < 0)
1892 error (EXIT_FAILURE
, errno
, "write to '%s'",
1894 input_flag_type okflag
;
1896 ? flag_missing_first
1897 : flag_spurious_first
) + e
;
1898 for (size_t i
= 0; i
< it
->num_flags
; i
++)
1899 if (it
->flags
[i
].type
== okflag
)
1900 if (fprintf (fp
, " %s-ok%s",
1905 error (EXIT_FAILURE
, errno
, "write to '%s'",
1909 /* Print errno expectations. */
1913 must_erange
= false;
1915 if (may_edom
&& !must_edom
)
1917 if (fputs (" errno-edom-ok", fp
) < 0)
1918 error (EXIT_FAILURE
, errno
, "write to '%s'",
1924 if (fputs (" errno-edom", fp
) < 0)
1925 error (EXIT_FAILURE
, errno
, "write to '%s'",
1927 input_flag_type okflag
= (must_edom
1928 ? flag_missing_errno
1929 : flag_spurious_errno
);
1930 for (size_t i
= 0; i
< it
->num_flags
; i
++)
1931 if (it
->flags
[i
].type
== okflag
)
1932 if (fprintf (fp
, " errno-edom-ok%s",
1936 error (EXIT_FAILURE
, errno
, "write to '%s'",
1939 if (may_erange
&& !must_erange
)
1941 if (fputs (" errno-erange-ok", fp
) < 0)
1942 error (EXIT_FAILURE
, errno
, "write to '%s'",
1948 if (fputs (" errno-erange", fp
) < 0)
1949 error (EXIT_FAILURE
, errno
, "write to '%s'",
1951 input_flag_type okflag
= (must_erange
1952 ? flag_missing_errno
1953 : flag_spurious_errno
);
1954 for (size_t i
= 0; i
< it
->num_flags
; i
++)
1955 if (it
->flags
[i
].type
== okflag
)
1956 if (fprintf (fp
, " errno-erange-ok%s",
1960 error (EXIT_FAILURE
, errno
, "write to '%s'",
1963 if (putc ('\n', fp
) < 0)
1964 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1967 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
1969 if (generic_outputs
[i
].type
== gtype_fp
)
1970 for (rounding_mode m
= rm_first_mode
; m
< rm_num_modes
; m
++)
1971 mpfr_clear (all_res
[i
][m
]);
1976 for (size_t i
= 0; i
< tf
->num_ret
; i
++)
1977 generic_value_free (&generic_outputs
[i
]);
1980 /* Generate test output data to FILENAME. */
1983 generate_output (const char *filename
)
1985 FILE *fp
= fopen (filename
, "w");
1987 error (EXIT_FAILURE
, errno
, "open '%s'", filename
);
1988 for (size_t i
= 0; i
< ARRAY_SIZE (test_functions
); i
++)
1990 test_function
*tf
= &test_functions
[i
];
1991 for (size_t j
= 0; j
< tf
->num_tests
; j
++)
1993 input_test
*it
= &tf
->tests
[j
];
1994 if (fputs (it
->line
, fp
) < 0)
1995 error (EXIT_FAILURE
, errno
, "write to '%s'", filename
);
1996 for (size_t k
= 0; k
< it
->num_input_cases
; k
++)
1997 output_for_one_input_case (fp
, filename
, tf
, it
, it
->inputs
[k
]);
2000 if (fclose (fp
) != 0)
2001 error (EXIT_FAILURE
, errno
, "close '%s'", filename
);
2005 main (int argc
, char **argv
)
2008 error (EXIT_FAILURE
, 0, "usage: gen-auto-libm-tests <input> <output>");
2009 const char *input_filename
= argv
[1];
2010 const char *output_filename
= argv
[2];
2012 read_input (input_filename
);
2013 generate_output (output_filename
);
2014 exit (EXIT_SUCCESS
);