]> sourceware.org Git - glibc.git/blob - math/libm-test-driver.c
Refactor some code in libm-test-driver.c.
[glibc.git] / math / libm-test-driver.c
1 /* Support code for testing libm functions.
2 Copyright (C) 1997-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 /* Part of testsuite for libm.
20
21 libm-test.inc is processed by a perl script. The resulting file has to
22 be included by a master file that defines:
23
24 Macros:
25 FUNC(function): converts general function name (like cos) to
26 name with correct suffix (e.g. cosl or cosf)
27 FLOAT: floating point type to test
28 chooses one of the parameters as delta for testing
29 equality
30 PREFIX A macro which defines the prefix for common macros for the
31 type (i.e LDBL, DBL, or FLT).
32 LIT A function which appends the correct suffix to a literal.
33 TYPE_STR A macro which defines a stringitized name of the type.
34 FTOSTR This macro defines a function similar in type to strfromf
35 which converts a FLOAT to a string. */
36
37 /* Parameter handling is primitive in the moment:
38 --verbose=[0..3] for different levels of output:
39 0: only error count
40 1: basic report on failed tests (default)
41 2: full report on all tests
42 -v for full output (equals --verbose=3)
43 -u for generation of an ULPs file
44 */
45
46 /* "Philosophy":
47
48 This suite tests some aspects of the correct implementation of
49 mathematical functions in libm. Some simple, specific parameters
50 are tested for correctness but there's no exhaustive
51 testing. Handling of specific inputs (e.g. infinity, not-a-number)
52 is also tested. Correct handling of exceptions is checked
53 against. These implemented tests should check all cases that are
54 specified in ISO C99.
55
56 NaN values: The payload of NaNs is set in inputs for functions
57 where it is significant, and is examined in the outputs of some
58 functions.
59
60 Inline functions: Inlining functions should give an improvement in
61 speed - but not in precission. The inlined functions return
62 reasonable values for a reasonable range of input values. The
63 result is not necessarily correct for all values and exceptions are
64 not correctly raised in all cases. Problematic input and return
65 values are infinity, not-a-number and minus zero. This suite
66 therefore does not check these specific inputs and the exception
67 handling for inlined mathematical functions - just the "reasonable"
68 values are checked.
69
70 Beware: The tests might fail for any of the following reasons:
71 - Tests are wrong
72 - Functions are wrong
73 - Floating Point Unit not working properly
74 - Compiler has errors
75
76 With e.g. gcc 2.7.2.2 the test for cexp fails because of a compiler error.
77
78
79 To Do: All parameter should be numbers that can be represented as
80 exact floating point values. Currently some values cannot be
81 represented exactly and therefore the result is not the expected
82 result. For this we will use 36 digits so that numbers can be
83 represented exactly. */
84
85 #ifndef _GNU_SOURCE
86 # define _GNU_SOURCE
87 #endif
88
89 #include <complex.h>
90 #include <math.h>
91 #include <float.h>
92 #include <fenv.h>
93 #include <limits.h>
94
95 #include <errno.h>
96 #include <stdlib.h>
97 #include <stdint.h>
98 #include <stdio.h>
99 #include <string.h>
100 #include <argp.h>
101 #include <tininess.h>
102 #include <math-tests.h>
103 #include <math-tests-arch.h>
104 #include <nan-high-order-bit.h>
105
106 /* This header defines func_ulps, func_real_ulps and func_imag_ulps
107 arrays. */
108 #include "libm-test-ulps.h"
109
110 /* Flags set by the including file. */
111 static const int flag_test_errno = TEST_ERRNO;
112 static const int flag_test_exceptions = TEST_EXCEPTIONS;
113 static const int flag_test_finite = TEST_FINITE;
114 static const int flag_test_inline = TEST_INLINE;
115 static const int flag_test_mathvec = TEST_MATHVEC;
116
117 #define STRX(x) #x
118 #define STR(x) STRX (x)
119 #define STR_FLOAT STR (FLOAT)
120 #define STR_VEC_LEN STR (VEC_LEN)
121
122 /* Informal description of the functions being tested. */
123 #if TEST_MATHVEC
124 # define TEST_MSG "testing " STR_FLOAT " (vector length " STR_VEC_LEN ")\n"
125 #elif TEST_INLINE
126 # define TEST_MSG "testing " STR_FLOAT " (inline functions)\n"
127 #elif TEST_FINITE
128 # define TEST_MSG "testing " STR_FLOAT " (finite-math-only)\n"
129 #else
130 # define TEST_MSG "testing " STR_FLOAT " (without inline functions)\n"
131 #endif
132 static const char test_msg[] = TEST_MSG;
133
134 /* Allow platforms without all rounding modes to test properly,
135 assuming they provide an __FE_UNDEFINED in <bits/fenv.h> which
136 causes fesetround() to return failure. */
137 #ifndef FE_TONEAREST
138 # define FE_TONEAREST __FE_UNDEFINED
139 #endif
140 #ifndef FE_TOWARDZERO
141 # define FE_TOWARDZERO __FE_UNDEFINED
142 #endif
143 #ifndef FE_UPWARD
144 # define FE_UPWARD __FE_UNDEFINED
145 #endif
146 #ifndef FE_DOWNWARD
147 # define FE_DOWNWARD __FE_UNDEFINED
148 #endif
149
150 /* Possible exceptions */
151 #define NO_EXCEPTION 0x0
152 #define INVALID_EXCEPTION 0x1
153 #define DIVIDE_BY_ZERO_EXCEPTION 0x2
154 #define OVERFLOW_EXCEPTION 0x4
155 #define UNDERFLOW_EXCEPTION 0x8
156 #define INEXACT_EXCEPTION 0x10
157 /* The next flags signals that those exceptions are allowed but not required. */
158 #define INVALID_EXCEPTION_OK 0x20
159 #define DIVIDE_BY_ZERO_EXCEPTION_OK 0x40
160 #define OVERFLOW_EXCEPTION_OK 0x80
161 #define UNDERFLOW_EXCEPTION_OK 0x100
162 /* For "inexact" exceptions, the default is allowed but not required
163 unless INEXACT_EXCEPTION or NO_INEXACT_EXCEPTION is specified. */
164 #define NO_INEXACT_EXCEPTION 0x200
165 #define EXCEPTIONS_OK INVALID_EXCEPTION_OK+DIVIDE_BY_ZERO_EXCEPTION_OK
166 /* Some special test flags, passed together with exceptions. */
167 #define IGNORE_ZERO_INF_SIGN 0x400
168 #define TEST_NAN_SIGN 0x800
169 #define TEST_NAN_PAYLOAD 0x1000
170 #define NO_TEST_INLINE 0x2000
171 #define XFAIL_TEST 0x4000
172 /* Indicate errno settings required or disallowed. */
173 #define ERRNO_UNCHANGED 0x8000
174 #define ERRNO_EDOM 0x10000
175 #define ERRNO_ERANGE 0x20000
176 /* Flags generated by gen-libm-test.pl, not entered here manually. */
177 #define IGNORE_RESULT 0x40000
178 #define NON_FINITE 0x80000
179 #define TEST_SNAN 0x100000
180 #define NO_TEST_MATHVEC 0x200000
181
182 #define TEST_NAN_PAYLOAD_CANONICALIZE (SNAN_TESTS_PRESERVE_PAYLOAD \
183 ? TEST_NAN_PAYLOAD \
184 : 0)
185
186 #define __CONCATX(a,b) __CONCAT(a,b)
187
188 #define TYPE_MIN __CONCATX (PREFIX, _MIN)
189 #define TYPE_TRUE_MIN __CONCATX (PREFIX, _TRUE_MIN)
190 #define TYPE_MAX __CONCATX (PREFIX, _MAX)
191 #define MIN_EXP __CONCATX (PREFIX, _MIN_EXP)
192 #define MAX_EXP __CONCATX (PREFIX, _MAX_EXP)
193 #define MANT_DIG __CONCATX (PREFIX, _MANT_DIG)
194
195 /* Maximum character buffer to store a stringitized FLOAT value. */
196 #define FSTR_MAX (128)
197
198 #if TEST_INLINE
199 static const int ulp_idx = __CONCATX (ULP_I_, PREFIX);
200 static const char qtype_str[] = "i" TYPE_STR;
201 #else
202 static const int ulp_idx = __CONCATX (ULP_, PREFIX);
203 static const char qtype_str[] = TYPE_STR;
204 #endif
205
206 /* Format specific test macros. */
207 #define TEST_COND_binary32 (MANT_DIG == 24 \
208 && MIN_EXP == -125 \
209 && MAX_EXP == 128)
210
211 #define TEST_COND_binary64 (MANT_DIG == 53 \
212 && MIN_EXP == -1021 \
213 && MAX_EXP == 1024)
214
215 #define TEST_COND_binary128 (MANT_DIG == 113 \
216 && MIN_EXP == -16381 \
217 && MAX_EXP == 16384)
218
219 #define TEST_COND_ibm128 (MANT_DIG == 106)
220
221 #define TEST_COND_intel96 (MANT_DIG == 64 \
222 && MIN_EXP == -16381 \
223 && MAX_EXP == 16384)
224
225 #define TEST_COND_m68k96 (MANT_DIG == 64 \
226 && MIN_EXP == -16382 \
227 && MAX_EXP == 16384)
228
229 /* The condition ibm128-libgcc is used instead of ibm128 to mark tests
230 where in principle the glibc code is OK but the tests fail because
231 of limitations of the libgcc support for that format (e.g. GCC bug
232 59666, in non-default rounding modes). */
233 #define TEST_COND_ibm128_libgcc TEST_COND_ibm128
234
235 /* Mark a test as expected to fail for ibm128-libgcc. This is used
236 via XFAIL_ROUNDING_IBM128_LIBGCC, which gen-libm-test.pl transforms
237 appropriately for each rounding mode. */
238 #define XFAIL_IBM128_LIBGCC (TEST_COND_ibm128_libgcc ? XFAIL_TEST : 0)
239
240 /* Number of bits in NaN payload. */
241 #if TEST_COND_ibm128
242 # define PAYLOAD_DIG (DBL_MANT_DIG - 2)
243 #else
244 # define PAYLOAD_DIG (MANT_DIG - 2)
245 #endif
246
247 /* Values underflowing only for float. */
248 #if TEST_COND_binary32
249 # define UNDERFLOW_EXCEPTION_FLOAT UNDERFLOW_EXCEPTION
250 # define UNDERFLOW_EXCEPTION_OK_FLOAT UNDERFLOW_EXCEPTION_OK
251 #else
252 # define UNDERFLOW_EXCEPTION_FLOAT 0
253 # define UNDERFLOW_EXCEPTION_OK_FLOAT 0
254 #endif
255
256 /* Values underflowing only for double or types with a larger least
257 positive normal value. */
258 #if TEST_COND_binary32 || TEST_COND_binary64 || TEST_COND_ibm128
259 # define UNDERFLOW_EXCEPTION_DOUBLE UNDERFLOW_EXCEPTION
260 # define UNDERFLOW_EXCEPTION_OK_DOUBLE UNDERFLOW_EXCEPTION_OK
261 #else
262 # define UNDERFLOW_EXCEPTION_DOUBLE 0
263 # define UNDERFLOW_EXCEPTION_OK_DOUBLE 0
264 #endif
265
266 /* Values underflowing only for IBM long double or types with a larger least
267 positive normal value. */
268 #if TEST_COND_binary32 || TEST_COND_ibm128
269 # define UNDERFLOW_EXCEPTION_LDOUBLE_IBM UNDERFLOW_EXCEPTION
270 #else
271 # define UNDERFLOW_EXCEPTION_LDOUBLE_IBM 0
272 #endif
273
274 /* Values underflowing on architectures detecting tininess before
275 rounding, but not on those detecting tininess after rounding. */
276 #define UNDERFLOW_EXCEPTION_BEFORE_ROUNDING (TININESS_AFTER_ROUNDING \
277 ? 0 \
278 : UNDERFLOW_EXCEPTION)
279
280 #if LONG_MAX == 0x7fffffff
281 # define TEST_COND_long32 1
282 # define TEST_COND_long64 0
283 #else
284 # define TEST_COND_long32 0
285 # define TEST_COND_long64 1
286 #endif
287 #define TEST_COND_before_rounding (!TININESS_AFTER_ROUNDING)
288 #define TEST_COND_after_rounding TININESS_AFTER_ROUNDING
289
290 /* Various constants derived from pi. We must supply them precalculated for
291 accuracy. They are written as a series of postfix operations to keep
292 them concise yet somewhat readable. */
293
294 /* (pi * 3) / 4 */
295 #define lit_pi_3_m_4_d LIT (2.356194490192344928846982537459627163)
296 /* pi * 3 / (4 * ln(10)) */
297 #define lit_pi_3_m_4_ln10_m_d LIT (1.023282265381381010614337719073516828)
298 /* pi / (2 * ln(10)) */
299 #define lit_pi_2_ln10_m_d LIT (0.682188176920920673742891812715677885)
300 /* pi / (4 * ln(10)) */
301 #define lit_pi_4_ln10_m_d LIT (0.341094088460460336871445906357838943)
302 /* pi / ln(10) */
303 #define lit_pi_ln10_d LIT (1.364376353841841347485783625431355770)
304 /* pi / 2 */
305 #define lit_pi_2_d LITM (M_PI_2)
306 /* pi / 4 */
307 #define lit_pi_4_d LITM (M_PI_4)
308 /* pi */
309 #define lit_pi LITM (M_PI)
310
311 /* Other useful constants. */
312
313 /* e */
314 #define lit_e LITM (M_E)
315
316 #define ulps_file_name "ULPs" /* Name of the ULPs file. */
317 static FILE *ulps_file; /* File to document difference. */
318 static int output_ulps; /* Should ulps printed? */
319 static char *output_dir; /* Directory where generated files will be written. */
320
321 static int noErrors; /* number of errors */
322 static int noTests; /* number of tests (without testing exceptions) */
323 static int noExcTests; /* number of tests for exception flags */
324 static int noErrnoTests;/* number of tests for errno values */
325
326 static int verbose;
327 static int output_max_error; /* Should the maximal errors printed? */
328 static int output_points; /* Should the single function results printed? */
329 static int ignore_max_ulp; /* Should we ignore max_ulp? */
330
331 #define plus_zero LIT (0.0)
332 #define minus_zero LIT (-0.0)
333 #define plus_infty FUNC (__builtin_inf) ()
334 #define minus_infty -(FUNC (__builtin_inf) ())
335 #define qnan_value_pl(S) FUNC (__builtin_nan) (S)
336 #define qnan_value qnan_value_pl ("")
337 #define snan_value_pl(S) FUNC (__builtin_nans) (S)
338 #define snan_value snan_value_pl ("")
339 #define max_value TYPE_MAX
340 #define min_value TYPE_MIN
341 #define min_subnorm_value TYPE_TRUE_MIN
342
343 /* For nexttoward tests. */
344 #define snan_value_ld __builtin_nansl ("")
345
346 static FLOAT max_error, real_max_error, imag_max_error;
347
348 static FLOAT prev_max_error, prev_real_max_error, prev_imag_max_error;
349
350 static FLOAT max_valid_error;
351
352 /* Sufficient numbers of digits to represent any floating-point value
353 unambiguously (for any choice of the number of bits in the first
354 hex digit, in the case of TYPE_HEX_DIG). When used with printf
355 formats where the precision counts only digits after the point, 1
356 is subtracted from these values. */
357 #define TYPE_DECIMAL_DIG __CONCATX (PREFIX, _DECIMAL_DIG)
358 #define TYPE_HEX_DIG ((MANT_DIG + 6) / 4)
359
360 /* Converts VALUE (a floating-point number) to string and writes it to DEST.
361 PRECISION specifies the number of fractional digits that should be printed.
362 CONVERSION is the conversion specifier, such as in printf, e.g. 'f' or 'a'.
363 The output is prepended with an empty space if VALUE is non-negative. */
364 static void
365 fmt_ftostr (char *dest, size_t size, int precision, const char *conversion,
366 FLOAT value)
367 {
368 char format[64];
369 char *ptr_format;
370 int ret;
371
372 /* Generate the format string. */
373 ptr_format = stpcpy (format, "%.");
374 ret = sprintf (ptr_format, "%d", precision);
375 ptr_format += ret;
376 ptr_format = stpcpy (ptr_format, conversion);
377
378 /* Add a space to the beginning of the output string, if the floating-point
379 number is non-negative. This mimics the behavior of the space (' ') flag
380 in snprintf, which is not available on strfrom. */
381 if (! signbit (value))
382 {
383 *dest = ' ';
384 dest++;
385 size--;
386 }
387
388 /* Call the float to string conversion function, e.g.: strfromd. */
389 FTOSTR (dest, size, format, value);
390 }
391
392 /* Compare KEY (a string, with the name of a function) with ULP (a
393 pointer to a struct ulp_data structure), returning a value less
394 than, equal to or greater than zero for use in bsearch. */
395
396 static int
397 compare_ulp_data (const void *key, const void *ulp)
398 {
399 const char *keystr = key;
400 const struct ulp_data *ulpdat = ulp;
401 return strcmp (keystr, ulpdat->name);
402 }
403
404 /* Return the ulps for NAME in array DATA with NMEMB elements, or 0 if
405 no ulps listed. */
406
407 static FLOAT
408 find_ulps (const char *name, const struct ulp_data *data, size_t nmemb)
409 {
410 const struct ulp_data *entry = bsearch (name, data, nmemb, sizeof (*data),
411 compare_ulp_data);
412 if (entry == NULL)
413 return 0;
414 else
415 return entry->max_ulp[ulp_idx];
416 }
417
418 static void
419 init_max_error (const char *name, int exact)
420 {
421 max_error = 0;
422 real_max_error = 0;
423 imag_max_error = 0;
424 prev_max_error = find_ulps (name, func_ulps,
425 sizeof (func_ulps) / sizeof (func_ulps[0]));
426 prev_real_max_error = find_ulps (name, func_real_ulps,
427 (sizeof (func_real_ulps)
428 / sizeof (func_real_ulps[0])));
429 prev_imag_max_error = find_ulps (name, func_imag_ulps,
430 (sizeof (func_imag_ulps)
431 / sizeof (func_imag_ulps[0])));
432 #if TEST_COND_ibm128
433 /* The documented accuracy of IBM long double division is 3ulp (see
434 libgcc/config/rs6000/ibm-ldouble-format), so do not require
435 better accuracy for libm functions that are exactly defined for
436 other formats. */
437 max_valid_error = exact ? 3 : 16;
438 #else
439 max_valid_error = exact ? 0 : 9;
440 #endif
441 prev_max_error = (prev_max_error <= max_valid_error
442 ? prev_max_error
443 : max_valid_error);
444 prev_real_max_error = (prev_real_max_error <= max_valid_error
445 ? prev_real_max_error
446 : max_valid_error);
447 prev_imag_max_error = (prev_imag_max_error <= max_valid_error
448 ? prev_imag_max_error
449 : max_valid_error);
450 feclearexcept (FE_ALL_EXCEPT);
451 errno = 0;
452 }
453
454 static void
455 set_max_error (FLOAT current, FLOAT *curr_max_error)
456 {
457 if (current > *curr_max_error && current <= max_valid_error)
458 *curr_max_error = current;
459 }
460
461
462 /* Print a FLOAT. */
463 static void
464 print_float (FLOAT f)
465 {
466 /* As printf doesn't differ between a sNaN and a qNaN, do this manually. */
467 if (issignaling (f))
468 printf ("sNaN\n");
469 else if (isnan (f))
470 printf ("qNaN\n");
471 else
472 {
473 char fstrn[FSTR_MAX], fstrx[FSTR_MAX];
474 fmt_ftostr (fstrn, FSTR_MAX, TYPE_DECIMAL_DIG - 1, "e", f);
475 fmt_ftostr (fstrx, FSTR_MAX, TYPE_HEX_DIG - 1, "a", f);
476 printf ("%s %s\n", fstrn, fstrx);
477 }
478 }
479
480 /* Should the message print to screen? This depends on the verbose flag,
481 and the test status. */
482 static int
483 print_screen (int ok)
484 {
485 if (output_points
486 && (verbose > 1
487 || (verbose == 1 && ok == 0)))
488 return 1;
489 return 0;
490 }
491
492
493 /* Should the message print to screen? This depends on the verbose flag,
494 and the test status. */
495 static int
496 print_screen_max_error (int ok)
497 {
498 if (output_max_error
499 && (verbose > 1
500 || ((verbose == 1) && (ok == 0))))
501 return 1;
502 return 0;
503 }
504
505 /* Update statistic counters. */
506 static void
507 update_stats (int ok)
508 {
509 ++noTests;
510 if (!ok)
511 ++noErrors;
512 }
513
514 static void
515 print_function_ulps (const char *function_name, FLOAT ulp)
516 {
517 if (output_ulps)
518 {
519 char ustrn[FSTR_MAX];
520 FTOSTR (ustrn, FSTR_MAX, "%.0f", FUNC (ceil) (ulp));
521 fprintf (ulps_file, "Function: \"%s\":\n", function_name);
522 fprintf (ulps_file, "%s: %s\n", qtype_str, ustrn);
523 }
524 }
525
526
527 static void
528 print_complex_function_ulps (const char *function_name, FLOAT real_ulp,
529 FLOAT imag_ulp)
530 {
531 if (output_ulps)
532 {
533 char fstrn[FSTR_MAX];
534 if (real_ulp != 0.0)
535 {
536 FTOSTR (fstrn, FSTR_MAX, "%.0f", FUNC (ceil) (real_ulp));
537 fprintf (ulps_file, "Function: Real part of \"%s\":\n", function_name);
538 fprintf (ulps_file, "%s: %s\n", qtype_str, fstrn);
539 }
540 if (imag_ulp != 0.0)
541 {
542 FTOSTR (fstrn, FSTR_MAX, "%.0f", FUNC (ceil) (imag_ulp));
543 fprintf (ulps_file, "Function: Imaginary part of \"%s\":\n", function_name);
544 fprintf (ulps_file, "%s: %s\n", qtype_str, fstrn);
545 }
546
547
548 }
549 }
550
551
552
553 /* Test if Floating-Point stack hasn't changed */
554 static void
555 fpstack_test (const char *test_name)
556 {
557 #if defined (__i386__) || defined (__x86_64__)
558 static int old_stack;
559 int sw;
560
561 asm ("fnstsw" : "=a" (sw));
562 sw >>= 11;
563 sw &= 7;
564
565 if (sw != old_stack)
566 {
567 printf ("FP-Stack wrong after test %s (%d, should be %d)\n",
568 test_name, sw, old_stack);
569 ++noErrors;
570 old_stack = sw;
571 }
572 #endif
573 }
574
575
576 static void
577 print_max_error (const char *func_name)
578 {
579 int ok = 0;
580
581 if (max_error == 0.0 || (max_error <= prev_max_error && !ignore_max_ulp))
582 {
583 ok = 1;
584 }
585
586 if (!ok)
587 print_function_ulps (func_name, max_error);
588
589
590 if (print_screen_max_error (ok))
591 {
592 char mestr[FSTR_MAX], pmestr[FSTR_MAX];
593 FTOSTR (mestr, FSTR_MAX, "%.0f", FUNC (ceil) (max_error));
594 FTOSTR (pmestr, FSTR_MAX, "%.0f", FUNC (ceil) (prev_max_error));
595 printf ("Maximal error of `%s'\n", func_name);
596 printf (" is : %s ulp\n", mestr);
597 printf (" accepted: %s ulp\n", pmestr);
598 }
599
600 update_stats (ok);
601 }
602
603
604 static void
605 print_complex_max_error (const char *func_name)
606 {
607 int real_ok = 0, imag_ok = 0, ok;
608
609 if (real_max_error == 0
610 || (real_max_error <= prev_real_max_error && !ignore_max_ulp))
611 {
612 real_ok = 1;
613 }
614
615 if (imag_max_error == 0
616 || (imag_max_error <= prev_imag_max_error && !ignore_max_ulp))
617 {
618 imag_ok = 1;
619 }
620
621 ok = real_ok && imag_ok;
622
623 if (!ok)
624 print_complex_function_ulps (func_name,
625 real_ok ? 0 : real_max_error,
626 imag_ok ? 0 : imag_max_error);
627
628 if (print_screen_max_error (ok))
629 {
630 char rmestr[FSTR_MAX], prmestr[FSTR_MAX];
631 char imestr[FSTR_MAX], pimestr[FSTR_MAX];
632 FTOSTR (rmestr, FSTR_MAX, "%.0f", FUNC (ceil) (real_max_error));
633 FTOSTR (prmestr, FSTR_MAX, "%.0f", FUNC (ceil) (prev_real_max_error));
634 FTOSTR (imestr, FSTR_MAX, "%.0f", FUNC (ceil) (imag_max_error));
635 FTOSTR (pimestr, FSTR_MAX, "%.0f", FUNC (ceil) (prev_imag_max_error));
636 printf ("Maximal error of real part of: %s\n", func_name);
637 printf (" is : %s ulp\n", rmestr);
638 printf (" accepted: %s ulp\n", prmestr);
639 printf ("Maximal error of imaginary part of: %s\n", func_name);
640 printf (" is : %s ulp\n", imestr);
641 printf (" accepted: %s ulp\n", pimestr);
642 }
643
644 update_stats (ok);
645 }
646
647
648 #if FE_ALL_EXCEPT
649 /* Test whether a given exception was raised. */
650 static void
651 test_single_exception (const char *test_name,
652 int exception,
653 int exc_flag,
654 int fe_flag,
655 const char *flag_name)
656 {
657 int ok = 1;
658 if (exception & exc_flag)
659 {
660 if (fetestexcept (fe_flag))
661 {
662 if (print_screen (1))
663 printf ("Pass: %s: Exception \"%s\" set\n", test_name, flag_name);
664 }
665 else
666 {
667 ok = 0;
668 if (print_screen (0))
669 printf ("Failure: %s: Exception \"%s\" not set\n",
670 test_name, flag_name);
671 }
672 }
673 else
674 {
675 if (fetestexcept (fe_flag))
676 {
677 ok = 0;
678 if (print_screen (0))
679 printf ("Failure: %s: Exception \"%s\" set\n",
680 test_name, flag_name);
681 }
682 else
683 {
684 if (print_screen (1))
685 printf ("%s: Exception \"%s\" not set\n", test_name,
686 flag_name);
687 }
688 }
689 if (!ok)
690 ++noErrors;
691 }
692 #endif
693
694 /* Test whether exceptions given by EXCEPTION are raised. Ignore thereby
695 allowed but not required exceptions.
696 */
697 static void
698 test_exceptions (const char *test_name, int exception)
699 {
700 if (flag_test_exceptions && EXCEPTION_TESTS (FLOAT))
701 {
702 ++noExcTests;
703 #ifdef FE_DIVBYZERO
704 if ((exception & DIVIDE_BY_ZERO_EXCEPTION_OK) == 0)
705 test_single_exception (test_name, exception,
706 DIVIDE_BY_ZERO_EXCEPTION, FE_DIVBYZERO,
707 "Divide by zero");
708 #endif
709 #ifdef FE_INVALID
710 if ((exception & INVALID_EXCEPTION_OK) == 0)
711 test_single_exception (test_name, exception,
712 INVALID_EXCEPTION, FE_INVALID,
713 "Invalid operation");
714 #endif
715 #ifdef FE_OVERFLOW
716 if ((exception & OVERFLOW_EXCEPTION_OK) == 0)
717 test_single_exception (test_name, exception, OVERFLOW_EXCEPTION,
718 FE_OVERFLOW, "Overflow");
719 #endif
720 /* Spurious "underflow" and "inexact" exceptions are always
721 allowed for IBM long double, in line with the underlying
722 arithmetic. */
723 #ifdef FE_UNDERFLOW
724 if ((exception & UNDERFLOW_EXCEPTION_OK) == 0
725 && !(TEST_COND_ibm128
726 && (exception & UNDERFLOW_EXCEPTION) == 0))
727 test_single_exception (test_name, exception, UNDERFLOW_EXCEPTION,
728 FE_UNDERFLOW, "Underflow");
729 #endif
730 #ifdef FE_INEXACT
731 if ((exception & (INEXACT_EXCEPTION | NO_INEXACT_EXCEPTION)) != 0
732 && !(TEST_COND_ibm128
733 && (exception & NO_INEXACT_EXCEPTION) != 0))
734 test_single_exception (test_name, exception, INEXACT_EXCEPTION,
735 FE_INEXACT, "Inexact");
736 #endif
737 }
738 feclearexcept (FE_ALL_EXCEPT);
739 }
740
741 /* Test whether errno for TEST_NAME, set to ERRNO_VALUE, has value
742 EXPECTED_VALUE (description EXPECTED_NAME). */
743 static void
744 test_single_errno (const char *test_name, int errno_value,
745 int expected_value, const char *expected_name)
746 {
747 if (errno_value == expected_value)
748 {
749 if (print_screen (1))
750 printf ("Pass: %s: errno set to %d (%s)\n", test_name, errno_value,
751 expected_name);
752 }
753 else
754 {
755 ++noErrors;
756 if (print_screen (0))
757 printf ("Failure: %s: errno set to %d, expected %d (%s)\n",
758 test_name, errno_value, expected_value, expected_name);
759 }
760 }
761
762 /* Test whether errno (value ERRNO_VALUE) has been for TEST_NAME set
763 as required by EXCEPTIONS. */
764 static void
765 test_errno (const char *test_name, int errno_value, int exceptions)
766 {
767 if (flag_test_errno)
768 {
769 ++noErrnoTests;
770 if (exceptions & ERRNO_UNCHANGED)
771 test_single_errno (test_name, errno_value, 0, "unchanged");
772 if (exceptions & ERRNO_EDOM)
773 test_single_errno (test_name, errno_value, EDOM, "EDOM");
774 if (exceptions & ERRNO_ERANGE)
775 test_single_errno (test_name, errno_value, ERANGE, "ERANGE");
776 }
777 }
778
779 /* Returns the number of ulps that GIVEN is away from EXPECTED. */
780 #define ULPDIFF(given, expected) \
781 (FUNC(fabs) ((given) - (expected)) / ulp (expected))
782
783 /* Returns the size of an ulp for VALUE. */
784 static FLOAT
785 ulp (FLOAT value)
786 {
787 FLOAT ulp;
788
789 switch (fpclassify (value))
790 {
791 case FP_ZERO:
792 /* We compute the distance to the next FP which is the same as the
793 value of the smallest subnormal number. Previously we used
794 2^-(MANT_DIG - 1) which is too large a value to be useful. Note that we
795 can't use ilogb(0), since that isn't a valid thing to do. As a point
796 of comparison Java's ulp returns the next normal value e.g.
797 2^(1 - MAX_EXP) for ulp(0), but that is not what we want for
798 glibc. */
799 /* Fall through... */
800 case FP_SUBNORMAL:
801 /* The next closest subnormal value is a constant distance away. */
802 ulp = FUNC(ldexp) (1.0, MIN_EXP - MANT_DIG);
803 break;
804
805 case FP_NORMAL:
806 ulp = FUNC(ldexp) (1.0, FUNC(ilogb) (value) - MANT_DIG + 1);
807 break;
808
809 default:
810 /* It should never happen. */
811 abort ();
812 break;
813 }
814 return ulp;
815 }
816
817 static void
818 check_float_internal (const char *test_name, FLOAT computed, FLOAT expected,
819 int exceptions,
820 FLOAT *curr_max_error, FLOAT max_ulp)
821 {
822 int ok = 0;
823 int print_diff = 0;
824 FLOAT diff = 0;
825 FLOAT ulps = 0;
826 int errno_value = errno;
827
828 test_exceptions (test_name, exceptions);
829 test_errno (test_name, errno_value, exceptions);
830 if (exceptions & IGNORE_RESULT)
831 goto out;
832 if (issignaling (computed) && issignaling (expected))
833 {
834 if ((exceptions & TEST_NAN_SIGN) != 0
835 && signbit (computed) != signbit (expected))
836 {
837 ok = 0;
838 printf ("signaling NaN has wrong sign.\n");
839 }
840 else if ((exceptions & TEST_NAN_PAYLOAD) != 0
841 && (FUNC (getpayload) (&computed)
842 != FUNC (getpayload) (&expected)))
843 {
844 ok = 0;
845 printf ("signaling NaN has wrong payload.\n");
846 }
847 else
848 ok = 1;
849 }
850 else if (issignaling (computed) || issignaling (expected))
851 ok = 0;
852 else if (isnan (computed) && isnan (expected))
853 {
854 if ((exceptions & TEST_NAN_SIGN) != 0
855 && signbit (computed) != signbit (expected))
856 {
857 ok = 0;
858 printf ("quiet NaN has wrong sign.\n");
859 }
860 else if ((exceptions & TEST_NAN_PAYLOAD) != 0
861 && (FUNC (getpayload) (&computed)
862 != FUNC (getpayload) (&expected)))
863 {
864 ok = 0;
865 printf ("quiet NaN has wrong payload.\n");
866 }
867 else
868 ok = 1;
869 }
870 else if (isinf (computed) && isinf (expected))
871 {
872 /* Test for sign of infinities. */
873 if ((exceptions & IGNORE_ZERO_INF_SIGN) == 0
874 && signbit (computed) != signbit (expected))
875 {
876 ok = 0;
877 printf ("infinity has wrong sign.\n");
878 }
879 else
880 ok = 1;
881 }
882 /* Don't calculate ULPs for infinities or any kind of NaNs. */
883 else if (isinf (computed) || isnan (computed)
884 || isinf (expected) || isnan (expected))
885 ok = 0;
886 else
887 {
888 diff = FUNC(fabs) (computed - expected);
889 ulps = ULPDIFF (computed, expected);
890 set_max_error (ulps, curr_max_error);
891 print_diff = 1;
892 if ((exceptions & IGNORE_ZERO_INF_SIGN) == 0
893 && computed == 0.0 && expected == 0.0
894 && signbit(computed) != signbit (expected))
895 ok = 0;
896 else if (ulps <= max_ulp && !ignore_max_ulp)
897 ok = 1;
898 else
899 ok = 0;
900 }
901 if (print_screen (ok))
902 {
903 if (!ok)
904 printf ("Failure: ");
905 printf ("Test: %s\n", test_name);
906 printf ("Result:\n");
907 printf (" is: ");
908 print_float (computed);
909 printf (" should be: ");
910 print_float (expected);
911 if (print_diff)
912 {
913 char dstrn[FSTR_MAX], dstrx[FSTR_MAX];
914 char ustrn[FSTR_MAX], mustrn[FSTR_MAX];
915 fmt_ftostr (dstrn, FSTR_MAX, TYPE_DECIMAL_DIG - 1, "e", diff);
916 fmt_ftostr (dstrx, FSTR_MAX, TYPE_HEX_DIG - 1, "a", diff);
917 fmt_ftostr (ustrn, FSTR_MAX, 4, "f", ulps);
918 fmt_ftostr (mustrn, FSTR_MAX, 4, "f", max_ulp);
919 printf (" difference: %s %s\n", dstrn, dstrx);
920 printf (" ulp : %s\n", ustrn);
921 printf (" max.ulp : %s\n", mustrn);
922 }
923 }
924 update_stats (ok);
925
926 out:
927 fpstack_test (test_name);
928 errno = 0;
929 }
930
931
932 static void
933 check_float (const char *test_name, FLOAT computed, FLOAT expected,
934 int exceptions)
935 {
936 check_float_internal (test_name, computed, expected,
937 exceptions, &max_error, prev_max_error);
938 }
939
940
941 static void
942 check_complex (const char *test_name, __complex__ FLOAT computed,
943 __complex__ FLOAT expected,
944 int exception)
945 {
946 FLOAT part_comp, part_exp;
947 char *str;
948
949 if (asprintf (&str, "Real part of: %s", test_name) == -1)
950 abort ();
951
952 part_comp = __real__ computed;
953 part_exp = __real__ expected;
954
955 check_float_internal (str, part_comp, part_exp,
956 exception, &real_max_error, prev_real_max_error);
957 free (str);
958
959 if (asprintf (&str, "Imaginary part of: %s", test_name) == -1)
960 abort ();
961
962 part_comp = __imag__ computed;
963 part_exp = __imag__ expected;
964
965 /* Don't check again for exceptions or errno, just pass through the
966 other relevant flags. */
967 check_float_internal (str, part_comp, part_exp,
968 exception & (IGNORE_ZERO_INF_SIGN
969 | TEST_NAN_SIGN
970 | IGNORE_RESULT),
971 &imag_max_error, prev_imag_max_error);
972 free (str);
973 }
974
975
976 /* Check that computed and expected values are equal (int values). */
977 static void
978 check_int (const char *test_name, int computed, int expected,
979 int exceptions)
980 {
981 int ok = 0;
982 int errno_value = errno;
983
984 test_exceptions (test_name, exceptions);
985 test_errno (test_name, errno_value, exceptions);
986 if (exceptions & IGNORE_RESULT)
987 goto out;
988 noTests++;
989 if (computed == expected)
990 ok = 1;
991
992 if (print_screen (ok))
993 {
994 if (!ok)
995 printf ("Failure: ");
996 printf ("Test: %s\n", test_name);
997 printf ("Result:\n");
998 printf (" is: %d\n", computed);
999 printf (" should be: %d\n", expected);
1000 }
1001
1002 update_stats (ok);
1003 out:
1004 fpstack_test (test_name);
1005 errno = 0;
1006 }
1007
1008
1009 /* Check that computed and expected values are equal (long int values). */
1010 static void
1011 check_long (const char *test_name, long int computed, long int expected,
1012 int exceptions)
1013 {
1014 int ok = 0;
1015 int errno_value = errno;
1016
1017 test_exceptions (test_name, exceptions);
1018 test_errno (test_name, errno_value, exceptions);
1019 if (exceptions & IGNORE_RESULT)
1020 goto out;
1021 noTests++;
1022 if (computed == expected)
1023 ok = 1;
1024
1025 if (print_screen (ok))
1026 {
1027 if (!ok)
1028 printf ("Failure: ");
1029 printf ("Test: %s\n", test_name);
1030 printf ("Result:\n");
1031 printf (" is: %ld\n", computed);
1032 printf (" should be: %ld\n", expected);
1033 }
1034
1035 update_stats (ok);
1036 out:
1037 fpstack_test (test_name);
1038 errno = 0;
1039 }
1040
1041
1042 /* Check that computed value is true/false. */
1043 static void
1044 check_bool (const char *test_name, int computed, int expected,
1045 int exceptions)
1046 {
1047 int ok = 0;
1048 int errno_value = errno;
1049
1050 test_exceptions (test_name, exceptions);
1051 test_errno (test_name, errno_value, exceptions);
1052 if (exceptions & IGNORE_RESULT)
1053 goto out;
1054 noTests++;
1055 if ((computed == 0) == (expected == 0))
1056 ok = 1;
1057
1058 if (print_screen (ok))
1059 {
1060 if (!ok)
1061 printf ("Failure: ");
1062 printf ("Test: %s\n", test_name);
1063 printf ("Result:\n");
1064 printf (" is: %d\n", computed);
1065 printf (" should be: %d\n", expected);
1066 }
1067
1068 update_stats (ok);
1069 out:
1070 fpstack_test (test_name);
1071 errno = 0;
1072 }
1073
1074
1075 /* check that computed and expected values are equal (long int values) */
1076 static void
1077 check_longlong (const char *test_name, long long int computed,
1078 long long int expected,
1079 int exceptions)
1080 {
1081 int ok = 0;
1082 int errno_value = errno;
1083
1084 test_exceptions (test_name, exceptions);
1085 test_errno (test_name, errno_value, exceptions);
1086 if (exceptions & IGNORE_RESULT)
1087 goto out;
1088 noTests++;
1089 if (computed == expected)
1090 ok = 1;
1091
1092 if (print_screen (ok))
1093 {
1094 if (!ok)
1095 printf ("Failure:");
1096 printf ("Test: %s\n", test_name);
1097 printf ("Result:\n");
1098 printf (" is: %lld\n", computed);
1099 printf (" should be: %lld\n", expected);
1100 }
1101
1102 update_stats (ok);
1103 out:
1104 fpstack_test (test_name);
1105 errno = 0;
1106 }
1107
1108
1109 /* Check that computed and expected values are equal (intmax_t values). */
1110 static void
1111 check_intmax_t (const char *test_name, intmax_t computed,
1112 intmax_t expected, int exceptions)
1113 {
1114 int ok = 0;
1115 int errno_value = errno;
1116
1117 test_exceptions (test_name, exceptions);
1118 test_errno (test_name, errno_value, exceptions);
1119 if (exceptions & IGNORE_RESULT)
1120 goto out;
1121 noTests++;
1122 if (computed == expected)
1123 ok = 1;
1124
1125 if (print_screen (ok))
1126 {
1127 if (!ok)
1128 printf ("Failure:");
1129 printf ("Test: %s\n", test_name);
1130 printf ("Result:\n");
1131 printf (" is: %jd\n", computed);
1132 printf (" should be: %jd\n", expected);
1133 }
1134
1135 update_stats (ok);
1136 out:
1137 fpstack_test (test_name);
1138 errno = 0;
1139 }
1140
1141
1142 /* Check that computed and expected values are equal (uintmax_t values). */
1143 static void
1144 check_uintmax_t (const char *test_name, uintmax_t computed,
1145 uintmax_t expected, int exceptions)
1146 {
1147 int ok = 0;
1148 int errno_value = errno;
1149
1150 test_exceptions (test_name, exceptions);
1151 test_errno (test_name, errno_value, exceptions);
1152 if (exceptions & IGNORE_RESULT)
1153 goto out;
1154 noTests++;
1155 if (computed == expected)
1156 ok = 1;
1157
1158 if (print_screen (ok))
1159 {
1160 if (!ok)
1161 printf ("Failure:");
1162 printf ("Test: %s\n", test_name);
1163 printf ("Result:\n");
1164 printf (" is: %ju\n", computed);
1165 printf (" should be: %ju\n", expected);
1166 }
1167
1168 update_stats (ok);
1169 out:
1170 fpstack_test (test_name);
1171 errno = 0;
1172 }
1173
1174 /* Return whether a test with flags EXCEPTIONS should be run. */
1175 static int
1176 enable_test (int exceptions)
1177 {
1178 if (exceptions & XFAIL_TEST)
1179 return 0;
1180 if (flag_test_inline && (exceptions & NO_TEST_INLINE))
1181 return 0;
1182 if (flag_test_finite && (exceptions & NON_FINITE) != 0)
1183 return 0;
1184 if (!SNAN_TESTS (FLOAT) && (exceptions & TEST_SNAN) != 0)
1185 return 0;
1186 if (flag_test_mathvec && (exceptions & NO_TEST_MATHVEC) != 0)
1187 return 0;
1188
1189 return 1;
1190 }
1191
1192 /* Structures for each kind of test. */
1193 /* Used for both RUN_TEST_LOOP_f_f and RUN_TEST_LOOP_fp_f. */
1194 struct test_f_f_data
1195 {
1196 const char *arg_str;
1197 FLOAT arg;
1198 struct
1199 {
1200 FLOAT expected;
1201 int exceptions;
1202 } rd, rn, rz, ru;
1203 };
1204 struct test_ff_f_data
1205 {
1206 const char *arg_str;
1207 FLOAT arg1, arg2;
1208 struct
1209 {
1210 FLOAT expected;
1211 int exceptions;
1212 } rd, rn, rz, ru;
1213 };
1214 /* Strictly speaking, a j type argument is one gen-libm-test.pl will not
1215 attempt to muck with. For now, it is only used to prevent it from
1216 mucking up an explicitly long double argument. */
1217 struct test_fj_f_data
1218 {
1219 const char *arg_str;
1220 FLOAT arg1;
1221 long double arg2;
1222 struct
1223 {
1224 FLOAT expected;
1225 int exceptions;
1226 } rd, rn, rz, ru;
1227 };
1228 struct test_fi_f_data
1229 {
1230 const char *arg_str;
1231 FLOAT arg1;
1232 int arg2;
1233 struct
1234 {
1235 FLOAT expected;
1236 int exceptions;
1237 } rd, rn, rz, ru;
1238 };
1239 struct test_fl_f_data
1240 {
1241 const char *arg_str;
1242 FLOAT arg1;
1243 long int arg2;
1244 struct
1245 {
1246 FLOAT expected;
1247 int exceptions;
1248 } rd, rn, rz, ru;
1249 };
1250 struct test_if_f_data
1251 {
1252 const char *arg_str;
1253 int arg1;
1254 FLOAT arg2;
1255 struct
1256 {
1257 FLOAT expected;
1258 int exceptions;
1259 } rd, rn, rz, ru;
1260 };
1261 struct test_fff_f_data
1262 {
1263 const char *arg_str;
1264 FLOAT arg1, arg2, arg3;
1265 struct
1266 {
1267 FLOAT expected;
1268 int exceptions;
1269 } rd, rn, rz, ru;
1270 };
1271 struct test_fiu_M_data
1272 {
1273 const char *arg_str;
1274 FLOAT arg1;
1275 int arg2;
1276 unsigned int arg3;
1277 struct
1278 {
1279 intmax_t expected;
1280 int exceptions;
1281 } rd, rn, rz, ru;
1282 };
1283 struct test_fiu_U_data
1284 {
1285 const char *arg_str;
1286 FLOAT arg1;
1287 int arg2;
1288 unsigned int arg3;
1289 struct
1290 {
1291 uintmax_t expected;
1292 int exceptions;
1293 } rd, rn, rz, ru;
1294 };
1295 struct test_c_f_data
1296 {
1297 const char *arg_str;
1298 FLOAT argr, argc;
1299 struct
1300 {
1301 FLOAT expected;
1302 int exceptions;
1303 } rd, rn, rz, ru;
1304 };
1305 /* Used for both RUN_TEST_LOOP_f_f1 and RUN_TEST_LOOP_fI_f1. */
1306 struct test_f_f1_data
1307 {
1308 const char *arg_str;
1309 FLOAT arg;
1310 struct
1311 {
1312 FLOAT expected;
1313 int exceptions;
1314 int extra_test;
1315 int extra_expected;
1316 } rd, rn, rz, ru;
1317 };
1318 struct test_fF_f1_data
1319 {
1320 const char *arg_str;
1321 FLOAT arg;
1322 struct
1323 {
1324 FLOAT expected;
1325 int exceptions;
1326 int extra_test;
1327 FLOAT extra_expected;
1328 } rd, rn, rz, ru;
1329 };
1330 struct test_ffI_f1_data
1331 {
1332 const char *arg_str;
1333 FLOAT arg1, arg2;
1334 struct
1335 {
1336 FLOAT expected;
1337 int exceptions;
1338 int extra_test;
1339 int extra_expected;
1340 } rd, rn, rz, ru;
1341 };
1342 struct test_c_c_data
1343 {
1344 const char *arg_str;
1345 FLOAT argr, argc;
1346 struct
1347 {
1348 FLOAT expr, expc;
1349 int exceptions;
1350 } rd, rn, rz, ru;
1351 };
1352 struct test_cc_c_data
1353 {
1354 const char *arg_str;
1355 FLOAT arg1r, arg1c, arg2r, arg2c;
1356 struct
1357 {
1358 FLOAT expr, expc;
1359 int exceptions;
1360 } rd, rn, rz, ru;
1361 };
1362 /* Used for all of RUN_TEST_LOOP_f_i, RUN_TEST_LOOP_f_i_tg,
1363 RUN_TEST_LOOP_f_b and RUN_TEST_LOOP_f_b_tg. */
1364 struct test_f_i_data
1365 {
1366 const char *arg_str;
1367 FLOAT arg;
1368 struct
1369 {
1370 int expected;
1371 int exceptions;
1372 } rd, rn, rz, ru;
1373 };
1374 /* Used for both RUN_TEST_LOOP_ff_b and RUN_TEST_LOOP_ff_i_tg. */
1375 struct test_ff_i_data
1376 {
1377 const char *arg_str;
1378 FLOAT arg1, arg2;
1379 struct
1380 {
1381 int expected;
1382 int exceptions;
1383 } rd, rn, rz, ru;
1384 };
1385 struct test_f_l_data
1386 {
1387 const char *arg_str;
1388 FLOAT arg;
1389 struct
1390 {
1391 long int expected;
1392 int exceptions;
1393 } rd, rn, rz, ru;
1394 };
1395 struct test_f_L_data
1396 {
1397 const char *arg_str;
1398 FLOAT arg;
1399 struct
1400 {
1401 long long int expected;
1402 int exceptions;
1403 } rd, rn, rz, ru;
1404 };
1405 struct test_fFF_11_data
1406 {
1407 const char *arg_str;
1408 FLOAT arg;
1409 struct
1410 {
1411 int exceptions;
1412 int extra1_test;
1413 FLOAT extra1_expected;
1414 int extra2_test;
1415 FLOAT extra2_expected;
1416 } rd, rn, rz, ru;
1417 };
1418 /* Used for both RUN_TEST_LOOP_Ff_b1 and RUN_TEST_LOOP_Ffp_b1. */
1419 struct test_Ff_b1_data
1420 {
1421 const char *arg_str;
1422 FLOAT arg;
1423 struct
1424 {
1425 int expected;
1426 int exceptions;
1427 int extra_test;
1428 FLOAT extra_expected;
1429 } rd, rn, rz, ru;
1430 };
1431
1432 /* Set the rounding mode, or restore the saved value. */
1433 #define IF_ROUND_INIT_ /* Empty. */
1434 #define IF_ROUND_INIT_FE_DOWNWARD \
1435 int save_round_mode = fegetround (); \
1436 if (ROUNDING_TESTS (FLOAT, FE_DOWNWARD) \
1437 && fesetround (FE_DOWNWARD) == 0)
1438 #define IF_ROUND_INIT_FE_TONEAREST \
1439 int save_round_mode = fegetround (); \
1440 if (ROUNDING_TESTS (FLOAT, FE_TONEAREST) \
1441 && fesetround (FE_TONEAREST) == 0)
1442 #define IF_ROUND_INIT_FE_TOWARDZERO \
1443 int save_round_mode = fegetround (); \
1444 if (ROUNDING_TESTS (FLOAT, FE_TOWARDZERO) \
1445 && fesetround (FE_TOWARDZERO) == 0)
1446 #define IF_ROUND_INIT_FE_UPWARD \
1447 int save_round_mode = fegetround (); \
1448 if (ROUNDING_TESTS (FLOAT, FE_UPWARD) \
1449 && fesetround (FE_UPWARD) == 0)
1450 #define ROUND_RESTORE_ /* Empty. */
1451 #define ROUND_RESTORE_FE_DOWNWARD \
1452 fesetround (save_round_mode)
1453 #define ROUND_RESTORE_FE_TONEAREST \
1454 fesetround (save_round_mode)
1455 #define ROUND_RESTORE_FE_TOWARDZERO \
1456 fesetround (save_round_mode)
1457 #define ROUND_RESTORE_FE_UPWARD \
1458 fesetround (save_round_mode)
1459
1460 /* Field name to use for a given rounding mode. */
1461 #define RM_ rn
1462 #define RM_FE_DOWNWARD rd
1463 #define RM_FE_TONEAREST rn
1464 #define RM_FE_TOWARDZERO rz
1465 #define RM_FE_UPWARD ru
1466
1467 /* Common setup for an individual test. */
1468 #define COMMON_TEST_SETUP(ARG_STR) \
1469 char *test_name; \
1470 if (asprintf (&test_name, "%s (%s)", this_func, (ARG_STR)) == -1) \
1471 abort ()
1472
1473 /* Setup for a test with an extra output. */
1474 #define EXTRA_OUTPUT_TEST_SETUP(ARG_STR, N) \
1475 char *extra##N##_name; \
1476 if (asprintf (&extra##N##_name, "%s (%s) extra output " #N, \
1477 this_func, (ARG_STR)) == -1) \
1478 abort ()
1479
1480 /* Common cleanup after an individual test. */
1481 #define COMMON_TEST_CLEANUP \
1482 free (test_name)
1483
1484 /* Cleanup for a test with an extra output. */
1485 #define EXTRA_OUTPUT_TEST_CLEANUP(N) \
1486 free (extra##N##_name)
1487
1488 /* Run an individual test, including any required setup and checking
1489 of results, or loop over all tests in an array. */
1490 #define RUN_TEST_f_f(ARG_STR, FUNC_NAME, ARG, EXPECTED, \
1491 EXCEPTIONS) \
1492 do \
1493 if (enable_test (EXCEPTIONS)) \
1494 { \
1495 COMMON_TEST_SETUP (ARG_STR); \
1496 check_float (test_name, FUNC_TEST (FUNC_NAME) (ARG), \
1497 EXPECTED, EXCEPTIONS); \
1498 COMMON_TEST_CLEANUP; \
1499 } \
1500 while (0)
1501 #define RUN_TEST_LOOP_f_f(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1502 IF_ROUND_INIT_ ## ROUNDING_MODE \
1503 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1504 RUN_TEST_f_f ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
1505 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1506 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1507 ROUND_RESTORE_ ## ROUNDING_MODE
1508 #define RUN_TEST_fp_f(ARG_STR, FUNC_NAME, ARG, EXPECTED, \
1509 EXCEPTIONS) \
1510 do \
1511 if (enable_test (EXCEPTIONS)) \
1512 { \
1513 COMMON_TEST_SETUP (ARG_STR); \
1514 check_float (test_name, FUNC_TEST (FUNC_NAME) (&(ARG)), \
1515 EXPECTED, EXCEPTIONS); \
1516 COMMON_TEST_CLEANUP; \
1517 } \
1518 while (0)
1519 #define RUN_TEST_LOOP_fp_f(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1520 IF_ROUND_INIT_ ## ROUNDING_MODE \
1521 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1522 RUN_TEST_fp_f ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
1523 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1524 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1525 ROUND_RESTORE_ ## ROUNDING_MODE
1526 #define RUN_TEST_2_f(ARG_STR, FUNC_NAME, ARG1, ARG2, EXPECTED, \
1527 EXCEPTIONS) \
1528 do \
1529 if (enable_test (EXCEPTIONS)) \
1530 { \
1531 COMMON_TEST_SETUP (ARG_STR); \
1532 check_float (test_name, FUNC_TEST (FUNC_NAME) (ARG1, ARG2), \
1533 EXPECTED, EXCEPTIONS); \
1534 COMMON_TEST_CLEANUP; \
1535 } \
1536 while (0)
1537 #define RUN_TEST_LOOP_2_f(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1538 IF_ROUND_INIT_ ## ROUNDING_MODE \
1539 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1540 RUN_TEST_2_f ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg1, \
1541 (ARRAY)[i].arg2, \
1542 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1543 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1544 ROUND_RESTORE_ ## ROUNDING_MODE
1545 #define RUN_TEST_ff_f RUN_TEST_2_f
1546 #define RUN_TEST_LOOP_ff_f RUN_TEST_LOOP_2_f
1547 #define RUN_TEST_LOOP_fj_f RUN_TEST_LOOP_2_f
1548 #define RUN_TEST_fi_f RUN_TEST_2_f
1549 #define RUN_TEST_LOOP_fi_f RUN_TEST_LOOP_2_f
1550 #define RUN_TEST_fl_f RUN_TEST_2_f
1551 #define RUN_TEST_LOOP_fl_f RUN_TEST_LOOP_2_f
1552 #define RUN_TEST_if_f RUN_TEST_2_f
1553 #define RUN_TEST_LOOP_if_f RUN_TEST_LOOP_2_f
1554 #define RUN_TEST_fff_f(ARG_STR, FUNC_NAME, ARG1, ARG2, ARG3, \
1555 EXPECTED, EXCEPTIONS) \
1556 do \
1557 if (enable_test (EXCEPTIONS)) \
1558 { \
1559 COMMON_TEST_SETUP (ARG_STR); \
1560 check_float (test_name, FUNC_TEST (FUNC_NAME) (ARG1, ARG2, ARG3), \
1561 EXPECTED, EXCEPTIONS); \
1562 COMMON_TEST_CLEANUP; \
1563 } \
1564 while (0)
1565 #define RUN_TEST_LOOP_fff_f(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1566 IF_ROUND_INIT_ ## ROUNDING_MODE \
1567 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1568 RUN_TEST_fff_f ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg1, \
1569 (ARRAY)[i].arg2, (ARRAY)[i].arg3, \
1570 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1571 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1572 ROUND_RESTORE_ ## ROUNDING_MODE
1573 #define RUN_TEST_fiu_M(ARG_STR, FUNC_NAME, ARG1, ARG2, ARG3, \
1574 EXPECTED, EXCEPTIONS) \
1575 do \
1576 if (enable_test (EXCEPTIONS)) \
1577 { \
1578 COMMON_TEST_SETUP (ARG_STR); \
1579 check_intmax_t (test_name, \
1580 FUNC_TEST (FUNC_NAME) (ARG1, ARG2, ARG3), \
1581 EXPECTED, EXCEPTIONS); \
1582 COMMON_TEST_CLEANUP; \
1583 } \
1584 while (0)
1585 #define RUN_TEST_LOOP_fiu_M(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1586 IF_ROUND_INIT_ ## ROUNDING_MODE \
1587 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1588 RUN_TEST_fiu_M ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg1, \
1589 (ARRAY)[i].arg2, (ARRAY)[i].arg3, \
1590 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1591 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1592 ROUND_RESTORE_ ## ROUNDING_MODE
1593 #define RUN_TEST_fiu_U(ARG_STR, FUNC_NAME, ARG1, ARG2, ARG3, \
1594 EXPECTED, EXCEPTIONS) \
1595 do \
1596 if (enable_test (EXCEPTIONS)) \
1597 { \
1598 COMMON_TEST_SETUP (ARG_STR); \
1599 check_uintmax_t (test_name, \
1600 FUNC_TEST (FUNC_NAME) (ARG1, ARG2, ARG3), \
1601 EXPECTED, EXCEPTIONS); \
1602 COMMON_TEST_CLEANUP; \
1603 } \
1604 while (0)
1605 #define RUN_TEST_LOOP_fiu_U(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1606 IF_ROUND_INIT_ ## ROUNDING_MODE \
1607 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1608 RUN_TEST_fiu_U ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg1, \
1609 (ARRAY)[i].arg2, (ARRAY)[i].arg3, \
1610 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1611 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1612 ROUND_RESTORE_ ## ROUNDING_MODE
1613 #define RUN_TEST_c_f(ARG_STR, FUNC_NAME, ARG1, ARG2, EXPECTED, \
1614 EXCEPTIONS) \
1615 do \
1616 if (enable_test (EXCEPTIONS)) \
1617 { \
1618 COMMON_TEST_SETUP (ARG_STR); \
1619 check_float (test_name, \
1620 FUNC_TEST (FUNC_NAME) (BUILD_COMPLEX (ARG1, ARG2)),\
1621 EXPECTED, EXCEPTIONS); \
1622 COMMON_TEST_CLEANUP; \
1623 } \
1624 while (0)
1625 #define RUN_TEST_LOOP_c_f(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1626 IF_ROUND_INIT_ ## ROUNDING_MODE \
1627 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1628 RUN_TEST_c_f ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].argr, \
1629 (ARRAY)[i].argc, \
1630 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1631 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1632 ROUND_RESTORE_ ## ROUNDING_MODE
1633 #define RUN_TEST_f_f1(ARG_STR, FUNC_NAME, ARG, EXPECTED, \
1634 EXCEPTIONS, EXTRA_VAR, EXTRA_TEST, \
1635 EXTRA_EXPECTED) \
1636 do \
1637 if (enable_test (EXCEPTIONS)) \
1638 { \
1639 COMMON_TEST_SETUP (ARG_STR); \
1640 (EXTRA_VAR) = (EXTRA_EXPECTED) == 0 ? 1 : 0; \
1641 check_float (test_name, FUNC_TEST (FUNC_NAME) (ARG), EXPECTED, \
1642 EXCEPTIONS); \
1643 EXTRA_OUTPUT_TEST_SETUP (ARG_STR, 1); \
1644 if (EXTRA_TEST) \
1645 check_int (extra1_name, EXTRA_VAR, EXTRA_EXPECTED, 0); \
1646 EXTRA_OUTPUT_TEST_CLEANUP (1); \
1647 COMMON_TEST_CLEANUP; \
1648 } \
1649 while (0)
1650 #define RUN_TEST_LOOP_f_f1(FUNC_NAME, ARRAY, ROUNDING_MODE, EXTRA_VAR) \
1651 IF_ROUND_INIT_ ## ROUNDING_MODE \
1652 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1653 RUN_TEST_f_f1 ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
1654 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1655 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions, \
1656 EXTRA_VAR, \
1657 (ARRAY)[i].RM_##ROUNDING_MODE.extra_test, \
1658 (ARRAY)[i].RM_##ROUNDING_MODE.extra_expected); \
1659 ROUND_RESTORE_ ## ROUNDING_MODE
1660 #define RUN_TEST_fF_f1(ARG_STR, FUNC_NAME, ARG, EXPECTED, \
1661 EXCEPTIONS, EXTRA_VAR, EXTRA_TEST, \
1662 EXTRA_EXPECTED) \
1663 do \
1664 if (enable_test (EXCEPTIONS)) \
1665 { \
1666 COMMON_TEST_SETUP (ARG_STR); \
1667 (EXTRA_VAR) = (EXTRA_EXPECTED) == 0 ? 1 : 0; \
1668 check_float (test_name, FUNC_TEST (FUNC_NAME) (ARG, &(EXTRA_VAR)), \
1669 EXPECTED, EXCEPTIONS); \
1670 EXTRA_OUTPUT_TEST_SETUP (ARG_STR, 1); \
1671 if (EXTRA_TEST) \
1672 check_float (extra1_name, EXTRA_VAR, EXTRA_EXPECTED, 0); \
1673 EXTRA_OUTPUT_TEST_CLEANUP (1); \
1674 COMMON_TEST_CLEANUP; \
1675 } \
1676 while (0)
1677 #define RUN_TEST_LOOP_fF_f1(FUNC_NAME, ARRAY, ROUNDING_MODE, EXTRA_VAR) \
1678 IF_ROUND_INIT_ ## ROUNDING_MODE \
1679 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1680 RUN_TEST_fF_f1 ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
1681 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1682 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions, \
1683 EXTRA_VAR, \
1684 (ARRAY)[i].RM_##ROUNDING_MODE.extra_test, \
1685 (ARRAY)[i].RM_##ROUNDING_MODE.extra_expected); \
1686 ROUND_RESTORE_ ## ROUNDING_MODE
1687 #define RUN_TEST_fI_f1(ARG_STR, FUNC_NAME, ARG, EXPECTED, \
1688 EXCEPTIONS, EXTRA_VAR, EXTRA_TEST, \
1689 EXTRA_EXPECTED) \
1690 do \
1691 if (enable_test (EXCEPTIONS)) \
1692 { \
1693 COMMON_TEST_SETUP (ARG_STR); \
1694 (EXTRA_VAR) = (EXTRA_EXPECTED) == 0 ? 1 : 0; \
1695 check_float (test_name, FUNC_TEST (FUNC_NAME) (ARG, &(EXTRA_VAR)), \
1696 EXPECTED, EXCEPTIONS); \
1697 EXTRA_OUTPUT_TEST_SETUP (ARG_STR, 1); \
1698 if (EXTRA_TEST) \
1699 check_int (extra1_name, EXTRA_VAR, EXTRA_EXPECTED, 0); \
1700 EXTRA_OUTPUT_TEST_CLEANUP (1); \
1701 COMMON_TEST_CLEANUP; \
1702 } \
1703 while (0)
1704 #define RUN_TEST_LOOP_fI_f1(FUNC_NAME, ARRAY, ROUNDING_MODE, EXTRA_VAR) \
1705 IF_ROUND_INIT_ ## ROUNDING_MODE \
1706 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1707 RUN_TEST_fI_f1 ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
1708 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1709 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions, \
1710 EXTRA_VAR, \
1711 (ARRAY)[i].RM_##ROUNDING_MODE.extra_test, \
1712 (ARRAY)[i].RM_##ROUNDING_MODE.extra_expected); \
1713 ROUND_RESTORE_ ## ROUNDING_MODE
1714 #define RUN_TEST_ffI_f1_mod8(ARG_STR, FUNC_NAME, ARG1, ARG2, EXPECTED, \
1715 EXCEPTIONS, EXTRA_VAR, EXTRA_TEST, \
1716 EXTRA_EXPECTED) \
1717 do \
1718 if (enable_test (EXCEPTIONS)) \
1719 { \
1720 COMMON_TEST_SETUP (ARG_STR); \
1721 (EXTRA_VAR) = (EXTRA_EXPECTED) == 0 ? 1 : 0; \
1722 check_float (test_name, \
1723 FUNC_TEST (FUNC_NAME) (ARG1, ARG2, &(EXTRA_VAR)), \
1724 EXPECTED, EXCEPTIONS); \
1725 EXTRA_OUTPUT_TEST_SETUP (ARG_STR, 1); \
1726 if (EXTRA_TEST) \
1727 check_int (extra1_name, (EXTRA_VAR) % 8, EXTRA_EXPECTED, 0); \
1728 EXTRA_OUTPUT_TEST_CLEANUP (1); \
1729 COMMON_TEST_CLEANUP; \
1730 } \
1731 while (0)
1732 #define RUN_TEST_LOOP_ffI_f1_mod8(FUNC_NAME, ARRAY, ROUNDING_MODE, \
1733 EXTRA_VAR) \
1734 IF_ROUND_INIT_ ## ROUNDING_MODE \
1735 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1736 RUN_TEST_ffI_f1_mod8 ((ARRAY)[i].arg_str, FUNC_NAME, \
1737 (ARRAY)[i].arg1, (ARRAY)[i].arg2, \
1738 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1739 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions, \
1740 EXTRA_VAR, \
1741 (ARRAY)[i].RM_##ROUNDING_MODE.extra_test, \
1742 (ARRAY)[i].RM_##ROUNDING_MODE.extra_expected); \
1743 ROUND_RESTORE_ ## ROUNDING_MODE
1744 #define RUN_TEST_Ff_b1(ARG_STR, FUNC_NAME, ARG, EXPECTED, \
1745 EXCEPTIONS, EXTRA_VAR, EXTRA_TEST, \
1746 EXTRA_EXPECTED) \
1747 do \
1748 if (enable_test (EXCEPTIONS)) \
1749 { \
1750 COMMON_TEST_SETUP (ARG_STR); \
1751 (EXTRA_VAR) = (EXTRA_EXPECTED) == 0 ? 1 : 0; \
1752 /* Clear any exceptions from comparison involving sNaN \
1753 EXTRA_EXPECTED. */ \
1754 feclearexcept (FE_ALL_EXCEPT); \
1755 check_bool (test_name, FUNC_TEST (FUNC_NAME) (&(EXTRA_VAR), \
1756 (ARG)), \
1757 EXPECTED, EXCEPTIONS); \
1758 EXTRA_OUTPUT_TEST_SETUP (ARG_STR, 1); \
1759 if (EXTRA_TEST) \
1760 check_float (extra1_name, EXTRA_VAR, EXTRA_EXPECTED, \
1761 (EXCEPTIONS) & TEST_NAN_PAYLOAD); \
1762 EXTRA_OUTPUT_TEST_CLEANUP (1); \
1763 COMMON_TEST_CLEANUP; \
1764 } \
1765 while (0)
1766 #define RUN_TEST_LOOP_Ff_b1(FUNC_NAME, ARRAY, ROUNDING_MODE, \
1767 EXTRA_VAR) \
1768 IF_ROUND_INIT_ ## ROUNDING_MODE \
1769 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1770 RUN_TEST_Ff_b1 ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
1771 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1772 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions, \
1773 EXTRA_VAR, \
1774 (ARRAY)[i].RM_##ROUNDING_MODE.extra_test, \
1775 (ARRAY)[i].RM_##ROUNDING_MODE.extra_expected); \
1776 ROUND_RESTORE_ ## ROUNDING_MODE
1777 #define RUN_TEST_Ffp_b1(ARG_STR, FUNC_NAME, ARG, EXPECTED, \
1778 EXCEPTIONS, EXTRA_VAR, EXTRA_TEST, \
1779 EXTRA_EXPECTED) \
1780 do \
1781 if (enable_test (EXCEPTIONS)) \
1782 { \
1783 COMMON_TEST_SETUP (ARG_STR); \
1784 (EXTRA_VAR) = (EXTRA_EXPECTED) == 0 ? 1 : 0; \
1785 check_bool (test_name, FUNC_TEST (FUNC_NAME) (&(EXTRA_VAR), \
1786 &(ARG)), \
1787 EXPECTED, EXCEPTIONS); \
1788 EXTRA_OUTPUT_TEST_SETUP (ARG_STR, 1); \
1789 if (EXTRA_TEST) \
1790 check_float (extra1_name, EXTRA_VAR, EXTRA_EXPECTED, \
1791 (EXCEPTIONS) & TEST_NAN_PAYLOAD); \
1792 EXTRA_OUTPUT_TEST_CLEANUP (1); \
1793 COMMON_TEST_CLEANUP; \
1794 } \
1795 while (0)
1796 #define RUN_TEST_LOOP_Ffp_b1(FUNC_NAME, ARRAY, ROUNDING_MODE, \
1797 EXTRA_VAR) \
1798 IF_ROUND_INIT_ ## ROUNDING_MODE \
1799 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1800 RUN_TEST_Ffp_b1 ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
1801 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1802 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions, \
1803 EXTRA_VAR, \
1804 (ARRAY)[i].RM_##ROUNDING_MODE.extra_test, \
1805 (ARRAY)[i].RM_##ROUNDING_MODE.extra_expected); \
1806 ROUND_RESTORE_ ## ROUNDING_MODE
1807 #define RUN_TEST_c_c(ARG_STR, FUNC_NAME, ARGR, ARGC, EXPR, EXPC, \
1808 EXCEPTIONS) \
1809 do \
1810 if (enable_test (EXCEPTIONS)) \
1811 { \
1812 COMMON_TEST_SETUP (ARG_STR); \
1813 check_complex (test_name, \
1814 FUNC_TEST (FUNC_NAME) (BUILD_COMPLEX (ARGR, ARGC)), \
1815 BUILD_COMPLEX (EXPR, EXPC), EXCEPTIONS); \
1816 COMMON_TEST_CLEANUP; \
1817 } \
1818 while (0)
1819 #define RUN_TEST_LOOP_c_c(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1820 IF_ROUND_INIT_ ## ROUNDING_MODE \
1821 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1822 RUN_TEST_c_c ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].argr, \
1823 (ARRAY)[i].argc, \
1824 (ARRAY)[i].RM_##ROUNDING_MODE.expr, \
1825 (ARRAY)[i].RM_##ROUNDING_MODE.expc, \
1826 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1827 ROUND_RESTORE_ ## ROUNDING_MODE
1828 #define RUN_TEST_cc_c(ARG_STR, FUNC_NAME, ARG1R, ARG1C, ARG2R, ARG2C, \
1829 EXPR, EXPC, EXCEPTIONS) \
1830 do \
1831 if (enable_test (EXCEPTIONS)) \
1832 { \
1833 COMMON_TEST_SETUP (ARG_STR); \
1834 check_complex (test_name, \
1835 FUNC_TEST (FUNC_NAME) (BUILD_COMPLEX (ARG1R, ARG1C), \
1836 BUILD_COMPLEX (ARG2R, ARG2C)), \
1837 BUILD_COMPLEX (EXPR, EXPC), EXCEPTIONS); \
1838 COMMON_TEST_CLEANUP; \
1839 } \
1840 while (0)
1841 #define RUN_TEST_LOOP_cc_c(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1842 IF_ROUND_INIT_ ## ROUNDING_MODE \
1843 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1844 RUN_TEST_cc_c ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg1r, \
1845 (ARRAY)[i].arg1c, (ARRAY)[i].arg2r, \
1846 (ARRAY)[i].arg2c, \
1847 (ARRAY)[i].RM_##ROUNDING_MODE.expr, \
1848 (ARRAY)[i].RM_##ROUNDING_MODE.expc, \
1849 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1850 ROUND_RESTORE_ ## ROUNDING_MODE
1851 #define RUN_TEST_f_i(ARG_STR, FUNC_NAME, ARG, EXPECTED, EXCEPTIONS) \
1852 do \
1853 if (enable_test (EXCEPTIONS)) \
1854 { \
1855 COMMON_TEST_SETUP (ARG_STR); \
1856 check_int (test_name, FUNC_TEST (FUNC_NAME) (ARG), EXPECTED, \
1857 EXCEPTIONS); \
1858 COMMON_TEST_CLEANUP; \
1859 } \
1860 while (0)
1861 #define RUN_TEST_LOOP_f_i(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1862 IF_ROUND_INIT_ ## ROUNDING_MODE \
1863 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1864 RUN_TEST_f_i ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
1865 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1866 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1867 ROUND_RESTORE_ ## ROUNDING_MODE
1868 #define RUN_TEST_f_i_tg(ARG_STR, FUNC_NAME, ARG, EXPECTED, \
1869 EXCEPTIONS) \
1870 do \
1871 if (enable_test (EXCEPTIONS)) \
1872 { \
1873 COMMON_TEST_SETUP (ARG_STR); \
1874 check_int (test_name, FUNC_NAME (ARG), EXPECTED, EXCEPTIONS); \
1875 COMMON_TEST_CLEANUP; \
1876 } \
1877 while (0)
1878 #define RUN_TEST_LOOP_f_i_tg(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1879 IF_ROUND_INIT_ ## ROUNDING_MODE \
1880 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1881 RUN_TEST_f_i_tg ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
1882 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1883 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1884 ROUND_RESTORE_ ## ROUNDING_MODE
1885 #define RUN_TEST_ff_b(ARG_STR, FUNC_NAME, ARG1, ARG2, EXPECTED, \
1886 EXCEPTIONS) \
1887 do \
1888 if (enable_test (EXCEPTIONS)) \
1889 { \
1890 COMMON_TEST_SETUP (ARG_STR); \
1891 check_bool (test_name, FUNC_TEST (FUNC_NAME) (ARG1, ARG2), \
1892 EXPECTED, EXCEPTIONS); \
1893 COMMON_TEST_CLEANUP; \
1894 } \
1895 while (0)
1896 #define RUN_TEST_LOOP_ff_b(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1897 IF_ROUND_INIT_ ## ROUNDING_MODE \
1898 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1899 RUN_TEST_ff_b ((ARRAY)[i].arg_str, FUNC_NAME, \
1900 (ARRAY)[i].arg1, (ARRAY)[i].arg2, \
1901 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1902 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1903 ROUND_RESTORE_ ## ROUNDING_MODE
1904 #define RUN_TEST_ff_i_tg(ARG_STR, FUNC_NAME, ARG1, ARG2, EXPECTED, \
1905 EXCEPTIONS) \
1906 do \
1907 if (enable_test (EXCEPTIONS)) \
1908 { \
1909 COMMON_TEST_SETUP (ARG_STR); \
1910 check_int (test_name, FUNC_NAME (ARG1, ARG2), EXPECTED, \
1911 EXCEPTIONS); \
1912 COMMON_TEST_CLEANUP; \
1913 } \
1914 while (0)
1915 #define RUN_TEST_LOOP_ff_i_tg(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1916 IF_ROUND_INIT_ ## ROUNDING_MODE \
1917 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1918 RUN_TEST_ff_i_tg ((ARRAY)[i].arg_str, FUNC_NAME, \
1919 (ARRAY)[i].arg1, (ARRAY)[i].arg2, \
1920 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1921 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1922 ROUND_RESTORE_ ## ROUNDING_MODE
1923 #define RUN_TEST_f_b(ARG_STR, FUNC_NAME, ARG, EXPECTED, EXCEPTIONS) \
1924 do \
1925 if (enable_test (EXCEPTIONS)) \
1926 { \
1927 COMMON_TEST_SETUP (ARG_STR); \
1928 check_bool (test_name, FUNC_TEST (FUNC_NAME) (ARG), EXPECTED, \
1929 EXCEPTIONS); \
1930 COMMON_TEST_CLEANUP; \
1931 } \
1932 while (0)
1933 #define RUN_TEST_LOOP_f_b(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1934 IF_ROUND_INIT_ ## ROUNDING_MODE \
1935 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1936 RUN_TEST_f_b ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
1937 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1938 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1939 ROUND_RESTORE_ ## ROUNDING_MODE
1940 #define RUN_TEST_f_b_tg(ARG_STR, FUNC_NAME, ARG, EXPECTED, \
1941 EXCEPTIONS) \
1942 do \
1943 if (enable_test (EXCEPTIONS)) \
1944 { \
1945 COMMON_TEST_SETUP (ARG_STR); \
1946 check_bool (test_name, FUNC_NAME (ARG), EXPECTED, EXCEPTIONS); \
1947 COMMON_TEST_CLEANUP; \
1948 } \
1949 while (0)
1950 #define RUN_TEST_LOOP_f_b_tg(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1951 IF_ROUND_INIT_ ## ROUNDING_MODE \
1952 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1953 RUN_TEST_f_b_tg ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
1954 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1955 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1956 ROUND_RESTORE_ ## ROUNDING_MODE
1957 #define RUN_TEST_f_l(ARG_STR, FUNC_NAME, ARG, EXPECTED, EXCEPTIONS) \
1958 do \
1959 if (enable_test (EXCEPTIONS)) \
1960 { \
1961 COMMON_TEST_SETUP (ARG_STR); \
1962 check_long (test_name, FUNC_TEST (FUNC_NAME) (ARG), EXPECTED, \
1963 EXCEPTIONS); \
1964 COMMON_TEST_CLEANUP; \
1965 } \
1966 while (0)
1967 #define RUN_TEST_LOOP_f_l(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1968 IF_ROUND_INIT_ ## ROUNDING_MODE \
1969 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1970 RUN_TEST_f_l ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
1971 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1972 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1973 ROUND_RESTORE_ ## ROUNDING_MODE
1974 #define RUN_TEST_f_L(ARG_STR, FUNC_NAME, ARG, EXPECTED, EXCEPTIONS) \
1975 do \
1976 if (enable_test (EXCEPTIONS)) \
1977 { \
1978 COMMON_TEST_SETUP (ARG_STR); \
1979 check_longlong (test_name, FUNC_TEST (FUNC_NAME) (ARG), \
1980 EXPECTED, EXCEPTIONS); \
1981 COMMON_TEST_CLEANUP; \
1982 } \
1983 while (0)
1984 #define RUN_TEST_LOOP_f_L(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1985 IF_ROUND_INIT_ ## ROUNDING_MODE \
1986 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1987 RUN_TEST_f_L ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
1988 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1989 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1990 ROUND_RESTORE_ ## ROUNDING_MODE
1991 #define RUN_TEST_fFF_11(ARG_STR, FUNC_NAME, ARG, EXCEPTIONS, \
1992 EXTRA1_VAR, EXTRA1_TEST, \
1993 EXTRA1_EXPECTED, EXTRA2_VAR, \
1994 EXTRA2_TEST, EXTRA2_EXPECTED) \
1995 do \
1996 if (enable_test (EXCEPTIONS)) \
1997 { \
1998 COMMON_TEST_SETUP (ARG_STR); \
1999 FUNC_TEST (FUNC_NAME) (ARG, &(EXTRA1_VAR), &(EXTRA2_VAR)); \
2000 EXTRA_OUTPUT_TEST_SETUP (ARG_STR, 1); \
2001 if (EXTRA1_TEST) \
2002 check_float (extra1_name, EXTRA1_VAR, EXTRA1_EXPECTED, \
2003 EXCEPTIONS); \
2004 EXTRA_OUTPUT_TEST_CLEANUP (1); \
2005 EXTRA_OUTPUT_TEST_SETUP (ARG_STR, 2); \
2006 if (EXTRA2_TEST) \
2007 check_float (extra2_name, EXTRA2_VAR, EXTRA2_EXPECTED, 0); \
2008 EXTRA_OUTPUT_TEST_CLEANUP (2); \
2009 COMMON_TEST_CLEANUP; \
2010 } \
2011 while (0)
2012 #define RUN_TEST_LOOP_fFF_11(FUNC_NAME, ARRAY, ROUNDING_MODE, \
2013 EXTRA1_VAR, EXTRA2_VAR) \
2014 IF_ROUND_INIT_ ## ROUNDING_MODE \
2015 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
2016 RUN_TEST_fFF_11 ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
2017 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions, \
2018 EXTRA1_VAR, \
2019 (ARRAY)[i].RM_##ROUNDING_MODE.extra1_test, \
2020 (ARRAY)[i].RM_##ROUNDING_MODE.extra1_expected, \
2021 EXTRA2_VAR, \
2022 (ARRAY)[i].RM_##ROUNDING_MODE.extra2_test, \
2023 (ARRAY)[i].RM_##ROUNDING_MODE.extra2_expected); \
2024 ROUND_RESTORE_ ## ROUNDING_MODE
2025
2026 #if !TEST_MATHVEC
2027 # define VEC_SUFF
2028 #endif
2029
2030 #define STR_CONCAT(a, b, c) __STRING (a##b##c)
2031 #define STR_CON3(a, b, c) STR_CONCAT (a, b, c)
2032
2033 /* This generated header defines series of macros started with HAVE_VECTOR_. */
2034 #include "libm-have-vector-test.h"
2035
2036 #define HAVE_VECTOR(func) __CONCAT (HAVE_VECTOR_, func)
2037
2038 /* Start and end the tests for a given function. */
2039 #define START(FUN, SUFF, EXACT) \
2040 CHECK_ARCH_EXT; \
2041 if (TEST_MATHVEC && !HAVE_VECTOR (FUNC (FUN))) return; \
2042 const char *this_func = STR_CON3 (FUN, SUFF, VEC_SUFF); \
2043 init_max_error (this_func, EXACT)
2044 #define END \
2045 print_max_error (this_func)
2046 #define END_COMPLEX \
2047 print_complex_max_error (this_func)
2048
2049 /* Run tests for a given function in all rounding modes. */
2050 #define ALL_RM_TEST(FUNC, EXACT, ARRAY, LOOP_MACRO, END_MACRO, ...) \
2051 do \
2052 { \
2053 do \
2054 { \
2055 START (FUNC,, EXACT); \
2056 LOOP_MACRO (FUNC, ARRAY, , ## __VA_ARGS__); \
2057 END_MACRO; \
2058 } \
2059 while (0); \
2060 do \
2061 { \
2062 START (FUNC, _downward, EXACT); \
2063 LOOP_MACRO (FUNC, ARRAY, FE_DOWNWARD, ## __VA_ARGS__); \
2064 END_MACRO; \
2065 } \
2066 while (0); \
2067 do \
2068 { \
2069 START (FUNC, _towardzero, EXACT); \
2070 LOOP_MACRO (FUNC, ARRAY, FE_TOWARDZERO, ## __VA_ARGS__); \
2071 END_MACRO; \
2072 } \
2073 while (0); \
2074 do \
2075 { \
2076 START (FUNC, _upward, EXACT); \
2077 LOOP_MACRO (FUNC, ARRAY, FE_UPWARD, ## __VA_ARGS__); \
2078 END_MACRO; \
2079 } \
2080 while (0); \
2081 } \
2082 while (0);
2083
2084 /* This is to prevent messages from the SVID libm emulation. */
2085 int
2086 matherr (struct exception *x __attribute__ ((unused)))
2087 {
2088 return 1;
2089 }
2090
2091 static void
2092 initialize (void)
2093 {
2094 fpstack_test ("start *init*");
2095
2096 /* Clear all exceptions. From now on we must not get random exceptions. */
2097 feclearexcept (FE_ALL_EXCEPT);
2098 errno = 0;
2099
2100 /* Test to make sure we start correctly. */
2101 fpstack_test ("end *init*");
2102 }
2103
2104 /* Definitions of arguments for argp functions. */
2105 static const struct argp_option options[] =
2106 {
2107 { "verbose", 'v', "NUMBER", 0, "Level of verbosity (0..3)"},
2108 { "ulps-file", 'u', NULL, 0, "Output ulps to file ULPs"},
2109 { "no-max-error", 'f', NULL, 0,
2110 "Don't output maximal errors of functions"},
2111 { "no-points", 'p', NULL, 0,
2112 "Don't output results of functions invocations"},
2113 { "ignore-max-ulp", 'i', "yes/no", 0,
2114 "Ignore given maximal errors"},
2115 { "output-dir", 'o', "DIR", 0,
2116 "Directory where generated files will be placed"},
2117 { NULL, 0, NULL, 0, NULL }
2118 };
2119
2120 /* Short description of program. */
2121 static const char doc[] = "Math test suite: " TEST_MSG ;
2122
2123 /* Prototype for option handler. */
2124 static error_t parse_opt (int key, char *arg, struct argp_state *state);
2125
2126 /* Data structure to communicate with argp functions. */
2127 static struct argp argp =
2128 {
2129 options, parse_opt, NULL, doc,
2130 };
2131
2132
2133 /* Handle program arguments. */
2134 static error_t
2135 parse_opt (int key, char *arg, struct argp_state *state)
2136 {
2137 switch (key)
2138 {
2139 case 'f':
2140 output_max_error = 0;
2141 break;
2142 case 'i':
2143 if (strcmp (arg, "yes") == 0)
2144 ignore_max_ulp = 1;
2145 else if (strcmp (arg, "no") == 0)
2146 ignore_max_ulp = 0;
2147 break;
2148 case 'o':
2149 output_dir = (char *) malloc (strlen (arg) + 1);
2150 if (output_dir != NULL)
2151 strcpy (output_dir, arg);
2152 else
2153 return errno;
2154 break;
2155 case 'p':
2156 output_points = 0;
2157 break;
2158 case 'u':
2159 output_ulps = 1;
2160 break;
2161 case 'v':
2162 if (optarg)
2163 verbose = (unsigned int) strtoul (optarg, NULL, 0);
2164 else
2165 verbose = 3;
2166 break;
2167 default:
2168 return ARGP_ERR_UNKNOWN;
2169 }
2170 return 0;
2171 }
2172
2173 /* Verify that our ulp () implementation is behaving as expected
2174 or abort. */
2175 void
2176 check_ulp (void)
2177 {
2178 FLOAT ulps, ulpx, value;
2179 int i;
2180 /* Check ulp of zero is a subnormal value... */
2181 ulps = ulp (0x0.0p0);
2182 if (fpclassify (ulps) != FP_SUBNORMAL)
2183 {
2184 fprintf (stderr, "ulp (0x0.0p0) is not FP_SUBNORMAL!\n");
2185 exit (EXIT_FAILURE);
2186 }
2187 /* Check that the ulp of one is a normal value... */
2188 ulps = ulp (1.0L);
2189 if (fpclassify (ulps) != FP_NORMAL)
2190 {
2191 fprintf (stderr, "ulp (1.0L) is not FP_NORMAL\n");
2192 exit (EXIT_FAILURE);
2193 }
2194
2195 /* Compute the next subnormal value using nextafter to validate ulp.
2196 We allow +/- 1 ulp around the represented value. */
2197 value = FUNC(nextafter) (0, 1);
2198 ulps = ULPDIFF (value, 0);
2199 ulpx = ulp (1.0L);
2200 if (ulps < (1.0L - ulpx) || ulps > (1.0L + ulpx))
2201 {
2202 fprintf (stderr, "Value outside of 1 +/- 1ulp.\n");
2203 exit (EXIT_FAILURE);
2204 }
2205 /* Compute the nearest representable number from 10 towards 20.
2206 The result is 10 + 1ulp. We use this to check the ulp function.
2207 We allow +/- 1 ulp around the represented value. */
2208 value = FUNC(nextafter) (10, 20);
2209 ulps = ULPDIFF (value, 10);
2210 ulpx = ulp (1.0L);
2211 if (ulps < (1.0L - ulpx) || ulps > (1.0L + ulpx))
2212 {
2213 fprintf (stderr, "Value outside of 1 +/- 1ulp.\n");
2214 exit (EXIT_FAILURE);
2215 }
2216 /* This gives one more ulp. */
2217 value = FUNC(nextafter) (value, 20);
2218 ulps = ULPDIFF (value, 10);
2219 ulpx = ulp (2.0L);
2220 if (ulps < (2.0L - ulpx) || ulps > (2.0L + ulpx))
2221 {
2222 fprintf (stderr, "Value outside of 2 +/- 1ulp.\n");
2223 exit (EXIT_FAILURE);
2224 }
2225 /* And now calculate 100 ulp. */
2226 for (i = 2; i < 100; i++)
2227 value = FUNC(nextafter) (value, 20);
2228 ulps = ULPDIFF (value, 10);
2229 ulpx = ulp (100.0L);
2230 if (ulps < (100.0L - ulpx) || ulps > (100.0L + ulpx))
2231 {
2232 fprintf (stderr, "Value outside of 100 +/- 1ulp.\n");
2233 exit (EXIT_FAILURE);
2234 }
2235 }
2236
2237 static void do_test (void);
2238
2239 /* Do all initialization for a test run with arguments given by ARGC
2240 and ARGV. */
2241 static void
2242 libm_test_init (int argc, char **argv)
2243 {
2244 int remaining;
2245 char *ulps_file_path;
2246 size_t dir_len = 0;
2247
2248 verbose = 1;
2249 output_ulps = 0;
2250 output_max_error = 1;
2251 output_points = 1;
2252 output_dir = NULL;
2253 /* XXX set to 0 for releases. */
2254 ignore_max_ulp = 0;
2255
2256 /* Parse and process arguments. */
2257 argp_parse (&argp, argc, argv, 0, &remaining, NULL);
2258
2259 if (remaining != argc)
2260 {
2261 fprintf (stderr, "wrong number of arguments");
2262 argp_help (&argp, stdout, ARGP_HELP_SEE, program_invocation_short_name);
2263 exit (EXIT_FAILURE);
2264 }
2265
2266 if (output_ulps)
2267 {
2268 if (output_dir != NULL)
2269 dir_len = strlen (output_dir);
2270 ulps_file_path = (char *) malloc (dir_len + strlen (ulps_file_name) + 1);
2271 if (ulps_file_path == NULL)
2272 {
2273 perror ("can't allocate path for `ULPs' file: ");
2274 exit (1);
2275 }
2276 sprintf (ulps_file_path, "%s%s", output_dir == NULL ? "" : output_dir, ulps_file_name);
2277 ulps_file = fopen (ulps_file_path, "a");
2278 if (ulps_file == NULL)
2279 {
2280 perror ("can't open file `ULPs' for writing: ");
2281 exit (1);
2282 }
2283 }
2284
2285
2286 initialize ();
2287 fputs (test_msg, stdout);
2288
2289 INIT_ARCH_EXT;
2290
2291 check_ulp ();
2292 }
2293
2294 /* Process the test results, returning the exit status. */
2295 static int
2296 libm_test_finish (void)
2297 {
2298 if (output_ulps)
2299 fclose (ulps_file);
2300
2301 printf ("\nTest suite completed:\n");
2302 printf (" %d test cases plus %d tests for exception flags and\n"
2303 " %d tests for errno executed.\n",
2304 noTests, noExcTests, noErrnoTests);
2305 if (noErrors)
2306 {
2307 printf (" %d errors occurred.\n", noErrors);
2308 return 1;
2309 }
2310 printf (" All tests passed successfully.\n");
2311
2312 return 0;
2313 }
2314
2315 int
2316 main (int argc, char **argv)
2317 {
2318 libm_test_init (argc, argv);
2319 do_test ();
2320 return libm_test_finish ();
2321 }
This page took 0.141723 seconds and 6 git commands to generate.