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