Get rid of Versions.def source file
[glibc.git] / math / gen-auto-libm-tests.c
blob61097e480cd7fd4a007cd70e8a6a5125294340ea
1 /* Generate expected output for libm tests with MPFR and MPC.
2 Copyright (C) 2013-2014 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
31 empty lines.
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
65 exception.
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
98 Bugzilla.
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" and "long64". Inputs and outputs are specified as hex
108 floats with the required suffix for the floating-point type, or
109 plus_infty or minus_infty for infinite expected results, or as
110 integer constant expressions (not necessarily with the right type)
111 or IGNORE for integer inputs and outputs. Flags are
112 "no-test-inline", "xfail", "<exception>", "<exception>-ok",
113 "errno-<value>", "errno-<value>-ok", which may be unconditional or
114 conditional. "<exception>" indicates that a correct result means
115 the given exception should be raised. "errno-<value>" indicates
116 that a correct result means errno should be set to the given value.
117 "-ok" means not to test for the given exception or errno value
118 (whether because it was marked as possibly missing or spurious, or
119 because the calculation of correct results indicated it was
120 optional). Conditions "before-rounding" and "after-rounding"
121 indicate tests where expectations for underflow exceptions depend
122 on how the architecture detects tininess. */
124 #define _GNU_SOURCE
126 #include <assert.h>
127 #include <ctype.h>
128 #include <errno.h>
129 #include <error.h>
130 #include <stdbool.h>
131 #include <stdint.h>
132 #include <stdio.h>
133 #include <stdlib.h>
134 #include <string.h>
136 #include <gmp.h>
137 #include <mpfr.h>
138 #include <mpc.h>
140 #define ARRAY_SIZE(A) (sizeof (A) / sizeof ((A)[0]))
142 /* The supported floating-point formats. */
143 typedef enum
145 fp_flt_32,
146 fp_dbl_64,
147 fp_ldbl_96_intel,
148 fp_ldbl_96_m68k,
149 fp_ldbl_128,
150 fp_ldbl_128ibm,
151 fp_num_formats,
152 fp_first_format = 0
153 } fp_format;
155 /* Structure describing a single floating-point format. */
156 typedef struct
158 /* The name of the format. */
159 const char *name;
160 /* The suffix to use on floating-point constants with this
161 format. */
162 const char *suffix;
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. */
167 int mant_dig;
168 /* The least N such that 2^N overflows. */
169 int max_exp;
170 /* One more than the least N such that 2^N is normal. */
171 int min_exp;
172 /* The largest normal value. */
173 mpfr_t max;
174 /* The least positive normal value, 2^(MIN_EXP-1). */
175 mpfr_t min;
176 /* The greatest positive subnormal value. */
177 mpfr_t subnorm_max;
178 /* The least positive subnormal value, 2^(MIN_EXP-MANT_DIG). */
179 mpfr_t subnorm_min;
180 } fp_format_desc;
182 /* List of floating-point formats, in the same order as the fp_format
183 enumeration. */
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. */
196 typedef enum
198 rm_downward,
199 rm_tonearest,
200 rm_towardzero,
201 rm_upward,
202 rm_num_modes,
203 rm_first_mode = 0
204 } rounding_mode;
206 /* Structure describing a single rounding mode. */
207 typedef struct
209 /* The name of the rounding mode. */
210 const char *name;
211 /* The MPFR rounding mode. */
212 mpfr_rnd_t mpfr_mode;
213 /* The MPC rounding mode. */
214 mpc_rnd_t mpc_mode;
215 } rounding_mode_desc;
217 /* List of rounding modes, in the same order as the rounding_mode
218 enumeration. */
219 static const rounding_mode_desc rounding_modes[rm_num_modes] =
221 { "downward", MPFR_RNDD, MPC_RNDDD },
222 { "tonearest", MPFR_RNDN, MPC_RNDNN },
223 { "towardzero", MPFR_RNDZ, MPC_RNDZZ },
224 { "upward", MPFR_RNDU, MPC_RNDUU },
227 /* The supported exceptions. */
228 typedef enum
230 exc_divbyzero,
231 exc_inexact,
232 exc_invalid,
233 exc_overflow,
234 exc_underflow,
235 exc_num_exceptions,
236 exc_first_exception = 0
237 } fp_exception;
239 /* List of exceptions, in the same order as the fp_exception
240 enumeration. */
241 static const char *const exceptions[exc_num_exceptions] =
243 "divbyzero",
244 "inexact",
245 "invalid",
246 "overflow",
247 "underflow",
250 /* The internal precision to use for most MPFR calculations, which
251 must be at least 2 more than the greatest precision of any
252 supported floating-point format. */
253 static int internal_precision;
255 /* A value that overflows all supported floating-point formats. */
256 static mpfr_t global_max;
258 /* A value that is at most half the least subnormal in any
259 floating-point format and so is rounded the same way as all
260 sufficiently small positive values. */
261 static mpfr_t global_min;
263 /* The maximum number of (real or integer) arguments to a function
264 handled by this program (complex arguments count as two real
265 arguments). */
266 #define MAX_NARGS 4
268 /* The maximum number of (real or integer) return values from a
269 function handled by this program. */
270 #define MAX_NRET 2
272 /* A type of a function argument or return value. */
273 typedef enum
275 /* No type (not a valid argument or return value). */
276 type_none,
277 /* A floating-point value with the type corresponding to that of
278 the function. */
279 type_fp,
280 /* An integer value of type int. */
281 type_int,
282 /* An integer value of type long. */
283 type_long,
284 /* An integer value of type long long. */
285 type_long_long,
286 } arg_ret_type;
288 /* A type of a generic real or integer value. */
289 typedef enum
291 /* No type. */
292 gtype_none,
293 /* Floating-point (represented with MPFR). */
294 gtype_fp,
295 /* Integer (represented with GMP). */
296 gtype_int,
297 } generic_value_type;
299 /* A generic value (argument or result). */
300 typedef struct
302 /* The type of this value. */
303 generic_value_type type;
304 /* Its value. */
305 union
307 mpfr_t f;
308 mpz_t i;
309 } value;
310 } generic_value;
312 /* A type of input flag. */
313 typedef enum
315 flag_no_test_inline,
316 flag_xfail,
317 flag_xfail_rounding,
318 /* The "spurious" and "missing" flags must be in the same order as
319 the fp_exception enumeration. */
320 flag_spurious_divbyzero,
321 flag_spurious_inexact,
322 flag_spurious_invalid,
323 flag_spurious_overflow,
324 flag_spurious_underflow,
325 flag_spurious_errno,
326 flag_missing_divbyzero,
327 flag_missing_inexact,
328 flag_missing_invalid,
329 flag_missing_overflow,
330 flag_missing_underflow,
331 flag_missing_errno,
332 num_input_flag_types,
333 flag_first_flag = 0,
334 flag_spurious_first = flag_spurious_divbyzero,
335 flag_missing_first = flag_missing_divbyzero
336 } input_flag_type;
338 /* List of flags, in the same order as the input_flag_type
339 enumeration. */
340 static const char *const input_flags[num_input_flag_types] =
342 "no-test-inline",
343 "xfail",
344 "xfail-rounding",
345 "spurious-divbyzero",
346 "spurious-inexact",
347 "spurious-invalid",
348 "spurious-overflow",
349 "spurious-underflow",
350 "spurious-errno",
351 "missing-divbyzero",
352 "missing-inexact",
353 "missing-invalid",
354 "missing-overflow",
355 "missing-underflow",
356 "missing-errno",
359 /* An input flag, possibly conditional. */
360 typedef struct
362 /* The type of this flag. */
363 input_flag_type type;
364 /* The conditions on this flag, as a string ":cond1:cond2..." or
365 NULL. */
366 const char *cond;
367 } input_flag;
369 /* Structure describing a single test from the input file (which may
370 expand into many tests in the output). The choice of function,
371 which implies the numbers and types of arguments and results, is
372 implicit rather than stored in this structure (except as part of
373 the source line). */
374 typedef struct
376 /* The text of the input line describing the test, including the
377 trailing newline. */
378 const char *line;
379 /* The number of combinations of interpretations of input values for
380 different floating-point formats and rounding modes. */
381 size_t num_input_cases;
382 /* The corresponding lists of inputs. */
383 generic_value **inputs;
384 /* The number of flags for this test. */
385 size_t num_flags;
386 /* The corresponding list of flags. */
387 input_flag *flags;
388 /* The old output for this test. */
389 const char *old_output;
390 } input_test;
392 /* Ways to calculate a function. */
393 typedef enum
395 /* MPFR function with a single argument and result. */
396 mpfr_f_f,
397 /* MPFR function with two arguments and one result. */
398 mpfr_ff_f,
399 /* MPFR function with three arguments and one result. */
400 mpfr_fff_f,
401 /* MPFR function with a single argument and floating-point and
402 integer results. */
403 mpfr_f_f1,
404 /* MPFR function with integer and floating-point arguments and one
405 result. */
406 mpfr_if_f,
407 /* MPFR function with a single argument and two floating-point
408 results. */
409 mpfr_f_11,
410 /* MPC function with a single complex argument and one real
411 result. */
412 mpc_c_f,
413 /* MPC function with a single complex argument and one complex
414 result. */
415 mpc_c_c,
416 /* MPC function with two complex arguments and one complex
417 result. */
418 mpc_cc_c,
419 } func_calc_method;
421 /* Description of how to calculate a function. */
422 typedef struct
424 /* Which method is used to calculate the function. */
425 func_calc_method method;
426 /* The specific function called. */
427 union
429 int (*mpfr_f_f) (mpfr_t, const mpfr_t, mpfr_rnd_t);
430 int (*mpfr_ff_f) (mpfr_t, const mpfr_t, const mpfr_t, mpfr_rnd_t);
431 int (*mpfr_fff_f) (mpfr_t, const mpfr_t, const mpfr_t, const mpfr_t,
432 mpfr_rnd_t);
433 int (*mpfr_f_f1) (mpfr_t, int *, const mpfr_t, mpfr_rnd_t);
434 int (*mpfr_if_f) (mpfr_t, long, const mpfr_t, mpfr_rnd_t);
435 int (*mpfr_f_11) (mpfr_t, mpfr_t, const mpfr_t, mpfr_rnd_t);
436 int (*mpc_c_f) (mpfr_t, const mpc_t, mpfr_rnd_t);
437 int (*mpc_c_c) (mpc_t, const mpc_t, mpc_rnd_t);
438 int (*mpc_cc_c) (mpc_t, const mpc_t, const mpc_t, mpc_rnd_t);
439 } func;
440 } func_calc_desc;
442 /* Structure describing a function handled by this program. */
443 typedef struct
445 /* The name of the function. */
446 const char *name;
447 /* The number of arguments. */
448 size_t num_args;
449 /* The types of the arguments. */
450 arg_ret_type arg_types[MAX_NARGS];
451 /* The number of return values. */
452 size_t num_ret;
453 /* The types of the return values. */
454 arg_ret_type ret_types[MAX_NRET];
455 /* Whether the function has exactly determined results and
456 exceptions. */
457 bool exact;
458 /* Whether the function is a complex function, so errno setting is
459 optional. */
460 bool complex_fn;
461 /* Whether to treat arguments given as floating-point constants as
462 exact only, rather than rounding them up and down to all
463 formats. */
464 bool exact_args;
465 /* How to calculate this function. */
466 func_calc_desc calc;
467 /* The number of tests allocated for this function. */
468 size_t num_tests_alloc;
469 /* The number of tests for this function. */
470 size_t num_tests;
471 /* The tests themselves. */
472 input_test *tests;
473 } test_function;
475 #define ARGS1(T1) 1, { T1 }
476 #define ARGS2(T1, T2) 2, { T1, T2 }
477 #define ARGS3(T1, T2, T3) 3, { T1, T2, T3 }
478 #define ARGS4(T1, T2, T3, T4) 4, { T1, T2, T3, T4 }
479 #define RET1(T1) 1, { T1 }
480 #define RET2(T1, T2) 2, { T1, T2 }
481 #define CALC(TYPE, FN) { TYPE, { .TYPE = FN } }
482 #define FUNC(NAME, ARGS, RET, EXACT, COMPLEX_FN, EXACT_ARGS, CALC) \
484 NAME, ARGS, RET, EXACT, COMPLEX_FN, EXACT_ARGS, CALC, 0, 0, NULL \
487 #define FUNC_mpfr_f_f(NAME, MPFR_FUNC, EXACT) \
488 FUNC (NAME, ARGS1 (type_fp), RET1 (type_fp), EXACT, false, false, \
489 CALC (mpfr_f_f, MPFR_FUNC))
490 #define FUNC_mpfr_ff_f(NAME, MPFR_FUNC, EXACT) \
491 FUNC (NAME, ARGS2 (type_fp, type_fp), RET1 (type_fp), EXACT, false, \
492 false, CALC (mpfr_ff_f, MPFR_FUNC))
493 #define FUNC_mpfr_if_f(NAME, MPFR_FUNC, EXACT) \
494 FUNC (NAME, ARGS2 (type_int, type_fp), RET1 (type_fp), EXACT, false, \
495 false, CALC (mpfr_if_f, MPFR_FUNC))
496 #define FUNC_mpc_c_f(NAME, MPFR_FUNC, EXACT) \
497 FUNC (NAME, ARGS2 (type_fp, type_fp), RET1 (type_fp), EXACT, true, \
498 false, CALC (mpc_c_f, MPFR_FUNC))
499 #define FUNC_mpc_c_c(NAME, MPFR_FUNC, EXACT) \
500 FUNC (NAME, ARGS2 (type_fp, type_fp), RET2 (type_fp, type_fp), EXACT, \
501 true, false, CALC (mpc_c_c, MPFR_FUNC))
503 /* List of functions handled by this program. */
504 static test_function test_functions[] =
506 FUNC_mpfr_f_f ("acos", mpfr_acos, false),
507 FUNC_mpfr_f_f ("acosh", mpfr_acosh, false),
508 FUNC_mpfr_f_f ("asin", mpfr_asin, false),
509 FUNC_mpfr_f_f ("asinh", mpfr_asinh, false),
510 FUNC_mpfr_f_f ("atan", mpfr_atan, false),
511 FUNC_mpfr_ff_f ("atan2", mpfr_atan2, false),
512 FUNC_mpfr_f_f ("atanh", mpfr_atanh, false),
513 FUNC_mpc_c_f ("cabs", mpc_abs, false),
514 FUNC_mpc_c_c ("cacos", mpc_acos, false),
515 FUNC_mpc_c_c ("cacosh", mpc_acosh, false),
516 FUNC_mpc_c_f ("carg", mpc_arg, false),
517 FUNC_mpc_c_c ("casin", mpc_asin, false),
518 FUNC_mpc_c_c ("casinh", mpc_asinh, false),
519 FUNC_mpc_c_c ("catan", mpc_atan, false),
520 FUNC_mpc_c_c ("catanh", mpc_atanh, false),
521 FUNC_mpfr_f_f ("cbrt", mpfr_cbrt, false),
522 FUNC_mpc_c_c ("ccos", mpc_cos, false),
523 FUNC_mpc_c_c ("ccosh", mpc_cosh, false),
524 FUNC_mpc_c_c ("cexp", mpc_exp, false),
525 FUNC_mpc_c_c ("clog", mpc_log, false),
526 FUNC_mpc_c_c ("clog10", mpc_log10, false),
527 FUNC_mpfr_f_f ("cos", mpfr_cos, false),
528 FUNC_mpfr_f_f ("cosh", mpfr_cosh, false),
529 FUNC ("cpow", ARGS4 (type_fp, type_fp, type_fp, type_fp),
530 RET2 (type_fp, type_fp), false, true, false,
531 CALC (mpc_cc_c, mpc_pow)),
532 FUNC_mpc_c_c ("csin", mpc_sin, false),
533 FUNC_mpc_c_c ("csinh", mpc_sinh, false),
534 FUNC_mpc_c_c ("csqrt", mpc_sqrt, false),
535 FUNC_mpc_c_c ("ctan", mpc_tan, false),
536 FUNC_mpc_c_c ("ctanh", mpc_tanh, false),
537 FUNC_mpfr_f_f ("erf", mpfr_erf, false),
538 FUNC_mpfr_f_f ("erfc", mpfr_erfc, false),
539 FUNC_mpfr_f_f ("exp", mpfr_exp, false),
540 FUNC_mpfr_f_f ("exp10", mpfr_exp10, false),
541 FUNC_mpfr_f_f ("exp2", mpfr_exp2, false),
542 FUNC_mpfr_f_f ("expm1", mpfr_expm1, false),
543 FUNC ("fma", ARGS3 (type_fp, type_fp, type_fp), RET1 (type_fp),
544 true, false, true, CALC (mpfr_fff_f, mpfr_fma)),
545 FUNC_mpfr_ff_f ("hypot", mpfr_hypot, false),
546 FUNC_mpfr_f_f ("j0", mpfr_j0, false),
547 FUNC_mpfr_f_f ("j1", mpfr_j1, false),
548 FUNC_mpfr_if_f ("jn", mpfr_jn, false),
549 FUNC ("lgamma", ARGS1 (type_fp), RET2 (type_fp, type_int), false, false,
550 false, CALC (mpfr_f_f1, mpfr_lgamma)),
551 FUNC_mpfr_f_f ("log", mpfr_log, false),
552 FUNC_mpfr_f_f ("log10", mpfr_log10, false),
553 FUNC_mpfr_f_f ("log1p", mpfr_log1p, false),
554 FUNC_mpfr_f_f ("log2", mpfr_log2, false),
555 FUNC_mpfr_ff_f ("pow", mpfr_pow, false),
556 FUNC_mpfr_f_f ("sin", mpfr_sin, false),
557 FUNC ("sincos", ARGS1 (type_fp), RET2 (type_fp, type_fp), false, false,
558 false, CALC (mpfr_f_11, mpfr_sin_cos)),
559 FUNC_mpfr_f_f ("sinh", mpfr_sinh, false),
560 FUNC_mpfr_f_f ("sqrt", mpfr_sqrt, true),
561 FUNC_mpfr_f_f ("tan", mpfr_tan, false),
562 FUNC_mpfr_f_f ("tanh", mpfr_tanh, false),
563 FUNC_mpfr_f_f ("tgamma", mpfr_gamma, false),
564 FUNC_mpfr_f_f ("y0", mpfr_y0, false),
565 FUNC_mpfr_f_f ("y1", mpfr_y1, false),
566 FUNC_mpfr_if_f ("yn", mpfr_yn, false),
569 /* Allocate memory, with error checking. */
571 static void *
572 xmalloc (size_t n)
574 void *p = malloc (n);
575 if (p == NULL)
576 error (EXIT_FAILURE, errno, "xmalloc failed");
577 return p;
580 static void *
581 xrealloc (void *p, size_t n)
583 p = realloc (p, n);
584 if (p == NULL)
585 error (EXIT_FAILURE, errno, "xrealloc failed");
586 return p;
589 static char *
590 xstrdup (const char *s)
592 char *p = strdup (s);
593 if (p == NULL)
594 error (EXIT_FAILURE, errno, "xstrdup failed");
595 return p;
598 /* Assert that the result of an MPFR operation was exact; that is,
599 that the returned ternary value was 0. */
601 static void
602 assert_exact (int i)
604 assert (i == 0);
607 /* Return the generic type of an argument or return value type T. */
609 static generic_value_type
610 generic_arg_ret_type (arg_ret_type t)
612 switch (t)
614 case type_fp:
615 return gtype_fp;
617 case type_int:
618 case type_long:
619 case type_long_long:
620 return gtype_int;
622 default:
623 abort ();
627 /* Free a generic_value *V. */
629 static void
630 generic_value_free (generic_value *v)
632 switch (v->type)
634 case gtype_fp:
635 mpfr_clear (v->value.f);
636 break;
638 case gtype_int:
639 mpz_clear (v->value.i);
640 break;
642 default:
643 abort ();
647 /* Copy a generic_value *SRC to *DEST. */
649 static void
650 generic_value_copy (generic_value *dest, const generic_value *src)
652 dest->type = src->type;
653 switch (src->type)
655 case gtype_fp:
656 mpfr_init (dest->value.f);
657 assert_exact (mpfr_set (dest->value.f, src->value.f, MPFR_RNDN));
658 break;
660 case gtype_int:
661 mpz_init (dest->value.i);
662 mpz_set (dest->value.i, src->value.i);
663 break;
665 default:
666 abort ();
670 /* Initialize data for floating-point formats. */
672 static void
673 init_fp_formats ()
675 int global_max_exp = 0, global_min_subnorm_exp = 0;
676 for (fp_format f = fp_first_format; f < fp_num_formats; f++)
678 if (fp_formats[f].mant_dig + 2 > internal_precision)
679 internal_precision = fp_formats[f].mant_dig + 2;
680 if (fp_formats[f].max_exp > global_max_exp)
681 global_max_exp = fp_formats[f].max_exp;
682 int min_subnorm_exp = fp_formats[f].min_exp - fp_formats[f].mant_dig;
683 if (min_subnorm_exp < global_min_subnorm_exp)
684 global_min_subnorm_exp = min_subnorm_exp;
685 mpfr_init2 (fp_formats[f].max, fp_formats[f].mant_dig);
686 if (fp_formats[f].max_string != NULL)
688 char *ep = NULL;
689 assert_exact (mpfr_strtofr (fp_formats[f].max,
690 fp_formats[f].max_string,
691 &ep, 0, MPFR_RNDN));
692 assert (*ep == 0);
694 else
696 assert_exact (mpfr_set_ui_2exp (fp_formats[f].max, 1,
697 fp_formats[f].max_exp,
698 MPFR_RNDN));
699 mpfr_nextbelow (fp_formats[f].max);
701 mpfr_init2 (fp_formats[f].min, fp_formats[f].mant_dig);
702 assert_exact (mpfr_set_ui_2exp (fp_formats[f].min, 1,
703 fp_formats[f].min_exp - 1,
704 MPFR_RNDN));
705 mpfr_init2 (fp_formats[f].subnorm_max, fp_formats[f].mant_dig);
706 assert_exact (mpfr_set (fp_formats[f].subnorm_max, fp_formats[f].min,
707 MPFR_RNDN));
708 mpfr_nextbelow (fp_formats[f].subnorm_max);
709 mpfr_nextbelow (fp_formats[f].subnorm_max);
710 mpfr_init2 (fp_formats[f].subnorm_min, fp_formats[f].mant_dig);
711 assert_exact (mpfr_set_ui_2exp (fp_formats[f].subnorm_min, 1,
712 min_subnorm_exp, MPFR_RNDN));
714 mpfr_set_default_prec (internal_precision);
715 mpfr_init (global_max);
716 assert_exact (mpfr_set_ui_2exp (global_max, 1, global_max_exp, MPFR_RNDN));
717 mpfr_init (global_min);
718 assert_exact (mpfr_set_ui_2exp (global_min, 1, global_min_subnorm_exp - 1,
719 MPFR_RNDN));
722 /* Fill in mpfr_t values for special strings in input arguments. */
724 static size_t
725 special_fill_max (mpfr_t res0, mpfr_t res1 __attribute__ ((unused)),
726 fp_format format)
728 mpfr_init2 (res0, fp_formats[format].mant_dig);
729 assert_exact (mpfr_set (res0, fp_formats[format].max, MPFR_RNDN));
730 return 1;
733 static size_t
734 special_fill_minus_max (mpfr_t res0, mpfr_t res1 __attribute__ ((unused)),
735 fp_format format)
737 mpfr_init2 (res0, fp_formats[format].mant_dig);
738 assert_exact (mpfr_neg (res0, fp_formats[format].max, MPFR_RNDN));
739 return 1;
742 static size_t
743 special_fill_min (mpfr_t res0, mpfr_t res1 __attribute__ ((unused)),
744 fp_format format)
746 mpfr_init2 (res0, fp_formats[format].mant_dig);
747 assert_exact (mpfr_set (res0, fp_formats[format].min, MPFR_RNDN));
748 return 1;
751 static size_t
752 special_fill_minus_min (mpfr_t res0, mpfr_t res1 __attribute__ ((unused)),
753 fp_format format)
755 mpfr_init2 (res0, fp_formats[format].mant_dig);
756 assert_exact (mpfr_neg (res0, fp_formats[format].min, MPFR_RNDN));
757 return 1;
760 static size_t
761 special_fill_min_subnorm (mpfr_t res0, mpfr_t res1 __attribute__ ((unused)),
762 fp_format format)
764 mpfr_init2 (res0, fp_formats[format].mant_dig);
765 assert_exact (mpfr_set (res0, fp_formats[format].subnorm_min, MPFR_RNDN));
766 return 1;
769 static size_t
770 special_fill_minus_min_subnorm (mpfr_t res0,
771 mpfr_t res1 __attribute__ ((unused)),
772 fp_format format)
774 mpfr_init2 (res0, fp_formats[format].mant_dig);
775 assert_exact (mpfr_neg (res0, fp_formats[format].subnorm_min, MPFR_RNDN));
776 return 1;
779 static size_t
780 special_fill_min_subnorm_p120 (mpfr_t res0,
781 mpfr_t res1 __attribute__ ((unused)),
782 fp_format format)
784 mpfr_init2 (res0, fp_formats[format].mant_dig);
785 assert_exact (mpfr_mul_2ui (res0, fp_formats[format].subnorm_min,
786 120, MPFR_RNDN));
787 return 1;
790 static size_t
791 special_fill_pi (mpfr_t res0, mpfr_t res1, fp_format format)
793 mpfr_init2 (res0, fp_formats[format].mant_dig);
794 mpfr_const_pi (res0, MPFR_RNDU);
795 mpfr_init2 (res1, fp_formats[format].mant_dig);
796 mpfr_const_pi (res1, MPFR_RNDD);
797 return 2;
800 static size_t
801 special_fill_minus_pi (mpfr_t res0, mpfr_t res1, fp_format format)
803 mpfr_init2 (res0, fp_formats[format].mant_dig);
804 mpfr_const_pi (res0, MPFR_RNDU);
805 assert_exact (mpfr_neg (res0, res0, MPFR_RNDN));
806 mpfr_init2 (res1, fp_formats[format].mant_dig);
807 mpfr_const_pi (res1, MPFR_RNDD);
808 assert_exact (mpfr_neg (res1, res1, MPFR_RNDN));
809 return 2;
812 static size_t
813 special_fill_pi_2 (mpfr_t res0, mpfr_t res1, fp_format format)
815 mpfr_init2 (res0, fp_formats[format].mant_dig);
816 mpfr_const_pi (res0, MPFR_RNDU);
817 assert_exact (mpfr_div_ui (res0, res0, 2, 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 return 2;
824 static size_t
825 special_fill_minus_pi_2 (mpfr_t res0, mpfr_t res1, fp_format format)
827 mpfr_init2 (res0, fp_formats[format].mant_dig);
828 mpfr_const_pi (res0, MPFR_RNDU);
829 assert_exact (mpfr_div_ui (res0, res0, 2, MPFR_RNDN));
830 assert_exact (mpfr_neg (res0, res0, MPFR_RNDN));
831 mpfr_init2 (res1, fp_formats[format].mant_dig);
832 mpfr_const_pi (res1, MPFR_RNDD);
833 assert_exact (mpfr_div_ui (res1, res1, 2, MPFR_RNDN));
834 assert_exact (mpfr_neg (res1, res1, MPFR_RNDN));
835 return 2;
838 static size_t
839 special_fill_pi_4 (mpfr_t res0, mpfr_t res1, fp_format format)
841 mpfr_init2 (res0, fp_formats[format].mant_dig);
842 assert_exact (mpfr_set_si (res0, 1, MPFR_RNDN));
843 mpfr_atan (res0, res0, MPFR_RNDU);
844 mpfr_init2 (res1, fp_formats[format].mant_dig);
845 assert_exact (mpfr_set_si (res1, 1, MPFR_RNDN));
846 mpfr_atan (res1, res1, MPFR_RNDD);
847 return 2;
850 static size_t
851 special_fill_pi_6 (mpfr_t res0, mpfr_t res1, fp_format format)
853 mpfr_init2 (res0, fp_formats[format].mant_dig);
854 assert_exact (mpfr_set_si_2exp (res0, 1, -1, MPFR_RNDN));
855 mpfr_asin (res0, res0, MPFR_RNDU);
856 mpfr_init2 (res1, fp_formats[format].mant_dig);
857 assert_exact (mpfr_set_si_2exp (res1, 1, -1, MPFR_RNDN));
858 mpfr_asin (res1, res1, MPFR_RNDD);
859 return 2;
862 static size_t
863 special_fill_minus_pi_6 (mpfr_t res0, mpfr_t res1, fp_format format)
865 mpfr_init2 (res0, fp_formats[format].mant_dig);
866 assert_exact (mpfr_set_si_2exp (res0, -1, -1, MPFR_RNDN));
867 mpfr_asin (res0, res0, MPFR_RNDU);
868 mpfr_init2 (res1, fp_formats[format].mant_dig);
869 assert_exact (mpfr_set_si_2exp (res1, -1, -1, MPFR_RNDN));
870 mpfr_asin (res1, res1, MPFR_RNDD);
871 return 2;
874 static size_t
875 special_fill_pi_3 (mpfr_t res0, mpfr_t res1, fp_format format)
877 mpfr_init2 (res0, fp_formats[format].mant_dig);
878 assert_exact (mpfr_set_si_2exp (res0, 1, -1, MPFR_RNDN));
879 mpfr_acos (res0, res0, MPFR_RNDU);
880 mpfr_init2 (res1, fp_formats[format].mant_dig);
881 assert_exact (mpfr_set_si_2exp (res1, 1, -1, MPFR_RNDN));
882 mpfr_acos (res1, res1, MPFR_RNDD);
883 return 2;
886 static size_t
887 special_fill_2pi_3 (mpfr_t res0, mpfr_t res1, fp_format format)
889 mpfr_init2 (res0, fp_formats[format].mant_dig);
890 assert_exact (mpfr_set_si_2exp (res0, -1, -1, MPFR_RNDN));
891 mpfr_acos (res0, res0, MPFR_RNDU);
892 mpfr_init2 (res1, fp_formats[format].mant_dig);
893 assert_exact (mpfr_set_si_2exp (res1, -1, -1, MPFR_RNDN));
894 mpfr_acos (res1, res1, MPFR_RNDD);
895 return 2;
898 static size_t
899 special_fill_2pi (mpfr_t res0, mpfr_t res1, fp_format format)
901 mpfr_init2 (res0, fp_formats[format].mant_dig);
902 mpfr_const_pi (res0, MPFR_RNDU);
903 assert_exact (mpfr_mul_ui (res0, res0, 2, MPFR_RNDN));
904 mpfr_init2 (res1, fp_formats[format].mant_dig);
905 mpfr_const_pi (res1, MPFR_RNDD);
906 assert_exact (mpfr_mul_ui (res1, res1, 2, MPFR_RNDN));
907 return 2;
910 static size_t
911 special_fill_e (mpfr_t res0, mpfr_t res1, fp_format format)
913 mpfr_init2 (res0, fp_formats[format].mant_dig);
914 assert_exact (mpfr_set_si (res0, 1, MPFR_RNDN));
915 mpfr_exp (res0, res0, MPFR_RNDU);
916 mpfr_init2 (res1, fp_formats[format].mant_dig);
917 assert_exact (mpfr_set_si (res1, 1, MPFR_RNDN));
918 mpfr_exp (res1, res1, MPFR_RNDD);
919 return 2;
922 static size_t
923 special_fill_1_e (mpfr_t res0, mpfr_t res1, fp_format format)
925 mpfr_init2 (res0, fp_formats[format].mant_dig);
926 assert_exact (mpfr_set_si (res0, -1, MPFR_RNDN));
927 mpfr_exp (res0, res0, MPFR_RNDU);
928 mpfr_init2 (res1, fp_formats[format].mant_dig);
929 assert_exact (mpfr_set_si (res1, -1, MPFR_RNDN));
930 mpfr_exp (res1, res1, MPFR_RNDD);
931 return 2;
934 static size_t
935 special_fill_e_minus_1 (mpfr_t res0, mpfr_t res1, fp_format format)
937 mpfr_init2 (res0, fp_formats[format].mant_dig);
938 assert_exact (mpfr_set_si (res0, 1, MPFR_RNDN));
939 mpfr_expm1 (res0, res0, MPFR_RNDU);
940 mpfr_init2 (res1, fp_formats[format].mant_dig);
941 assert_exact (mpfr_set_si (res1, 1, MPFR_RNDN));
942 mpfr_expm1 (res1, res1, MPFR_RNDD);
943 return 2;
946 /* A special string accepted in input arguments. */
947 typedef struct
949 /* The string. */
950 const char *str;
951 /* The function that interprets it for a given floating-point
952 format, filling in up to two mpfr_t values and returning the
953 number of values filled. */
954 size_t (*func) (mpfr_t, mpfr_t, fp_format);
955 } special_real_input;
957 /* List of special strings accepted in input arguments. */
959 static const special_real_input special_real_inputs[] =
961 { "max", special_fill_max },
962 { "-max", special_fill_minus_max },
963 { "min", special_fill_min },
964 { "-min", special_fill_minus_min },
965 { "min_subnorm", special_fill_min_subnorm },
966 { "-min_subnorm", special_fill_minus_min_subnorm },
967 { "min_subnorm_p120", special_fill_min_subnorm_p120 },
968 { "pi", special_fill_pi },
969 { "-pi", special_fill_minus_pi },
970 { "pi/2", special_fill_pi_2 },
971 { "-pi/2", special_fill_minus_pi_2 },
972 { "pi/4", special_fill_pi_4 },
973 { "pi/6", special_fill_pi_6 },
974 { "-pi/6", special_fill_minus_pi_6 },
975 { "pi/3", special_fill_pi_3 },
976 { "2pi/3", special_fill_2pi_3 },
977 { "2pi", special_fill_2pi },
978 { "e", special_fill_e },
979 { "1/e", special_fill_1_e },
980 { "e-1", special_fill_e_minus_1 },
983 /* Given a real number R computed in round-to-zero mode, set the
984 lowest bit as a sticky bit if INEXACT, and saturate the exponent
985 range for very large or small values. */
987 static void
988 adjust_real (mpfr_t r, bool inexact)
990 if (!inexact)
991 return;
992 /* NaNs are exact, as are infinities in round-to-zero mode. */
993 assert (mpfr_number_p (r));
994 if (mpfr_cmpabs (r, global_min) < 0)
995 assert_exact (mpfr_copysign (r, global_min, r, MPFR_RNDN));
996 else if (mpfr_cmpabs (r, global_max) > 0)
997 assert_exact (mpfr_copysign (r, global_max, r, MPFR_RNDN));
998 else
1000 mpz_t tmp;
1001 mpz_init (tmp);
1002 mpfr_exp_t e = mpfr_get_z_2exp (tmp, r);
1003 if (mpz_sgn (tmp) < 0)
1005 mpz_neg (tmp, tmp);
1006 mpz_setbit (tmp, 0);
1007 mpz_neg (tmp, tmp);
1009 else
1010 mpz_setbit (tmp, 0);
1011 assert_exact (mpfr_set_z_2exp (r, tmp, e, MPFR_RNDN));
1012 mpz_clear (tmp);
1016 /* Given a finite real number R with sticky bit, compute the roundings
1017 to FORMAT in each rounding mode, storing the results in RES, the
1018 before-rounding exceptions in EXC_BEFORE and the after-rounding
1019 exceptions in EXC_AFTER. */
1021 static void
1022 round_real (mpfr_t res[rm_num_modes],
1023 unsigned int exc_before[rm_num_modes],
1024 unsigned int exc_after[rm_num_modes],
1025 mpfr_t r, fp_format format)
1027 assert (mpfr_number_p (r));
1028 for (rounding_mode m = rm_first_mode; m < rm_num_modes; m++)
1030 mpfr_init2 (res[m], fp_formats[format].mant_dig);
1031 exc_before[m] = exc_after[m] = 0;
1032 bool inexact = mpfr_set (res[m], r, rounding_modes[m].mpfr_mode);
1033 if (mpfr_cmpabs (res[m], fp_formats[format].max) > 0)
1035 inexact = true;
1036 exc_before[m] |= 1U << exc_overflow;
1037 exc_after[m] |= 1U << exc_overflow;
1038 bool overflow_inf;
1039 switch (m)
1041 case rm_tonearest:
1042 overflow_inf = true;
1043 break;
1044 case rm_towardzero:
1045 overflow_inf = false;
1046 break;
1047 case rm_downward:
1048 overflow_inf = mpfr_signbit (res[m]);
1049 break;
1050 case rm_upward:
1051 overflow_inf = !mpfr_signbit (res[m]);
1052 break;
1053 default:
1054 abort ();
1056 if (overflow_inf)
1057 mpfr_set_inf (res[m], mpfr_signbit (res[m]) ? -1 : 1);
1058 else
1059 assert_exact (mpfr_copysign (res[m], fp_formats[format].max,
1060 res[m], MPFR_RNDN));
1062 if (mpfr_cmpabs (r, fp_formats[format].min) < 0)
1064 /* Tiny before rounding; may or may not be tiny after
1065 rounding, and underflow applies only if also inexact
1066 around rounding to a possibly subnormal value. */
1067 bool tiny_after_rounding
1068 = mpfr_cmpabs (res[m], fp_formats[format].min) < 0;
1069 /* To round to a possibly subnormal value, and determine
1070 inexactness as a subnormal in the process, scale up and
1071 round to integer, then scale back down. */
1072 mpfr_t tmp;
1073 mpfr_init (tmp);
1074 assert_exact (mpfr_mul_2si (tmp, r, (fp_formats[format].mant_dig
1075 - fp_formats[format].min_exp),
1076 MPFR_RNDN));
1077 int rint_res = mpfr_rint (tmp, tmp, rounding_modes[m].mpfr_mode);
1078 /* The integer must be representable. */
1079 assert (rint_res == 0 || rint_res == 2 || rint_res == -2);
1080 /* If rounding to full precision was inexact, so must
1081 rounding to subnormal precision be inexact. */
1082 if (inexact)
1083 assert (rint_res != 0);
1084 else
1085 inexact = rint_res != 0;
1086 assert_exact (mpfr_mul_2si (res[m], tmp,
1087 (fp_formats[format].min_exp
1088 - fp_formats[format].mant_dig),
1089 MPFR_RNDN));
1090 mpfr_clear (tmp);
1091 if (inexact)
1093 exc_before[m] |= 1U << exc_underflow;
1094 if (tiny_after_rounding)
1095 exc_after[m] |= 1U << exc_underflow;
1098 if (inexact)
1100 exc_before[m] |= 1U << exc_inexact;
1101 exc_after[m] |= 1U << exc_inexact;
1106 /* Handle the input argument at ARG (NUL-terminated), updating the
1107 lists of test inputs in IT accordingly. NUM_PREV_ARGS arguments
1108 are already in those lists. If EXACT_ARGS, interpret a value given
1109 as a floating-point constant exactly (it must be exact for some
1110 supported format) rather than rounding up and down. The argument,
1111 of type GTYPE, comes from file FILENAME, line LINENO. */
1113 static void
1114 handle_input_arg (const char *arg, input_test *it, size_t num_prev_args,
1115 generic_value_type gtype, bool exact_args,
1116 const char *filename, unsigned int lineno)
1118 size_t num_values = 0;
1119 generic_value values[2 * fp_num_formats];
1120 bool check_empty_list = false;
1121 switch (gtype)
1123 case gtype_fp:
1124 for (fp_format f = fp_first_format; f < fp_num_formats; f++)
1126 mpfr_t extra_values[2];
1127 size_t num_extra_values = 0;
1128 for (size_t i = 0; i < ARRAY_SIZE (special_real_inputs); i++)
1130 if (strcmp (arg, special_real_inputs[i].str) == 0)
1132 num_extra_values
1133 = special_real_inputs[i].func (extra_values[0],
1134 extra_values[1], f);
1135 assert (num_extra_values > 0
1136 && num_extra_values <= ARRAY_SIZE (extra_values));
1137 break;
1140 if (num_extra_values == 0)
1142 mpfr_t tmp;
1143 char *ep;
1144 if (exact_args)
1145 check_empty_list = true;
1146 mpfr_init (tmp);
1147 bool inexact = mpfr_strtofr (tmp, arg, &ep, 0, MPFR_RNDZ);
1148 if (*ep != 0 || !mpfr_number_p (tmp))
1149 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1150 "bad floating-point argument: '%s'", arg);
1151 adjust_real (tmp, inexact);
1152 mpfr_t rounded[rm_num_modes];
1153 unsigned int exc_before[rm_num_modes];
1154 unsigned int exc_after[rm_num_modes];
1155 round_real (rounded, exc_before, exc_after, tmp, f);
1156 mpfr_clear (tmp);
1157 if (mpfr_number_p (rounded[rm_upward])
1158 && (!exact_args || mpfr_equal_p (rounded[rm_upward],
1159 rounded[rm_downward])))
1161 mpfr_init2 (extra_values[num_extra_values],
1162 fp_formats[f].mant_dig);
1163 assert_exact (mpfr_set (extra_values[num_extra_values],
1164 rounded[rm_upward], MPFR_RNDN));
1165 num_extra_values++;
1167 if (mpfr_number_p (rounded[rm_downward]) && !exact_args)
1169 mpfr_init2 (extra_values[num_extra_values],
1170 fp_formats[f].mant_dig);
1171 assert_exact (mpfr_set (extra_values[num_extra_values],
1172 rounded[rm_downward], MPFR_RNDN));
1173 num_extra_values++;
1175 for (rounding_mode m = rm_first_mode; m < rm_num_modes; m++)
1176 mpfr_clear (rounded[m]);
1178 for (size_t i = 0; i < num_extra_values; i++)
1180 bool found = false;
1181 for (size_t j = 0; j < num_values; j++)
1183 if (mpfr_equal_p (values[j].value.f, extra_values[i])
1184 && ((mpfr_signbit (values[j].value.f) != 0)
1185 == (mpfr_signbit (extra_values[i]) != 0)))
1187 found = true;
1188 break;
1191 if (!found)
1193 assert (num_values < ARRAY_SIZE (values));
1194 values[num_values].type = gtype_fp;
1195 mpfr_init2 (values[num_values].value.f,
1196 fp_formats[f].mant_dig);
1197 assert_exact (mpfr_set (values[num_values].value.f,
1198 extra_values[i], MPFR_RNDN));
1199 num_values++;
1201 mpfr_clear (extra_values[i]);
1204 break;
1206 case gtype_int:
1207 num_values = 1;
1208 values[0].type = gtype_int;
1209 int ret = mpz_init_set_str (values[0].value.i, arg, 0);
1210 if (ret != 0)
1211 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1212 "bad integer argument: '%s'", arg);
1213 break;
1215 default:
1216 abort ();
1218 if (check_empty_list && num_values == 0)
1219 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1220 "floating-point argument not exact for any format: '%s'",
1221 arg);
1222 assert (num_values > 0 && num_values <= ARRAY_SIZE (values));
1223 if (it->num_input_cases >= SIZE_MAX / num_values)
1224 error_at_line (EXIT_FAILURE, 0, filename, lineno, "too many input cases");
1225 generic_value **old_inputs = it->inputs;
1226 size_t new_num_input_cases = it->num_input_cases * num_values;
1227 generic_value **new_inputs = xmalloc (new_num_input_cases
1228 * sizeof (new_inputs[0]));
1229 for (size_t i = 0; i < it->num_input_cases; i++)
1231 for (size_t j = 0; j < num_values; j++)
1233 size_t idx = i * num_values + j;
1234 new_inputs[idx] = xmalloc ((num_prev_args + 1)
1235 * sizeof (new_inputs[idx][0]));
1236 for (size_t k = 0; k < num_prev_args; k++)
1237 generic_value_copy (&new_inputs[idx][k], &old_inputs[i][k]);
1238 generic_value_copy (&new_inputs[idx][num_prev_args], &values[j]);
1240 for (size_t j = 0; j < num_prev_args; j++)
1241 generic_value_free (&old_inputs[i][j]);
1242 free (old_inputs[i]);
1244 free (old_inputs);
1245 for (size_t i = 0; i < num_values; i++)
1246 generic_value_free (&values[i]);
1247 it->inputs = new_inputs;
1248 it->num_input_cases = new_num_input_cases;
1251 /* Handle the input flag ARG (NUL-terminated), storing it in *FLAG.
1252 The flag comes from file FILENAME, line LINENO. */
1254 static void
1255 handle_input_flag (char *arg, input_flag *flag,
1256 const char *filename, unsigned int lineno)
1258 char *ep = strchr (arg, ':');
1259 if (ep == NULL)
1261 ep = strchr (arg, 0);
1262 assert (ep != NULL);
1264 char c = *ep;
1265 *ep = 0;
1266 bool found = false;
1267 for (input_flag_type i = flag_first_flag; i <= num_input_flag_types; i++)
1269 if (strcmp (arg, input_flags[i]) == 0)
1271 found = true;
1272 flag->type = i;
1273 break;
1276 if (!found)
1277 error_at_line (EXIT_FAILURE, 0, filename, lineno, "unknown flag: '%s'",
1278 arg);
1279 *ep = c;
1280 if (c == 0)
1281 flag->cond = NULL;
1282 else
1283 flag->cond = xstrdup (ep);
1286 /* Add the test LINE (file FILENAME, line LINENO) to the test
1287 data. */
1289 static void
1290 add_test (char *line, const char *filename, unsigned int lineno)
1292 size_t num_tokens = 1;
1293 char *p = line;
1294 while ((p = strchr (p, ' ')) != NULL)
1296 num_tokens++;
1297 p++;
1299 if (num_tokens < 2)
1300 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1301 "line too short: '%s'", line);
1302 p = strchr (line, ' ');
1303 size_t func_name_len = p - line;
1304 for (size_t i = 0; i < ARRAY_SIZE (test_functions); i++)
1306 if (func_name_len == strlen (test_functions[i].name)
1307 && strncmp (line, test_functions[i].name, func_name_len) == 0)
1309 test_function *tf = &test_functions[i];
1310 if (num_tokens < 1 + tf->num_args)
1311 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1312 "line too short: '%s'", line);
1313 if (tf->num_tests == tf->num_tests_alloc)
1315 tf->num_tests_alloc = 2 * tf->num_tests_alloc + 16;
1316 tf->tests
1317 = xrealloc (tf->tests,
1318 tf->num_tests_alloc * sizeof (tf->tests[0]));
1320 input_test *it = &tf->tests[tf->num_tests];
1321 it->line = line;
1322 it->num_input_cases = 1;
1323 it->inputs = xmalloc (sizeof (it->inputs[0]));
1324 it->inputs[0] = NULL;
1325 it->old_output = NULL;
1326 p++;
1327 for (size_t j = 0; j < tf->num_args; j++)
1329 char *ep = strchr (p, ' ');
1330 if (ep == NULL)
1332 ep = strchr (p, '\n');
1333 assert (ep != NULL);
1335 if (ep == p)
1336 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1337 "empty token in line: '%s'", line);
1338 for (char *t = p; t < ep; t++)
1339 if (isspace ((unsigned char) *t))
1340 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1341 "whitespace in token in line: '%s'", line);
1342 char c = *ep;
1343 *ep = 0;
1344 handle_input_arg (p, it, j,
1345 generic_arg_ret_type (tf->arg_types[j]),
1346 tf->exact_args, filename, lineno);
1347 *ep = c;
1348 p = ep + 1;
1350 it->num_flags = num_tokens - 1 - tf->num_args;
1351 it->flags = xmalloc (it->num_flags * sizeof (it->flags[0]));
1352 for (size_t j = 0; j < it->num_flags; j++)
1354 char *ep = strchr (p, ' ');
1355 if (ep == NULL)
1357 ep = strchr (p, '\n');
1358 assert (ep != NULL);
1360 if (ep == p)
1361 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1362 "empty token in line: '%s'", line);
1363 for (char *t = p; t < ep; t++)
1364 if (isspace ((unsigned char) *t))
1365 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1366 "whitespace in token in line: '%s'", line);
1367 char c = *ep;
1368 *ep = 0;
1369 handle_input_flag (p, &it->flags[j], filename, lineno);
1370 *ep = c;
1371 p = ep + 1;
1373 assert (*p == 0);
1374 tf->num_tests++;
1375 return;
1378 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1379 "unknown function in line: '%s'", line);
1382 /* Read in the test input data from FILENAME. */
1384 static void
1385 read_input (const char *filename)
1387 FILE *fp = fopen (filename, "r");
1388 if (fp == NULL)
1389 error (EXIT_FAILURE, errno, "open '%s'", filename);
1390 unsigned int lineno = 0;
1391 for (;;)
1393 size_t size = 0;
1394 char *line = NULL;
1395 ssize_t ret = getline (&line, &size, fp);
1396 if (ret == -1)
1397 break;
1398 lineno++;
1399 if (line[0] == '#' || line[0] == '\n')
1400 continue;
1401 add_test (line, filename, lineno);
1403 if (ferror (fp))
1404 error (EXIT_FAILURE, errno, "read from '%s'", filename);
1405 if (fclose (fp) != 0)
1406 error (EXIT_FAILURE, errno, "close '%s'", filename);
1409 /* Calculate the generic results (round-to-zero with sticky bit) for
1410 the function described by CALC, with inputs INPUTS, if MODE is
1411 rm_towardzero; for other modes, calculate results in that mode,
1412 which must be exact zero results. */
1414 static void
1415 calc_generic_results (generic_value *outputs, generic_value *inputs,
1416 const func_calc_desc *calc, rounding_mode mode)
1418 bool inexact;
1419 int mpc_ternary;
1420 mpc_t ci1, ci2, co;
1421 mpfr_rnd_t mode_mpfr = rounding_modes[mode].mpfr_mode;
1422 mpc_rnd_t mode_mpc = rounding_modes[mode].mpc_mode;
1424 switch (calc->method)
1426 case mpfr_f_f:
1427 assert (inputs[0].type == gtype_fp);
1428 outputs[0].type = gtype_fp;
1429 mpfr_init (outputs[0].value.f);
1430 inexact = calc->func.mpfr_f_f (outputs[0].value.f, inputs[0].value.f,
1431 mode_mpfr);
1432 if (mode != rm_towardzero)
1433 assert (!inexact && mpfr_zero_p (outputs[0].value.f));
1434 adjust_real (outputs[0].value.f, inexact);
1435 break;
1437 case mpfr_ff_f:
1438 assert (inputs[0].type == gtype_fp);
1439 assert (inputs[1].type == gtype_fp);
1440 outputs[0].type = gtype_fp;
1441 mpfr_init (outputs[0].value.f);
1442 inexact = calc->func.mpfr_ff_f (outputs[0].value.f, inputs[0].value.f,
1443 inputs[1].value.f, mode_mpfr);
1444 if (mode != rm_towardzero)
1445 assert (!inexact && mpfr_zero_p (outputs[0].value.f));
1446 adjust_real (outputs[0].value.f, inexact);
1447 break;
1449 case mpfr_fff_f:
1450 assert (inputs[0].type == gtype_fp);
1451 assert (inputs[1].type == gtype_fp);
1452 assert (inputs[2].type == gtype_fp);
1453 outputs[0].type = gtype_fp;
1454 mpfr_init (outputs[0].value.f);
1455 inexact = calc->func.mpfr_fff_f (outputs[0].value.f, inputs[0].value.f,
1456 inputs[1].value.f, inputs[2].value.f,
1457 mode_mpfr);
1458 if (mode != rm_towardzero)
1459 assert (!inexact && mpfr_zero_p (outputs[0].value.f));
1460 adjust_real (outputs[0].value.f, inexact);
1461 break;
1463 case mpfr_f_f1:
1464 assert (inputs[0].type == gtype_fp);
1465 outputs[0].type = gtype_fp;
1466 outputs[1].type = gtype_int;
1467 mpfr_init (outputs[0].value.f);
1468 int i = 0;
1469 inexact = calc->func.mpfr_f_f1 (outputs[0].value.f, &i,
1470 inputs[0].value.f, mode_mpfr);
1471 if (mode != rm_towardzero)
1472 assert (!inexact && mpfr_zero_p (outputs[0].value.f));
1473 adjust_real (outputs[0].value.f, inexact);
1474 mpz_init_set_si (outputs[1].value.i, i);
1475 break;
1477 case mpfr_if_f:
1478 assert (inputs[0].type == gtype_int);
1479 assert (inputs[1].type == gtype_fp);
1480 outputs[0].type = gtype_fp;
1481 mpfr_init (outputs[0].value.f);
1482 assert (mpz_fits_slong_p (inputs[0].value.i));
1483 long l = mpz_get_si (inputs[0].value.i);
1484 inexact = calc->func.mpfr_if_f (outputs[0].value.f, l,
1485 inputs[1].value.f, mode_mpfr);
1486 if (mode != rm_towardzero)
1487 assert (!inexact && mpfr_zero_p (outputs[0].value.f));
1488 adjust_real (outputs[0].value.f, inexact);
1489 break;
1491 case mpfr_f_11:
1492 assert (inputs[0].type == gtype_fp);
1493 outputs[0].type = gtype_fp;
1494 mpfr_init (outputs[0].value.f);
1495 outputs[1].type = gtype_fp;
1496 mpfr_init (outputs[1].value.f);
1497 int comb_ternary = calc->func.mpfr_f_11 (outputs[0].value.f,
1498 outputs[1].value.f,
1499 inputs[0].value.f,
1500 mode_mpfr);
1501 if (mode != rm_towardzero)
1502 assert (((comb_ternary & 0x3) == 0
1503 && mpfr_zero_p (outputs[0].value.f))
1504 || ((comb_ternary & 0xc) == 0
1505 && mpfr_zero_p (outputs[1].value.f)));
1506 adjust_real (outputs[0].value.f, (comb_ternary & 0x3) != 0);
1507 adjust_real (outputs[1].value.f, (comb_ternary & 0xc) != 0);
1508 break;
1510 case mpc_c_f:
1511 assert (inputs[0].type == gtype_fp);
1512 assert (inputs[1].type == gtype_fp);
1513 outputs[0].type = gtype_fp;
1514 mpfr_init (outputs[0].value.f);
1515 mpc_init2 (ci1, internal_precision);
1516 assert_exact (mpc_set_fr_fr (ci1, inputs[0].value.f, inputs[1].value.f,
1517 MPC_RNDNN));
1518 inexact = calc->func.mpc_c_f (outputs[0].value.f, ci1, mode_mpfr);
1519 if (mode != rm_towardzero)
1520 assert (!inexact && mpfr_zero_p (outputs[0].value.f));
1521 adjust_real (outputs[0].value.f, inexact);
1522 mpc_clear (ci1);
1523 break;
1525 case mpc_c_c:
1526 assert (inputs[0].type == gtype_fp);
1527 assert (inputs[1].type == gtype_fp);
1528 outputs[0].type = gtype_fp;
1529 mpfr_init (outputs[0].value.f);
1530 outputs[1].type = gtype_fp;
1531 mpfr_init (outputs[1].value.f);
1532 mpc_init2 (ci1, internal_precision);
1533 mpc_init2 (co, internal_precision);
1534 assert_exact (mpc_set_fr_fr (ci1, inputs[0].value.f, inputs[1].value.f,
1535 MPC_RNDNN));
1536 mpc_ternary = calc->func.mpc_c_c (co, ci1, mode_mpc);
1537 if (mode != rm_towardzero)
1538 assert ((!MPC_INEX_RE (mpc_ternary)
1539 && mpfr_zero_p (mpc_realref (co)))
1540 || (!MPC_INEX_IM (mpc_ternary)
1541 && mpfr_zero_p (mpc_imagref (co))));
1542 assert_exact (mpfr_set (outputs[0].value.f, mpc_realref (co),
1543 MPFR_RNDN));
1544 assert_exact (mpfr_set (outputs[1].value.f, mpc_imagref (co),
1545 MPFR_RNDN));
1546 adjust_real (outputs[0].value.f, MPC_INEX_RE (mpc_ternary));
1547 adjust_real (outputs[1].value.f, MPC_INEX_IM (mpc_ternary));
1548 mpc_clear (ci1);
1549 mpc_clear (co);
1550 break;
1552 case mpc_cc_c:
1553 assert (inputs[0].type == gtype_fp);
1554 assert (inputs[1].type == gtype_fp);
1555 assert (inputs[2].type == gtype_fp);
1556 assert (inputs[3].type == gtype_fp);
1557 outputs[0].type = gtype_fp;
1558 mpfr_init (outputs[0].value.f);
1559 outputs[1].type = gtype_fp;
1560 mpfr_init (outputs[1].value.f);
1561 mpc_init2 (ci1, internal_precision);
1562 mpc_init2 (ci2, internal_precision);
1563 mpc_init2 (co, internal_precision);
1564 assert_exact (mpc_set_fr_fr (ci1, inputs[0].value.f, inputs[1].value.f,
1565 MPC_RNDNN));
1566 assert_exact (mpc_set_fr_fr (ci2, inputs[2].value.f, inputs[3].value.f,
1567 MPC_RNDNN));
1568 mpc_ternary = calc->func.mpc_cc_c (co, ci1, ci2, mode_mpc);
1569 if (mode != rm_towardzero)
1570 assert ((!MPC_INEX_RE (mpc_ternary)
1571 && mpfr_zero_p (mpc_realref (co)))
1572 || (!MPC_INEX_IM (mpc_ternary)
1573 && mpfr_zero_p (mpc_imagref (co))));
1574 assert_exact (mpfr_set (outputs[0].value.f, mpc_realref (co),
1575 MPFR_RNDN));
1576 assert_exact (mpfr_set (outputs[1].value.f, mpc_imagref (co),
1577 MPFR_RNDN));
1578 adjust_real (outputs[0].value.f, MPC_INEX_RE (mpc_ternary));
1579 adjust_real (outputs[1].value.f, MPC_INEX_IM (mpc_ternary));
1580 mpc_clear (ci1);
1581 mpc_clear (ci2);
1582 mpc_clear (co);
1583 break;
1585 default:
1586 abort ();
1590 /* Return the number of bits for integer type TYPE, where "long" has
1591 LONG_BITS bits (32 or 64). */
1593 static int
1594 int_type_bits (arg_ret_type type, int long_bits)
1596 assert (long_bits == 32 || long_bits == 64);
1597 switch (type)
1599 case type_int:
1600 return 32;
1601 break;
1603 case type_long:
1604 return long_bits;
1605 break;
1607 case type_long_long:
1608 return 64;
1609 break;
1611 default:
1612 abort ();
1616 /* Check whether an integer Z fits a given type TYPE, where "long" has
1617 LONG_BITS bits (32 or 64). */
1619 static bool
1620 int_fits_type (mpz_t z, arg_ret_type type, int long_bits)
1622 int bits = int_type_bits (type, long_bits);
1623 bool ret = true;
1624 mpz_t t;
1625 mpz_init (t);
1626 mpz_ui_pow_ui (t, 2, bits - 1);
1627 if (mpz_cmp (z, t) >= 0)
1628 ret = false;
1629 mpz_neg (t, t);
1630 if (mpz_cmp (z, t) < 0)
1631 ret = false;
1632 mpz_clear (t);
1633 return ret;
1636 /* Print a generic value V to FP (name FILENAME), preceded by a space,
1637 for type TYPE, floating-point format FORMAT, LONG_BITS bits per
1638 long, printing " IGNORE" instead if IGNORE. */
1640 static void
1641 output_generic_value (FILE *fp, const char *filename, const generic_value *v,
1642 bool ignore, arg_ret_type type, fp_format format,
1643 int long_bits)
1645 if (ignore)
1647 if (fputs (" IGNORE", fp) < 0)
1648 error (EXIT_FAILURE, errno, "write to '%s'", filename);
1649 return;
1651 assert (v->type == generic_arg_ret_type (type));
1652 const char *suffix;
1653 switch (type)
1655 case type_fp:
1656 suffix = fp_formats[format].suffix;
1657 break;
1659 case type_int:
1660 suffix = "";
1661 break;
1663 case type_long:
1664 suffix = "L";
1665 break;
1667 case type_long_long:
1668 suffix = "LL";
1669 break;
1671 default:
1672 abort ();
1674 switch (v->type)
1676 case gtype_fp:
1677 if (mpfr_inf_p (v->value.f))
1679 if (fputs ((mpfr_signbit (v->value.f)
1680 ? " minus_infty" : " plus_infty"), fp) < 0)
1681 error (EXIT_FAILURE, errno, "write to '%s'", filename);
1683 else
1685 assert (mpfr_number_p (v->value.f));
1686 if (mpfr_fprintf (fp, " %Ra%s", v->value.f, suffix) < 0)
1687 error (EXIT_FAILURE, errno, "mpfr_fprintf to '%s'", filename);
1689 break;
1691 case gtype_int: ;
1692 int bits = int_type_bits (type, long_bits);
1693 mpz_t tmp;
1694 mpz_init (tmp);
1695 mpz_ui_pow_ui (tmp, 2, bits - 1);
1696 mpz_neg (tmp, tmp);
1697 if (mpz_cmp (v->value.i, tmp) == 0)
1699 mpz_add_ui (tmp, tmp, 1);
1700 if (mpfr_fprintf (fp, " (%Zd%s-1)", tmp, suffix) < 0)
1701 error (EXIT_FAILURE, errno, "mpfr_fprintf to '%s'", filename);
1703 else
1705 if (mpfr_fprintf (fp, " %Zd%s", v->value.i, suffix) < 0)
1706 error (EXIT_FAILURE, errno, "mpfr_fprintf to '%s'", filename);
1708 mpz_clear (tmp);
1709 break;
1711 default:
1712 abort ();
1716 /* Generate test output to FP (name FILENAME) for test function TF,
1717 input test IT, choice of input values INPUTS. */
1719 static void
1720 output_for_one_input_case (FILE *fp, const char *filename, test_function *tf,
1721 input_test *it, generic_value *inputs)
1723 bool long_bits_matters = false;
1724 bool fits_long32 = true;
1725 for (size_t i = 0; i < tf->num_args; i++)
1727 generic_value_type gtype = generic_arg_ret_type (tf->arg_types[i]);
1728 assert (inputs[i].type == gtype);
1729 if (gtype == gtype_int)
1731 bool fits_64 = int_fits_type (inputs[i].value.i, tf->arg_types[i],
1732 64);
1733 if (!fits_64)
1734 return;
1735 if (tf->arg_types[i] == type_long
1736 && !int_fits_type (inputs[i].value.i, tf->arg_types[i], 32))
1738 long_bits_matters = true;
1739 fits_long32 = false;
1743 generic_value generic_outputs[MAX_NRET];
1744 calc_generic_results (generic_outputs, inputs, &tf->calc, rm_towardzero);
1745 bool ignore_output_long32[MAX_NRET] = { false };
1746 bool ignore_output_long64[MAX_NRET] = { false };
1747 for (size_t i = 0; i < tf->num_ret; i++)
1749 assert (generic_outputs[i].type
1750 == generic_arg_ret_type (tf->ret_types[i]));
1751 switch (generic_outputs[i].type)
1753 case gtype_fp:
1754 if (!mpfr_number_p (generic_outputs[i].value.f))
1755 goto out; /* Result is NaN or exact infinity. */
1756 break;
1758 case gtype_int:
1759 ignore_output_long32[i] = !int_fits_type (generic_outputs[i].value.i,
1760 tf->ret_types[i], 32);
1761 ignore_output_long64[i] = !int_fits_type (generic_outputs[i].value.i,
1762 tf->ret_types[i], 64);
1763 if (ignore_output_long32[i] != ignore_output_long64[i])
1764 long_bits_matters = true;
1765 break;
1767 default:
1768 abort ();
1771 /* Iterate over relevant sizes of long and floating-point formats. */
1772 for (int long_bits = 32; long_bits <= 64; long_bits += 32)
1774 if (long_bits == 32 && !fits_long32)
1775 continue;
1776 if (long_bits == 64 && !long_bits_matters)
1777 continue;
1778 const char *long_cond;
1779 if (long_bits_matters)
1780 long_cond = (long_bits == 32 ? ":long32" : ":long64");
1781 else
1782 long_cond = "";
1783 bool *ignore_output = (long_bits == 32
1784 ? ignore_output_long32
1785 : ignore_output_long64);
1786 for (fp_format f = fp_first_format; f < fp_num_formats; f++)
1788 bool fits = true;
1789 mpfr_t res[rm_num_modes];
1790 unsigned int exc_before[rm_num_modes];
1791 unsigned int exc_after[rm_num_modes];
1792 for (size_t i = 0; i < tf->num_args; i++)
1794 if (inputs[i].type == gtype_fp)
1796 round_real (res, exc_before, exc_after, inputs[i].value.f,
1798 if (!mpfr_equal_p (res[rm_tonearest], inputs[i].value.f))
1799 fits = false;
1800 for (rounding_mode m = rm_first_mode; m < rm_num_modes; m++)
1801 mpfr_clear (res[m]);
1802 if (!fits)
1803 break;
1806 if (!fits)
1807 continue;
1808 /* The inputs fit this type, so compute the ideal outputs
1809 and exceptions. */
1810 mpfr_t all_res[MAX_NRET][rm_num_modes];
1811 unsigned int all_exc_before[MAX_NRET][rm_num_modes];
1812 unsigned int all_exc_after[MAX_NRET][rm_num_modes];
1813 unsigned int merged_exc_before[rm_num_modes] = { 0 };
1814 unsigned int merged_exc_after[rm_num_modes] = { 0 };
1815 /* For functions not exactly determined, track whether
1816 underflow is required (some result is inexact, and
1817 magnitude does not exceed the greatest magnitude
1818 subnormal), and permitted (not an exact zero, and
1819 magnitude does not exceed the least magnitude
1820 normal). */
1821 bool must_underflow = false;
1822 bool may_underflow = false;
1823 for (size_t i = 0; i < tf->num_ret; i++)
1825 switch (generic_outputs[i].type)
1827 case gtype_fp:
1828 round_real (all_res[i], all_exc_before[i], all_exc_after[i],
1829 generic_outputs[i].value.f, f);
1830 for (rounding_mode m = rm_first_mode; m < rm_num_modes; m++)
1832 merged_exc_before[m] |= all_exc_before[i][m];
1833 merged_exc_after[m] |= all_exc_after[i][m];
1834 if (!tf->exact)
1836 must_underflow
1837 |= ((all_exc_before[i][m]
1838 & (1U << exc_inexact)) != 0
1839 && (mpfr_cmpabs (generic_outputs[i].value.f,
1840 fp_formats[f].subnorm_max)
1841 <= 0));
1842 may_underflow
1843 |= (!mpfr_zero_p (generic_outputs[i].value.f)
1844 && mpfr_cmpabs (generic_outputs[i].value.f,
1845 fp_formats[f].min) <= 0);
1847 /* If the result is an exact zero, the sign may
1848 depend on the rounding mode, so recompute it
1849 directly in that mode. */
1850 if (mpfr_zero_p (all_res[i][m])
1851 && (all_exc_before[i][m] & (1U << exc_inexact)) == 0)
1853 generic_value outputs_rm[MAX_NRET];
1854 calc_generic_results (outputs_rm, inputs,
1855 &tf->calc, m);
1856 assert_exact (mpfr_set (all_res[i][m],
1857 outputs_rm[i].value.f,
1858 MPFR_RNDN));
1859 for (size_t j = 0; j < tf->num_ret; j++)
1860 generic_value_free (&outputs_rm[j]);
1863 break;
1865 case gtype_int:
1866 if (ignore_output[i])
1867 for (rounding_mode m = rm_first_mode;
1868 m < rm_num_modes;
1869 m++)
1871 merged_exc_before[m] |= 1U << exc_invalid;
1872 merged_exc_after[m] |= 1U << exc_invalid;
1874 break;
1876 default:
1877 abort ();
1880 assert (may_underflow || !must_underflow);
1881 for (rounding_mode m = rm_first_mode; m < rm_num_modes; m++)
1883 bool before_after_matters
1884 = tf->exact && merged_exc_before[m] != merged_exc_after[m];
1885 if (before_after_matters)
1887 assert ((merged_exc_before[m] ^ merged_exc_after[m])
1888 == (1U << exc_underflow));
1889 assert ((merged_exc_before[m] & (1U << exc_underflow)) != 0);
1891 unsigned int merged_exc = merged_exc_before[m];
1892 if (fprintf (fp, "= %s %s %s%s", tf->name,
1893 rounding_modes[m].name, fp_formats[f].name,
1894 long_cond) < 0)
1895 error (EXIT_FAILURE, errno, "write to '%s'", filename);
1896 /* Print inputs. */
1897 for (size_t i = 0; i < tf->num_args; i++)
1898 output_generic_value (fp, filename, &inputs[i], false,
1899 tf->arg_types[i], f, long_bits);
1900 if (fputs (" :", fp) < 0)
1901 error (EXIT_FAILURE, errno, "write to '%s'", filename);
1902 /* Print outputs. */
1903 bool must_erange = false;
1904 for (size_t i = 0; i < tf->num_ret; i++)
1906 generic_value g;
1907 g.type = generic_outputs[i].type;
1908 switch (g.type)
1910 case gtype_fp:
1911 if (mpfr_inf_p (all_res[i][m])
1912 && (all_exc_before[i][m]
1913 & (1U << exc_overflow)) != 0)
1914 must_erange = true;
1915 if (mpfr_zero_p (all_res[i][m])
1916 && (tf->exact
1917 || mpfr_zero_p (all_res[i][rm_tonearest]))
1918 && (all_exc_before[i][m]
1919 & (1U << exc_underflow)) != 0)
1920 must_erange = true;
1921 mpfr_init2 (g.value.f, fp_formats[f].mant_dig);
1922 assert_exact (mpfr_set (g.value.f, all_res[i][m],
1923 MPFR_RNDN));
1924 break;
1926 case gtype_int:
1927 mpz_init (g.value.i);
1928 mpz_set (g.value.i, generic_outputs[i].value.i);
1929 break;
1931 default:
1932 abort ();
1934 output_generic_value (fp, filename, &g, ignore_output[i],
1935 tf->ret_types[i], f, long_bits);
1936 generic_value_free (&g);
1938 if (fputs (" :", fp) < 0)
1939 error (EXIT_FAILURE, errno, "write to '%s'", filename);
1940 /* Print miscellaneous flags (passed through from
1941 input). */
1942 for (size_t i = 0; i < it->num_flags; i++)
1943 switch (it->flags[i].type)
1945 case flag_no_test_inline:
1946 case flag_xfail:
1947 if (fprintf (fp, " %s%s",
1948 input_flags[it->flags[i].type],
1949 (it->flags[i].cond
1950 ? it->flags[i].cond
1951 : "")) < 0)
1952 error (EXIT_FAILURE, errno, "write to '%s'",
1953 filename);
1954 break;
1955 case flag_xfail_rounding:
1956 if (m != rm_tonearest)
1957 if (fprintf (fp, " xfail%s",
1958 (it->flags[i].cond
1959 ? it->flags[i].cond
1960 : "")) < 0)
1961 error (EXIT_FAILURE, errno, "write to '%s'",
1962 filename);
1963 break;
1964 default:
1965 break;
1967 /* Print exception flags and compute errno
1968 expectations where not already computed. */
1969 bool may_edom = false;
1970 bool must_edom = false;
1971 bool may_erange = must_erange || may_underflow;
1972 for (fp_exception e = exc_first_exception;
1973 e < exc_num_exceptions;
1974 e++)
1976 bool expect_e = (merged_exc & (1U << e)) != 0;
1977 bool e_optional = false;
1978 switch (e)
1980 case exc_divbyzero:
1981 if (expect_e)
1982 may_erange = must_erange = true;
1983 break;
1985 case exc_inexact:
1986 if (!tf->exact)
1987 e_optional = true;
1988 break;
1990 case exc_invalid:
1991 if (expect_e)
1992 may_edom = must_edom = true;
1993 break;
1995 case exc_overflow:
1996 if (expect_e)
1997 may_erange = true;
1998 break;
2000 case exc_underflow:
2001 if (expect_e)
2002 may_erange = true;
2003 if (must_underflow)
2004 assert (expect_e);
2005 if (may_underflow && !must_underflow)
2006 e_optional = true;
2007 break;
2009 default:
2010 abort ();
2012 if (e_optional)
2014 assert (!before_after_matters);
2015 if (fprintf (fp, " %s-ok", exceptions[e]) < 0)
2016 error (EXIT_FAILURE, errno, "write to '%s'",
2017 filename);
2019 else
2021 if (expect_e)
2022 if (fprintf (fp, " %s", exceptions[e]) < 0)
2023 error (EXIT_FAILURE, errno, "write to '%s'",
2024 filename);
2025 if (before_after_matters && e == exc_underflow)
2026 if (fputs (":before-rounding", fp) < 0)
2027 error (EXIT_FAILURE, errno, "write to '%s'",
2028 filename);
2029 for (int after = 0; after <= 1; after++)
2031 bool expect_e_here = expect_e;
2032 if (after == 1 && (!before_after_matters
2033 || e != exc_underflow))
2034 continue;
2035 const char *after_cond;
2036 if (before_after_matters && e == exc_underflow)
2038 after_cond = (after
2039 ? ":after-rounding"
2040 : ":before-rounding");
2041 expect_e_here = !after;
2043 else
2044 after_cond = "";
2045 input_flag_type okflag;
2046 okflag = (expect_e_here
2047 ? flag_missing_first
2048 : flag_spurious_first) + e;
2049 for (size_t i = 0; i < it->num_flags; i++)
2050 if (it->flags[i].type == okflag)
2051 if (fprintf (fp, " %s-ok%s%s",
2052 exceptions[e],
2053 (it->flags[i].cond
2054 ? it->flags[i].cond
2055 : ""), after_cond) < 0)
2056 error (EXIT_FAILURE, errno, "write to '%s'",
2057 filename);
2061 /* Print errno expectations. */
2062 if (tf->complex_fn)
2064 must_edom = false;
2065 must_erange = false;
2067 if (may_edom && !must_edom)
2069 if (fputs (" errno-edom-ok", fp) < 0)
2070 error (EXIT_FAILURE, errno, "write to '%s'",
2071 filename);
2073 else
2075 if (must_edom)
2076 if (fputs (" errno-edom", fp) < 0)
2077 error (EXIT_FAILURE, errno, "write to '%s'",
2078 filename);
2079 input_flag_type okflag = (must_edom
2080 ? flag_missing_errno
2081 : flag_spurious_errno);
2082 for (size_t i = 0; i < it->num_flags; i++)
2083 if (it->flags[i].type == okflag)
2084 if (fprintf (fp, " errno-edom-ok%s",
2085 (it->flags[i].cond
2086 ? it->flags[i].cond
2087 : "")) < 0)
2088 error (EXIT_FAILURE, errno, "write to '%s'",
2089 filename);
2091 if (before_after_matters)
2092 assert (may_erange && !must_erange);
2093 if (may_erange && !must_erange)
2095 if (fprintf (fp, " errno-erange-ok%s",
2096 (before_after_matters
2097 ? ":before-rounding"
2098 : "")) < 0)
2099 error (EXIT_FAILURE, errno, "write to '%s'",
2100 filename);
2102 if (before_after_matters || !(may_erange && !must_erange))
2104 if (must_erange)
2105 if (fputs (" errno-erange", fp) < 0)
2106 error (EXIT_FAILURE, errno, "write to '%s'",
2107 filename);
2108 input_flag_type okflag = (must_erange
2109 ? flag_missing_errno
2110 : flag_spurious_errno);
2111 for (size_t i = 0; i < it->num_flags; i++)
2112 if (it->flags[i].type == okflag)
2113 if (fprintf (fp, " errno-erange-ok%s%s",
2114 (it->flags[i].cond
2115 ? it->flags[i].cond
2116 : ""),
2117 (before_after_matters
2118 ? ":after-rounding"
2119 : "")) < 0)
2120 error (EXIT_FAILURE, errno, "write to '%s'",
2121 filename);
2123 if (putc ('\n', fp) < 0)
2124 error (EXIT_FAILURE, errno, "write to '%s'", filename);
2126 for (size_t i = 0; i < tf->num_ret; i++)
2128 if (generic_outputs[i].type == gtype_fp)
2129 for (rounding_mode m = rm_first_mode; m < rm_num_modes; m++)
2130 mpfr_clear (all_res[i][m]);
2134 out:
2135 for (size_t i = 0; i < tf->num_ret; i++)
2136 generic_value_free (&generic_outputs[i]);
2139 /* Generate test output data to FILENAME. */
2141 static void
2142 generate_output (const char *filename)
2144 FILE *fp = fopen (filename, "w");
2145 if (fp == NULL)
2146 error (EXIT_FAILURE, errno, "open '%s'", filename);
2147 for (size_t i = 0; i < ARRAY_SIZE (test_functions); i++)
2149 test_function *tf = &test_functions[i];
2150 for (size_t j = 0; j < tf->num_tests; j++)
2152 input_test *it = &tf->tests[j];
2153 if (fputs (it->line, fp) < 0)
2154 error (EXIT_FAILURE, errno, "write to '%s'", filename);
2155 for (size_t k = 0; k < it->num_input_cases; k++)
2156 output_for_one_input_case (fp, filename, tf, it, it->inputs[k]);
2159 if (fclose (fp) != 0)
2160 error (EXIT_FAILURE, errno, "close '%s'", filename);
2164 main (int argc, char **argv)
2166 if (argc != 3)
2167 error (EXIT_FAILURE, 0, "usage: gen-auto-libm-tests <input> <output>");
2168 const char *input_filename = argv[1];
2169 const char *output_filename = argv[2];
2170 init_fp_formats ();
2171 read_input (input_filename);
2172 generate_output (output_filename);
2173 exit (EXIT_SUCCESS);