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