]> git.ipfire.org Git - thirdparty/glibc.git/blob - math/gen-auto-libm-tests.c
Update copyright notices with scripts/update-copyrights
[thirdparty/glibc.git] / math / gen-auto-libm-tests.c
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.
4
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.
9
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.
14
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/>. */
18
19 /* Compile this program as:
20
21 gcc -std=gnu99 -O2 -Wall -Wextra gen-auto-libm-tests.c -lmpc -lmpfr -lgmp \
22 -o gen-auto-libm-tests
23
24 (use of current MPC and MPFR versions recommended) and run it as:
25
26 gen-auto-libm-tests auto-libm-test-in auto-libm-test-out
27
28 The input file auto-libm-test-in contains three kinds of lines:
29
30 Lines beginning with "#" are comments, and are ignored, as are
31 empty lines.
32
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.
40
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)).
51
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.
66
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.
85
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.
99
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). */
123
124 #define _GNU_SOURCE
125
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>
135
136 #include <gmp.h>
137 #include <mpfr.h>
138 #include <mpc.h>
139
140 #define ARRAY_SIZE(A) (sizeof (A) / sizeof ((A)[0]))
141
142 /* The supported floating-point formats. */
143 typedef enum
144 {
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;
154
155 /* Structure describing a single floating-point format. */
156 typedef struct
157 {
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;
181
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] =
185 {
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, {}, {}, {}, {} },
193 };
194
195 /* The supported rounding modes. */
196 typedef enum
197 {
198 rm_downward,
199 rm_tonearest,
200 rm_towardzero,
201 rm_upward,
202 rm_num_modes,
203 rm_first_mode = 0
204 } rounding_mode;
205
206 /* Structure describing a single rounding mode. */
207 typedef struct
208 {
209 /* The name of the rounding mode. */
210 const char *name;
211 /* The MPFR rounding mode. */
212 mpfr_rnd_t mpfr_mode;
213 } rounding_mode_desc;
214
215 /* List of rounding modes, in the same order as the rounding_mode
216 enumeration. */
217 static const rounding_mode_desc rounding_modes[rm_num_modes] =
218 {
219 { "downward", MPFR_RNDD },
220 { "tonearest", MPFR_RNDN },
221 { "towardzero", MPFR_RNDZ },
222 { "upward", MPFR_RNDU },
223 };
224
225 /* The supported exceptions. */
226 typedef enum
227 {
228 exc_divbyzero,
229 exc_inexact,
230 exc_invalid,
231 exc_overflow,
232 exc_underflow,
233 exc_num_exceptions,
234 exc_first_exception = 0
235 } fp_exception;
236
237 /* List of exceptions, in the same order as the fp_exception
238 enumeration. */
239 static const char *const exceptions[exc_num_exceptions] =
240 {
241 "divbyzero",
242 "inexact",
243 "invalid",
244 "overflow",
245 "underflow",
246 };
247
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;
252
253 /* A value that overflows all supported floating-point formats. */
254 static mpfr_t global_max;
255
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;
260
261 /* The maximum number of (real or integer) arguments to a function
262 handled by this program (complex arguments count as two real
263 arguments). */
264 #define MAX_NARGS 4
265
266 /* The maximum number of (real or integer) return values from a
267 function handled by this program. */
268 #define MAX_NRET 2
269
270 /* A type of a function argument or return value. */
271 typedef enum
272 {
273 /* No type (not a valid argument or return value). */
274 type_none,
275 /* A floating-point value with the type corresponding to that of
276 the function. */
277 type_fp,
278 /* An integer value of type int. */
279 type_int,
280 /* An integer value of type long. */
281 type_long,
282 /* An integer value of type long long. */
283 type_long_long,
284 } arg_ret_type;
285
286 /* A type of a generic real or integer value. */
287 typedef enum
288 {
289 /* No type. */
290 gtype_none,
291 /* Floating-point (represented with MPFR). */
292 gtype_fp,
293 /* Integer (represented with GMP). */
294 gtype_int,
295 } generic_value_type;
296
297 /* A generic value (argument or result). */
298 typedef struct
299 {
300 /* The type of this value. */
301 generic_value_type type;
302 /* Its value. */
303 union
304 {
305 mpfr_t f;
306 mpz_t i;
307 } value;
308 } generic_value;
309
310 /* A type of input flag. */
311 typedef enum
312 {
313 flag_no_test_inline,
314 flag_xfail,
315 flag_xfail_rounding,
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,
323 flag_spurious_errno,
324 flag_missing_divbyzero,
325 flag_missing_inexact,
326 flag_missing_invalid,
327 flag_missing_overflow,
328 flag_missing_underflow,
329 flag_missing_errno,
330 num_input_flag_types,
331 flag_first_flag = 0,
332 flag_spurious_first = flag_spurious_divbyzero,
333 flag_missing_first = flag_missing_divbyzero
334 } input_flag_type;
335
336 /* List of flags, in the same order as the input_flag_type
337 enumeration. */
338 static const char *const input_flags[num_input_flag_types] =
339 {
340 "no-test-inline",
341 "xfail",
342 "xfail-rounding",
343 "spurious-divbyzero",
344 "spurious-inexact",
345 "spurious-invalid",
346 "spurious-overflow",
347 "spurious-underflow",
348 "spurious-errno",
349 "missing-divbyzero",
350 "missing-inexact",
351 "missing-invalid",
352 "missing-overflow",
353 "missing-underflow",
354 "missing-errno",
355 };
356
357 /* An input flag, possibly conditional. */
358 typedef struct
359 {
360 /* The type of this flag. */
361 input_flag_type type;
362 /* The conditions on this flag, as a string ":cond1:cond2..." or
363 NULL. */
364 const char *cond;
365 } input_flag;
366
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
371 the source line). */
372 typedef struct
373 {
374 /* The text of the input line describing the test, including the
375 trailing newline. */
376 const char *line;
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. */
383 size_t num_flags;
384 /* The corresponding list of flags. */
385 input_flag *flags;
386 /* The old output for this test. */
387 const char *old_output;
388 } input_test;
389
390 /* Ways to calculate a function. */
391 typedef enum
392 {
393 /* MPFR function with a single argument and result. */
394 mpfr_f_f,
395 /* MPFR function with two arguments and one result. */
396 mpfr_ff_f,
397 /* MPFR function with a single argument and floating-point and
398 integer results. */
399 mpfr_f_f1,
400 /* MPFR function with integer and floating-point arguments and one
401 result. */
402 mpfr_if_f,
403 /* MPFR function with a single argument and two floating-point
404 results. */
405 mpfr_f_11,
406 /* MPC function with a single complex argument and one real
407 result. */
408 mpc_c_f,
409 /* MPC function with a single complex argument and one complex
410 result. */
411 mpc_c_c,
412 /* MPC function with two complex arguments and one complex
413 result. */
414 mpc_cc_c,
415 } func_calc_method;
416
417 /* Description of how to calculate a function. */
418 typedef struct
419 {
420 /* Which method is used to calculate the function. */
421 func_calc_method method;
422 /* The specific function called. */
423 union
424 {
425 int (*mpfr_f_f) (mpfr_t, const mpfr_t, mpfr_rnd_t);
426 int (*mpfr_ff_f) (mpfr_t, const mpfr_t, const mpfr_t, mpfr_rnd_t);
427 int (*mpfr_f_f1) (mpfr_t, int *, const mpfr_t, mpfr_rnd_t);
428 int (*mpfr_if_f) (mpfr_t, long, const mpfr_t, mpfr_rnd_t);
429 int (*mpfr_f_11) (mpfr_t, mpfr_t, const mpfr_t, mpfr_rnd_t);
430 int (*mpc_c_f) (mpfr_t, const mpc_t, mpfr_rnd_t);
431 int (*mpc_c_c) (mpc_t, const mpc_t, mpc_rnd_t);
432 int (*mpc_cc_c) (mpc_t, const mpc_t, const mpc_t, mpc_rnd_t);
433 } func;
434 } func_calc_desc;
435
436 /* Structure describing a function handled by this program. */
437 typedef struct
438 {
439 /* The name of the function. */
440 const char *name;
441 /* The number of arguments. */
442 size_t num_args;
443 /* The types of the arguments. */
444 arg_ret_type arg_types[MAX_NARGS];
445 /* The number of return values. */
446 size_t num_ret;
447 /* The types of the return values. */
448 arg_ret_type ret_types[MAX_NRET];
449 /* Whether the function has exactly determined results and
450 exceptions. */
451 bool exact;
452 /* Whether the function is a complex function, so errno setting is
453 optional. */
454 bool complex_fn;
455 /* How to calculate this function. */
456 func_calc_desc calc;
457 /* The number of tests allocated for this function. */
458 size_t num_tests_alloc;
459 /* The number of tests for this function. */
460 size_t num_tests;
461 /* The tests themselves. */
462 input_test *tests;
463 } test_function;
464
465 #define ARGS1(T1) 1, { T1 }
466 #define ARGS2(T1, T2) 2, { T1, T2 }
467 #define ARGS3(T1, T2, T3) 3, { T1, T2, T3 }
468 #define ARGS4(T1, T2, T3, T4) 4, { T1, T2, T3, T4 }
469 #define RET1(T1) 1, { T1 }
470 #define RET2(T1, T2) 2, { T1, T2 }
471 #define CALC(TYPE, FN) { TYPE, { .TYPE = FN } }
472 #define FUNC(NAME, ARGS, RET, EXACT, COMPLEX_FN, CALC) \
473 { \
474 NAME, ARGS, RET, EXACT, COMPLEX_FN, CALC, 0, 0, NULL \
475 }
476
477 #define FUNC_mpfr_f_f(NAME, MPFR_FUNC, EXACT) \
478 FUNC (NAME, ARGS1 (type_fp), RET1 (type_fp), EXACT, false, \
479 CALC (mpfr_f_f, MPFR_FUNC))
480 #define FUNC_mpfr_ff_f(NAME, MPFR_FUNC, EXACT) \
481 FUNC (NAME, ARGS2 (type_fp, type_fp), RET1 (type_fp), EXACT, false, \
482 CALC (mpfr_ff_f, MPFR_FUNC))
483 #define FUNC_mpfr_if_f(NAME, MPFR_FUNC, EXACT) \
484 FUNC (NAME, ARGS2 (type_int, type_fp), RET1 (type_fp), EXACT, false, \
485 CALC (mpfr_if_f, MPFR_FUNC))
486 #define FUNC_mpc_c_f(NAME, MPFR_FUNC, EXACT) \
487 FUNC (NAME, ARGS2 (type_fp, type_fp), RET1 (type_fp), EXACT, true, \
488 CALC (mpc_c_f, MPFR_FUNC))
489 #define FUNC_mpc_c_c(NAME, MPFR_FUNC, EXACT) \
490 FUNC (NAME, ARGS2 (type_fp, type_fp), RET2 (type_fp, type_fp), EXACT, \
491 true, CALC (mpc_c_c, MPFR_FUNC))
492
493 /* List of functions handled by this program. */
494 static test_function test_functions[] =
495 {
496 FUNC_mpfr_f_f ("acos", mpfr_acos, false),
497 FUNC_mpfr_f_f ("acosh", mpfr_acosh, false),
498 FUNC_mpfr_f_f ("asin", mpfr_asin, false),
499 FUNC_mpfr_f_f ("asinh", mpfr_asinh, false),
500 FUNC_mpfr_f_f ("atan", mpfr_atan, false),
501 FUNC_mpfr_ff_f ("atan2", mpfr_atan2, false),
502 FUNC_mpfr_f_f ("atanh", mpfr_atanh, false),
503 FUNC_mpc_c_f ("cabs", mpc_abs, false),
504 FUNC_mpc_c_c ("cacos", mpc_acos, false),
505 FUNC_mpc_c_c ("cacosh", mpc_acosh, false),
506 FUNC_mpc_c_f ("carg", mpc_arg, false),
507 FUNC_mpc_c_c ("casin", mpc_asin, false),
508 FUNC_mpc_c_c ("casinh", mpc_asinh, false),
509 FUNC_mpc_c_c ("catan", mpc_atan, false),
510 FUNC_mpc_c_c ("catanh", mpc_atanh, false),
511 FUNC_mpfr_f_f ("cbrt", mpfr_cbrt, false),
512 FUNC_mpc_c_c ("ccos", mpc_cos, false),
513 FUNC_mpc_c_c ("ccosh", mpc_cosh, false),
514 FUNC_mpc_c_c ("cexp", mpc_exp, false),
515 FUNC_mpc_c_c ("clog", mpc_log, false),
516 FUNC_mpc_c_c ("clog10", mpc_log10, false),
517 FUNC_mpfr_f_f ("cos", mpfr_cos, false),
518 FUNC_mpfr_f_f ("cosh", mpfr_cosh, false),
519 FUNC ("cpow", ARGS4 (type_fp, type_fp, type_fp, type_fp),
520 RET2 (type_fp, type_fp), false, true, CALC (mpc_cc_c, mpc_pow)),
521 FUNC_mpc_c_c ("csin", mpc_sin, false),
522 FUNC_mpc_c_c ("csinh", mpc_sinh, false),
523 FUNC_mpc_c_c ("csqrt", mpc_sqrt, false),
524 FUNC_mpc_c_c ("ctan", mpc_tan, false),
525 FUNC_mpc_c_c ("ctanh", mpc_tanh, false),
526 FUNC_mpfr_f_f ("erf", mpfr_erf, false),
527 FUNC_mpfr_f_f ("erfc", mpfr_erfc, false),
528 FUNC_mpfr_f_f ("exp", mpfr_exp, false),
529 FUNC_mpfr_f_f ("exp10", mpfr_exp10, false),
530 FUNC_mpfr_f_f ("exp2", mpfr_exp2, false),
531 FUNC_mpfr_f_f ("expm1", mpfr_expm1, false),
532 FUNC_mpfr_ff_f ("hypot", mpfr_hypot, false),
533 FUNC_mpfr_f_f ("j0", mpfr_j0, false),
534 FUNC_mpfr_f_f ("j1", mpfr_j1, false),
535 FUNC_mpfr_if_f ("jn", mpfr_jn, false),
536 FUNC ("lgamma", ARGS1 (type_fp), RET2 (type_fp, type_int), false, false,
537 CALC (mpfr_f_f1, mpfr_lgamma)),
538 FUNC_mpfr_f_f ("log", mpfr_log, false),
539 FUNC_mpfr_f_f ("log10", mpfr_log10, false),
540 FUNC_mpfr_f_f ("log1p", mpfr_log1p, false),
541 FUNC_mpfr_f_f ("log2", mpfr_log2, false),
542 FUNC_mpfr_ff_f ("pow", mpfr_pow, false),
543 FUNC_mpfr_f_f ("sin", mpfr_sin, false),
544 FUNC ("sincos", ARGS1 (type_fp), RET2 (type_fp, type_fp), false, false,
545 CALC (mpfr_f_11, mpfr_sin_cos)),
546 FUNC_mpfr_f_f ("sinh", mpfr_sinh, false),
547 FUNC_mpfr_f_f ("sqrt", mpfr_sqrt, true),
548 FUNC_mpfr_f_f ("tan", mpfr_tan, false),
549 FUNC_mpfr_f_f ("tanh", mpfr_tanh, false),
550 FUNC_mpfr_f_f ("tgamma", mpfr_gamma, false),
551 FUNC_mpfr_f_f ("y0", mpfr_y0, false),
552 FUNC_mpfr_f_f ("y1", mpfr_y1, false),
553 FUNC_mpfr_if_f ("yn", mpfr_yn, false),
554 };
555
556 /* Allocate memory, with error checking. */
557
558 static void *
559 xmalloc (size_t n)
560 {
561 void *p = malloc (n);
562 if (p == NULL)
563 error (EXIT_FAILURE, errno, "xmalloc failed");
564 return p;
565 }
566
567 static void *
568 xrealloc (void *p, size_t n)
569 {
570 p = realloc (p, n);
571 if (p == NULL)
572 error (EXIT_FAILURE, errno, "xrealloc failed");
573 return p;
574 }
575
576 static char *
577 xstrdup (const char *s)
578 {
579 char *p = strdup (s);
580 if (p == NULL)
581 error (EXIT_FAILURE, errno, "xstrdup failed");
582 return p;
583 }
584
585 /* Assert that the result of an MPFR operation was exact; that is,
586 that the returned ternary value was 0. */
587
588 static void
589 assert_exact (int i)
590 {
591 assert (i == 0);
592 }
593
594 /* Return the generic type of an argument or return value type T. */
595
596 static generic_value_type
597 generic_arg_ret_type (arg_ret_type t)
598 {
599 switch (t)
600 {
601 case type_fp:
602 return gtype_fp;
603
604 case type_int:
605 case type_long:
606 case type_long_long:
607 return gtype_int;
608
609 default:
610 abort ();
611 }
612 }
613
614 /* Free a generic_value *V. */
615
616 static void
617 generic_value_free (generic_value *v)
618 {
619 switch (v->type)
620 {
621 case gtype_fp:
622 mpfr_clear (v->value.f);
623 break;
624
625 case gtype_int:
626 mpz_clear (v->value.i);
627 break;
628
629 default:
630 abort ();
631 }
632 }
633
634 /* Copy a generic_value *SRC to *DEST. */
635
636 static void
637 generic_value_copy (generic_value *dest, const generic_value *src)
638 {
639 dest->type = src->type;
640 switch (src->type)
641 {
642 case gtype_fp:
643 mpfr_init (dest->value.f);
644 assert_exact (mpfr_set (dest->value.f, src->value.f, MPFR_RNDN));
645 break;
646
647 case gtype_int:
648 mpz_init (dest->value.i);
649 mpz_set (dest->value.i, src->value.i);
650 break;
651
652 default:
653 abort ();
654 }
655 }
656
657 /* Initialize data for floating-point formats. */
658
659 static void
660 init_fp_formats ()
661 {
662 int global_max_exp = 0, global_min_subnorm_exp = 0;
663 for (fp_format f = fp_first_format; f < fp_num_formats; f++)
664 {
665 if (fp_formats[f].mant_dig + 2 > internal_precision)
666 internal_precision = fp_formats[f].mant_dig + 2;
667 if (fp_formats[f].max_exp > global_max_exp)
668 global_max_exp = fp_formats[f].max_exp;
669 int min_subnorm_exp = fp_formats[f].min_exp - fp_formats[f].mant_dig;
670 if (min_subnorm_exp < global_min_subnorm_exp)
671 global_min_subnorm_exp = min_subnorm_exp;
672 mpfr_init2 (fp_formats[f].max, fp_formats[f].mant_dig);
673 if (fp_formats[f].max_string != NULL)
674 {
675 char *ep = NULL;
676 assert_exact (mpfr_strtofr (fp_formats[f].max,
677 fp_formats[f].max_string,
678 &ep, 0, MPFR_RNDN));
679 assert (*ep == 0);
680 }
681 else
682 {
683 assert_exact (mpfr_set_ui_2exp (fp_formats[f].max, 1,
684 fp_formats[f].max_exp,
685 MPFR_RNDN));
686 mpfr_nextbelow (fp_formats[f].max);
687 }
688 mpfr_init2 (fp_formats[f].min, fp_formats[f].mant_dig);
689 assert_exact (mpfr_set_ui_2exp (fp_formats[f].min, 1,
690 fp_formats[f].min_exp - 1,
691 MPFR_RNDN));
692 mpfr_init2 (fp_formats[f].subnorm_max, fp_formats[f].mant_dig);
693 assert_exact (mpfr_set (fp_formats[f].subnorm_max, fp_formats[f].min,
694 MPFR_RNDN));
695 mpfr_nextbelow (fp_formats[f].subnorm_max);
696 mpfr_nextbelow (fp_formats[f].subnorm_max);
697 mpfr_init2 (fp_formats[f].subnorm_min, fp_formats[f].mant_dig);
698 assert_exact (mpfr_set_ui_2exp (fp_formats[f].subnorm_min, 1,
699 min_subnorm_exp, MPFR_RNDN));
700 }
701 mpfr_set_default_prec (internal_precision);
702 mpfr_init (global_max);
703 assert_exact (mpfr_set_ui_2exp (global_max, 1, global_max_exp, MPFR_RNDN));
704 mpfr_init (global_min);
705 assert_exact (mpfr_set_ui_2exp (global_min, 1, global_min_subnorm_exp - 1,
706 MPFR_RNDN));
707 }
708
709 /* Fill in mpfr_t values for special strings in input arguments. */
710
711 static size_t
712 special_fill_max (mpfr_t res0, mpfr_t res1 __attribute__ ((unused)),
713 fp_format format)
714 {
715 mpfr_init2 (res0, fp_formats[format].mant_dig);
716 assert_exact (mpfr_set (res0, fp_formats[format].max, MPFR_RNDN));
717 return 1;
718 }
719
720 static size_t
721 special_fill_minus_max (mpfr_t res0, mpfr_t res1 __attribute__ ((unused)),
722 fp_format format)
723 {
724 mpfr_init2 (res0, fp_formats[format].mant_dig);
725 assert_exact (mpfr_neg (res0, fp_formats[format].max, MPFR_RNDN));
726 return 1;
727 }
728
729 static size_t
730 special_fill_min (mpfr_t res0, mpfr_t res1 __attribute__ ((unused)),
731 fp_format format)
732 {
733 mpfr_init2 (res0, fp_formats[format].mant_dig);
734 assert_exact (mpfr_set (res0, fp_formats[format].min, MPFR_RNDN));
735 return 1;
736 }
737
738 static size_t
739 special_fill_minus_min (mpfr_t res0, mpfr_t res1 __attribute__ ((unused)),
740 fp_format format)
741 {
742 mpfr_init2 (res0, fp_formats[format].mant_dig);
743 assert_exact (mpfr_neg (res0, fp_formats[format].min, MPFR_RNDN));
744 return 1;
745 }
746
747 static size_t
748 special_fill_min_subnorm (mpfr_t res0, mpfr_t res1 __attribute__ ((unused)),
749 fp_format format)
750 {
751 mpfr_init2 (res0, fp_formats[format].mant_dig);
752 assert_exact (mpfr_set (res0, fp_formats[format].subnorm_min, MPFR_RNDN));
753 return 1;
754 }
755
756 static size_t
757 special_fill_minus_min_subnorm (mpfr_t res0,
758 mpfr_t res1 __attribute__ ((unused)),
759 fp_format format)
760 {
761 mpfr_init2 (res0, fp_formats[format].mant_dig);
762 assert_exact (mpfr_neg (res0, fp_formats[format].subnorm_min, MPFR_RNDN));
763 return 1;
764 }
765
766 static size_t
767 special_fill_min_subnorm_p120 (mpfr_t res0,
768 mpfr_t res1 __attribute__ ((unused)),
769 fp_format format)
770 {
771 mpfr_init2 (res0, fp_formats[format].mant_dig);
772 assert_exact (mpfr_mul_2ui (res0, fp_formats[format].subnorm_min,
773 120, MPFR_RNDN));
774 return 1;
775 }
776
777 static size_t
778 special_fill_pi (mpfr_t res0, mpfr_t res1, fp_format format)
779 {
780 mpfr_init2 (res0, fp_formats[format].mant_dig);
781 mpfr_const_pi (res0, MPFR_RNDU);
782 mpfr_init2 (res1, fp_formats[format].mant_dig);
783 mpfr_const_pi (res1, MPFR_RNDD);
784 return 2;
785 }
786
787 static size_t
788 special_fill_minus_pi (mpfr_t res0, mpfr_t res1, fp_format format)
789 {
790 mpfr_init2 (res0, fp_formats[format].mant_dig);
791 mpfr_const_pi (res0, MPFR_RNDU);
792 assert_exact (mpfr_neg (res0, res0, MPFR_RNDN));
793 mpfr_init2 (res1, fp_formats[format].mant_dig);
794 mpfr_const_pi (res1, MPFR_RNDD);
795 assert_exact (mpfr_neg (res1, res1, MPFR_RNDN));
796 return 2;
797 }
798
799 static size_t
800 special_fill_pi_2 (mpfr_t res0, mpfr_t res1, fp_format format)
801 {
802 mpfr_init2 (res0, fp_formats[format].mant_dig);
803 mpfr_const_pi (res0, MPFR_RNDU);
804 assert_exact (mpfr_div_ui (res0, res0, 2, MPFR_RNDN));
805 mpfr_init2 (res1, fp_formats[format].mant_dig);
806 mpfr_const_pi (res1, MPFR_RNDD);
807 assert_exact (mpfr_div_ui (res1, res1, 2, MPFR_RNDN));
808 return 2;
809 }
810
811 static size_t
812 special_fill_minus_pi_2 (mpfr_t res0, mpfr_t res1, fp_format format)
813 {
814 mpfr_init2 (res0, fp_formats[format].mant_dig);
815 mpfr_const_pi (res0, MPFR_RNDU);
816 assert_exact (mpfr_div_ui (res0, res0, 2, MPFR_RNDN));
817 assert_exact (mpfr_neg (res0, res0, MPFR_RNDN));
818 mpfr_init2 (res1, fp_formats[format].mant_dig);
819 mpfr_const_pi (res1, MPFR_RNDD);
820 assert_exact (mpfr_div_ui (res1, res1, 2, MPFR_RNDN));
821 assert_exact (mpfr_neg (res1, res1, MPFR_RNDN));
822 return 2;
823 }
824
825 static size_t
826 special_fill_pi_4 (mpfr_t res0, mpfr_t res1, fp_format format)
827 {
828 mpfr_init2 (res0, fp_formats[format].mant_dig);
829 assert_exact (mpfr_set_si (res0, 1, MPFR_RNDN));
830 mpfr_atan (res0, res0, MPFR_RNDU);
831 mpfr_init2 (res1, fp_formats[format].mant_dig);
832 assert_exact (mpfr_set_si (res1, 1, MPFR_RNDN));
833 mpfr_atan (res1, res1, MPFR_RNDD);
834 return 2;
835 }
836
837 static size_t
838 special_fill_pi_6 (mpfr_t res0, mpfr_t res1, fp_format format)
839 {
840 mpfr_init2 (res0, fp_formats[format].mant_dig);
841 assert_exact (mpfr_set_si_2exp (res0, 1, -1, MPFR_RNDN));
842 mpfr_asin (res0, res0, MPFR_RNDU);
843 mpfr_init2 (res1, fp_formats[format].mant_dig);
844 assert_exact (mpfr_set_si_2exp (res1, 1, -1, MPFR_RNDN));
845 mpfr_asin (res1, res1, MPFR_RNDD);
846 return 2;
847 }
848
849 static size_t
850 special_fill_minus_pi_6 (mpfr_t res0, mpfr_t res1, fp_format format)
851 {
852 mpfr_init2 (res0, fp_formats[format].mant_dig);
853 assert_exact (mpfr_set_si_2exp (res0, -1, -1, MPFR_RNDN));
854 mpfr_asin (res0, res0, MPFR_RNDU);
855 mpfr_init2 (res1, fp_formats[format].mant_dig);
856 assert_exact (mpfr_set_si_2exp (res1, -1, -1, MPFR_RNDN));
857 mpfr_asin (res1, res1, MPFR_RNDD);
858 return 2;
859 }
860
861 static size_t
862 special_fill_pi_3 (mpfr_t res0, mpfr_t res1, fp_format format)
863 {
864 mpfr_init2 (res0, fp_formats[format].mant_dig);
865 assert_exact (mpfr_set_si_2exp (res0, 1, -1, MPFR_RNDN));
866 mpfr_acos (res0, res0, MPFR_RNDU);
867 mpfr_init2 (res1, fp_formats[format].mant_dig);
868 assert_exact (mpfr_set_si_2exp (res1, 1, -1, MPFR_RNDN));
869 mpfr_acos (res1, res1, MPFR_RNDD);
870 return 2;
871 }
872
873 static size_t
874 special_fill_2pi_3 (mpfr_t res0, mpfr_t res1, fp_format format)
875 {
876 mpfr_init2 (res0, fp_formats[format].mant_dig);
877 assert_exact (mpfr_set_si_2exp (res0, -1, -1, MPFR_RNDN));
878 mpfr_acos (res0, res0, MPFR_RNDU);
879 mpfr_init2 (res1, fp_formats[format].mant_dig);
880 assert_exact (mpfr_set_si_2exp (res1, -1, -1, MPFR_RNDN));
881 mpfr_acos (res1, res1, MPFR_RNDD);
882 return 2;
883 }
884
885 static size_t
886 special_fill_2pi (mpfr_t res0, mpfr_t res1, fp_format format)
887 {
888 mpfr_init2 (res0, fp_formats[format].mant_dig);
889 mpfr_const_pi (res0, MPFR_RNDU);
890 assert_exact (mpfr_mul_ui (res0, res0, 2, MPFR_RNDN));
891 mpfr_init2 (res1, fp_formats[format].mant_dig);
892 mpfr_const_pi (res1, MPFR_RNDD);
893 assert_exact (mpfr_mul_ui (res1, res1, 2, MPFR_RNDN));
894 return 2;
895 }
896
897 static size_t
898 special_fill_e (mpfr_t res0, mpfr_t res1, fp_format format)
899 {
900 mpfr_init2 (res0, fp_formats[format].mant_dig);
901 assert_exact (mpfr_set_si (res0, 1, MPFR_RNDN));
902 mpfr_exp (res0, res0, MPFR_RNDU);
903 mpfr_init2 (res1, fp_formats[format].mant_dig);
904 assert_exact (mpfr_set_si (res1, 1, MPFR_RNDN));
905 mpfr_exp (res1, res1, MPFR_RNDD);
906 return 2;
907 }
908
909 static size_t
910 special_fill_1_e (mpfr_t res0, mpfr_t res1, fp_format format)
911 {
912 mpfr_init2 (res0, fp_formats[format].mant_dig);
913 assert_exact (mpfr_set_si (res0, -1, MPFR_RNDN));
914 mpfr_exp (res0, res0, MPFR_RNDU);
915 mpfr_init2 (res1, fp_formats[format].mant_dig);
916 assert_exact (mpfr_set_si (res1, -1, MPFR_RNDN));
917 mpfr_exp (res1, res1, MPFR_RNDD);
918 return 2;
919 }
920
921 static size_t
922 special_fill_e_minus_1 (mpfr_t res0, mpfr_t res1, fp_format format)
923 {
924 mpfr_init2 (res0, fp_formats[format].mant_dig);
925 assert_exact (mpfr_set_si (res0, 1, MPFR_RNDN));
926 mpfr_expm1 (res0, res0, MPFR_RNDU);
927 mpfr_init2 (res1, fp_formats[format].mant_dig);
928 assert_exact (mpfr_set_si (res1, 1, MPFR_RNDN));
929 mpfr_expm1 (res1, res1, MPFR_RNDD);
930 return 2;
931 }
932
933 /* A special string accepted in input arguments. */
934 typedef struct
935 {
936 /* The string. */
937 const char *str;
938 /* The function that interprets it for a given floating-point
939 format, filling in up to two mpfr_t values and returning the
940 number of values filled. */
941 size_t (*func) (mpfr_t, mpfr_t, fp_format);
942 } special_real_input;
943
944 /* List of special strings accepted in input arguments. */
945
946 static const special_real_input special_real_inputs[] =
947 {
948 { "max", special_fill_max },
949 { "-max", special_fill_minus_max },
950 { "min", special_fill_min },
951 { "-min", special_fill_minus_min },
952 { "min_subnorm", special_fill_min_subnorm },
953 { "-min_subnorm", special_fill_minus_min_subnorm },
954 { "min_subnorm_p120", special_fill_min_subnorm_p120 },
955 { "pi", special_fill_pi },
956 { "-pi", special_fill_minus_pi },
957 { "pi/2", special_fill_pi_2 },
958 { "-pi/2", special_fill_minus_pi_2 },
959 { "pi/4", special_fill_pi_4 },
960 { "pi/6", special_fill_pi_6 },
961 { "-pi/6", special_fill_minus_pi_6 },
962 { "pi/3", special_fill_pi_3 },
963 { "2pi/3", special_fill_2pi_3 },
964 { "2pi", special_fill_2pi },
965 { "e", special_fill_e },
966 { "1/e", special_fill_1_e },
967 { "e-1", special_fill_e_minus_1 },
968 };
969
970 /* Given a real number R computed in round-to-zero mode, set the
971 lowest bit as a sticky bit if INEXACT, and saturate the exponent
972 range for very large or small values. */
973
974 static void
975 adjust_real (mpfr_t r, bool inexact)
976 {
977 if (!inexact)
978 return;
979 /* NaNs are exact, as are infinities in round-to-zero mode. */
980 assert (mpfr_number_p (r));
981 if (mpfr_cmpabs (r, global_min) < 0)
982 assert_exact (mpfr_copysign (r, global_min, r, MPFR_RNDN));
983 else if (mpfr_cmpabs (r, global_max) > 0)
984 assert_exact (mpfr_copysign (r, global_max, r, MPFR_RNDN));
985 else
986 {
987 mpz_t tmp;
988 mpz_init (tmp);
989 mpfr_exp_t e = mpfr_get_z_2exp (tmp, r);
990 mpz_setbit (tmp, 0);
991 assert_exact (mpfr_set_z_2exp (r, tmp, e, MPFR_RNDN));
992 mpz_clear (tmp);
993 }
994 }
995
996 /* Given a finite real number R with sticky bit, compute the roundings
997 to FORMAT in each rounding mode, storing the results in RES, the
998 before-rounding exceptions in EXC_BEFORE and the after-rounding
999 exceptions in EXC_AFTER. */
1000
1001 static void
1002 round_real (mpfr_t res[rm_num_modes],
1003 unsigned int exc_before[rm_num_modes],
1004 unsigned int exc_after[rm_num_modes],
1005 mpfr_t r, fp_format format)
1006 {
1007 assert (mpfr_number_p (r));
1008 for (rounding_mode m = rm_first_mode; m < rm_num_modes; m++)
1009 {
1010 mpfr_init2 (res[m], fp_formats[format].mant_dig);
1011 exc_before[m] = exc_after[m] = 0;
1012 bool inexact = mpfr_set (res[m], r, rounding_modes[m].mpfr_mode);
1013 if (mpfr_cmpabs (res[m], fp_formats[format].max) > 0)
1014 {
1015 inexact = true;
1016 exc_before[m] |= 1U << exc_overflow;
1017 exc_after[m] |= 1U << exc_overflow;
1018 bool overflow_inf;
1019 switch (m)
1020 {
1021 case rm_tonearest:
1022 overflow_inf = true;
1023 break;
1024 case rm_towardzero:
1025 overflow_inf = false;
1026 break;
1027 case rm_downward:
1028 overflow_inf = mpfr_signbit (res[m]);
1029 break;
1030 case rm_upward:
1031 overflow_inf = !mpfr_signbit (res[m]);
1032 break;
1033 default:
1034 abort ();
1035 }
1036 if (overflow_inf)
1037 mpfr_set_inf (res[m], mpfr_signbit (res[m]) ? -1 : 1);
1038 else
1039 assert_exact (mpfr_copysign (res[m], fp_formats[format].max,
1040 res[m], MPFR_RNDN));
1041 }
1042 if (mpfr_cmpabs (r, fp_formats[format].min) < 0)
1043 {
1044 /* Tiny before rounding; may or may not be tiny after
1045 rounding, and underflow applies only if also inexact
1046 around rounding to a possibly subnormal value. */
1047 bool tiny_after_rounding
1048 = mpfr_cmpabs (res[m], fp_formats[format].min) < 0;
1049 /* To round to a possibly subnormal value, and determine
1050 inexactness as a subnormal in the process, scale up and
1051 round to integer, then scale back down. */
1052 mpfr_t tmp;
1053 mpfr_init (tmp);
1054 assert_exact (mpfr_mul_2si (tmp, r, (fp_formats[format].mant_dig
1055 - fp_formats[format].min_exp),
1056 MPFR_RNDN));
1057 int rint_res = mpfr_rint (tmp, tmp, rounding_modes[m].mpfr_mode);
1058 /* The integer must be representable. */
1059 assert (rint_res == 0 || rint_res == 2 || rint_res == -2);
1060 /* If rounding to full precision was inexact, so must
1061 rounding to subnormal precision be inexact. */
1062 if (inexact)
1063 assert (rint_res != 0);
1064 else
1065 inexact = rint_res != 0;
1066 assert_exact (mpfr_mul_2si (res[m], tmp,
1067 (fp_formats[format].min_exp
1068 - fp_formats[format].mant_dig),
1069 MPFR_RNDN));
1070 mpfr_clear (tmp);
1071 if (inexact)
1072 {
1073 exc_before[m] |= 1U << exc_underflow;
1074 if (tiny_after_rounding)
1075 exc_after[m] |= 1U << exc_underflow;
1076 }
1077 }
1078 if (inexact)
1079 {
1080 exc_before[m] |= 1U << exc_inexact;
1081 exc_after[m] |= 1U << exc_inexact;
1082 }
1083 }
1084 }
1085
1086 /* Handle the input argument at ARG (NUL-terminated), updating the
1087 lists of test inputs in IT accordingly. NUM_PREV_ARGS arguments
1088 are already in those lists. The argument, of type GTYPE, comes
1089 from file FILENAME, line LINENO. */
1090
1091 static void
1092 handle_input_arg (const char *arg, input_test *it, size_t num_prev_args,
1093 generic_value_type gtype,
1094 const char *filename, unsigned int lineno)
1095 {
1096 size_t num_values = 0;
1097 generic_value values[2 * fp_num_formats];
1098 switch (gtype)
1099 {
1100 case gtype_fp:
1101 for (fp_format f = fp_first_format; f < fp_num_formats; f++)
1102 {
1103 mpfr_t extra_values[2];
1104 size_t num_extra_values = 0;
1105 for (size_t i = 0; i < ARRAY_SIZE (special_real_inputs); i++)
1106 {
1107 if (strcmp (arg, special_real_inputs[i].str) == 0)
1108 {
1109 num_extra_values
1110 = special_real_inputs[i].func (extra_values[0],
1111 extra_values[1], f);
1112 assert (num_extra_values > 0
1113 && num_extra_values <= ARRAY_SIZE (extra_values));
1114 break;
1115 }
1116 }
1117 if (num_extra_values == 0)
1118 {
1119 mpfr_t tmp;
1120 char *ep;
1121 mpfr_init (tmp);
1122 bool inexact = mpfr_strtofr (tmp, arg, &ep, 0, MPFR_RNDZ);
1123 if (*ep != 0 || !mpfr_number_p (tmp))
1124 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1125 "bad floating-point argument: '%s'", arg);
1126 adjust_real (tmp, inexact);
1127 mpfr_t rounded[rm_num_modes];
1128 unsigned int exc_before[rm_num_modes];
1129 unsigned int exc_after[rm_num_modes];
1130 round_real (rounded, exc_before, exc_after, tmp, f);
1131 mpfr_clear (tmp);
1132 if (mpfr_number_p (rounded[rm_upward]))
1133 {
1134 mpfr_init2 (extra_values[num_extra_values],
1135 fp_formats[f].mant_dig);
1136 assert_exact (mpfr_set (extra_values[num_extra_values],
1137 rounded[rm_upward], MPFR_RNDN));
1138 num_extra_values++;
1139 }
1140 if (mpfr_number_p (rounded[rm_downward]))
1141 {
1142 mpfr_init2 (extra_values[num_extra_values],
1143 fp_formats[f].mant_dig);
1144 assert_exact (mpfr_set (extra_values[num_extra_values],
1145 rounded[rm_downward], MPFR_RNDN));
1146 num_extra_values++;
1147 }
1148 for (rounding_mode m = rm_first_mode; m < rm_num_modes; m++)
1149 mpfr_clear (rounded[m]);
1150 }
1151 for (size_t i = 0; i < num_extra_values; i++)
1152 {
1153 bool found = false;
1154 for (size_t j = 0; j < num_values; j++)
1155 {
1156 if (mpfr_equal_p (values[j].value.f, extra_values[i])
1157 && ((mpfr_signbit (values[j].value.f) != 0)
1158 == (mpfr_signbit (extra_values[i]) != 0)))
1159 {
1160 found = true;
1161 break;
1162 }
1163 }
1164 if (!found)
1165 {
1166 assert (num_values < ARRAY_SIZE (values));
1167 values[num_values].type = gtype_fp;
1168 mpfr_init2 (values[num_values].value.f,
1169 fp_formats[f].mant_dig);
1170 assert_exact (mpfr_set (values[num_values].value.f,
1171 extra_values[i], MPFR_RNDN));
1172 num_values++;
1173 }
1174 mpfr_clear (extra_values[i]);
1175 }
1176 }
1177 break;
1178
1179 case gtype_int:
1180 num_values = 1;
1181 values[0].type = gtype_int;
1182 int ret = mpz_init_set_str (values[0].value.i, arg, 0);
1183 if (ret != 0)
1184 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1185 "bad integer argument: '%s'", arg);
1186 break;
1187
1188 default:
1189 abort ();
1190 }
1191 assert (num_values > 0 && num_values <= ARRAY_SIZE (values));
1192 if (it->num_input_cases >= SIZE_MAX / num_values)
1193 error_at_line (EXIT_FAILURE, 0, filename, lineno, "too many input cases");
1194 generic_value **old_inputs = it->inputs;
1195 size_t new_num_input_cases = it->num_input_cases * num_values;
1196 generic_value **new_inputs = xmalloc (new_num_input_cases
1197 * sizeof (new_inputs[0]));
1198 for (size_t i = 0; i < it->num_input_cases; i++)
1199 {
1200 for (size_t j = 0; j < num_values; j++)
1201 {
1202 size_t idx = i * num_values + j;
1203 new_inputs[idx] = xmalloc ((num_prev_args + 1)
1204 * sizeof (new_inputs[idx][0]));
1205 for (size_t k = 0; k < num_prev_args; k++)
1206 generic_value_copy (&new_inputs[idx][k], &old_inputs[i][k]);
1207 generic_value_copy (&new_inputs[idx][num_prev_args], &values[j]);
1208 }
1209 for (size_t j = 0; j < num_prev_args; j++)
1210 generic_value_free (&old_inputs[i][j]);
1211 free (old_inputs[i]);
1212 }
1213 free (old_inputs);
1214 for (size_t i = 0; i < num_values; i++)
1215 generic_value_free (&values[i]);
1216 it->inputs = new_inputs;
1217 it->num_input_cases = new_num_input_cases;
1218 }
1219
1220 /* Handle the input flag ARG (NUL-terminated), storing it in *FLAG.
1221 The flag comes from file FILENAME, line LINENO. */
1222
1223 static void
1224 handle_input_flag (char *arg, input_flag *flag,
1225 const char *filename, unsigned int lineno)
1226 {
1227 char *ep = strchr (arg, ':');
1228 if (ep == NULL)
1229 {
1230 ep = strchr (arg, 0);
1231 assert (ep != NULL);
1232 }
1233 char c = *ep;
1234 *ep = 0;
1235 bool found = false;
1236 for (input_flag_type i = flag_first_flag; i <= num_input_flag_types; i++)
1237 {
1238 if (strcmp (arg, input_flags[i]) == 0)
1239 {
1240 found = true;
1241 flag->type = i;
1242 break;
1243 }
1244 }
1245 if (!found)
1246 error_at_line (EXIT_FAILURE, 0, filename, lineno, "unknown flag: '%s'",
1247 arg);
1248 *ep = c;
1249 if (c == 0)
1250 flag->cond = NULL;
1251 else
1252 flag->cond = xstrdup (ep);
1253 }
1254
1255 /* Add the test LINE (file FILENAME, line LINENO) to the test
1256 data. */
1257
1258 static void
1259 add_test (char *line, const char *filename, unsigned int lineno)
1260 {
1261 size_t num_tokens = 1;
1262 char *p = line;
1263 while ((p = strchr (p, ' ')) != NULL)
1264 {
1265 num_tokens++;
1266 p++;
1267 }
1268 if (num_tokens < 2)
1269 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1270 "line too short: '%s'", line);
1271 p = strchr (line, ' ');
1272 size_t func_name_len = p - line;
1273 for (size_t i = 0; i < ARRAY_SIZE (test_functions); i++)
1274 {
1275 if (func_name_len == strlen (test_functions[i].name)
1276 && strncmp (line, test_functions[i].name, func_name_len) == 0)
1277 {
1278 test_function *tf = &test_functions[i];
1279 if (num_tokens < 1 + tf->num_args)
1280 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1281 "line too short: '%s'", line);
1282 if (tf->num_tests == tf->num_tests_alloc)
1283 {
1284 tf->num_tests_alloc = 2 * tf->num_tests_alloc + 16;
1285 tf->tests
1286 = xrealloc (tf->tests,
1287 tf->num_tests_alloc * sizeof (tf->tests[0]));
1288 }
1289 input_test *it = &tf->tests[tf->num_tests];
1290 it->line = line;
1291 it->num_input_cases = 1;
1292 it->inputs = xmalloc (sizeof (it->inputs[0]));
1293 it->inputs[0] = NULL;
1294 it->old_output = NULL;
1295 p++;
1296 for (size_t j = 0; j < tf->num_args; j++)
1297 {
1298 char *ep = strchr (p, ' ');
1299 if (ep == NULL)
1300 {
1301 ep = strchr (p, '\n');
1302 assert (ep != NULL);
1303 }
1304 if (ep == p)
1305 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1306 "empty token in line: '%s'", line);
1307 for (char *t = p; t < ep; t++)
1308 if (isspace ((unsigned char) *t))
1309 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1310 "whitespace in token in line: '%s'", line);
1311 char c = *ep;
1312 *ep = 0;
1313 handle_input_arg (p, it, j,
1314 generic_arg_ret_type (tf->arg_types[j]),
1315 filename, lineno);
1316 *ep = c;
1317 p = ep + 1;
1318 }
1319 it->num_flags = num_tokens - 1 - tf->num_args;
1320 it->flags = xmalloc (it->num_flags * sizeof (it->flags[0]));
1321 for (size_t j = 0; j < it->num_flags; j++)
1322 {
1323 char *ep = strchr (p, ' ');
1324 if (ep == NULL)
1325 {
1326 ep = strchr (p, '\n');
1327 assert (ep != NULL);
1328 }
1329 if (ep == p)
1330 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1331 "empty token in line: '%s'", line);
1332 for (char *t = p; t < ep; t++)
1333 if (isspace ((unsigned char) *t))
1334 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1335 "whitespace in token in line: '%s'", line);
1336 char c = *ep;
1337 *ep = 0;
1338 handle_input_flag (p, &it->flags[j], filename, lineno);
1339 *ep = c;
1340 p = ep + 1;
1341 }
1342 assert (*p == 0);
1343 tf->num_tests++;
1344 return;
1345 }
1346 }
1347 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1348 "unknown function in line: '%s'", line);
1349 }
1350
1351 /* Read in the test input data from FILENAME. */
1352
1353 static void
1354 read_input (const char *filename)
1355 {
1356 FILE *fp = fopen (filename, "r");
1357 if (fp == NULL)
1358 error (EXIT_FAILURE, errno, "open '%s'", filename);
1359 unsigned int lineno = 0;
1360 for (;;)
1361 {
1362 size_t size = 0;
1363 char *line = NULL;
1364 ssize_t ret = getline (&line, &size, fp);
1365 if (ret == -1)
1366 break;
1367 lineno++;
1368 if (line[0] == '#' || line[0] == '\n')
1369 continue;
1370 add_test (line, filename, lineno);
1371 }
1372 if (ferror (fp))
1373 error (EXIT_FAILURE, errno, "read from '%s'", filename);
1374 if (fclose (fp) != 0)
1375 error (EXIT_FAILURE, errno, "close '%s'", filename);
1376 }
1377
1378 /* Calculate the generic results (round-to-zero with sticky bit) for
1379 the function described by CALC, with inputs INPUTS. */
1380
1381 static void
1382 calc_generic_results (generic_value *outputs, generic_value *inputs,
1383 const func_calc_desc *calc)
1384 {
1385 bool inexact;
1386 int mpc_ternary;
1387 mpc_t ci1, ci2, co;
1388
1389 switch (calc->method)
1390 {
1391 case mpfr_f_f:
1392 assert (inputs[0].type == gtype_fp);
1393 outputs[0].type = gtype_fp;
1394 mpfr_init (outputs[0].value.f);
1395 inexact = calc->func.mpfr_f_f (outputs[0].value.f, inputs[0].value.f,
1396 MPFR_RNDZ);
1397 adjust_real (outputs[0].value.f, inexact);
1398 break;
1399
1400 case mpfr_ff_f:
1401 assert (inputs[0].type == gtype_fp);
1402 assert (inputs[1].type == gtype_fp);
1403 outputs[0].type = gtype_fp;
1404 mpfr_init (outputs[0].value.f);
1405 inexact = calc->func.mpfr_ff_f (outputs[0].value.f, inputs[0].value.f,
1406 inputs[1].value.f, MPFR_RNDZ);
1407 adjust_real (outputs[0].value.f, inexact);
1408 break;
1409
1410 case mpfr_f_f1:
1411 assert (inputs[0].type == gtype_fp);
1412 outputs[0].type = gtype_fp;
1413 outputs[1].type = gtype_int;
1414 mpfr_init (outputs[0].value.f);
1415 int i = 0;
1416 inexact = calc->func.mpfr_f_f1 (outputs[0].value.f, &i,
1417 inputs[0].value.f, MPFR_RNDZ);
1418 adjust_real (outputs[0].value.f, inexact);
1419 mpz_init_set_si (outputs[1].value.i, i);
1420 break;
1421
1422 case mpfr_if_f:
1423 assert (inputs[0].type == gtype_int);
1424 assert (inputs[1].type == gtype_fp);
1425 outputs[0].type = gtype_fp;
1426 mpfr_init (outputs[0].value.f);
1427 assert (mpz_fits_slong_p (inputs[0].value.i));
1428 long l = mpz_get_si (inputs[0].value.i);
1429 inexact = calc->func.mpfr_if_f (outputs[0].value.f, l,
1430 inputs[1].value.f, MPFR_RNDZ);
1431 adjust_real (outputs[0].value.f, inexact);
1432 break;
1433
1434 case mpfr_f_11:
1435 assert (inputs[0].type == gtype_fp);
1436 outputs[0].type = gtype_fp;
1437 mpfr_init (outputs[0].value.f);
1438 outputs[1].type = gtype_fp;
1439 mpfr_init (outputs[1].value.f);
1440 int comb_ternary = calc->func.mpfr_f_11 (outputs[0].value.f,
1441 outputs[1].value.f,
1442 inputs[0].value.f,
1443 MPFR_RNDZ);
1444 adjust_real (outputs[0].value.f, (comb_ternary & 0x3) != 0);
1445 adjust_real (outputs[1].value.f, (comb_ternary & 0xc) != 0);
1446 break;
1447
1448 case mpc_c_f:
1449 assert (inputs[0].type == gtype_fp);
1450 assert (inputs[1].type == gtype_fp);
1451 outputs[0].type = gtype_fp;
1452 mpfr_init (outputs[0].value.f);
1453 mpc_init2 (ci1, internal_precision);
1454 assert_exact (mpc_set_fr_fr (ci1, inputs[0].value.f, inputs[1].value.f,
1455 MPC_RNDNN));
1456 inexact = calc->func.mpc_c_f (outputs[0].value.f, ci1, MPFR_RNDZ);
1457 adjust_real (outputs[0].value.f, inexact);
1458 mpc_clear (ci1);
1459 break;
1460
1461 case mpc_c_c:
1462 assert (inputs[0].type == gtype_fp);
1463 assert (inputs[1].type == gtype_fp);
1464 outputs[0].type = gtype_fp;
1465 mpfr_init (outputs[0].value.f);
1466 outputs[1].type = gtype_fp;
1467 mpfr_init (outputs[1].value.f);
1468 mpc_init2 (ci1, internal_precision);
1469 mpc_init2 (co, internal_precision);
1470 assert_exact (mpc_set_fr_fr (ci1, inputs[0].value.f, inputs[1].value.f,
1471 MPC_RNDNN));
1472 mpc_ternary = calc->func.mpc_c_c (co, ci1, MPC_RNDZZ);
1473 assert_exact (mpfr_set (outputs[0].value.f, mpc_realref (co),
1474 MPFR_RNDN));
1475 assert_exact (mpfr_set (outputs[1].value.f, mpc_imagref (co),
1476 MPFR_RNDN));
1477 adjust_real (outputs[0].value.f, MPC_INEX_RE (mpc_ternary));
1478 adjust_real (outputs[1].value.f, MPC_INEX_IM (mpc_ternary));
1479 mpc_clear (ci1);
1480 mpc_clear (co);
1481 break;
1482
1483 case mpc_cc_c:
1484 assert (inputs[0].type == gtype_fp);
1485 assert (inputs[1].type == gtype_fp);
1486 assert (inputs[2].type == gtype_fp);
1487 assert (inputs[3].type == gtype_fp);
1488 outputs[0].type = gtype_fp;
1489 mpfr_init (outputs[0].value.f);
1490 outputs[1].type = gtype_fp;
1491 mpfr_init (outputs[1].value.f);
1492 mpc_init2 (ci1, internal_precision);
1493 mpc_init2 (ci2, internal_precision);
1494 mpc_init2 (co, internal_precision);
1495 assert_exact (mpc_set_fr_fr (ci1, inputs[0].value.f, inputs[1].value.f,
1496 MPC_RNDNN));
1497 assert_exact (mpc_set_fr_fr (ci2, inputs[2].value.f, inputs[3].value.f,
1498 MPC_RNDNN));
1499 mpc_ternary = calc->func.mpc_cc_c (co, ci1, ci2, MPC_RNDZZ);
1500 assert_exact (mpfr_set (outputs[0].value.f, mpc_realref (co),
1501 MPFR_RNDN));
1502 assert_exact (mpfr_set (outputs[1].value.f, mpc_imagref (co),
1503 MPFR_RNDN));
1504 adjust_real (outputs[0].value.f, MPC_INEX_RE (mpc_ternary));
1505 adjust_real (outputs[1].value.f, MPC_INEX_IM (mpc_ternary));
1506 mpc_clear (ci1);
1507 mpc_clear (ci2);
1508 mpc_clear (co);
1509 break;
1510
1511 default:
1512 abort ();
1513 }
1514 }
1515
1516 /* Return the number of bits for integer type TYPE, where "long" has
1517 LONG_BITS bits (32 or 64). */
1518
1519 static int
1520 int_type_bits (arg_ret_type type, int long_bits)
1521 {
1522 assert (long_bits == 32 || long_bits == 64);
1523 switch (type)
1524 {
1525 case type_int:
1526 return 32;
1527 break;
1528
1529 case type_long:
1530 return long_bits;
1531 break;
1532
1533 case type_long_long:
1534 return 64;
1535 break;
1536
1537 default:
1538 abort ();
1539 }
1540 }
1541
1542 /* Check whether an integer Z fits a given type TYPE, where "long" has
1543 LONG_BITS bits (32 or 64). */
1544
1545 static bool
1546 int_fits_type (mpz_t z, arg_ret_type type, int long_bits)
1547 {
1548 int bits = int_type_bits (type, long_bits);
1549 bool ret = true;
1550 mpz_t t;
1551 mpz_init (t);
1552 mpz_ui_pow_ui (t, 2, bits - 1);
1553 if (mpz_cmp (z, t) >= 0)
1554 ret = false;
1555 mpz_neg (t, t);
1556 if (mpz_cmp (z, t) < 0)
1557 ret = false;
1558 mpz_clear (t);
1559 return ret;
1560 }
1561
1562 /* Print a generic value V to FP (name FILENAME), preceded by a space,
1563 for type TYPE, floating-point format FORMAT, LONG_BITS bits per
1564 long, printing " IGNORE" instead if IGNORE. */
1565
1566 static void
1567 output_generic_value (FILE *fp, const char *filename, const generic_value *v,
1568 bool ignore, arg_ret_type type, fp_format format,
1569 int long_bits)
1570 {
1571 if (ignore)
1572 {
1573 if (fputs (" IGNORE", fp) < 0)
1574 error (EXIT_FAILURE, errno, "write to '%s'", filename);
1575 return;
1576 }
1577 assert (v->type == generic_arg_ret_type (type));
1578 const char *suffix;
1579 switch (type)
1580 {
1581 case type_fp:
1582 suffix = fp_formats[format].suffix;
1583 break;
1584
1585 case type_int:
1586 suffix = "";
1587 break;
1588
1589 case type_long:
1590 suffix = "L";
1591 break;
1592
1593 case type_long_long:
1594 suffix = "LL";
1595 break;
1596
1597 default:
1598 abort ();
1599 }
1600 switch (v->type)
1601 {
1602 case gtype_fp:
1603 if (mpfr_inf_p (v->value.f))
1604 {
1605 if (fputs ((mpfr_signbit (v->value.f)
1606 ? " minus_infty" : " plus_infty"), fp) < 0)
1607 error (EXIT_FAILURE, errno, "write to '%s'", filename);
1608 }
1609 else
1610 {
1611 assert (mpfr_number_p (v->value.f));
1612 if (mpfr_fprintf (fp, " %Ra%s", v->value.f, suffix) < 0)
1613 error (EXIT_FAILURE, errno, "mpfr_fprintf to '%s'", filename);
1614 }
1615 break;
1616
1617 case gtype_int: ;
1618 int bits = int_type_bits (type, long_bits);
1619 mpz_t tmp;
1620 mpz_init (tmp);
1621 mpz_ui_pow_ui (tmp, 2, bits - 1);
1622 mpz_neg (tmp, tmp);
1623 if (mpz_cmp (v->value.i, tmp) == 0)
1624 {
1625 mpz_add_ui (tmp, tmp, 1);
1626 if (mpfr_fprintf (fp, " (%Zd%s-1)", tmp, suffix) < 0)
1627 error (EXIT_FAILURE, errno, "mpfr_fprintf to '%s'", filename);
1628 }
1629 else
1630 {
1631 if (mpfr_fprintf (fp, " %Zd%s", v->value.i, suffix) < 0)
1632 error (EXIT_FAILURE, errno, "mpfr_fprintf to '%s'", filename);
1633 }
1634 mpz_clear (tmp);
1635 break;
1636
1637 default:
1638 abort ();
1639 }
1640 }
1641
1642 /* Generate test output to FP (name FILENAME) for test function TF,
1643 input test IT, choice of input values INPUTS. */
1644
1645 static void
1646 output_for_one_input_case (FILE *fp, const char *filename, test_function *tf,
1647 input_test *it, generic_value *inputs)
1648 {
1649 bool long_bits_matters = false;
1650 bool fits_long32 = true;
1651 for (size_t i = 0; i < tf->num_args; i++)
1652 {
1653 generic_value_type gtype = generic_arg_ret_type (tf->arg_types[i]);
1654 assert (inputs[i].type == gtype);
1655 if (gtype == gtype_int)
1656 {
1657 bool fits_64 = int_fits_type (inputs[i].value.i, tf->arg_types[i],
1658 64);
1659 if (!fits_64)
1660 return;
1661 if (tf->arg_types[i] == type_long
1662 && !int_fits_type (inputs[i].value.i, tf->arg_types[i], 32))
1663 {
1664 long_bits_matters = true;
1665 fits_long32 = false;
1666 }
1667 }
1668 }
1669 generic_value generic_outputs[MAX_NRET];
1670 calc_generic_results (generic_outputs, inputs, &tf->calc);
1671 bool ignore_output_long32[MAX_NRET] = { false };
1672 bool ignore_output_long64[MAX_NRET] = { false };
1673 for (size_t i = 0; i < tf->num_ret; i++)
1674 {
1675 assert (generic_outputs[i].type
1676 == generic_arg_ret_type (tf->ret_types[i]));
1677 switch (generic_outputs[i].type)
1678 {
1679 case gtype_fp:
1680 if (!mpfr_number_p (generic_outputs[i].value.f))
1681 goto out; /* Result is NaN or exact infinity. */
1682 break;
1683
1684 case gtype_int:
1685 ignore_output_long32[i] = !int_fits_type (generic_outputs[i].value.i,
1686 tf->ret_types[i], 32);
1687 ignore_output_long64[i] = !int_fits_type (generic_outputs[i].value.i,
1688 tf->ret_types[i], 64);
1689 if (ignore_output_long32[i] != ignore_output_long64[i])
1690 long_bits_matters = true;
1691 break;
1692
1693 default:
1694 abort ();
1695 }
1696 }
1697 /* Iterate over relevant sizes of long and floating-point formats. */
1698 for (int long_bits = 32; long_bits <= 64; long_bits += 32)
1699 {
1700 if (long_bits == 32 && !fits_long32)
1701 continue;
1702 if (long_bits == 64 && !long_bits_matters)
1703 continue;
1704 const char *long_cond;
1705 if (long_bits_matters)
1706 long_cond = (long_bits == 32 ? ":long32" : ":long64");
1707 else
1708 long_cond = "";
1709 bool *ignore_output = (long_bits == 32
1710 ? ignore_output_long32
1711 : ignore_output_long64);
1712 for (fp_format f = fp_first_format; f < fp_num_formats; f++)
1713 {
1714 bool fits = true;
1715 mpfr_t res[rm_num_modes];
1716 unsigned int exc_before[rm_num_modes];
1717 unsigned int exc_after[rm_num_modes];
1718 for (size_t i = 0; i < tf->num_args; i++)
1719 {
1720 if (inputs[i].type == gtype_fp)
1721 {
1722 round_real (res, exc_before, exc_after, inputs[i].value.f,
1723 f);
1724 if (!mpfr_equal_p (res[rm_tonearest], inputs[i].value.f))
1725 fits = false;
1726 for (rounding_mode m = rm_first_mode; m < rm_num_modes; m++)
1727 mpfr_clear (res[m]);
1728 if (!fits)
1729 break;
1730 }
1731 }
1732 if (!fits)
1733 continue;
1734 /* The inputs fit this type, so compute the ideal outputs
1735 and exceptions. */
1736 mpfr_t all_res[MAX_NRET][rm_num_modes];
1737 unsigned int all_exc_before[MAX_NRET][rm_num_modes];
1738 unsigned int all_exc_after[MAX_NRET][rm_num_modes];
1739 unsigned int merged_exc_before[rm_num_modes] = { 0 };
1740 unsigned int merged_exc_after[rm_num_modes] = { 0 };
1741 /* For functions not exactly determined, track whether
1742 underflow is required (some result is inexact, and
1743 magnitude does not exceed the greatest magnitude
1744 subnormal), and permitted (not an exact zero, and
1745 magnitude does not exceed the least magnitude
1746 normal). */
1747 bool must_underflow = false;
1748 bool may_underflow = false;
1749 for (size_t i = 0; i < tf->num_ret; i++)
1750 {
1751 switch (generic_outputs[i].type)
1752 {
1753 case gtype_fp:
1754 round_real (all_res[i], all_exc_before[i], all_exc_after[i],
1755 generic_outputs[i].value.f, f);
1756 for (rounding_mode m = rm_first_mode; m < rm_num_modes; m++)
1757 {
1758 merged_exc_before[m] |= all_exc_before[i][m];
1759 merged_exc_after[m] |= all_exc_after[i][m];
1760 if (!tf->exact)
1761 {
1762 must_underflow
1763 |= ((all_exc_before[i][m]
1764 & (1U << exc_inexact)) != 0
1765 && (mpfr_cmpabs (generic_outputs[i].value.f,
1766 fp_formats[f].subnorm_max)
1767 <= 0));
1768 may_underflow
1769 |= (!mpfr_zero_p (generic_outputs[i].value.f)
1770 && mpfr_cmpabs (generic_outputs[i].value.f,
1771 fp_formats[f].min) <= 0);
1772 }
1773 }
1774 break;
1775
1776 case gtype_int:
1777 if (ignore_output[i])
1778 for (rounding_mode m = rm_first_mode;
1779 m < rm_num_modes;
1780 m++)
1781 {
1782 merged_exc_before[m] |= 1U << exc_invalid;
1783 merged_exc_after[m] |= 1U << exc_invalid;
1784 }
1785 break;
1786
1787 default:
1788 abort ();
1789 }
1790 }
1791 assert (may_underflow || !must_underflow);
1792 for (rounding_mode m = rm_first_mode; m < rm_num_modes; m++)
1793 {
1794 bool before_after_matters
1795 = tf->exact && merged_exc_before[m] != merged_exc_after[m];
1796 for (int after = 0; after <= 1; after++)
1797 {
1798 if (after == 1 && !before_after_matters)
1799 continue;
1800 const char *after_cond;
1801 if (before_after_matters)
1802 after_cond = (after
1803 ? ":after-rounding"
1804 : ":before-rounding");
1805 else
1806 after_cond = "";
1807 unsigned int merged_exc = (after
1808 ? merged_exc_after[m]
1809 : merged_exc_before[m]);
1810 if (fprintf (fp, "= %s %s %s%s%s", tf->name,
1811 rounding_modes[m].name, fp_formats[f].name,
1812 long_cond, after_cond) < 0)
1813 error (EXIT_FAILURE, errno, "write to '%s'", filename);
1814 /* Print inputs. */
1815 for (size_t i = 0; i < tf->num_args; i++)
1816 output_generic_value (fp, filename, &inputs[i], false,
1817 tf->arg_types[i], f, long_bits);
1818 if (fputs (" :", fp) < 0)
1819 error (EXIT_FAILURE, errno, "write to '%s'", filename);
1820 /* Print outputs. */
1821 bool must_erange = false;
1822 for (size_t i = 0; i < tf->num_ret; i++)
1823 {
1824 generic_value g;
1825 g.type = generic_outputs[i].type;
1826 switch (g.type)
1827 {
1828 case gtype_fp:
1829 if (mpfr_inf_p (all_res[i][m])
1830 && (all_exc_before[i][m]
1831 & (1U << exc_overflow)) != 0)
1832 must_erange = true;
1833 if (mpfr_zero_p (all_res[i][m])
1834 && (tf->exact
1835 || mpfr_zero_p (all_res[i][rm_tonearest]))
1836 && (all_exc_before[i][m]
1837 & (1U << exc_underflow)) != 0)
1838 must_erange = true;
1839 mpfr_init2 (g.value.f, fp_formats[f].mant_dig);
1840 assert_exact (mpfr_set (g.value.f, all_res[i][m],
1841 MPFR_RNDN));
1842 break;
1843
1844 case gtype_int:
1845 mpz_init (g.value.i);
1846 mpz_set (g.value.i, generic_outputs[i].value.i);
1847 break;
1848
1849 default:
1850 abort ();
1851 }
1852 output_generic_value (fp, filename, &g, ignore_output[i],
1853 tf->ret_types[i], f, long_bits);
1854 generic_value_free (&g);
1855 }
1856 if (fputs (" :", fp) < 0)
1857 error (EXIT_FAILURE, errno, "write to '%s'", filename);
1858 /* Print miscellaneous flags (passed through from
1859 input). */
1860 for (size_t i = 0; i < it->num_flags; i++)
1861 switch (it->flags[i].type)
1862 {
1863 case flag_no_test_inline:
1864 case flag_xfail:
1865 if (fprintf (fp, " %s%s",
1866 input_flags[it->flags[i].type],
1867 (it->flags[i].cond
1868 ? it->flags[i].cond
1869 : "")) < 0)
1870 error (EXIT_FAILURE, errno, "write to '%s'",
1871 filename);
1872 break;
1873 case flag_xfail_rounding:
1874 if (m != rm_tonearest)
1875 if (fprintf (fp, " xfail%s",
1876 (it->flags[i].cond
1877 ? it->flags[i].cond
1878 : "")) < 0)
1879 error (EXIT_FAILURE, errno, "write to '%s'",
1880 filename);
1881 break;
1882 default:
1883 break;
1884 }
1885 /* Print exception flags and compute errno
1886 expectations where not already computed. */
1887 bool may_edom = false;
1888 bool must_edom = false;
1889 bool may_erange = must_erange || may_underflow;
1890 for (fp_exception e = exc_first_exception;
1891 e < exc_num_exceptions;
1892 e++)
1893 {
1894 bool expect_e = (merged_exc & (1U << e)) != 0;
1895 bool e_optional = false;
1896 switch (e)
1897 {
1898 case exc_divbyzero:
1899 if (expect_e)
1900 may_erange = must_erange = true;
1901 break;
1902
1903 case exc_inexact:
1904 if (!tf->exact)
1905 e_optional = true;
1906 break;
1907
1908 case exc_invalid:
1909 if (expect_e)
1910 may_edom = must_edom = true;
1911 break;
1912
1913 case exc_overflow:
1914 if (expect_e)
1915 may_erange = true;
1916 break;
1917
1918 case exc_underflow:
1919 if (expect_e)
1920 may_erange = true;
1921 if (must_underflow)
1922 assert (expect_e);
1923 if (may_underflow && !must_underflow)
1924 e_optional = true;
1925 break;
1926
1927 default:
1928 abort ();
1929 }
1930 if (e_optional)
1931 {
1932 if (fprintf (fp, " %s-ok", exceptions[e]) < 0)
1933 error (EXIT_FAILURE, errno, "write to '%s'",
1934 filename);
1935 }
1936 else
1937 {
1938 if (expect_e)
1939 if (fprintf (fp, " %s", exceptions[e]) < 0)
1940 error (EXIT_FAILURE, errno, "write to '%s'",
1941 filename);
1942 input_flag_type okflag;
1943 okflag = (expect_e
1944 ? flag_missing_first
1945 : flag_spurious_first) + e;
1946 for (size_t i = 0; i < it->num_flags; i++)
1947 if (it->flags[i].type == okflag)
1948 if (fprintf (fp, " %s-ok%s",
1949 exceptions[e],
1950 (it->flags[i].cond
1951 ? it->flags[i].cond
1952 : "")) < 0)
1953 error (EXIT_FAILURE, errno, "write to '%s'",
1954 filename);
1955 }
1956 }
1957 /* Print errno expectations. */
1958 if (tf->complex_fn)
1959 {
1960 must_edom = false;
1961 must_erange = false;
1962 }
1963 if (may_edom && !must_edom)
1964 {
1965 if (fputs (" errno-edom-ok", fp) < 0)
1966 error (EXIT_FAILURE, errno, "write to '%s'",
1967 filename);
1968 }
1969 else
1970 {
1971 if (must_edom)
1972 if (fputs (" errno-edom", fp) < 0)
1973 error (EXIT_FAILURE, errno, "write to '%s'",
1974 filename);
1975 input_flag_type okflag = (must_edom
1976 ? flag_missing_errno
1977 : flag_spurious_errno);
1978 for (size_t i = 0; i < it->num_flags; i++)
1979 if (it->flags[i].type == okflag)
1980 if (fprintf (fp, " errno-edom-ok%s",
1981 (it->flags[i].cond
1982 ? it->flags[i].cond
1983 : "")) < 0)
1984 error (EXIT_FAILURE, errno, "write to '%s'",
1985 filename);
1986 }
1987 if (may_erange && !must_erange)
1988 {
1989 if (fputs (" errno-erange-ok", fp) < 0)
1990 error (EXIT_FAILURE, errno, "write to '%s'",
1991 filename);
1992 }
1993 else
1994 {
1995 if (must_erange)
1996 if (fputs (" errno-erange", fp) < 0)
1997 error (EXIT_FAILURE, errno, "write to '%s'",
1998 filename);
1999 input_flag_type okflag = (must_erange
2000 ? flag_missing_errno
2001 : flag_spurious_errno);
2002 for (size_t i = 0; i < it->num_flags; i++)
2003 if (it->flags[i].type == okflag)
2004 if (fprintf (fp, " errno-erange-ok%s",
2005 (it->flags[i].cond
2006 ? it->flags[i].cond
2007 : "")) < 0)
2008 error (EXIT_FAILURE, errno, "write to '%s'",
2009 filename);
2010 }
2011 if (putc ('\n', fp) < 0)
2012 error (EXIT_FAILURE, errno, "write to '%s'", filename);
2013 }
2014 }
2015 for (size_t i = 0; i < tf->num_ret; i++)
2016 {
2017 if (generic_outputs[i].type == gtype_fp)
2018 for (rounding_mode m = rm_first_mode; m < rm_num_modes; m++)
2019 mpfr_clear (all_res[i][m]);
2020 }
2021 }
2022 }
2023 out:
2024 for (size_t i = 0; i < tf->num_ret; i++)
2025 generic_value_free (&generic_outputs[i]);
2026 }
2027
2028 /* Generate test output data to FILENAME. */
2029
2030 static void
2031 generate_output (const char *filename)
2032 {
2033 FILE *fp = fopen (filename, "w");
2034 if (fp == NULL)
2035 error (EXIT_FAILURE, errno, "open '%s'", filename);
2036 for (size_t i = 0; i < ARRAY_SIZE (test_functions); i++)
2037 {
2038 test_function *tf = &test_functions[i];
2039 for (size_t j = 0; j < tf->num_tests; j++)
2040 {
2041 input_test *it = &tf->tests[j];
2042 if (fputs (it->line, fp) < 0)
2043 error (EXIT_FAILURE, errno, "write to '%s'", filename);
2044 for (size_t k = 0; k < it->num_input_cases; k++)
2045 output_for_one_input_case (fp, filename, tf, it, it->inputs[k]);
2046 }
2047 }
2048 if (fclose (fp) != 0)
2049 error (EXIT_FAILURE, errno, "close '%s'", filename);
2050 }
2051
2052 int
2053 main (int argc, char **argv)
2054 {
2055 if (argc != 3)
2056 error (EXIT_FAILURE, 0, "usage: gen-auto-libm-tests <input> <output>");
2057 const char *input_filename = argv[1];
2058 const char *output_filename = argv[2];
2059 init_fp_formats ();
2060 read_input (input_filename);
2061 generate_output (output_filename);
2062 exit (EXIT_SUCCESS);
2063 }