2 * fp-test.c - test QEMU's softfloat implementation using Berkeley's Testfloat
4 * Copyright (C) 2018, Emilio G. Cota <cota@braap.org>
6 * License: GNU GPL, version 2 or later.
7 * See the COPYING file in the top-level directory.
9 * This file is derived from testfloat/source/testsoftfloat.c. Its copyright
12 * Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
13 * University of California. All rights reserved.
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions are met:
18 * 1. Redistributions of source code must retain the above copyright notice,
19 * this list of conditions, and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright notice,
22 * this list of conditions, and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
25 * 3. Neither the name of the University nor the names of its contributors may
26 * be used to endorse or promote products derived from this software without
27 * specific prior written permission.
29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
30 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
31 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
32 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
33 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
36 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 #error Must define HW_POISON_H to work around TARGET_* poisoning
44 #include "qemu/osdep.h"
45 #include "qemu/cutils.h"
47 #include "fpu/softfloat.h"
51 #include "slowfloat.h"
52 #include "functions.h"
55 #include "writeCase.h"
56 #include "testLoops.h"
58 typedef float16_t (*abz_f16
)(float16_t
, float16_t
);
59 typedef bool (*ab_f16_z_bool
)(float16_t
, float16_t
);
60 typedef float32_t (*abz_f32
)(float32_t
, float32_t
);
61 typedef bool (*ab_f32_z_bool
)(float32_t
, float32_t
);
62 typedef float64_t (*abz_f64
)(float64_t
, float64_t
);
63 typedef bool (*ab_f64_z_bool
)(float64_t
, float64_t
);
64 typedef void (*abz_extF80M
)(const extFloat80_t
*, const extFloat80_t
*,
66 typedef bool (*ab_extF80M_z_bool
)(const extFloat80_t
*, const extFloat80_t
*);
67 typedef void (*abz_f128M
)(const float128_t
*, const float128_t
*, float128_t
*);
68 typedef bool (*ab_f128M_z_bool
)(const float128_t
*, const float128_t
*);
70 static const char * const round_mode_names
[] = {
71 [ROUND_NEAR_EVEN
] = "even",
72 [ROUND_MINMAG
] = "zero",
75 [ROUND_NEAR_MAXMAG
] = "tieaway",
78 static unsigned int *test_ops
;
79 static unsigned int n_test_ops
;
80 static unsigned int n_max_errors
= 20;
81 static unsigned int test_round_mode
= ROUND_NEAR_EVEN
;
82 static unsigned int *round_modes
;
83 static unsigned int n_round_modes
;
84 static int test_level
= 1;
85 static uint8_t slow_init_flags
;
86 static uint8_t qemu_init_flags
;
88 /* qemu softfloat status */
89 static float_status qsf
;
91 static const char commands_string
[] =
93 " <int>_to_<float> <float>_add <float>_eq\n"
94 " <float>_to_<int> <float>_sub <float>_le\n"
95 " <float>_to_<int>_r_minMag <float>_mul <float>_lt\n"
96 " <float>_to_<float> <float>_mulAdd <float>_eq_signaling\n"
97 " <float>_roundToInt <float>_div <float>_le_quiet\n"
98 " <float>_rem <float>_lt_quiet\n"
100 " Where <int>: ui32, ui64, i32, i64\n"
101 " <float>: f16, f32, f64, extF80, f128\n"
102 " If no operation is provided, all the above are tested\n"
104 " -e = max error count per test. Default: 20. Set no limit with 0\n"
105 " -f = initial FP exception flags (vioux). Default: none\n"
106 " -l = thoroughness level (1 (default), 2)\n"
107 " -r = rounding mode (even (default), zero, down, up, tieaway, odd)\n"
108 " Set to 'all' to test all rounding modes, if applicable\n"
109 " -s = stop when a test fails\n"
110 " -q = minimise noise when testing, just show each function being tested";
112 static void usage_complete(int argc
, char *argv
[])
114 fprintf(stderr
, "Usage: %s [options] [operation1 ...]\n", argv
[0]);
115 fprintf(stderr
, "%s\n", commands_string
);
119 /* keep wrappers separate but do not bother defining headers for all of them */
120 #include "wrap.c.inc"
122 static void not_implemented(void)
124 fprintf(stderr
, "Not implemented.\n");
127 static bool is_allowed(unsigned op
, int rmode
)
129 /* odd has not been implemented for any 80-bit ops */
130 if (rmode
== softfloat_round_odd
) {
136 case EXTF80_TO_UI32_R_MINMAG
:
137 case EXTF80_TO_UI64_R_MINMAG
:
138 case EXTF80_TO_I32_R_MINMAG
:
139 case EXTF80_TO_I64_R_MINMAG
:
144 case EXTF80_ROUNDTOINT
:
154 case EXTF80_EQ_SIGNALING
:
155 case EXTF80_LE_QUIET
:
156 case EXTF80_LT_QUIET
:
171 static void do_testfloat(int op
, int rmode
, bool exact
)
173 abz_f16 true_abz_f16
;
174 abz_f16 subj_abz_f16
;
175 ab_f16_z_bool true_f16_z_bool
;
176 ab_f16_z_bool subj_f16_z_bool
;
177 abz_f32 true_abz_f32
;
178 abz_f32 subj_abz_f32
;
179 ab_f32_z_bool true_ab_f32_z_bool
;
180 ab_f32_z_bool subj_ab_f32_z_bool
;
181 abz_f64 true_abz_f64
;
182 abz_f64 subj_abz_f64
;
183 ab_f64_z_bool true_ab_f64_z_bool
;
184 ab_f64_z_bool subj_ab_f64_z_bool
;
185 abz_extF80M true_abz_extF80M
;
186 abz_extF80M subj_abz_extF80M
;
187 ab_extF80M_z_bool true_ab_extF80M_z_bool
;
188 ab_extF80M_z_bool subj_ab_extF80M_z_bool
;
189 abz_f128M true_abz_f128M
;
190 abz_f128M subj_abz_f128M
;
191 ab_f128M_z_bool true_ab_f128M_z_bool
;
192 ab_f128M_z_bool subj_ab_f128M_z_bool
;
194 if (verCases_verbosity
) {
195 fputs(">> Testing ", stderr
);
196 verCases_writeFunctionName(stderr
);
200 if (!is_allowed(op
, rmode
)) {
207 test_a_ui32_z_f16(slow_ui32_to_f16
, qemu_ui32_to_f16
);
210 test_a_ui32_z_f32(slow_ui32_to_f32
, qemu_ui32_to_f32
);
213 test_a_ui32_z_f64(slow_ui32_to_f64
, qemu_ui32_to_f64
);
222 test_a_ui64_z_f16(slow_ui64_to_f16
, qemu_ui64_to_f16
);
225 test_a_ui64_z_f32(slow_ui64_to_f32
, qemu_ui64_to_f32
);
228 test_a_ui64_z_f64(slow_ui64_to_f64
, qemu_ui64_to_f64
);
234 test_a_ui64_z_f128(slow_ui64_to_f128M
, qemu_ui64_to_f128M
);
237 test_a_i32_z_f16(slow_i32_to_f16
, qemu_i32_to_f16
);
240 test_a_i32_z_f32(slow_i32_to_f32
, qemu_i32_to_f32
);
243 test_a_i32_z_f64(slow_i32_to_f64
, qemu_i32_to_f64
);
246 test_a_i32_z_extF80(slow_i32_to_extF80M
, qemu_i32_to_extF80M
);
249 test_a_i32_z_f128(slow_i32_to_f128M
, qemu_i32_to_f128M
);
252 test_a_i64_z_f16(slow_i64_to_f16
, qemu_i64_to_f16
);
255 test_a_i64_z_f32(slow_i64_to_f32
, qemu_i64_to_f32
);
258 test_a_i64_z_f64(slow_i64_to_f64
, qemu_i64_to_f64
);
261 test_a_i64_z_extF80(slow_i64_to_extF80M
, qemu_i64_to_extF80M
);
264 test_a_i64_z_f128(slow_i64_to_f128M
, qemu_i64_to_f128M
);
267 test_a_f16_z_ui32_rx(slow_f16_to_ui32
, qemu_f16_to_ui32
, rmode
, exact
);
270 test_a_f16_z_ui64_rx(slow_f16_to_ui64
, qemu_f16_to_ui64
, rmode
, exact
);
273 test_a_f16_z_i32_rx(slow_f16_to_i32
, qemu_f16_to_i32
, rmode
, exact
);
276 test_a_f16_z_i64_rx(slow_f16_to_i64
, qemu_f16_to_i64
, rmode
, exact
);
278 case F16_TO_UI32_R_MINMAG
:
279 test_a_f16_z_ui32_x(slow_f16_to_ui32_r_minMag
,
280 qemu_f16_to_ui32_r_minMag
, exact
);
282 case F16_TO_UI64_R_MINMAG
:
283 test_a_f16_z_ui64_x(slow_f16_to_ui64_r_minMag
,
284 qemu_f16_to_ui64_r_minMag
, exact
);
286 case F16_TO_I32_R_MINMAG
:
287 test_a_f16_z_i32_x(slow_f16_to_i32_r_minMag
, qemu_f16_to_i32_r_minMag
,
290 case F16_TO_I64_R_MINMAG
:
291 test_a_f16_z_i64_x(slow_f16_to_i64_r_minMag
, qemu_f16_to_i64_r_minMag
,
295 test_a_f16_z_f32(slow_f16_to_f32
, qemu_f16_to_f32
);
298 test_a_f16_z_f64(slow_f16_to_f64
, qemu_f16_to_f64
);
307 test_az_f16_rx(slow_f16_roundToInt
, qemu_f16_roundToInt
, rmode
, exact
);
310 true_abz_f16
= slow_f16_add
;
311 subj_abz_f16
= qemu_f16_add
;
314 true_abz_f16
= slow_f16_sub
;
315 subj_abz_f16
= qemu_f16_sub
;
318 true_abz_f16
= slow_f16_mul
;
319 subj_abz_f16
= qemu_f16_mul
;
322 true_abz_f16
= slow_f16_div
;
323 subj_abz_f16
= qemu_f16_div
;
329 test_abz_f16(true_abz_f16
, subj_abz_f16
);
332 test_abcz_f16(slow_f16_mulAdd
, qemu_f16_mulAdd
);
335 test_az_f16(slow_f16_sqrt
, qemu_f16_sqrt
);
338 true_f16_z_bool
= slow_f16_eq
;
339 subj_f16_z_bool
= qemu_f16_eq
;
340 goto test_ab_f16_z_bool
;
342 true_f16_z_bool
= slow_f16_le
;
343 subj_f16_z_bool
= qemu_f16_le
;
344 goto test_ab_f16_z_bool
;
346 true_f16_z_bool
= slow_f16_lt
;
347 subj_f16_z_bool
= qemu_f16_lt
;
348 goto test_ab_f16_z_bool
;
349 case F16_EQ_SIGNALING
:
350 true_f16_z_bool
= slow_f16_eq_signaling
;
351 subj_f16_z_bool
= qemu_f16_eq_signaling
;
352 goto test_ab_f16_z_bool
;
354 true_f16_z_bool
= slow_f16_le_quiet
;
355 subj_f16_z_bool
= qemu_f16_le_quiet
;
356 goto test_ab_f16_z_bool
;
358 true_f16_z_bool
= slow_f16_lt_quiet
;
359 subj_f16_z_bool
= qemu_f16_lt_quiet
;
361 test_ab_f16_z_bool(true_f16_z_bool
, subj_f16_z_bool
);
364 test_a_f32_z_ui32_rx(slow_f32_to_ui32
, qemu_f32_to_ui32
, rmode
, exact
);
367 test_a_f32_z_ui64_rx(slow_f32_to_ui64
, qemu_f32_to_ui64
, rmode
, exact
);
370 test_a_f32_z_i32_rx(slow_f32_to_i32
, qemu_f32_to_i32
, rmode
, exact
);
373 test_a_f32_z_i64_rx(slow_f32_to_i64
, qemu_f32_to_i64
, rmode
, exact
);
375 case F32_TO_UI32_R_MINMAG
:
376 test_a_f32_z_ui32_x(slow_f32_to_ui32_r_minMag
,
377 qemu_f32_to_ui32_r_minMag
, exact
);
379 case F32_TO_UI64_R_MINMAG
:
380 test_a_f32_z_ui64_x(slow_f32_to_ui64_r_minMag
,
381 qemu_f32_to_ui64_r_minMag
, exact
);
383 case F32_TO_I32_R_MINMAG
:
384 test_a_f32_z_i32_x(slow_f32_to_i32_r_minMag
, qemu_f32_to_i32_r_minMag
,
387 case F32_TO_I64_R_MINMAG
:
388 test_a_f32_z_i64_x(slow_f32_to_i64_r_minMag
, qemu_f32_to_i64_r_minMag
,
392 test_a_f32_z_f16(slow_f32_to_f16
, qemu_f32_to_f16
);
395 test_a_f32_z_f64(slow_f32_to_f64
, qemu_f32_to_f64
);
398 test_a_f32_z_extF80(slow_f32_to_extF80M
, qemu_f32_to_extF80M
);
401 test_a_f32_z_f128(slow_f32_to_f128M
, qemu_f32_to_f128M
);
404 test_az_f32_rx(slow_f32_roundToInt
, qemu_f32_roundToInt
, rmode
, exact
);
407 true_abz_f32
= slow_f32_add
;
408 subj_abz_f32
= qemu_f32_add
;
411 true_abz_f32
= slow_f32_sub
;
412 subj_abz_f32
= qemu_f32_sub
;
415 true_abz_f32
= slow_f32_mul
;
416 subj_abz_f32
= qemu_f32_mul
;
419 true_abz_f32
= slow_f32_div
;
420 subj_abz_f32
= qemu_f32_div
;
423 true_abz_f32
= slow_f32_rem
;
424 subj_abz_f32
= qemu_f32_rem
;
426 test_abz_f32(true_abz_f32
, subj_abz_f32
);
429 test_abcz_f32(slow_f32_mulAdd
, qemu_f32_mulAdd
);
432 test_az_f32(slow_f32_sqrt
, qemu_f32_sqrt
);
435 true_ab_f32_z_bool
= slow_f32_eq
;
436 subj_ab_f32_z_bool
= qemu_f32_eq
;
437 goto test_ab_f32_z_bool
;
439 true_ab_f32_z_bool
= slow_f32_le
;
440 subj_ab_f32_z_bool
= qemu_f32_le
;
441 goto test_ab_f32_z_bool
;
443 true_ab_f32_z_bool
= slow_f32_lt
;
444 subj_ab_f32_z_bool
= qemu_f32_lt
;
445 goto test_ab_f32_z_bool
;
446 case F32_EQ_SIGNALING
:
447 true_ab_f32_z_bool
= slow_f32_eq_signaling
;
448 subj_ab_f32_z_bool
= qemu_f32_eq_signaling
;
449 goto test_ab_f32_z_bool
;
451 true_ab_f32_z_bool
= slow_f32_le_quiet
;
452 subj_ab_f32_z_bool
= qemu_f32_le_quiet
;
453 goto test_ab_f32_z_bool
;
455 true_ab_f32_z_bool
= slow_f32_lt_quiet
;
456 subj_ab_f32_z_bool
= qemu_f32_lt_quiet
;
458 test_ab_f32_z_bool(true_ab_f32_z_bool
, subj_ab_f32_z_bool
);
461 test_a_f64_z_ui32_rx(slow_f64_to_ui32
, qemu_f64_to_ui32
, rmode
, exact
);
464 test_a_f64_z_ui64_rx(slow_f64_to_ui64
, qemu_f64_to_ui64
, rmode
, exact
);
467 test_a_f64_z_i32_rx(slow_f64_to_i32
, qemu_f64_to_i32
, rmode
, exact
);
470 test_a_f64_z_i64_rx(slow_f64_to_i64
, qemu_f64_to_i64
, rmode
, exact
);
472 case F64_TO_UI32_R_MINMAG
:
473 test_a_f64_z_ui32_x(slow_f64_to_ui32_r_minMag
,
474 qemu_f64_to_ui32_r_minMag
, exact
);
476 case F64_TO_UI64_R_MINMAG
:
477 test_a_f64_z_ui64_x(slow_f64_to_ui64_r_minMag
,
478 qemu_f64_to_ui64_r_minMag
, exact
);
480 case F64_TO_I32_R_MINMAG
:
481 test_a_f64_z_i32_x(slow_f64_to_i32_r_minMag
, qemu_f64_to_i32_r_minMag
,
484 case F64_TO_I64_R_MINMAG
:
485 test_a_f64_z_i64_x(slow_f64_to_i64_r_minMag
, qemu_f64_to_i64_r_minMag
,
489 test_a_f64_z_f16(slow_f64_to_f16
, qemu_f64_to_f16
);
492 test_a_f64_z_f32(slow_f64_to_f32
, qemu_f64_to_f32
);
495 test_a_f64_z_extF80(slow_f64_to_extF80M
, qemu_f64_to_extF80M
);
498 test_a_f64_z_f128(slow_f64_to_f128M
, qemu_f64_to_f128M
);
501 test_az_f64_rx(slow_f64_roundToInt
, qemu_f64_roundToInt
, rmode
, exact
);
504 true_abz_f64
= slow_f64_add
;
505 subj_abz_f64
= qemu_f64_add
;
508 true_abz_f64
= slow_f64_sub
;
509 subj_abz_f64
= qemu_f64_sub
;
512 true_abz_f64
= slow_f64_mul
;
513 subj_abz_f64
= qemu_f64_mul
;
516 true_abz_f64
= slow_f64_div
;
517 subj_abz_f64
= qemu_f64_div
;
520 true_abz_f64
= slow_f64_rem
;
521 subj_abz_f64
= qemu_f64_rem
;
523 test_abz_f64(true_abz_f64
, subj_abz_f64
);
526 test_abcz_f64(slow_f64_mulAdd
, qemu_f64_mulAdd
);
529 test_az_f64(slow_f64_sqrt
, qemu_f64_sqrt
);
532 true_ab_f64_z_bool
= slow_f64_eq
;
533 subj_ab_f64_z_bool
= qemu_f64_eq
;
534 goto test_ab_f64_z_bool
;
536 true_ab_f64_z_bool
= slow_f64_le
;
537 subj_ab_f64_z_bool
= qemu_f64_le
;
538 goto test_ab_f64_z_bool
;
540 true_ab_f64_z_bool
= slow_f64_lt
;
541 subj_ab_f64_z_bool
= qemu_f64_lt
;
542 goto test_ab_f64_z_bool
;
543 case F64_EQ_SIGNALING
:
544 true_ab_f64_z_bool
= slow_f64_eq_signaling
;
545 subj_ab_f64_z_bool
= qemu_f64_eq_signaling
;
546 goto test_ab_f64_z_bool
;
548 true_ab_f64_z_bool
= slow_f64_le_quiet
;
549 subj_ab_f64_z_bool
= qemu_f64_le_quiet
;
550 goto test_ab_f64_z_bool
;
552 true_ab_f64_z_bool
= slow_f64_lt_quiet
;
553 subj_ab_f64_z_bool
= qemu_f64_lt_quiet
;
555 test_ab_f64_z_bool(true_ab_f64_z_bool
, subj_ab_f64_z_bool
);
564 test_a_extF80_z_i32_rx(slow_extF80M_to_i32
, qemu_extF80M_to_i32
, rmode
,
568 test_a_extF80_z_i64_rx(slow_extF80M_to_i64
, qemu_extF80M_to_i64
, rmode
,
571 case EXTF80_TO_UI32_R_MINMAG
:
574 case EXTF80_TO_UI64_R_MINMAG
:
577 case EXTF80_TO_I32_R_MINMAG
:
578 test_a_extF80_z_i32_x(slow_extF80M_to_i32_r_minMag
,
579 qemu_extF80M_to_i32_r_minMag
, exact
);
581 case EXTF80_TO_I64_R_MINMAG
:
582 test_a_extF80_z_i64_x(slow_extF80M_to_i64_r_minMag
,
583 qemu_extF80M_to_i64_r_minMag
, exact
);
589 test_a_extF80_z_f32(slow_extF80M_to_f32
, qemu_extF80M_to_f32
);
592 test_a_extF80_z_f64(slow_extF80M_to_f64
, qemu_extF80M_to_f64
);
595 test_a_extF80_z_f128(slow_extF80M_to_f128M
, qemu_extF80M_to_f128M
);
597 case EXTF80_ROUNDTOINT
:
598 test_az_extF80_rx(slow_extF80M_roundToInt
, qemu_extF80M_roundToInt
,
602 true_abz_extF80M
= slow_extF80M_add
;
603 subj_abz_extF80M
= qemu_extF80M_add
;
604 goto test_abz_extF80
;
606 true_abz_extF80M
= slow_extF80M_sub
;
607 subj_abz_extF80M
= qemu_extF80M_sub
;
608 goto test_abz_extF80
;
610 true_abz_extF80M
= slow_extF80M_mul
;
611 subj_abz_extF80M
= qemu_extF80M_mul
;
612 goto test_abz_extF80
;
614 true_abz_extF80M
= slow_extF80M_div
;
615 subj_abz_extF80M
= qemu_extF80M_div
;
616 goto test_abz_extF80
;
618 true_abz_extF80M
= slow_extF80M_rem
;
619 subj_abz_extF80M
= qemu_extF80M_rem
;
621 test_abz_extF80(true_abz_extF80M
, subj_abz_extF80M
);
624 test_az_extF80(slow_extF80M_sqrt
, qemu_extF80M_sqrt
);
627 true_ab_extF80M_z_bool
= slow_extF80M_eq
;
628 subj_ab_extF80M_z_bool
= qemu_extF80M_eq
;
629 goto test_ab_extF80_z_bool
;
631 true_ab_extF80M_z_bool
= slow_extF80M_le
;
632 subj_ab_extF80M_z_bool
= qemu_extF80M_le
;
633 goto test_ab_extF80_z_bool
;
635 true_ab_extF80M_z_bool
= slow_extF80M_lt
;
636 subj_ab_extF80M_z_bool
= qemu_extF80M_lt
;
637 goto test_ab_extF80_z_bool
;
638 case EXTF80_EQ_SIGNALING
:
639 true_ab_extF80M_z_bool
= slow_extF80M_eq_signaling
;
640 subj_ab_extF80M_z_bool
= qemu_extF80M_eq_signaling
;
641 goto test_ab_extF80_z_bool
;
642 case EXTF80_LE_QUIET
:
643 true_ab_extF80M_z_bool
= slow_extF80M_le_quiet
;
644 subj_ab_extF80M_z_bool
= qemu_extF80M_le_quiet
;
645 goto test_ab_extF80_z_bool
;
646 case EXTF80_LT_QUIET
:
647 true_ab_extF80M_z_bool
= slow_extF80M_lt_quiet
;
648 subj_ab_extF80M_z_bool
= qemu_extF80M_lt_quiet
;
649 test_ab_extF80_z_bool
:
650 test_ab_extF80_z_bool(true_ab_extF80M_z_bool
, subj_ab_extF80M_z_bool
);
653 test_a_f128_z_ui32_rx(slow_f128M_to_ui32
, qemu_f128M_to_ui32
, rmode
,
657 test_a_f128_z_ui64_rx(slow_f128M_to_ui64
, qemu_f128M_to_ui64
, rmode
,
661 test_a_f128_z_i32_rx(slow_f128M_to_i32
, qemu_f128M_to_i32
, rmode
,
665 test_a_f128_z_i64_rx(slow_f128M_to_i64
, qemu_f128M_to_i64
, rmode
,
668 case F128_TO_UI32_R_MINMAG
:
669 test_a_f128_z_ui32_x(slow_f128M_to_ui32_r_minMag
,
670 qemu_f128M_to_ui32_r_minMag
, exact
);
672 case F128_TO_UI64_R_MINMAG
:
673 test_a_f128_z_ui64_x(slow_f128M_to_ui64_r_minMag
,
674 qemu_f128M_to_ui64_r_minMag
, exact
);
676 case F128_TO_I32_R_MINMAG
:
677 test_a_f128_z_i32_x(slow_f128M_to_i32_r_minMag
,
678 qemu_f128M_to_i32_r_minMag
, exact
);
680 case F128_TO_I64_R_MINMAG
:
681 test_a_f128_z_i64_x(slow_f128M_to_i64_r_minMag
,
682 qemu_f128M_to_i64_r_minMag
, exact
);
688 test_a_f128_z_f32(slow_f128M_to_f32
, qemu_f128M_to_f32
);
691 test_a_f128_z_f64(slow_f128M_to_f64
, qemu_f128M_to_f64
);
694 test_a_f128_z_extF80(slow_f128M_to_extF80M
, qemu_f128M_to_extF80M
);
696 case F128_ROUNDTOINT
:
697 test_az_f128_rx(slow_f128M_roundToInt
, qemu_f128M_roundToInt
, rmode
,
701 true_abz_f128M
= slow_f128M_add
;
702 subj_abz_f128M
= qemu_f128M_add
;
705 true_abz_f128M
= slow_f128M_sub
;
706 subj_abz_f128M
= qemu_f128M_sub
;
709 true_abz_f128M
= slow_f128M_mul
;
710 subj_abz_f128M
= qemu_f128M_mul
;
713 true_abz_f128M
= slow_f128M_div
;
714 subj_abz_f128M
= qemu_f128M_div
;
717 true_abz_f128M
= slow_f128M_rem
;
718 subj_abz_f128M
= qemu_f128M_rem
;
720 test_abz_f128(true_abz_f128M
, subj_abz_f128M
);
723 test_abcz_f128(slow_f128M_mulAdd
, qemu_f128M_mulAdd
);
726 test_az_f128(slow_f128M_sqrt
, qemu_f128M_sqrt
);
729 true_ab_f128M_z_bool
= slow_f128M_eq
;
730 subj_ab_f128M_z_bool
= qemu_f128M_eq
;
731 goto test_ab_f128_z_bool
;
733 true_ab_f128M_z_bool
= slow_f128M_le
;
734 subj_ab_f128M_z_bool
= qemu_f128M_le
;
735 goto test_ab_f128_z_bool
;
737 true_ab_f128M_z_bool
= slow_f128M_lt
;
738 subj_ab_f128M_z_bool
= qemu_f128M_lt
;
739 goto test_ab_f128_z_bool
;
740 case F128_EQ_SIGNALING
:
741 true_ab_f128M_z_bool
= slow_f128M_eq_signaling
;
742 subj_ab_f128M_z_bool
= qemu_f128M_eq_signaling
;
743 goto test_ab_f128_z_bool
;
745 true_ab_f128M_z_bool
= slow_f128M_le_quiet
;
746 subj_ab_f128M_z_bool
= qemu_f128M_le_quiet
;
747 goto test_ab_f128_z_bool
;
749 true_ab_f128M_z_bool
= slow_f128M_lt_quiet
;
750 subj_ab_f128M_z_bool
= qemu_f128M_lt_quiet
;
752 test_ab_f128_z_bool(true_ab_f128M_z_bool
, subj_ab_f128M_z_bool
);
755 if ((verCases_errorStop
&& verCases_anyErrors
)) {
756 verCases_exitWithStatus();
760 static unsigned int test_name_to_op(const char *arg
)
764 /* counting begins at 1 */
765 for (i
= 1; i
< NUM_FUNCTIONS
; i
++) {
766 const char *name
= functionInfos
[i
].namePtr
;
768 if (name
&& !strcmp(name
, arg
)) {
775 static unsigned int round_name_to_mode(const char *name
)
779 /* counting begins at 1 */
780 for (i
= 1; i
< NUM_ROUNDINGMODES
; i
++) {
781 if (!strcmp(round_mode_names
[i
], name
)) {
788 static int set_init_flags(const char *flags
)
792 for (p
= flags
; *p
!= '\0'; p
++) {
795 slow_init_flags
|= softfloat_flag_invalid
;
796 qemu_init_flags
|= float_flag_invalid
;
799 slow_init_flags
|= softfloat_flag_infinite
;
800 qemu_init_flags
|= float_flag_divbyzero
;
803 slow_init_flags
|= softfloat_flag_overflow
;
804 qemu_init_flags
|= float_flag_overflow
;
807 slow_init_flags
|= softfloat_flag_underflow
;
808 qemu_init_flags
|= float_flag_underflow
;
811 slow_init_flags
|= softfloat_flag_inexact
;
812 qemu_init_flags
|= float_flag_inexact
;
821 static uint_fast8_t slow_clear_flags(void)
823 uint8_t prev
= slowfloat_exceptionFlags
;
825 slowfloat_exceptionFlags
= slow_init_flags
;
829 static uint_fast8_t qemu_clear_flags(void)
831 uint8_t prev
= qemu_flags_to_sf(qsf
.float_exception_flags
);
833 qsf
.float_exception_flags
= qemu_init_flags
;
837 static void parse_args(int argc
, char *argv
[])
843 c
= getopt(argc
, argv
, "he:f:l:r:sq");
849 usage_complete(argc
, argv
);
852 if (qemu_strtoui(optarg
, NULL
, 0, &n_max_errors
)) {
853 fprintf(stderr
, "fatal: invalid max error count\n");
858 if (set_init_flags(optarg
)) {
859 fprintf(stderr
, "fatal: flags must be a subset of 'vioux'\n");
864 if (qemu_strtoi(optarg
, NULL
, 0, &test_level
)) {
865 fprintf(stderr
, "fatal: invalid test level\n");
870 if (!strcmp(optarg
, "all")) {
873 test_round_mode
= round_name_to_mode(optarg
);
874 if (test_round_mode
== 0) {
875 fprintf(stderr
, "fatal: invalid rounding mode\n");
881 * The following flags are declared in testfloat/source/verCases_common.c
884 verCases_errorStop
= true;
887 verCases_verbosity
= 0;
890 /* invalid option or missing argument; getopt prints error info */
895 /* set rounding modes */
896 if (test_round_mode
== 0) {
897 /* test all rounding modes; note that counting begins at 1 */
898 n_round_modes
= NUM_ROUNDINGMODES
- 1;
899 round_modes
= g_malloc_n(n_round_modes
, sizeof(*round_modes
));
900 for (i
= 0; i
< n_round_modes
; i
++) {
901 round_modes
[i
] = i
+ 1;
905 round_modes
= g_malloc(sizeof(*round_modes
));
906 round_modes
[0] = test_round_mode
;
910 if (optind
== argc
) {
911 /* test all ops; note that counting begins at 1 */
912 n_test_ops
= NUM_FUNCTIONS
- 1;
913 test_ops
= g_malloc_n(n_test_ops
, sizeof(*test_ops
));
914 for (i
= 0; i
< n_test_ops
; i
++) {
918 n_test_ops
= argc
- optind
;
919 test_ops
= g_malloc_n(n_test_ops
, sizeof(*test_ops
));
920 for (i
= 0; i
< n_test_ops
; i
++) {
921 const char *name
= argv
[i
+ optind
];
922 unsigned int op
= test_name_to_op(name
);
925 fprintf(stderr
, "fatal: invalid op '%s'\n", name
);
938 genCases_setLevel(test_level
);
939 verCases_maxErrorCount
= n_max_errors
;
941 testLoops_trueFlagsFunction
= slow_clear_flags
;
942 testLoops_subjFlagsFunction
= qemu_clear_flags
;
944 for (i
= 0; i
< n_test_ops
; i
++) {
945 unsigned int op
= test_ops
[i
];
948 if (functionInfos
[op
].namePtr
== NULL
) {
951 verCases_functionNamePtr
= functionInfos
[op
].namePtr
;
953 for (j
= 0; j
< n_round_modes
; j
++) {
954 int attrs
= functionInfos
[op
].attribs
;
955 int round
= round_modes
[j
];
956 int rmode
= roundingModes
[round
];
959 verCases_roundingCode
= 0;
960 slowfloat_roundingMode
= rmode
;
961 qsf
.float_rounding_mode
= sf_rounding_to_qemu(rmode
);
963 if (attrs
& (FUNC_ARG_ROUNDINGMODE
| FUNC_EFF_ROUNDINGMODE
)) {
964 /* print rounding mode if the op is affected by it */
965 verCases_roundingCode
= round
;
967 /* if the op is not sensitive to rounding, move on */
971 /* QEMU doesn't have !exact */
972 verCases_exact
= true;
973 verCases_usesExact
= !!(attrs
& FUNC_ARG_EXACT
);
975 for (k
= 0; k
< 3; k
++) {
976 FloatX80RoundPrec qsf_prec80
= floatx80_precision_x
;
982 qsf_prec80
= floatx80_precision_d
;
985 qsf_prec80
= floatx80_precision_s
;
988 verCases_roundingPrecision
= 0;
989 slow_extF80_roundingPrecision
= prec80
;
990 qsf
.floatx80_rounding_precision
= qsf_prec80
;
992 if (attrs
& FUNC_EFF_ROUNDINGPRECISION
) {
993 verCases_roundingPrecision
= prec80
;
995 /* if the op is not sensitive to prec80, move on */
999 /* note: the count begins at 1 */
1000 for (l
= 1; l
< NUM_TININESSMODES
; l
++) {
1001 int tmode
= tininessModes
[l
];
1003 verCases_tininessCode
= 0;
1004 slowfloat_detectTininess
= tmode
;
1005 qsf
.tininess_before_rounding
= sf_tininess_to_qemu(tmode
);
1007 if (attrs
& FUNC_EFF_TININESSMODE
||
1008 ((attrs
& FUNC_EFF_TININESSMODE_REDUCEDPREC
) &&
1009 prec80
&& prec80
< 80)) {
1010 verCases_tininessCode
= l
;
1012 /* if the op is not sensitive to tininess, move on */
1016 do_testfloat(op
, rmode
, true);
1021 verCases_exitWithStatus();
1022 /* old compilers might miss that we exited */
1023 g_assert_not_reached();
1026 int main(int argc
, char *argv
[])
1028 parse_args(argc
, argv
);
1029 fail_programName
= argv
[0];
1030 run_test(); /* does not return */