Drop fpregset unused symbol exposition
[glibc.git] / math / gen-auto-libm-tests.c
blobcf157f535f4a0dd7b1dab898dbe85cf61ccc1918
1 /* Generate expected output for libm tests with MPFR and MPC.
2 Copyright (C) 2013-2018 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
19 /* Compile this program as:
21 gcc -std=gnu11 -O2 -Wall -Wextra gen-auto-libm-tests.c -lmpc -lmpfr -lgmp \
22 -o gen-auto-libm-tests
24 (use of current MPC and MPFR versions recommended) and run it as:
26 gen-auto-libm-tests auto-libm-test-in <func> auto-libm-test-out-<func>
28 to generate results for normal libm functions, or
30 gen-auto-libm-tests --narrow auto-libm-test-in <func> \
31 auto-libm-test-out-narrow-<func>
33 to generate results for a function rounding results to a narrower
34 type (in the case of fma and sqrt, both output files are generated
35 from the same test inputs).
37 The input file auto-libm-test-in contains three kinds of lines:
39 Lines beginning with "#" are comments, and are ignored, as are
40 empty lines.
42 Other lines are test lines, of the form "function input1 input2
43 ... [flag1 flag2 ...]". Inputs are either finite real numbers or
44 integers, depending on the function under test. Real numbers may
45 be in any form acceptable to mpfr_strtofr (base 0); integers in any
46 form acceptable to mpz_set_str (base 0). In addition, real numbers
47 may be certain special strings such as "pi", as listed in the
48 special_real_inputs array.
50 Each flag is a flag name possibly followed by a series of
51 ":condition". Conditions may be any of the names of floating-point
52 formats in the floating_point_formats array, "long32" and "long64"
53 to indicate the number of bits in the "long" type, or other strings
54 for which libm-test.inc defines a TEST_COND_<condition> macro (with
55 "-"- changed to "_" in the condition name) evaluating to nonzero
56 when the condition is true and zero when the condition is false.
57 The meaning is that the flag applies to the test if all the listed
58 conditions are true. "flag:cond1:cond2 flag:cond3:cond4" means the
59 flag applies if ((cond1 && cond2) || (cond3 && cond4)).
61 A real number specified as an input is considered to represent the
62 set of real numbers arising from rounding the given number in any
63 direction for any supported floating-point format; any roundings
64 that give infinity are ignored. Each input on a test line has all
65 the possible roundings considered independently. Each resulting
66 choice of the tuple of inputs to the function is ignored if the
67 mathematical result of the function involves a NaN or an exact
68 infinity, and is otherwise considered for each floating-point
69 format for which all those inputs are exactly representable. Thus
70 tests may result in "overflow", "underflow" and "inexact"
71 exceptions; "invalid" may arise only when the final result type is
72 an integer type and it is the conversion of a mathematically
73 defined finite result to integer type that results in that
74 exception.
76 By default, it is assumed that "overflow" and "underflow"
77 exceptions should be correct, but that "inexact" exceptions should
78 only be correct for functions listed as exactly determined. For
79 such functions, "underflow" exceptions should respect whether the
80 machine has before-rounding or after-rounding tininess detection.
81 For other functions, it is considered that if the exact result is
82 somewhere between the greatest magnitude subnormal of a given sign
83 (exclusive) and the least magnitude normal of that sign
84 (inclusive), underflow exceptions are permitted but optional on all
85 machines, and they are also permitted but optional for smaller
86 subnormal exact results for functions that are not exactly
87 determined. errno setting is expected for overflow to infinity and
88 underflow to zero (for real functions), and for out-of-range
89 conversion of a finite result to integer type, and is considered
90 permitted but optional for all other cases where overflow
91 exceptions occur, and where underflow exceptions occur or are
92 permitted. In other cases (where no overflow or underflow is
93 permitted), errno is expected to be left unchanged.
95 The flag "no-test-inline" indicates a test is disabled for inline
96 function testing; "ignore-zero-inf-sign" indicates the the signs of
97 zero and infinite results should be ignored; "xfail" indicates the
98 test is disabled as expected to produce incorrect results,
99 "xfail-rounding" indicates the test is disabled only in rounding
100 modes other than round-to-nearest. Otherwise, test flags are of
101 the form "spurious-<exception>" and "missing-<exception>", for any
102 exception ("overflow", "underflow", "inexact", "invalid",
103 "divbyzero"), "spurious-errno" and "missing-errno", to indicate
104 when tests are expected to deviate from the exception and errno
105 settings corresponding to the mathematical results. "xfail",
106 "xfail-rounding", "spurious-" and "missing-" flags should be
107 accompanied by a comment referring to an open bug in glibc
108 Bugzilla.
110 The output file auto-libm-test-out-<func> contains the test lines from
111 auto-libm-test-in, and, after the line for a given test, some
112 number of output test lines. An output test line is of the form "=
113 function rounding-mode format input1 input2 ... : output1 output2
114 ... : flags". rounding-mode is "tonearest", "towardzero", "upward"
115 or "downward". format is a name from the floating_point_formats
116 array, possibly followed by a sequence of ":flag" for flags from
117 "long32" and "long64". Inputs and outputs are specified as hex
118 floats with the required suffix for the floating-point type, or
119 plus_infty or minus_infty for infinite expected results, or as
120 integer constant expressions (not necessarily with the right type)
121 or IGNORE for integer inputs and outputs. Flags are
122 "no-test-inline", "ignore-zero-info-sign", "xfail", "<exception>",
123 "<exception>-ok", "errno-<value>", "errno-<value>-ok", which may be
124 unconditional or conditional. "<exception>" indicates that a
125 correct result means the given exception should be raised.
126 "errno-<value>" indicates that a correct result means errno should
127 be set to the given value. "-ok" means not to test for the given
128 exception or errno value (whether because it was marked as possibly
129 missing or spurious, or because the calculation of correct results
130 indicated it was optional). Conditions "before-rounding" and
131 "after-rounding" indicate tests where expectations for underflow
132 exceptions depend on how the architecture detects tininess.
134 For functions rounding their results to a narrower type, the format
135 given on an output test line is the result format followed by
136 information about the requirements on the argument format to be
137 able to represent the argument values, in the form
138 "format:arg_fmt(MAX_EXP,NUM_ONES,MIN_EXP,MAX_PREC)". Instead of
139 separate lines for separate argument formats, an output test line
140 relates to all argument formats that can represent the values.
141 MAX_EXP is the maximum exponent of a nonzero bit in any argument,
142 or 0 if all arguments are zero; NUM_ONES is the maximum number of
143 leading bits with value 1 in an argument with exponent MAX_EXP, or
144 0 if all arguments are zero; MIN_EXP is the minimum exponent of a
145 nonzero bit in any argument, or 0 if all arguments are zero;
146 MAX_PREC is the maximum precision required to represent all
147 arguments, or 0 if all arguments are zero. */
149 #define _GNU_SOURCE
151 #include <assert.h>
152 #include <ctype.h>
153 #include <errno.h>
154 #include <error.h>
155 #include <stdbool.h>
156 #include <stdint.h>
157 #include <stdio.h>
158 #include <stdlib.h>
159 #include <string.h>
161 #include <gmp.h>
162 #include <mpfr.h>
163 #include <mpc.h>
165 #define ARRAY_SIZE(A) (sizeof (A) / sizeof ((A)[0]))
167 /* The supported floating-point formats. */
168 typedef enum
170 fp_flt_32,
171 fp_dbl_64,
172 fp_ldbl_96_intel,
173 fp_ldbl_96_m68k,
174 fp_ldbl_128,
175 fp_ldbl_128ibm,
176 fp_num_formats,
177 fp_first_format = 0
178 } fp_format;
180 /* Structure describing a single floating-point format. */
181 typedef struct
183 /* The name of the format. */
184 const char *name;
185 /* A string for the largest normal value, or NULL for IEEE formats
186 where this can be determined automatically. */
187 const char *max_string;
188 /* The number of mantissa bits. */
189 int mant_dig;
190 /* The least N such that 2^N overflows. */
191 int max_exp;
192 /* One more than the least N such that 2^N is normal. */
193 int min_exp;
194 /* The largest normal value. */
195 mpfr_t max;
196 /* The value 0.5ulp above the least positive normal value. */
197 mpfr_t min_plus_half;
198 /* The least positive normal value, 2^(MIN_EXP-1). */
199 mpfr_t min;
200 /* The greatest positive subnormal value. */
201 mpfr_t subnorm_max;
202 /* The least positive subnormal value, 2^(MIN_EXP-MANT_DIG). */
203 mpfr_t subnorm_min;
204 } fp_format_desc;
206 /* List of floating-point formats, in the same order as the fp_format
207 enumeration. */
208 static fp_format_desc fp_formats[fp_num_formats] =
210 { "binary32", NULL, 24, 128, -125, {}, {}, {}, {}, {} },
211 { "binary64", NULL, 53, 1024, -1021, {}, {}, {}, {}, {} },
212 { "intel96", NULL, 64, 16384, -16381, {}, {}, {}, {}, {} },
213 { "m68k96", NULL, 64, 16384, -16382, {}, {}, {}, {}, {} },
214 { "binary128", NULL, 113, 16384, -16381, {}, {}, {}, {}, {} },
215 { "ibm128", "0x1.fffffffffffff7ffffffffffff8p+1023",
216 106, 1024, -968, {}, {}, {}, {}, {} },
219 /* The supported rounding modes. */
220 typedef enum
222 rm_downward,
223 rm_tonearest,
224 rm_towardzero,
225 rm_upward,
226 rm_num_modes,
227 rm_first_mode = 0
228 } rounding_mode;
230 /* Structure describing a single rounding mode. */
231 typedef struct
233 /* The name of the rounding mode. */
234 const char *name;
235 /* The MPFR rounding mode. */
236 mpfr_rnd_t mpfr_mode;
237 /* The MPC rounding mode. */
238 mpc_rnd_t mpc_mode;
239 } rounding_mode_desc;
241 /* List of rounding modes, in the same order as the rounding_mode
242 enumeration. */
243 static const rounding_mode_desc rounding_modes[rm_num_modes] =
245 { "downward", MPFR_RNDD, MPC_RNDDD },
246 { "tonearest", MPFR_RNDN, MPC_RNDNN },
247 { "towardzero", MPFR_RNDZ, MPC_RNDZZ },
248 { "upward", MPFR_RNDU, MPC_RNDUU },
251 /* The supported exceptions. */
252 typedef enum
254 exc_divbyzero,
255 exc_inexact,
256 exc_invalid,
257 exc_overflow,
258 exc_underflow,
259 exc_num_exceptions,
260 exc_first_exception = 0
261 } fp_exception;
263 /* List of exceptions, in the same order as the fp_exception
264 enumeration. */
265 static const char *const exceptions[exc_num_exceptions] =
267 "divbyzero",
268 "inexact",
269 "invalid",
270 "overflow",
271 "underflow",
274 /* The internal precision to use for most MPFR calculations, which
275 must be at least 2 more than the greatest precision of any
276 supported floating-point format. */
277 static int internal_precision;
279 /* A value that overflows all supported floating-point formats. */
280 static mpfr_t global_max;
282 /* A value that is at most half the least subnormal in any
283 floating-point format and so is rounded the same way as all
284 sufficiently small positive values. */
285 static mpfr_t global_min;
287 /* The maximum number of (real or integer) arguments to a function
288 handled by this program (complex arguments count as two real
289 arguments). */
290 #define MAX_NARGS 4
292 /* The maximum number of (real or integer) return values from a
293 function handled by this program. */
294 #define MAX_NRET 2
296 /* A type of a function argument or return value. */
297 typedef enum
299 /* No type (not a valid argument or return value). */
300 type_none,
301 /* A floating-point value with the type corresponding to that of
302 the function. */
303 type_fp,
304 /* An integer value of type int. */
305 type_int,
306 /* An integer value of type long. */
307 type_long,
308 /* An integer value of type long long. */
309 type_long_long,
310 } arg_ret_type;
312 /* A type of a generic real or integer value. */
313 typedef enum
315 /* No type. */
316 gtype_none,
317 /* Floating-point (represented with MPFR). */
318 gtype_fp,
319 /* Integer (represented with GMP). */
320 gtype_int,
321 } generic_value_type;
323 /* A generic value (argument or result). */
324 typedef struct
326 /* The type of this value. */
327 generic_value_type type;
328 /* Its value. */
329 union
331 mpfr_t f;
332 mpz_t i;
333 } value;
334 } generic_value;
336 /* A type of input flag. */
337 typedef enum
339 flag_no_test_inline,
340 flag_ignore_zero_inf_sign,
341 flag_xfail,
342 flag_xfail_rounding,
343 /* The "spurious" and "missing" flags must be in the same order as
344 the fp_exception enumeration. */
345 flag_spurious_divbyzero,
346 flag_spurious_inexact,
347 flag_spurious_invalid,
348 flag_spurious_overflow,
349 flag_spurious_underflow,
350 flag_spurious_errno,
351 flag_missing_divbyzero,
352 flag_missing_inexact,
353 flag_missing_invalid,
354 flag_missing_overflow,
355 flag_missing_underflow,
356 flag_missing_errno,
357 num_input_flag_types,
358 flag_first_flag = 0,
359 flag_spurious_first = flag_spurious_divbyzero,
360 flag_missing_first = flag_missing_divbyzero
361 } input_flag_type;
363 /* List of flags, in the same order as the input_flag_type
364 enumeration. */
365 static const char *const input_flags[num_input_flag_types] =
367 "no-test-inline",
368 "ignore-zero-inf-sign",
369 "xfail",
370 "xfail-rounding",
371 "spurious-divbyzero",
372 "spurious-inexact",
373 "spurious-invalid",
374 "spurious-overflow",
375 "spurious-underflow",
376 "spurious-errno",
377 "missing-divbyzero",
378 "missing-inexact",
379 "missing-invalid",
380 "missing-overflow",
381 "missing-underflow",
382 "missing-errno",
385 /* An input flag, possibly conditional. */
386 typedef struct
388 /* The type of this flag. */
389 input_flag_type type;
390 /* The conditions on this flag, as a string ":cond1:cond2..." or
391 NULL. */
392 const char *cond;
393 } input_flag;
395 /* Structure describing a single test from the input file (which may
396 expand into many tests in the output). The choice of function,
397 which implies the numbers and types of arguments and results, is
398 implicit rather than stored in this structure (except as part of
399 the source line). */
400 typedef struct
402 /* The text of the input line describing the test, including the
403 trailing newline. */
404 const char *line;
405 /* The number of combinations of interpretations of input values for
406 different floating-point formats and rounding modes. */
407 size_t num_input_cases;
408 /* The corresponding lists of inputs. */
409 generic_value **inputs;
410 /* The number of flags for this test. */
411 size_t num_flags;
412 /* The corresponding list of flags. */
413 input_flag *flags;
414 /* The old output for this test. */
415 const char *old_output;
416 } input_test;
418 /* Ways to calculate a function. */
419 typedef enum
421 /* MPFR function with a single argument and result. */
422 mpfr_f_f,
423 /* MPFR function with two arguments and one result. */
424 mpfr_ff_f,
425 /* MPFR function with three arguments and one result. */
426 mpfr_fff_f,
427 /* MPFR function with a single argument and floating-point and
428 integer results. */
429 mpfr_f_f1,
430 /* MPFR function with integer and floating-point arguments and one
431 result. */
432 mpfr_if_f,
433 /* MPFR function with a single argument and two floating-point
434 results. */
435 mpfr_f_11,
436 /* MPC function with a single complex argument and one real
437 result. */
438 mpc_c_f,
439 /* MPC function with a single complex argument and one complex
440 result. */
441 mpc_c_c,
442 /* MPC function with two complex arguments and one complex
443 result. */
444 mpc_cc_c,
445 } func_calc_method;
447 /* Description of how to calculate a function. */
448 typedef struct
450 /* Which method is used to calculate the function. */
451 func_calc_method method;
452 /* The specific function called. */
453 union
455 int (*mpfr_f_f) (mpfr_t, const mpfr_t, mpfr_rnd_t);
456 int (*mpfr_ff_f) (mpfr_t, const mpfr_t, const mpfr_t, mpfr_rnd_t);
457 int (*mpfr_fff_f) (mpfr_t, const mpfr_t, const mpfr_t, const mpfr_t,
458 mpfr_rnd_t);
459 int (*mpfr_f_f1) (mpfr_t, int *, const mpfr_t, mpfr_rnd_t);
460 int (*mpfr_if_f) (mpfr_t, long, const mpfr_t, mpfr_rnd_t);
461 int (*mpfr_f_11) (mpfr_t, mpfr_t, const mpfr_t, mpfr_rnd_t);
462 int (*mpc_c_f) (mpfr_t, const mpc_t, mpfr_rnd_t);
463 int (*mpc_c_c) (mpc_t, const mpc_t, mpc_rnd_t);
464 int (*mpc_cc_c) (mpc_t, const mpc_t, const mpc_t, mpc_rnd_t);
465 } func;
466 } func_calc_desc;
468 /* Structure describing a function handled by this program. */
469 typedef struct
471 /* The name of the function. */
472 const char *name;
473 /* The number of arguments. */
474 size_t num_args;
475 /* The types of the arguments. */
476 arg_ret_type arg_types[MAX_NARGS];
477 /* The number of return values. */
478 size_t num_ret;
479 /* The types of the return values. */
480 arg_ret_type ret_types[MAX_NRET];
481 /* Whether the function has exactly determined results and
482 exceptions. */
483 bool exact;
484 /* Whether the function is a complex function, so errno setting is
485 optional. */
486 bool complex_fn;
487 /* Whether to treat arguments given as floating-point constants as
488 exact only, rather than rounding them up and down to all
489 formats. */
490 bool exact_args;
491 /* How to calculate this function. */
492 func_calc_desc calc;
493 /* The number of tests allocated for this function. */
494 size_t num_tests_alloc;
495 /* The number of tests for this function. */
496 size_t num_tests;
497 /* The tests themselves. */
498 input_test *tests;
499 } test_function;
501 #define ARGS1(T1) 1, { T1 }
502 #define ARGS2(T1, T2) 2, { T1, T2 }
503 #define ARGS3(T1, T2, T3) 3, { T1, T2, T3 }
504 #define ARGS4(T1, T2, T3, T4) 4, { T1, T2, T3, T4 }
505 #define RET1(T1) 1, { T1 }
506 #define RET2(T1, T2) 2, { T1, T2 }
507 #define CALC(TYPE, FN) { TYPE, { .TYPE = FN } }
508 #define FUNC(NAME, ARGS, RET, EXACT, COMPLEX_FN, EXACT_ARGS, CALC) \
510 NAME, ARGS, RET, EXACT, COMPLEX_FN, EXACT_ARGS, CALC, 0, 0, NULL \
513 #define FUNC_mpfr_f_f(NAME, MPFR_FUNC, EXACT) \
514 FUNC (NAME, ARGS1 (type_fp), RET1 (type_fp), EXACT, false, false, \
515 CALC (mpfr_f_f, MPFR_FUNC))
516 #define FUNC_mpfr_ff_f(NAME, MPFR_FUNC, EXACT) \
517 FUNC (NAME, ARGS2 (type_fp, type_fp), RET1 (type_fp), EXACT, false, \
518 false, CALC (mpfr_ff_f, MPFR_FUNC))
519 #define FUNC_mpfr_if_f(NAME, MPFR_FUNC, EXACT) \
520 FUNC (NAME, ARGS2 (type_int, type_fp), RET1 (type_fp), EXACT, false, \
521 false, CALC (mpfr_if_f, MPFR_FUNC))
522 #define FUNC_mpc_c_f(NAME, MPFR_FUNC, EXACT) \
523 FUNC (NAME, ARGS2 (type_fp, type_fp), RET1 (type_fp), EXACT, true, \
524 false, CALC (mpc_c_f, MPFR_FUNC))
525 #define FUNC_mpc_c_c(NAME, MPFR_FUNC, EXACT) \
526 FUNC (NAME, ARGS2 (type_fp, type_fp), RET2 (type_fp, type_fp), EXACT, \
527 true, false, CALC (mpc_c_c, MPFR_FUNC))
529 /* List of functions handled by this program. */
530 static test_function test_functions[] =
532 FUNC_mpfr_f_f ("acos", mpfr_acos, false),
533 FUNC_mpfr_f_f ("acosh", mpfr_acosh, false),
534 FUNC_mpfr_ff_f ("add", mpfr_add, true),
535 FUNC_mpfr_f_f ("asin", mpfr_asin, false),
536 FUNC_mpfr_f_f ("asinh", mpfr_asinh, false),
537 FUNC_mpfr_f_f ("atan", mpfr_atan, false),
538 FUNC_mpfr_ff_f ("atan2", mpfr_atan2, false),
539 FUNC_mpfr_f_f ("atanh", mpfr_atanh, false),
540 FUNC_mpc_c_f ("cabs", mpc_abs, false),
541 FUNC_mpc_c_c ("cacos", mpc_acos, false),
542 FUNC_mpc_c_c ("cacosh", mpc_acosh, false),
543 FUNC_mpc_c_f ("carg", mpc_arg, false),
544 FUNC_mpc_c_c ("casin", mpc_asin, false),
545 FUNC_mpc_c_c ("casinh", mpc_asinh, false),
546 FUNC_mpc_c_c ("catan", mpc_atan, false),
547 FUNC_mpc_c_c ("catanh", mpc_atanh, false),
548 FUNC_mpfr_f_f ("cbrt", mpfr_cbrt, false),
549 FUNC_mpc_c_c ("ccos", mpc_cos, false),
550 FUNC_mpc_c_c ("ccosh", mpc_cosh, false),
551 FUNC_mpc_c_c ("cexp", mpc_exp, false),
552 FUNC_mpc_c_c ("clog", mpc_log, false),
553 FUNC_mpc_c_c ("clog10", mpc_log10, false),
554 FUNC_mpfr_f_f ("cos", mpfr_cos, false),
555 FUNC_mpfr_f_f ("cosh", mpfr_cosh, false),
556 FUNC ("cpow", ARGS4 (type_fp, type_fp, type_fp, type_fp),
557 RET2 (type_fp, type_fp), false, true, false,
558 CALC (mpc_cc_c, mpc_pow)),
559 FUNC_mpc_c_c ("csin", mpc_sin, false),
560 FUNC_mpc_c_c ("csinh", mpc_sinh, false),
561 FUNC_mpc_c_c ("csqrt", mpc_sqrt, false),
562 FUNC_mpc_c_c ("ctan", mpc_tan, false),
563 FUNC_mpc_c_c ("ctanh", mpc_tanh, false),
564 FUNC_mpfr_f_f ("erf", mpfr_erf, false),
565 FUNC_mpfr_f_f ("erfc", mpfr_erfc, false),
566 FUNC_mpfr_f_f ("exp", mpfr_exp, false),
567 FUNC_mpfr_f_f ("exp10", mpfr_exp10, false),
568 FUNC_mpfr_f_f ("exp2", mpfr_exp2, false),
569 FUNC_mpfr_f_f ("expm1", mpfr_expm1, false),
570 FUNC ("fma", ARGS3 (type_fp, type_fp, type_fp), RET1 (type_fp),
571 true, false, true, CALC (mpfr_fff_f, mpfr_fma)),
572 FUNC_mpfr_ff_f ("hypot", mpfr_hypot, false),
573 FUNC_mpfr_f_f ("j0", mpfr_j0, false),
574 FUNC_mpfr_f_f ("j1", mpfr_j1, false),
575 FUNC_mpfr_if_f ("jn", mpfr_jn, false),
576 FUNC ("lgamma", ARGS1 (type_fp), RET2 (type_fp, type_int), false, false,
577 false, CALC (mpfr_f_f1, mpfr_lgamma)),
578 FUNC_mpfr_f_f ("log", mpfr_log, false),
579 FUNC_mpfr_f_f ("log10", mpfr_log10, false),
580 FUNC_mpfr_f_f ("log1p", mpfr_log1p, false),
581 FUNC_mpfr_f_f ("log2", mpfr_log2, false),
582 FUNC_mpfr_ff_f ("pow", mpfr_pow, false),
583 FUNC_mpfr_f_f ("sin", mpfr_sin, false),
584 FUNC ("sincos", ARGS1 (type_fp), RET2 (type_fp, type_fp), false, false,
585 false, CALC (mpfr_f_11, mpfr_sin_cos)),
586 FUNC_mpfr_f_f ("sinh", mpfr_sinh, false),
587 FUNC_mpfr_ff_f ("sub", mpfr_sub, true),
588 FUNC_mpfr_f_f ("sqrt", mpfr_sqrt, true),
589 FUNC_mpfr_f_f ("tan", mpfr_tan, false),
590 FUNC_mpfr_f_f ("tanh", mpfr_tanh, false),
591 FUNC_mpfr_f_f ("tgamma", mpfr_gamma, false),
592 FUNC_mpfr_f_f ("y0", mpfr_y0, false),
593 FUNC_mpfr_f_f ("y1", mpfr_y1, false),
594 FUNC_mpfr_if_f ("yn", mpfr_yn, false),
597 /* Allocate memory, with error checking. */
599 static void *
600 xmalloc (size_t n)
602 void *p = malloc (n);
603 if (p == NULL)
604 error (EXIT_FAILURE, errno, "xmalloc failed");
605 return p;
608 static void *
609 xrealloc (void *p, size_t n)
611 p = realloc (p, n);
612 if (p == NULL)
613 error (EXIT_FAILURE, errno, "xrealloc failed");
614 return p;
617 static char *
618 xstrdup (const char *s)
620 char *p = strdup (s);
621 if (p == NULL)
622 error (EXIT_FAILURE, errno, "xstrdup failed");
623 return p;
626 /* Assert that the result of an MPFR operation was exact; that is,
627 that the returned ternary value was 0. */
629 static void
630 assert_exact (int i)
632 assert (i == 0);
635 /* Return the generic type of an argument or return value type T. */
637 static generic_value_type
638 generic_arg_ret_type (arg_ret_type t)
640 switch (t)
642 case type_fp:
643 return gtype_fp;
645 case type_int:
646 case type_long:
647 case type_long_long:
648 return gtype_int;
650 default:
651 abort ();
655 /* Free a generic_value *V. */
657 static void
658 generic_value_free (generic_value *v)
660 switch (v->type)
662 case gtype_fp:
663 mpfr_clear (v->value.f);
664 break;
666 case gtype_int:
667 mpz_clear (v->value.i);
668 break;
670 default:
671 abort ();
675 /* Copy a generic_value *SRC to *DEST. */
677 static void
678 generic_value_copy (generic_value *dest, const generic_value *src)
680 dest->type = src->type;
681 switch (src->type)
683 case gtype_fp:
684 mpfr_init (dest->value.f);
685 assert_exact (mpfr_set (dest->value.f, src->value.f, MPFR_RNDN));
686 break;
688 case gtype_int:
689 mpz_init (dest->value.i);
690 mpz_set (dest->value.i, src->value.i);
691 break;
693 default:
694 abort ();
698 /* Initialize data for floating-point formats. */
700 static void
701 init_fp_formats (void)
703 int global_max_exp = 0, global_min_subnorm_exp = 0;
704 for (fp_format f = fp_first_format; f < fp_num_formats; f++)
706 if (fp_formats[f].mant_dig + 2 > internal_precision)
707 internal_precision = fp_formats[f].mant_dig + 2;
708 if (fp_formats[f].max_exp > global_max_exp)
709 global_max_exp = fp_formats[f].max_exp;
710 int min_subnorm_exp = fp_formats[f].min_exp - fp_formats[f].mant_dig;
711 if (min_subnorm_exp < global_min_subnorm_exp)
712 global_min_subnorm_exp = min_subnorm_exp;
713 mpfr_init2 (fp_formats[f].max, fp_formats[f].mant_dig);
714 if (fp_formats[f].max_string != NULL)
716 char *ep = NULL;
717 assert_exact (mpfr_strtofr (fp_formats[f].max,
718 fp_formats[f].max_string,
719 &ep, 0, MPFR_RNDN));
720 assert (*ep == 0);
722 else
724 assert_exact (mpfr_set_ui_2exp (fp_formats[f].max, 1,
725 fp_formats[f].max_exp,
726 MPFR_RNDN));
727 mpfr_nextbelow (fp_formats[f].max);
729 mpfr_init2 (fp_formats[f].min, fp_formats[f].mant_dig);
730 assert_exact (mpfr_set_ui_2exp (fp_formats[f].min, 1,
731 fp_formats[f].min_exp - 1,
732 MPFR_RNDN));
733 mpfr_init2 (fp_formats[f].min_plus_half, fp_formats[f].mant_dig + 1);
734 assert_exact (mpfr_set (fp_formats[f].min_plus_half,
735 fp_formats[f].min, MPFR_RNDN));
736 mpfr_nextabove (fp_formats[f].min_plus_half);
737 mpfr_init2 (fp_formats[f].subnorm_max, fp_formats[f].mant_dig);
738 assert_exact (mpfr_set (fp_formats[f].subnorm_max, fp_formats[f].min,
739 MPFR_RNDN));
740 mpfr_nextbelow (fp_formats[f].subnorm_max);
741 mpfr_nextbelow (fp_formats[f].subnorm_max);
742 mpfr_init2 (fp_formats[f].subnorm_min, fp_formats[f].mant_dig);
743 assert_exact (mpfr_set_ui_2exp (fp_formats[f].subnorm_min, 1,
744 min_subnorm_exp, MPFR_RNDN));
746 mpfr_set_default_prec (internal_precision);
747 mpfr_init (global_max);
748 assert_exact (mpfr_set_ui_2exp (global_max, 1, global_max_exp, MPFR_RNDN));
749 mpfr_init (global_min);
750 assert_exact (mpfr_set_ui_2exp (global_min, 1, global_min_subnorm_exp - 1,
751 MPFR_RNDN));
754 /* Fill in mpfr_t values for special strings in input arguments. */
756 static size_t
757 special_fill_max (mpfr_t res0, mpfr_t res1 __attribute__ ((unused)),
758 fp_format format)
760 mpfr_init2 (res0, fp_formats[format].mant_dig);
761 assert_exact (mpfr_set (res0, fp_formats[format].max, MPFR_RNDN));
762 return 1;
765 static size_t
766 special_fill_minus_max (mpfr_t res0, mpfr_t res1 __attribute__ ((unused)),
767 fp_format format)
769 mpfr_init2 (res0, fp_formats[format].mant_dig);
770 assert_exact (mpfr_neg (res0, fp_formats[format].max, MPFR_RNDN));
771 return 1;
774 static size_t
775 special_fill_min (mpfr_t res0, mpfr_t res1 __attribute__ ((unused)),
776 fp_format format)
778 mpfr_init2 (res0, fp_formats[format].mant_dig);
779 assert_exact (mpfr_set (res0, fp_formats[format].min, MPFR_RNDN));
780 return 1;
783 static size_t
784 special_fill_minus_min (mpfr_t res0, mpfr_t res1 __attribute__ ((unused)),
785 fp_format format)
787 mpfr_init2 (res0, fp_formats[format].mant_dig);
788 assert_exact (mpfr_neg (res0, fp_formats[format].min, MPFR_RNDN));
789 return 1;
792 static size_t
793 special_fill_min_subnorm (mpfr_t res0, mpfr_t res1 __attribute__ ((unused)),
794 fp_format format)
796 mpfr_init2 (res0, fp_formats[format].mant_dig);
797 assert_exact (mpfr_set (res0, fp_formats[format].subnorm_min, MPFR_RNDN));
798 return 1;
801 static size_t
802 special_fill_minus_min_subnorm (mpfr_t res0,
803 mpfr_t res1 __attribute__ ((unused)),
804 fp_format format)
806 mpfr_init2 (res0, fp_formats[format].mant_dig);
807 assert_exact (mpfr_neg (res0, fp_formats[format].subnorm_min, MPFR_RNDN));
808 return 1;
811 static size_t
812 special_fill_min_subnorm_p120 (mpfr_t res0,
813 mpfr_t res1 __attribute__ ((unused)),
814 fp_format format)
816 mpfr_init2 (res0, fp_formats[format].mant_dig);
817 assert_exact (mpfr_mul_2ui (res0, fp_formats[format].subnorm_min,
818 120, MPFR_RNDN));
819 return 1;
822 static size_t
823 special_fill_pi (mpfr_t res0, mpfr_t res1, fp_format format)
825 mpfr_init2 (res0, fp_formats[format].mant_dig);
826 mpfr_const_pi (res0, MPFR_RNDU);
827 mpfr_init2 (res1, fp_formats[format].mant_dig);
828 mpfr_const_pi (res1, MPFR_RNDD);
829 return 2;
832 static size_t
833 special_fill_minus_pi (mpfr_t res0, mpfr_t res1, fp_format format)
835 mpfr_init2 (res0, fp_formats[format].mant_dig);
836 mpfr_const_pi (res0, MPFR_RNDU);
837 assert_exact (mpfr_neg (res0, res0, MPFR_RNDN));
838 mpfr_init2 (res1, fp_formats[format].mant_dig);
839 mpfr_const_pi (res1, MPFR_RNDD);
840 assert_exact (mpfr_neg (res1, res1, MPFR_RNDN));
841 return 2;
844 static size_t
845 special_fill_pi_2 (mpfr_t res0, mpfr_t res1, fp_format format)
847 mpfr_init2 (res0, fp_formats[format].mant_dig);
848 mpfr_const_pi (res0, MPFR_RNDU);
849 assert_exact (mpfr_div_ui (res0, res0, 2, MPFR_RNDN));
850 mpfr_init2 (res1, fp_formats[format].mant_dig);
851 mpfr_const_pi (res1, MPFR_RNDD);
852 assert_exact (mpfr_div_ui (res1, res1, 2, MPFR_RNDN));
853 return 2;
856 static size_t
857 special_fill_minus_pi_2 (mpfr_t res0, mpfr_t res1, fp_format format)
859 mpfr_init2 (res0, fp_formats[format].mant_dig);
860 mpfr_const_pi (res0, MPFR_RNDU);
861 assert_exact (mpfr_div_ui (res0, res0, 2, MPFR_RNDN));
862 assert_exact (mpfr_neg (res0, res0, MPFR_RNDN));
863 mpfr_init2 (res1, fp_formats[format].mant_dig);
864 mpfr_const_pi (res1, MPFR_RNDD);
865 assert_exact (mpfr_div_ui (res1, res1, 2, MPFR_RNDN));
866 assert_exact (mpfr_neg (res1, res1, MPFR_RNDN));
867 return 2;
870 static size_t
871 special_fill_pi_4 (mpfr_t res0, mpfr_t res1, fp_format format)
873 mpfr_init2 (res0, fp_formats[format].mant_dig);
874 assert_exact (mpfr_set_si (res0, 1, MPFR_RNDN));
875 mpfr_atan (res0, res0, MPFR_RNDU);
876 mpfr_init2 (res1, fp_formats[format].mant_dig);
877 assert_exact (mpfr_set_si (res1, 1, MPFR_RNDN));
878 mpfr_atan (res1, res1, MPFR_RNDD);
879 return 2;
882 static size_t
883 special_fill_pi_6 (mpfr_t res0, mpfr_t res1, fp_format format)
885 mpfr_init2 (res0, fp_formats[format].mant_dig);
886 assert_exact (mpfr_set_si_2exp (res0, 1, -1, MPFR_RNDN));
887 mpfr_asin (res0, res0, MPFR_RNDU);
888 mpfr_init2 (res1, fp_formats[format].mant_dig);
889 assert_exact (mpfr_set_si_2exp (res1, 1, -1, MPFR_RNDN));
890 mpfr_asin (res1, res1, MPFR_RNDD);
891 return 2;
894 static size_t
895 special_fill_minus_pi_6 (mpfr_t res0, mpfr_t res1, fp_format format)
897 mpfr_init2 (res0, fp_formats[format].mant_dig);
898 assert_exact (mpfr_set_si_2exp (res0, -1, -1, MPFR_RNDN));
899 mpfr_asin (res0, res0, MPFR_RNDU);
900 mpfr_init2 (res1, fp_formats[format].mant_dig);
901 assert_exact (mpfr_set_si_2exp (res1, -1, -1, MPFR_RNDN));
902 mpfr_asin (res1, res1, MPFR_RNDD);
903 return 2;
906 static size_t
907 special_fill_pi_3 (mpfr_t res0, mpfr_t res1, fp_format format)
909 mpfr_init2 (res0, fp_formats[format].mant_dig);
910 assert_exact (mpfr_set_si_2exp (res0, 1, -1, MPFR_RNDN));
911 mpfr_acos (res0, res0, MPFR_RNDU);
912 mpfr_init2 (res1, fp_formats[format].mant_dig);
913 assert_exact (mpfr_set_si_2exp (res1, 1, -1, MPFR_RNDN));
914 mpfr_acos (res1, res1, MPFR_RNDD);
915 return 2;
918 static size_t
919 special_fill_2pi_3 (mpfr_t res0, mpfr_t res1, fp_format format)
921 mpfr_init2 (res0, fp_formats[format].mant_dig);
922 assert_exact (mpfr_set_si_2exp (res0, -1, -1, MPFR_RNDN));
923 mpfr_acos (res0, res0, MPFR_RNDU);
924 mpfr_init2 (res1, fp_formats[format].mant_dig);
925 assert_exact (mpfr_set_si_2exp (res1, -1, -1, MPFR_RNDN));
926 mpfr_acos (res1, res1, MPFR_RNDD);
927 return 2;
930 static size_t
931 special_fill_2pi (mpfr_t res0, mpfr_t res1, fp_format format)
933 mpfr_init2 (res0, fp_formats[format].mant_dig);
934 mpfr_const_pi (res0, MPFR_RNDU);
935 assert_exact (mpfr_mul_ui (res0, res0, 2, MPFR_RNDN));
936 mpfr_init2 (res1, fp_formats[format].mant_dig);
937 mpfr_const_pi (res1, MPFR_RNDD);
938 assert_exact (mpfr_mul_ui (res1, res1, 2, MPFR_RNDN));
939 return 2;
942 static size_t
943 special_fill_e (mpfr_t res0, mpfr_t res1, fp_format format)
945 mpfr_init2 (res0, fp_formats[format].mant_dig);
946 assert_exact (mpfr_set_si (res0, 1, MPFR_RNDN));
947 mpfr_exp (res0, res0, MPFR_RNDU);
948 mpfr_init2 (res1, fp_formats[format].mant_dig);
949 assert_exact (mpfr_set_si (res1, 1, MPFR_RNDN));
950 mpfr_exp (res1, res1, MPFR_RNDD);
951 return 2;
954 static size_t
955 special_fill_1_e (mpfr_t res0, mpfr_t res1, fp_format format)
957 mpfr_init2 (res0, fp_formats[format].mant_dig);
958 assert_exact (mpfr_set_si (res0, -1, MPFR_RNDN));
959 mpfr_exp (res0, res0, MPFR_RNDU);
960 mpfr_init2 (res1, fp_formats[format].mant_dig);
961 assert_exact (mpfr_set_si (res1, -1, MPFR_RNDN));
962 mpfr_exp (res1, res1, MPFR_RNDD);
963 return 2;
966 static size_t
967 special_fill_e_minus_1 (mpfr_t res0, mpfr_t res1, fp_format format)
969 mpfr_init2 (res0, fp_formats[format].mant_dig);
970 assert_exact (mpfr_set_si (res0, 1, MPFR_RNDN));
971 mpfr_expm1 (res0, res0, MPFR_RNDU);
972 mpfr_init2 (res1, fp_formats[format].mant_dig);
973 assert_exact (mpfr_set_si (res1, 1, MPFR_RNDN));
974 mpfr_expm1 (res1, res1, MPFR_RNDD);
975 return 2;
978 /* A special string accepted in input arguments. */
979 typedef struct
981 /* The string. */
982 const char *str;
983 /* The function that interprets it for a given floating-point
984 format, filling in up to two mpfr_t values and returning the
985 number of values filled. */
986 size_t (*func) (mpfr_t, mpfr_t, fp_format);
987 } special_real_input;
989 /* List of special strings accepted in input arguments. */
991 static const special_real_input special_real_inputs[] =
993 { "max", special_fill_max },
994 { "-max", special_fill_minus_max },
995 { "min", special_fill_min },
996 { "-min", special_fill_minus_min },
997 { "min_subnorm", special_fill_min_subnorm },
998 { "-min_subnorm", special_fill_minus_min_subnorm },
999 { "min_subnorm_p120", special_fill_min_subnorm_p120 },
1000 { "pi", special_fill_pi },
1001 { "-pi", special_fill_minus_pi },
1002 { "pi/2", special_fill_pi_2 },
1003 { "-pi/2", special_fill_minus_pi_2 },
1004 { "pi/4", special_fill_pi_4 },
1005 { "pi/6", special_fill_pi_6 },
1006 { "-pi/6", special_fill_minus_pi_6 },
1007 { "pi/3", special_fill_pi_3 },
1008 { "2pi/3", special_fill_2pi_3 },
1009 { "2pi", special_fill_2pi },
1010 { "e", special_fill_e },
1011 { "1/e", special_fill_1_e },
1012 { "e-1", special_fill_e_minus_1 },
1015 /* Given a real number R computed in round-to-zero mode, set the
1016 lowest bit as a sticky bit if INEXACT, and saturate the exponent
1017 range for very large or small values. */
1019 static void
1020 adjust_real (mpfr_t r, bool inexact)
1022 if (!inexact)
1023 return;
1024 /* NaNs are exact, as are infinities in round-to-zero mode. */
1025 assert (mpfr_number_p (r));
1026 if (mpfr_cmpabs (r, global_min) < 0)
1027 assert_exact (mpfr_copysign (r, global_min, r, MPFR_RNDN));
1028 else if (mpfr_cmpabs (r, global_max) > 0)
1029 assert_exact (mpfr_copysign (r, global_max, r, MPFR_RNDN));
1030 else
1032 mpz_t tmp;
1033 mpz_init (tmp);
1034 mpfr_exp_t e = mpfr_get_z_2exp (tmp, r);
1035 if (mpz_sgn (tmp) < 0)
1037 mpz_neg (tmp, tmp);
1038 mpz_setbit (tmp, 0);
1039 mpz_neg (tmp, tmp);
1041 else
1042 mpz_setbit (tmp, 0);
1043 assert_exact (mpfr_set_z_2exp (r, tmp, e, MPFR_RNDN));
1044 mpz_clear (tmp);
1048 /* Given a finite real number R with sticky bit, compute the roundings
1049 to FORMAT in each rounding mode, storing the results in RES, the
1050 before-rounding exceptions in EXC_BEFORE and the after-rounding
1051 exceptions in EXC_AFTER. */
1053 static void
1054 round_real (mpfr_t res[rm_num_modes],
1055 unsigned int exc_before[rm_num_modes],
1056 unsigned int exc_after[rm_num_modes],
1057 mpfr_t r, fp_format format)
1059 assert (mpfr_number_p (r));
1060 for (rounding_mode m = rm_first_mode; m < rm_num_modes; m++)
1062 mpfr_init2 (res[m], fp_formats[format].mant_dig);
1063 exc_before[m] = exc_after[m] = 0;
1064 bool inexact = mpfr_set (res[m], r, rounding_modes[m].mpfr_mode);
1065 if (mpfr_cmpabs (res[m], fp_formats[format].max) > 0)
1067 inexact = true;
1068 exc_before[m] |= 1U << exc_overflow;
1069 exc_after[m] |= 1U << exc_overflow;
1070 bool overflow_inf;
1071 switch (m)
1073 case rm_tonearest:
1074 overflow_inf = true;
1075 break;
1076 case rm_towardzero:
1077 overflow_inf = false;
1078 break;
1079 case rm_downward:
1080 overflow_inf = mpfr_signbit (res[m]);
1081 break;
1082 case rm_upward:
1083 overflow_inf = !mpfr_signbit (res[m]);
1084 break;
1085 default:
1086 abort ();
1088 if (overflow_inf)
1089 mpfr_set_inf (res[m], mpfr_signbit (res[m]) ? -1 : 1);
1090 else
1091 assert_exact (mpfr_copysign (res[m], fp_formats[format].max,
1092 res[m], MPFR_RNDN));
1094 if (mpfr_cmpabs (r, fp_formats[format].min) < 0)
1096 /* Tiny before rounding; may or may not be tiny after
1097 rounding, and underflow applies only if also inexact
1098 around rounding to a possibly subnormal value. */
1099 bool tiny_after_rounding
1100 = mpfr_cmpabs (res[m], fp_formats[format].min) < 0;
1101 /* To round to a possibly subnormal value, and determine
1102 inexactness as a subnormal in the process, scale up and
1103 round to integer, then scale back down. */
1104 mpfr_t tmp;
1105 mpfr_init (tmp);
1106 assert_exact (mpfr_mul_2si (tmp, r, (fp_formats[format].mant_dig
1107 - fp_formats[format].min_exp),
1108 MPFR_RNDN));
1109 int rint_res = mpfr_rint (tmp, tmp, rounding_modes[m].mpfr_mode);
1110 /* The integer must be representable. */
1111 assert (rint_res == 0 || rint_res == 2 || rint_res == -2);
1112 /* If rounding to full precision was inexact, so must
1113 rounding to subnormal precision be inexact. */
1114 if (inexact)
1115 assert (rint_res != 0);
1116 else
1117 inexact = rint_res != 0;
1118 assert_exact (mpfr_mul_2si (res[m], tmp,
1119 (fp_formats[format].min_exp
1120 - fp_formats[format].mant_dig),
1121 MPFR_RNDN));
1122 mpfr_clear (tmp);
1123 if (inexact)
1125 exc_before[m] |= 1U << exc_underflow;
1126 if (tiny_after_rounding)
1127 exc_after[m] |= 1U << exc_underflow;
1130 if (inexact)
1132 exc_before[m] |= 1U << exc_inexact;
1133 exc_after[m] |= 1U << exc_inexact;
1138 /* Handle the input argument at ARG (NUL-terminated), updating the
1139 lists of test inputs in IT accordingly. NUM_PREV_ARGS arguments
1140 are already in those lists. If EXACT_ARGS, interpret a value given
1141 as a floating-point constant exactly (it must be exact for some
1142 supported format) rather than rounding up and down. The argument,
1143 of type GTYPE, comes from file FILENAME, line LINENO. */
1145 static void
1146 handle_input_arg (const char *arg, input_test *it, size_t num_prev_args,
1147 generic_value_type gtype, bool exact_args,
1148 const char *filename, unsigned int lineno)
1150 size_t num_values = 0;
1151 generic_value values[2 * fp_num_formats];
1152 bool check_empty_list = false;
1153 switch (gtype)
1155 case gtype_fp:
1156 for (fp_format f = fp_first_format; f < fp_num_formats; f++)
1158 mpfr_t extra_values[2];
1159 size_t num_extra_values = 0;
1160 for (size_t i = 0; i < ARRAY_SIZE (special_real_inputs); i++)
1162 if (strcmp (arg, special_real_inputs[i].str) == 0)
1164 num_extra_values
1165 = special_real_inputs[i].func (extra_values[0],
1166 extra_values[1], f);
1167 assert (num_extra_values > 0
1168 && num_extra_values <= ARRAY_SIZE (extra_values));
1169 break;
1172 if (num_extra_values == 0)
1174 mpfr_t tmp;
1175 char *ep;
1176 if (exact_args)
1177 check_empty_list = true;
1178 mpfr_init (tmp);
1179 bool inexact = mpfr_strtofr (tmp, arg, &ep, 0, MPFR_RNDZ);
1180 if (*ep != 0 || !mpfr_number_p (tmp))
1181 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1182 "bad floating-point argument: '%s'", arg);
1183 adjust_real (tmp, inexact);
1184 mpfr_t rounded[rm_num_modes];
1185 unsigned int exc_before[rm_num_modes];
1186 unsigned int exc_after[rm_num_modes];
1187 round_real (rounded, exc_before, exc_after, tmp, f);
1188 mpfr_clear (tmp);
1189 if (mpfr_number_p (rounded[rm_upward])
1190 && (!exact_args || mpfr_equal_p (rounded[rm_upward],
1191 rounded[rm_downward])))
1193 mpfr_init2 (extra_values[num_extra_values],
1194 fp_formats[f].mant_dig);
1195 assert_exact (mpfr_set (extra_values[num_extra_values],
1196 rounded[rm_upward], MPFR_RNDN));
1197 num_extra_values++;
1199 if (mpfr_number_p (rounded[rm_downward]) && !exact_args)
1201 mpfr_init2 (extra_values[num_extra_values],
1202 fp_formats[f].mant_dig);
1203 assert_exact (mpfr_set (extra_values[num_extra_values],
1204 rounded[rm_downward], MPFR_RNDN));
1205 num_extra_values++;
1207 for (rounding_mode m = rm_first_mode; m < rm_num_modes; m++)
1208 mpfr_clear (rounded[m]);
1210 for (size_t i = 0; i < num_extra_values; i++)
1212 bool found = false;
1213 for (size_t j = 0; j < num_values; j++)
1215 if (mpfr_equal_p (values[j].value.f, extra_values[i])
1216 && ((mpfr_signbit (values[j].value.f) != 0)
1217 == (mpfr_signbit (extra_values[i]) != 0)))
1219 found = true;
1220 break;
1223 if (!found)
1225 assert (num_values < ARRAY_SIZE (values));
1226 values[num_values].type = gtype_fp;
1227 mpfr_init2 (values[num_values].value.f,
1228 fp_formats[f].mant_dig);
1229 assert_exact (mpfr_set (values[num_values].value.f,
1230 extra_values[i], MPFR_RNDN));
1231 num_values++;
1233 mpfr_clear (extra_values[i]);
1236 break;
1238 case gtype_int:
1239 num_values = 1;
1240 values[0].type = gtype_int;
1241 int ret = mpz_init_set_str (values[0].value.i, arg, 0);
1242 if (ret != 0)
1243 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1244 "bad integer argument: '%s'", arg);
1245 break;
1247 default:
1248 abort ();
1250 if (check_empty_list && num_values == 0)
1251 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1252 "floating-point argument not exact for any format: '%s'",
1253 arg);
1254 assert (num_values > 0 && num_values <= ARRAY_SIZE (values));
1255 if (it->num_input_cases >= SIZE_MAX / num_values)
1256 error_at_line (EXIT_FAILURE, 0, filename, lineno, "too many input cases");
1257 generic_value **old_inputs = it->inputs;
1258 size_t new_num_input_cases = it->num_input_cases * num_values;
1259 generic_value **new_inputs = xmalloc (new_num_input_cases
1260 * sizeof (new_inputs[0]));
1261 for (size_t i = 0; i < it->num_input_cases; i++)
1263 for (size_t j = 0; j < num_values; j++)
1265 size_t idx = i * num_values + j;
1266 new_inputs[idx] = xmalloc ((num_prev_args + 1)
1267 * sizeof (new_inputs[idx][0]));
1268 for (size_t k = 0; k < num_prev_args; k++)
1269 generic_value_copy (&new_inputs[idx][k], &old_inputs[i][k]);
1270 generic_value_copy (&new_inputs[idx][num_prev_args], &values[j]);
1272 for (size_t j = 0; j < num_prev_args; j++)
1273 generic_value_free (&old_inputs[i][j]);
1274 free (old_inputs[i]);
1276 free (old_inputs);
1277 for (size_t i = 0; i < num_values; i++)
1278 generic_value_free (&values[i]);
1279 it->inputs = new_inputs;
1280 it->num_input_cases = new_num_input_cases;
1283 /* Handle the input flag ARG (NUL-terminated), storing it in *FLAG.
1284 The flag comes from file FILENAME, line LINENO. */
1286 static void
1287 handle_input_flag (char *arg, input_flag *flag,
1288 const char *filename, unsigned int lineno)
1290 char *ep = strchr (arg, ':');
1291 if (ep == NULL)
1293 ep = strchr (arg, 0);
1294 assert (ep != NULL);
1296 char c = *ep;
1297 *ep = 0;
1298 bool found = false;
1299 for (input_flag_type i = flag_first_flag; i <= num_input_flag_types; i++)
1301 if (strcmp (arg, input_flags[i]) == 0)
1303 found = true;
1304 flag->type = i;
1305 break;
1308 if (!found)
1309 error_at_line (EXIT_FAILURE, 0, filename, lineno, "unknown flag: '%s'",
1310 arg);
1311 *ep = c;
1312 if (c == 0)
1313 flag->cond = NULL;
1314 else
1315 flag->cond = xstrdup (ep);
1318 /* Add the test LINE (file FILENAME, line LINENO) to the test
1319 data. */
1321 static void
1322 add_test (char *line, const char *filename, unsigned int lineno)
1324 size_t num_tokens = 1;
1325 char *p = line;
1326 while ((p = strchr (p, ' ')) != NULL)
1328 num_tokens++;
1329 p++;
1331 if (num_tokens < 2)
1332 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1333 "line too short: '%s'", line);
1334 p = strchr (line, ' ');
1335 size_t func_name_len = p - line;
1336 for (size_t i = 0; i < ARRAY_SIZE (test_functions); i++)
1338 if (func_name_len == strlen (test_functions[i].name)
1339 && strncmp (line, test_functions[i].name, func_name_len) == 0)
1341 test_function *tf = &test_functions[i];
1342 if (num_tokens < 1 + tf->num_args)
1343 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1344 "line too short: '%s'", line);
1345 if (tf->num_tests == tf->num_tests_alloc)
1347 tf->num_tests_alloc = 2 * tf->num_tests_alloc + 16;
1348 tf->tests
1349 = xrealloc (tf->tests,
1350 tf->num_tests_alloc * sizeof (tf->tests[0]));
1352 input_test *it = &tf->tests[tf->num_tests];
1353 it->line = line;
1354 it->num_input_cases = 1;
1355 it->inputs = xmalloc (sizeof (it->inputs[0]));
1356 it->inputs[0] = NULL;
1357 it->old_output = NULL;
1358 p++;
1359 for (size_t j = 0; j < tf->num_args; j++)
1361 char *ep = strchr (p, ' ');
1362 if (ep == NULL)
1364 ep = strchr (p, '\n');
1365 assert (ep != NULL);
1367 if (ep == p)
1368 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1369 "empty token in line: '%s'", line);
1370 for (char *t = p; t < ep; t++)
1371 if (isspace ((unsigned char) *t))
1372 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1373 "whitespace in token in line: '%s'", line);
1374 char c = *ep;
1375 *ep = 0;
1376 handle_input_arg (p, it, j,
1377 generic_arg_ret_type (tf->arg_types[j]),
1378 tf->exact_args, filename, lineno);
1379 *ep = c;
1380 p = ep + 1;
1382 it->num_flags = num_tokens - 1 - tf->num_args;
1383 it->flags = xmalloc (it->num_flags * sizeof (it->flags[0]));
1384 for (size_t j = 0; j < it->num_flags; j++)
1386 char *ep = strchr (p, ' ');
1387 if (ep == NULL)
1389 ep = strchr (p, '\n');
1390 assert (ep != NULL);
1392 if (ep == p)
1393 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1394 "empty token in line: '%s'", line);
1395 for (char *t = p; t < ep; t++)
1396 if (isspace ((unsigned char) *t))
1397 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1398 "whitespace in token in line: '%s'", line);
1399 char c = *ep;
1400 *ep = 0;
1401 handle_input_flag (p, &it->flags[j], filename, lineno);
1402 *ep = c;
1403 p = ep + 1;
1405 assert (*p == 0);
1406 tf->num_tests++;
1407 return;
1410 error_at_line (EXIT_FAILURE, 0, filename, lineno,
1411 "unknown function in line: '%s'", line);
1414 /* Read in the test input data from FILENAME. */
1416 static void
1417 read_input (const char *filename)
1419 FILE *fp = fopen (filename, "r");
1420 if (fp == NULL)
1421 error (EXIT_FAILURE, errno, "open '%s'", filename);
1422 unsigned int lineno = 0;
1423 for (;;)
1425 size_t size = 0;
1426 char *line = NULL;
1427 ssize_t ret = getline (&line, &size, fp);
1428 if (ret == -1)
1429 break;
1430 lineno++;
1431 if (line[0] == '#' || line[0] == '\n')
1432 continue;
1433 add_test (line, filename, lineno);
1435 if (ferror (fp))
1436 error (EXIT_FAILURE, errno, "read from '%s'", filename);
1437 if (fclose (fp) != 0)
1438 error (EXIT_FAILURE, errno, "close '%s'", filename);
1441 /* Calculate the generic results (round-to-zero with sticky bit) for
1442 the function described by CALC, with inputs INPUTS, if MODE is
1443 rm_towardzero; for other modes, calculate results in that mode,
1444 which must be exact zero results. */
1446 static void
1447 calc_generic_results (generic_value *outputs, generic_value *inputs,
1448 const func_calc_desc *calc, rounding_mode mode)
1450 bool inexact;
1451 int mpc_ternary;
1452 mpc_t ci1, ci2, co;
1453 mpfr_rnd_t mode_mpfr = rounding_modes[mode].mpfr_mode;
1454 mpc_rnd_t mode_mpc = rounding_modes[mode].mpc_mode;
1456 switch (calc->method)
1458 case mpfr_f_f:
1459 assert (inputs[0].type == gtype_fp);
1460 outputs[0].type = gtype_fp;
1461 mpfr_init (outputs[0].value.f);
1462 inexact = calc->func.mpfr_f_f (outputs[0].value.f, inputs[0].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;
1469 case mpfr_ff_f:
1470 assert (inputs[0].type == gtype_fp);
1471 assert (inputs[1].type == gtype_fp);
1472 outputs[0].type = gtype_fp;
1473 mpfr_init (outputs[0].value.f);
1474 inexact = calc->func.mpfr_ff_f (outputs[0].value.f, inputs[0].value.f,
1475 inputs[1].value.f, mode_mpfr);
1476 if (mode != rm_towardzero)
1477 assert (!inexact && mpfr_zero_p (outputs[0].value.f));
1478 adjust_real (outputs[0].value.f, inexact);
1479 break;
1481 case mpfr_fff_f:
1482 assert (inputs[0].type == gtype_fp);
1483 assert (inputs[1].type == gtype_fp);
1484 assert (inputs[2].type == gtype_fp);
1485 outputs[0].type = gtype_fp;
1486 mpfr_init (outputs[0].value.f);
1487 inexact = calc->func.mpfr_fff_f (outputs[0].value.f, inputs[0].value.f,
1488 inputs[1].value.f, inputs[2].value.f,
1489 mode_mpfr);
1490 if (mode != rm_towardzero)
1491 assert (!inexact && mpfr_zero_p (outputs[0].value.f));
1492 adjust_real (outputs[0].value.f, inexact);
1493 break;
1495 case mpfr_f_f1:
1496 assert (inputs[0].type == gtype_fp);
1497 outputs[0].type = gtype_fp;
1498 outputs[1].type = gtype_int;
1499 mpfr_init (outputs[0].value.f);
1500 int i = 0;
1501 inexact = calc->func.mpfr_f_f1 (outputs[0].value.f, &i,
1502 inputs[0].value.f, mode_mpfr);
1503 if (mode != rm_towardzero)
1504 assert (!inexact && mpfr_zero_p (outputs[0].value.f));
1505 adjust_real (outputs[0].value.f, inexact);
1506 mpz_init_set_si (outputs[1].value.i, i);
1507 break;
1509 case mpfr_if_f:
1510 assert (inputs[0].type == gtype_int);
1511 assert (inputs[1].type == gtype_fp);
1512 outputs[0].type = gtype_fp;
1513 mpfr_init (outputs[0].value.f);
1514 assert (mpz_fits_slong_p (inputs[0].value.i));
1515 long l = mpz_get_si (inputs[0].value.i);
1516 inexact = calc->func.mpfr_if_f (outputs[0].value.f, l,
1517 inputs[1].value.f, mode_mpfr);
1518 if (mode != rm_towardzero)
1519 assert (!inexact && mpfr_zero_p (outputs[0].value.f));
1520 adjust_real (outputs[0].value.f, inexact);
1521 break;
1523 case mpfr_f_11:
1524 assert (inputs[0].type == gtype_fp);
1525 outputs[0].type = gtype_fp;
1526 mpfr_init (outputs[0].value.f);
1527 outputs[1].type = gtype_fp;
1528 mpfr_init (outputs[1].value.f);
1529 int comb_ternary = calc->func.mpfr_f_11 (outputs[0].value.f,
1530 outputs[1].value.f,
1531 inputs[0].value.f,
1532 mode_mpfr);
1533 if (mode != rm_towardzero)
1534 assert (((comb_ternary & 0x3) == 0
1535 && mpfr_zero_p (outputs[0].value.f))
1536 || ((comb_ternary & 0xc) == 0
1537 && mpfr_zero_p (outputs[1].value.f)));
1538 adjust_real (outputs[0].value.f, (comb_ternary & 0x3) != 0);
1539 adjust_real (outputs[1].value.f, (comb_ternary & 0xc) != 0);
1540 break;
1542 case mpc_c_f:
1543 assert (inputs[0].type == gtype_fp);
1544 assert (inputs[1].type == gtype_fp);
1545 outputs[0].type = gtype_fp;
1546 mpfr_init (outputs[0].value.f);
1547 mpc_init2 (ci1, internal_precision);
1548 assert_exact (mpc_set_fr_fr (ci1, inputs[0].value.f, inputs[1].value.f,
1549 MPC_RNDNN));
1550 inexact = calc->func.mpc_c_f (outputs[0].value.f, ci1, mode_mpfr);
1551 if (mode != rm_towardzero)
1552 assert (!inexact && mpfr_zero_p (outputs[0].value.f));
1553 adjust_real (outputs[0].value.f, inexact);
1554 mpc_clear (ci1);
1555 break;
1557 case mpc_c_c:
1558 assert (inputs[0].type == gtype_fp);
1559 assert (inputs[1].type == gtype_fp);
1560 outputs[0].type = gtype_fp;
1561 mpfr_init (outputs[0].value.f);
1562 outputs[1].type = gtype_fp;
1563 mpfr_init (outputs[1].value.f);
1564 mpc_init2 (ci1, internal_precision);
1565 mpc_init2 (co, internal_precision);
1566 assert_exact (mpc_set_fr_fr (ci1, inputs[0].value.f, inputs[1].value.f,
1567 MPC_RNDNN));
1568 mpc_ternary = calc->func.mpc_c_c (co, ci1, 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 (co);
1582 break;
1584 case mpc_cc_c:
1585 assert (inputs[0].type == gtype_fp);
1586 assert (inputs[1].type == gtype_fp);
1587 assert (inputs[2].type == gtype_fp);
1588 assert (inputs[3].type == gtype_fp);
1589 outputs[0].type = gtype_fp;
1590 mpfr_init (outputs[0].value.f);
1591 outputs[1].type = gtype_fp;
1592 mpfr_init (outputs[1].value.f);
1593 mpc_init2 (ci1, internal_precision);
1594 mpc_init2 (ci2, internal_precision);
1595 mpc_init2 (co, internal_precision);
1596 assert_exact (mpc_set_fr_fr (ci1, inputs[0].value.f, inputs[1].value.f,
1597 MPC_RNDNN));
1598 assert_exact (mpc_set_fr_fr (ci2, inputs[2].value.f, inputs[3].value.f,
1599 MPC_RNDNN));
1600 mpc_ternary = calc->func.mpc_cc_c (co, ci1, ci2, mode_mpc);
1601 if (mode != rm_towardzero)
1602 assert ((!MPC_INEX_RE (mpc_ternary)
1603 && mpfr_zero_p (mpc_realref (co)))
1604 || (!MPC_INEX_IM (mpc_ternary)
1605 && mpfr_zero_p (mpc_imagref (co))));
1606 assert_exact (mpfr_set (outputs[0].value.f, mpc_realref (co),
1607 MPFR_RNDN));
1608 assert_exact (mpfr_set (outputs[1].value.f, mpc_imagref (co),
1609 MPFR_RNDN));
1610 adjust_real (outputs[0].value.f, MPC_INEX_RE (mpc_ternary));
1611 adjust_real (outputs[1].value.f, MPC_INEX_IM (mpc_ternary));
1612 mpc_clear (ci1);
1613 mpc_clear (ci2);
1614 mpc_clear (co);
1615 break;
1617 default:
1618 abort ();
1622 /* Return the number of bits for integer type TYPE, where "long" has
1623 LONG_BITS bits (32 or 64). */
1625 static int
1626 int_type_bits (arg_ret_type type, int long_bits)
1628 assert (long_bits == 32 || long_bits == 64);
1629 switch (type)
1631 case type_int:
1632 return 32;
1633 break;
1635 case type_long:
1636 return long_bits;
1637 break;
1639 case type_long_long:
1640 return 64;
1641 break;
1643 default:
1644 abort ();
1648 /* Check whether an integer Z fits a given type TYPE, where "long" has
1649 LONG_BITS bits (32 or 64). */
1651 static bool
1652 int_fits_type (mpz_t z, arg_ret_type type, int long_bits)
1654 int bits = int_type_bits (type, long_bits);
1655 bool ret = true;
1656 mpz_t t;
1657 mpz_init (t);
1658 mpz_ui_pow_ui (t, 2, bits - 1);
1659 if (mpz_cmp (z, t) >= 0)
1660 ret = false;
1661 mpz_neg (t, t);
1662 if (mpz_cmp (z, t) < 0)
1663 ret = false;
1664 mpz_clear (t);
1665 return ret;
1668 /* Print a generic value V to FP (name FILENAME), preceded by a space,
1669 for type TYPE, LONG_BITS bits per long, printing " IGNORE" instead
1670 if IGNORE. */
1672 static void
1673 output_generic_value (FILE *fp, const char *filename, const generic_value *v,
1674 bool ignore, arg_ret_type type, int long_bits)
1676 if (ignore)
1678 if (fputs (" IGNORE", fp) < 0)
1679 error (EXIT_FAILURE, errno, "write to '%s'", filename);
1680 return;
1682 assert (v->type == generic_arg_ret_type (type));
1683 const char *suffix;
1684 switch (type)
1686 case type_fp:
1687 suffix = "";
1688 break;
1690 case type_int:
1691 suffix = "";
1692 break;
1694 case type_long:
1695 suffix = "L";
1696 break;
1698 case type_long_long:
1699 suffix = "LL";
1700 break;
1702 default:
1703 abort ();
1705 switch (v->type)
1707 case gtype_fp:
1708 if (mpfr_inf_p (v->value.f))
1710 if (fputs ((mpfr_signbit (v->value.f)
1711 ? " minus_infty" : " plus_infty"), fp) < 0)
1712 error (EXIT_FAILURE, errno, "write to '%s'", filename);
1714 else
1716 assert (mpfr_number_p (v->value.f));
1717 if (mpfr_fprintf (fp, " %Ra%s", v->value.f, suffix) < 0)
1718 error (EXIT_FAILURE, errno, "mpfr_fprintf to '%s'", filename);
1720 break;
1722 case gtype_int: ;
1723 int bits = int_type_bits (type, long_bits);
1724 mpz_t tmp;
1725 mpz_init (tmp);
1726 mpz_ui_pow_ui (tmp, 2, bits - 1);
1727 mpz_neg (tmp, tmp);
1728 if (mpz_cmp (v->value.i, tmp) == 0)
1730 mpz_add_ui (tmp, tmp, 1);
1731 if (mpfr_fprintf (fp, " (%Zd%s-1)", tmp, suffix) < 0)
1732 error (EXIT_FAILURE, errno, "mpfr_fprintf to '%s'", filename);
1734 else
1736 if (mpfr_fprintf (fp, " %Zd%s", v->value.i, suffix) < 0)
1737 error (EXIT_FAILURE, errno, "mpfr_fprintf to '%s'", filename);
1739 mpz_clear (tmp);
1740 break;
1742 default:
1743 abort ();
1747 /* Generate test output to FP (name FILENAME) for test function TF
1748 (rounding results to a narrower type if NARROW), input test IT,
1749 choice of input values INPUTS. */
1751 static void
1752 output_for_one_input_case (FILE *fp, const char *filename, test_function *tf,
1753 bool narrow, input_test *it, generic_value *inputs)
1755 bool long_bits_matters = false;
1756 bool fits_long32 = true;
1757 for (size_t i = 0; i < tf->num_args; i++)
1759 generic_value_type gtype = generic_arg_ret_type (tf->arg_types[i]);
1760 assert (inputs[i].type == gtype);
1761 if (gtype == gtype_int)
1763 bool fits_64 = int_fits_type (inputs[i].value.i, tf->arg_types[i],
1764 64);
1765 if (!fits_64)
1766 return;
1767 if (tf->arg_types[i] == type_long
1768 && !int_fits_type (inputs[i].value.i, tf->arg_types[i], 32))
1770 long_bits_matters = true;
1771 fits_long32 = false;
1775 generic_value generic_outputs[MAX_NRET];
1776 calc_generic_results (generic_outputs, inputs, &tf->calc, rm_towardzero);
1777 bool ignore_output_long32[MAX_NRET] = { false };
1778 bool ignore_output_long64[MAX_NRET] = { false };
1779 for (size_t i = 0; i < tf->num_ret; i++)
1781 assert (generic_outputs[i].type
1782 == generic_arg_ret_type (tf->ret_types[i]));
1783 switch (generic_outputs[i].type)
1785 case gtype_fp:
1786 if (!mpfr_number_p (generic_outputs[i].value.f))
1787 goto out; /* Result is NaN or exact infinity. */
1788 break;
1790 case gtype_int:
1791 ignore_output_long32[i] = !int_fits_type (generic_outputs[i].value.i,
1792 tf->ret_types[i], 32);
1793 ignore_output_long64[i] = !int_fits_type (generic_outputs[i].value.i,
1794 tf->ret_types[i], 64);
1795 if (ignore_output_long32[i] != ignore_output_long64[i])
1796 long_bits_matters = true;
1797 break;
1799 default:
1800 abort ();
1803 /* Iterate over relevant sizes of long and floating-point formats. */
1804 for (int long_bits = 32; long_bits <= 64; long_bits += 32)
1806 if (long_bits == 32 && !fits_long32)
1807 continue;
1808 if (long_bits == 64 && !long_bits_matters)
1809 continue;
1810 const char *long_cond;
1811 if (long_bits_matters)
1812 long_cond = (long_bits == 32 ? ":long32" : ":long64");
1813 else
1814 long_cond = "";
1815 bool *ignore_output = (long_bits == 32
1816 ? ignore_output_long32
1817 : ignore_output_long64);
1818 for (fp_format f = fp_first_format; f < fp_num_formats; f++)
1820 bool fits = true;
1821 mpfr_t res[rm_num_modes];
1822 unsigned int exc_before[rm_num_modes];
1823 unsigned int exc_after[rm_num_modes];
1824 bool have_fp_arg = false;
1825 int max_exp = 0;
1826 int num_ones = 0;
1827 int min_exp = 0;
1828 int max_prec = 0;
1829 for (size_t i = 0; i < tf->num_args; i++)
1831 if (inputs[i].type == gtype_fp)
1833 if (narrow)
1835 if (mpfr_zero_p (inputs[i].value.f))
1836 continue;
1837 assert (mpfr_regular_p (inputs[i].value.f));
1838 int this_exp, this_num_ones, this_min_exp, this_prec;
1839 mpz_t tmp;
1840 mpz_init (tmp);
1841 mpfr_exp_t e = mpfr_get_z_2exp (tmp, inputs[i].value.f);
1842 if (mpz_sgn (tmp) < 0)
1843 mpz_neg (tmp, tmp);
1844 size_t bits = mpz_sizeinbase (tmp, 2);
1845 mp_bitcnt_t tz = mpz_scan1 (tmp, 0);
1846 this_min_exp = e + tz;
1847 this_prec = bits - tz;
1848 assert (this_prec > 0);
1849 this_exp = this_min_exp + this_prec - 1;
1850 assert (this_exp
1851 == mpfr_get_exp (inputs[i].value.f) - 1);
1852 this_num_ones = 1;
1853 while ((size_t) this_num_ones < bits
1854 && mpz_tstbit (tmp, bits - 1 - this_num_ones))
1855 this_num_ones++;
1856 mpz_clear (tmp);
1857 if (have_fp_arg)
1859 if (this_exp > max_exp
1860 || (this_exp == max_exp
1861 && this_num_ones > num_ones))
1863 max_exp = this_exp;
1864 num_ones = this_num_ones;
1866 if (this_min_exp < min_exp)
1867 min_exp = this_min_exp;
1868 if (this_prec > max_prec)
1869 max_prec = this_prec;
1871 else
1873 max_exp = this_exp;
1874 num_ones = this_num_ones;
1875 min_exp = this_min_exp;
1876 max_prec = this_prec;
1878 have_fp_arg = true;
1880 else
1882 round_real (res, exc_before, exc_after,
1883 inputs[i].value.f, f);
1884 if (!mpfr_equal_p (res[rm_tonearest], inputs[i].value.f))
1885 fits = false;
1886 for (rounding_mode m = rm_first_mode;
1887 m < rm_num_modes;
1888 m++)
1889 mpfr_clear (res[m]);
1890 if (!fits)
1891 break;
1895 if (!fits)
1896 continue;
1897 /* The inputs fit this type if required to do so, so compute
1898 the ideal outputs and exceptions. */
1899 mpfr_t all_res[MAX_NRET][rm_num_modes];
1900 unsigned int all_exc_before[MAX_NRET][rm_num_modes];
1901 unsigned int all_exc_after[MAX_NRET][rm_num_modes];
1902 unsigned int merged_exc_before[rm_num_modes] = { 0 };
1903 unsigned int merged_exc_after[rm_num_modes] = { 0 };
1904 /* For functions not exactly determined, track whether
1905 underflow is required (some result is inexact, and
1906 magnitude does not exceed the greatest magnitude
1907 subnormal), and permitted (not an exact zero, and
1908 magnitude does not exceed the least magnitude
1909 normal). */
1910 bool must_underflow = false;
1911 bool may_underflow = false;
1912 for (size_t i = 0; i < tf->num_ret; i++)
1914 switch (generic_outputs[i].type)
1916 case gtype_fp:
1917 round_real (all_res[i], all_exc_before[i], all_exc_after[i],
1918 generic_outputs[i].value.f, f);
1919 for (rounding_mode m = rm_first_mode; m < rm_num_modes; m++)
1921 merged_exc_before[m] |= all_exc_before[i][m];
1922 merged_exc_after[m] |= all_exc_after[i][m];
1923 if (!tf->exact)
1925 must_underflow
1926 |= ((all_exc_before[i][m]
1927 & (1U << exc_inexact)) != 0
1928 && (mpfr_cmpabs (generic_outputs[i].value.f,
1929 fp_formats[f].subnorm_max)
1930 <= 0));
1931 may_underflow
1932 |= (!mpfr_zero_p (generic_outputs[i].value.f)
1933 && (mpfr_cmpabs (generic_outputs[i].value.f,
1934 fp_formats[f].min_plus_half)
1935 <= 0));
1937 /* If the result is an exact zero, the sign may
1938 depend on the rounding mode, so recompute it
1939 directly in that mode. */
1940 if (mpfr_zero_p (all_res[i][m])
1941 && (all_exc_before[i][m] & (1U << exc_inexact)) == 0)
1943 generic_value outputs_rm[MAX_NRET];
1944 calc_generic_results (outputs_rm, inputs,
1945 &tf->calc, m);
1946 assert_exact (mpfr_set (all_res[i][m],
1947 outputs_rm[i].value.f,
1948 MPFR_RNDN));
1949 for (size_t j = 0; j < tf->num_ret; j++)
1950 generic_value_free (&outputs_rm[j]);
1953 break;
1955 case gtype_int:
1956 if (ignore_output[i])
1957 for (rounding_mode m = rm_first_mode;
1958 m < rm_num_modes;
1959 m++)
1961 merged_exc_before[m] |= 1U << exc_invalid;
1962 merged_exc_after[m] |= 1U << exc_invalid;
1964 break;
1966 default:
1967 abort ();
1970 assert (may_underflow || !must_underflow);
1971 for (rounding_mode m = rm_first_mode; m < rm_num_modes; m++)
1973 bool before_after_matters
1974 = tf->exact && merged_exc_before[m] != merged_exc_after[m];
1975 if (before_after_matters)
1977 assert ((merged_exc_before[m] ^ merged_exc_after[m])
1978 == (1U << exc_underflow));
1979 assert ((merged_exc_before[m] & (1U << exc_underflow)) != 0);
1981 unsigned int merged_exc = merged_exc_before[m];
1982 if (narrow)
1984 if (fprintf (fp, "= %s %s %s%s:arg_fmt(%d,%d,%d,%d)",
1985 tf->name, rounding_modes[m].name,
1986 fp_formats[f].name, long_cond, max_exp,
1987 num_ones, min_exp, max_prec) < 0)
1988 error (EXIT_FAILURE, errno, "write to '%s'", filename);
1990 else
1992 if (fprintf (fp, "= %s %s %s%s", tf->name,
1993 rounding_modes[m].name, fp_formats[f].name,
1994 long_cond) < 0)
1995 error (EXIT_FAILURE, errno, "write to '%s'", filename);
1997 /* Print inputs. */
1998 for (size_t i = 0; i < tf->num_args; i++)
1999 output_generic_value (fp, filename, &inputs[i], false,
2000 tf->arg_types[i], long_bits);
2001 if (fputs (" :", fp) < 0)
2002 error (EXIT_FAILURE, errno, "write to '%s'", filename);
2003 /* Print outputs. */
2004 bool must_erange = false;
2005 bool some_underflow_zero = false;
2006 for (size_t i = 0; i < tf->num_ret; i++)
2008 generic_value g;
2009 g.type = generic_outputs[i].type;
2010 switch (g.type)
2012 case gtype_fp:
2013 if (mpfr_inf_p (all_res[i][m])
2014 && (all_exc_before[i][m]
2015 & (1U << exc_overflow)) != 0)
2016 must_erange = true;
2017 if (mpfr_zero_p (all_res[i][m])
2018 && (tf->exact
2019 || mpfr_zero_p (all_res[i][rm_tonearest]))
2020 && (all_exc_before[i][m]
2021 & (1U << exc_underflow)) != 0)
2022 must_erange = true;
2023 if (mpfr_zero_p (all_res[i][rm_towardzero])
2024 && (all_exc_before[i][m]
2025 & (1U << exc_underflow)) != 0)
2026 some_underflow_zero = true;
2027 mpfr_init2 (g.value.f, fp_formats[f].mant_dig);
2028 assert_exact (mpfr_set (g.value.f, all_res[i][m],
2029 MPFR_RNDN));
2030 break;
2032 case gtype_int:
2033 mpz_init (g.value.i);
2034 mpz_set (g.value.i, generic_outputs[i].value.i);
2035 break;
2037 default:
2038 abort ();
2040 output_generic_value (fp, filename, &g, ignore_output[i],
2041 tf->ret_types[i], long_bits);
2042 generic_value_free (&g);
2044 if (fputs (" :", fp) < 0)
2045 error (EXIT_FAILURE, errno, "write to '%s'", filename);
2046 /* Print miscellaneous flags (passed through from
2047 input). */
2048 for (size_t i = 0; i < it->num_flags; i++)
2049 switch (it->flags[i].type)
2051 case flag_no_test_inline:
2052 case flag_ignore_zero_inf_sign:
2053 case flag_xfail:
2054 if (fprintf (fp, " %s%s",
2055 input_flags[it->flags[i].type],
2056 (it->flags[i].cond
2057 ? it->flags[i].cond
2058 : "")) < 0)
2059 error (EXIT_FAILURE, errno, "write to '%s'",
2060 filename);
2061 break;
2062 case flag_xfail_rounding:
2063 if (m != rm_tonearest)
2064 if (fprintf (fp, " xfail%s",
2065 (it->flags[i].cond
2066 ? it->flags[i].cond
2067 : "")) < 0)
2068 error (EXIT_FAILURE, errno, "write to '%s'",
2069 filename);
2070 break;
2071 default:
2072 break;
2074 /* For the ibm128 format, expect incorrect overflowing
2075 results in rounding modes other than to nearest;
2076 likewise incorrect results where the result may
2077 underflow to 0. */
2078 if (f == fp_ldbl_128ibm
2079 && m != rm_tonearest
2080 && (some_underflow_zero
2081 || (merged_exc_before[m] & (1U << exc_overflow)) != 0))
2082 if (fputs (" xfail:ibm128-libgcc", fp) < 0)
2083 error (EXIT_FAILURE, errno, "write to '%s'", filename);
2084 /* Print exception flags and compute errno
2085 expectations where not already computed. */
2086 bool may_edom = false;
2087 bool must_edom = false;
2088 bool may_erange = must_erange || may_underflow;
2089 for (fp_exception e = exc_first_exception;
2090 e < exc_num_exceptions;
2091 e++)
2093 bool expect_e = (merged_exc & (1U << e)) != 0;
2094 bool e_optional = false;
2095 switch (e)
2097 case exc_divbyzero:
2098 if (expect_e)
2099 may_erange = must_erange = true;
2100 break;
2102 case exc_inexact:
2103 if (!tf->exact)
2104 e_optional = true;
2105 break;
2107 case exc_invalid:
2108 if (expect_e)
2109 may_edom = must_edom = true;
2110 break;
2112 case exc_overflow:
2113 if (expect_e)
2114 may_erange = true;
2115 break;
2117 case exc_underflow:
2118 if (expect_e)
2119 may_erange = true;
2120 if (must_underflow)
2121 assert (expect_e);
2122 if (may_underflow && !must_underflow)
2123 e_optional = true;
2124 break;
2126 default:
2127 abort ();
2129 if (e_optional)
2131 assert (!before_after_matters);
2132 if (fprintf (fp, " %s-ok", exceptions[e]) < 0)
2133 error (EXIT_FAILURE, errno, "write to '%s'",
2134 filename);
2136 else
2138 if (expect_e)
2139 if (fprintf (fp, " %s", exceptions[e]) < 0)
2140 error (EXIT_FAILURE, errno, "write to '%s'",
2141 filename);
2142 if (before_after_matters && e == exc_underflow)
2143 if (fputs (":before-rounding", fp) < 0)
2144 error (EXIT_FAILURE, errno, "write to '%s'",
2145 filename);
2146 for (int after = 0; after <= 1; after++)
2148 bool expect_e_here = expect_e;
2149 if (after == 1 && (!before_after_matters
2150 || e != exc_underflow))
2151 continue;
2152 const char *after_cond;
2153 if (before_after_matters && e == exc_underflow)
2155 after_cond = (after
2156 ? ":after-rounding"
2157 : ":before-rounding");
2158 expect_e_here = !after;
2160 else
2161 after_cond = "";
2162 input_flag_type okflag;
2163 okflag = (expect_e_here
2164 ? flag_missing_first
2165 : flag_spurious_first) + e;
2166 for (size_t i = 0; i < it->num_flags; i++)
2167 if (it->flags[i].type == okflag)
2168 if (fprintf (fp, " %s-ok%s%s",
2169 exceptions[e],
2170 (it->flags[i].cond
2171 ? it->flags[i].cond
2172 : ""), after_cond) < 0)
2173 error (EXIT_FAILURE, errno, "write to '%s'",
2174 filename);
2178 /* Print errno expectations. */
2179 if (tf->complex_fn)
2181 must_edom = false;
2182 must_erange = false;
2184 if (may_edom && !must_edom)
2186 if (fputs (" errno-edom-ok", fp) < 0)
2187 error (EXIT_FAILURE, errno, "write to '%s'",
2188 filename);
2190 else
2192 if (must_edom)
2193 if (fputs (" errno-edom", fp) < 0)
2194 error (EXIT_FAILURE, errno, "write to '%s'",
2195 filename);
2196 input_flag_type okflag = (must_edom
2197 ? flag_missing_errno
2198 : flag_spurious_errno);
2199 for (size_t i = 0; i < it->num_flags; i++)
2200 if (it->flags[i].type == okflag)
2201 if (fprintf (fp, " errno-edom-ok%s",
2202 (it->flags[i].cond
2203 ? it->flags[i].cond
2204 : "")) < 0)
2205 error (EXIT_FAILURE, errno, "write to '%s'",
2206 filename);
2208 if (before_after_matters)
2209 assert (may_erange && !must_erange);
2210 if (may_erange && !must_erange)
2212 if (fprintf (fp, " errno-erange-ok%s",
2213 (before_after_matters
2214 ? ":before-rounding"
2215 : "")) < 0)
2216 error (EXIT_FAILURE, errno, "write to '%s'",
2217 filename);
2219 if (before_after_matters || !(may_erange && !must_erange))
2221 if (must_erange)
2222 if (fputs (" errno-erange", fp) < 0)
2223 error (EXIT_FAILURE, errno, "write to '%s'",
2224 filename);
2225 input_flag_type okflag = (must_erange
2226 ? flag_missing_errno
2227 : flag_spurious_errno);
2228 for (size_t i = 0; i < it->num_flags; i++)
2229 if (it->flags[i].type == okflag)
2230 if (fprintf (fp, " errno-erange-ok%s%s",
2231 (it->flags[i].cond
2232 ? it->flags[i].cond
2233 : ""),
2234 (before_after_matters
2235 ? ":after-rounding"
2236 : "")) < 0)
2237 error (EXIT_FAILURE, errno, "write to '%s'",
2238 filename);
2240 if (putc ('\n', fp) < 0)
2241 error (EXIT_FAILURE, errno, "write to '%s'", filename);
2243 for (size_t i = 0; i < tf->num_ret; i++)
2245 if (generic_outputs[i].type == gtype_fp)
2246 for (rounding_mode m = rm_first_mode; m < rm_num_modes; m++)
2247 mpfr_clear (all_res[i][m]);
2251 out:
2252 for (size_t i = 0; i < tf->num_ret; i++)
2253 generic_value_free (&generic_outputs[i]);
2256 /* Generate test output data for FUNCTION to FILENAME. The function
2257 is interpreted as rounding its results to a narrower type if
2258 NARROW. */
2260 static void
2261 generate_output (const char *function, bool narrow, const char *filename)
2263 FILE *fp = fopen (filename, "w");
2264 if (fp == NULL)
2265 error (EXIT_FAILURE, errno, "open '%s'", filename);
2266 for (size_t i = 0; i < ARRAY_SIZE (test_functions); i++)
2268 test_function *tf = &test_functions[i];
2269 if (strcmp (tf->name, function) != 0)
2270 continue;
2271 for (size_t j = 0; j < tf->num_tests; j++)
2273 input_test *it = &tf->tests[j];
2274 if (fputs (it->line, fp) < 0)
2275 error (EXIT_FAILURE, errno, "write to '%s'", filename);
2276 for (size_t k = 0; k < it->num_input_cases; k++)
2277 output_for_one_input_case (fp, filename, tf, narrow,
2278 it, it->inputs[k]);
2281 if (fclose (fp) != 0)
2282 error (EXIT_FAILURE, errno, "close '%s'", filename);
2286 main (int argc, char **argv)
2288 if (argc != 4
2289 && !(argc == 5 && strcmp (argv[1], "--narrow") == 0))
2290 error (EXIT_FAILURE, 0,
2291 "usage: gen-auto-libm-tests [--narrow] <input> <func> <output>");
2292 bool narrow;
2293 const char *input_filename = argv[1];
2294 const char *function = argv[2];
2295 const char *output_filename = argv[3];
2296 if (argc == 4)
2298 narrow = false;
2299 input_filename = argv[1];
2300 function = argv[2];
2301 output_filename = argv[3];
2303 else
2305 narrow = true;
2306 input_filename = argv[2];
2307 function = argv[3];
2308 output_filename = argv[4];
2310 init_fp_formats ();
2311 read_input (input_filename);
2312 generate_output (function, narrow, output_filename);
2313 exit (EXIT_SUCCESS);