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