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";
111 static void usage_complete(int argc
, char *argv
[])
113 fprintf(stderr
, "Usage: %s [options] [operation1 ...]\n", argv
[0]);
114 fprintf(stderr
, "%s\n", commands_string
);
118 /* keep wrappers separate but do not bother defining headers for all of them */
119 #include "wrap.c.inc"
121 static void not_implemented(void)
123 fprintf(stderr
, "Not implemented.\n");
126 static bool is_allowed(unsigned op
, int rmode
)
128 /* odd has not been implemented for any 80-bit ops */
129 if (rmode
== softfloat_round_odd
) {
135 case EXTF80_TO_UI32_R_MINMAG
:
136 case EXTF80_TO_UI64_R_MINMAG
:
137 case EXTF80_TO_I32_R_MINMAG
:
138 case EXTF80_TO_I64_R_MINMAG
:
143 case EXTF80_ROUNDTOINT
:
153 case EXTF80_EQ_SIGNALING
:
154 case EXTF80_LE_QUIET
:
155 case EXTF80_LT_QUIET
:
170 static void do_testfloat(int op
, int rmode
, bool exact
)
172 abz_f16 true_abz_f16
;
173 abz_f16 subj_abz_f16
;
174 ab_f16_z_bool true_f16_z_bool
;
175 ab_f16_z_bool subj_f16_z_bool
;
176 abz_f32 true_abz_f32
;
177 abz_f32 subj_abz_f32
;
178 ab_f32_z_bool true_ab_f32_z_bool
;
179 ab_f32_z_bool subj_ab_f32_z_bool
;
180 abz_f64 true_abz_f64
;
181 abz_f64 subj_abz_f64
;
182 ab_f64_z_bool true_ab_f64_z_bool
;
183 ab_f64_z_bool subj_ab_f64_z_bool
;
184 abz_extF80M true_abz_extF80M
;
185 abz_extF80M subj_abz_extF80M
;
186 ab_extF80M_z_bool true_ab_extF80M_z_bool
;
187 ab_extF80M_z_bool subj_ab_extF80M_z_bool
;
188 abz_f128M true_abz_f128M
;
189 abz_f128M subj_abz_f128M
;
190 ab_f128M_z_bool true_ab_f128M_z_bool
;
191 ab_f128M_z_bool subj_ab_f128M_z_bool
;
193 fputs(">> Testing ", stderr
);
194 verCases_writeFunctionName(stderr
);
197 if (!is_allowed(op
, rmode
)) {
204 test_a_ui32_z_f16(slow_ui32_to_f16
, qemu_ui32_to_f16
);
207 test_a_ui32_z_f32(slow_ui32_to_f32
, qemu_ui32_to_f32
);
210 test_a_ui32_z_f64(slow_ui32_to_f64
, qemu_ui32_to_f64
);
219 test_a_ui64_z_f16(slow_ui64_to_f16
, qemu_ui64_to_f16
);
222 test_a_ui64_z_f32(slow_ui64_to_f32
, qemu_ui64_to_f32
);
225 test_a_ui64_z_f64(slow_ui64_to_f64
, qemu_ui64_to_f64
);
231 test_a_ui64_z_f128(slow_ui64_to_f128M
, qemu_ui64_to_f128M
);
234 test_a_i32_z_f16(slow_i32_to_f16
, qemu_i32_to_f16
);
237 test_a_i32_z_f32(slow_i32_to_f32
, qemu_i32_to_f32
);
240 test_a_i32_z_f64(slow_i32_to_f64
, qemu_i32_to_f64
);
243 test_a_i32_z_extF80(slow_i32_to_extF80M
, qemu_i32_to_extF80M
);
246 test_a_i32_z_f128(slow_i32_to_f128M
, qemu_i32_to_f128M
);
249 test_a_i64_z_f16(slow_i64_to_f16
, qemu_i64_to_f16
);
252 test_a_i64_z_f32(slow_i64_to_f32
, qemu_i64_to_f32
);
255 test_a_i64_z_f64(slow_i64_to_f64
, qemu_i64_to_f64
);
258 test_a_i64_z_extF80(slow_i64_to_extF80M
, qemu_i64_to_extF80M
);
261 test_a_i64_z_f128(slow_i64_to_f128M
, qemu_i64_to_f128M
);
264 test_a_f16_z_ui32_rx(slow_f16_to_ui32
, qemu_f16_to_ui32
, rmode
, exact
);
267 test_a_f16_z_ui64_rx(slow_f16_to_ui64
, qemu_f16_to_ui64
, rmode
, exact
);
270 test_a_f16_z_i32_rx(slow_f16_to_i32
, qemu_f16_to_i32
, rmode
, exact
);
273 test_a_f16_z_i64_rx(slow_f16_to_i64
, qemu_f16_to_i64
, rmode
, exact
);
275 case F16_TO_UI32_R_MINMAG
:
276 test_a_f16_z_ui32_x(slow_f16_to_ui32_r_minMag
,
277 qemu_f16_to_ui32_r_minMag
, exact
);
279 case F16_TO_UI64_R_MINMAG
:
280 test_a_f16_z_ui64_x(slow_f16_to_ui64_r_minMag
,
281 qemu_f16_to_ui64_r_minMag
, exact
);
283 case F16_TO_I32_R_MINMAG
:
284 test_a_f16_z_i32_x(slow_f16_to_i32_r_minMag
, qemu_f16_to_i32_r_minMag
,
287 case F16_TO_I64_R_MINMAG
:
288 test_a_f16_z_i64_x(slow_f16_to_i64_r_minMag
, qemu_f16_to_i64_r_minMag
,
292 test_a_f16_z_f32(slow_f16_to_f32
, qemu_f16_to_f32
);
295 test_a_f16_z_f64(slow_f16_to_f64
, qemu_f16_to_f64
);
304 test_az_f16_rx(slow_f16_roundToInt
, qemu_f16_roundToInt
, rmode
, exact
);
307 true_abz_f16
= slow_f16_add
;
308 subj_abz_f16
= qemu_f16_add
;
311 true_abz_f16
= slow_f16_sub
;
312 subj_abz_f16
= qemu_f16_sub
;
315 true_abz_f16
= slow_f16_mul
;
316 subj_abz_f16
= qemu_f16_mul
;
319 true_abz_f16
= slow_f16_div
;
320 subj_abz_f16
= qemu_f16_div
;
326 test_abz_f16(true_abz_f16
, subj_abz_f16
);
329 test_abcz_f16(slow_f16_mulAdd
, qemu_f16_mulAdd
);
332 test_az_f16(slow_f16_sqrt
, qemu_f16_sqrt
);
335 true_f16_z_bool
= slow_f16_eq
;
336 subj_f16_z_bool
= qemu_f16_eq
;
337 goto test_ab_f16_z_bool
;
339 true_f16_z_bool
= slow_f16_le
;
340 subj_f16_z_bool
= qemu_f16_le
;
341 goto test_ab_f16_z_bool
;
343 true_f16_z_bool
= slow_f16_lt
;
344 subj_f16_z_bool
= qemu_f16_lt
;
345 goto test_ab_f16_z_bool
;
346 case F16_EQ_SIGNALING
:
347 true_f16_z_bool
= slow_f16_eq_signaling
;
348 subj_f16_z_bool
= qemu_f16_eq_signaling
;
349 goto test_ab_f16_z_bool
;
351 true_f16_z_bool
= slow_f16_le_quiet
;
352 subj_f16_z_bool
= qemu_f16_le_quiet
;
353 goto test_ab_f16_z_bool
;
355 true_f16_z_bool
= slow_f16_lt_quiet
;
356 subj_f16_z_bool
= qemu_f16_lt_quiet
;
358 test_ab_f16_z_bool(true_f16_z_bool
, subj_f16_z_bool
);
361 test_a_f32_z_ui32_rx(slow_f32_to_ui32
, qemu_f32_to_ui32
, rmode
, exact
);
364 test_a_f32_z_ui64_rx(slow_f32_to_ui64
, qemu_f32_to_ui64
, rmode
, exact
);
367 test_a_f32_z_i32_rx(slow_f32_to_i32
, qemu_f32_to_i32
, rmode
, exact
);
370 test_a_f32_z_i64_rx(slow_f32_to_i64
, qemu_f32_to_i64
, rmode
, exact
);
372 case F32_TO_UI32_R_MINMAG
:
373 test_a_f32_z_ui32_x(slow_f32_to_ui32_r_minMag
,
374 qemu_f32_to_ui32_r_minMag
, exact
);
376 case F32_TO_UI64_R_MINMAG
:
377 test_a_f32_z_ui64_x(slow_f32_to_ui64_r_minMag
,
378 qemu_f32_to_ui64_r_minMag
, exact
);
380 case F32_TO_I32_R_MINMAG
:
381 test_a_f32_z_i32_x(slow_f32_to_i32_r_minMag
, qemu_f32_to_i32_r_minMag
,
384 case F32_TO_I64_R_MINMAG
:
385 test_a_f32_z_i64_x(slow_f32_to_i64_r_minMag
, qemu_f32_to_i64_r_minMag
,
389 test_a_f32_z_f16(slow_f32_to_f16
, qemu_f32_to_f16
);
392 test_a_f32_z_f64(slow_f32_to_f64
, qemu_f32_to_f64
);
395 test_a_f32_z_extF80(slow_f32_to_extF80M
, qemu_f32_to_extF80M
);
398 test_a_f32_z_f128(slow_f32_to_f128M
, qemu_f32_to_f128M
);
401 test_az_f32_rx(slow_f32_roundToInt
, qemu_f32_roundToInt
, rmode
, exact
);
404 true_abz_f32
= slow_f32_add
;
405 subj_abz_f32
= qemu_f32_add
;
408 true_abz_f32
= slow_f32_sub
;
409 subj_abz_f32
= qemu_f32_sub
;
412 true_abz_f32
= slow_f32_mul
;
413 subj_abz_f32
= qemu_f32_mul
;
416 true_abz_f32
= slow_f32_div
;
417 subj_abz_f32
= qemu_f32_div
;
420 true_abz_f32
= slow_f32_rem
;
421 subj_abz_f32
= qemu_f32_rem
;
423 test_abz_f32(true_abz_f32
, subj_abz_f32
);
426 test_abcz_f32(slow_f32_mulAdd
, qemu_f32_mulAdd
);
429 test_az_f32(slow_f32_sqrt
, qemu_f32_sqrt
);
432 true_ab_f32_z_bool
= slow_f32_eq
;
433 subj_ab_f32_z_bool
= qemu_f32_eq
;
434 goto test_ab_f32_z_bool
;
436 true_ab_f32_z_bool
= slow_f32_le
;
437 subj_ab_f32_z_bool
= qemu_f32_le
;
438 goto test_ab_f32_z_bool
;
440 true_ab_f32_z_bool
= slow_f32_lt
;
441 subj_ab_f32_z_bool
= qemu_f32_lt
;
442 goto test_ab_f32_z_bool
;
443 case F32_EQ_SIGNALING
:
444 true_ab_f32_z_bool
= slow_f32_eq_signaling
;
445 subj_ab_f32_z_bool
= qemu_f32_eq_signaling
;
446 goto test_ab_f32_z_bool
;
448 true_ab_f32_z_bool
= slow_f32_le_quiet
;
449 subj_ab_f32_z_bool
= qemu_f32_le_quiet
;
450 goto test_ab_f32_z_bool
;
452 true_ab_f32_z_bool
= slow_f32_lt_quiet
;
453 subj_ab_f32_z_bool
= qemu_f32_lt_quiet
;
455 test_ab_f32_z_bool(true_ab_f32_z_bool
, subj_ab_f32_z_bool
);
458 test_a_f64_z_ui32_rx(slow_f64_to_ui32
, qemu_f64_to_ui32
, rmode
, exact
);
461 test_a_f64_z_ui64_rx(slow_f64_to_ui64
, qemu_f64_to_ui64
, rmode
, exact
);
464 test_a_f64_z_i32_rx(slow_f64_to_i32
, qemu_f64_to_i32
, rmode
, exact
);
467 test_a_f64_z_i64_rx(slow_f64_to_i64
, qemu_f64_to_i64
, rmode
, exact
);
469 case F64_TO_UI32_R_MINMAG
:
470 test_a_f64_z_ui32_x(slow_f64_to_ui32_r_minMag
,
471 qemu_f64_to_ui32_r_minMag
, exact
);
473 case F64_TO_UI64_R_MINMAG
:
474 test_a_f64_z_ui64_x(slow_f64_to_ui64_r_minMag
,
475 qemu_f64_to_ui64_r_minMag
, exact
);
477 case F64_TO_I32_R_MINMAG
:
478 test_a_f64_z_i32_x(slow_f64_to_i32_r_minMag
, qemu_f64_to_i32_r_minMag
,
481 case F64_TO_I64_R_MINMAG
:
482 test_a_f64_z_i64_x(slow_f64_to_i64_r_minMag
, qemu_f64_to_i64_r_minMag
,
486 test_a_f64_z_f16(slow_f64_to_f16
, qemu_f64_to_f16
);
489 test_a_f64_z_f32(slow_f64_to_f32
, qemu_f64_to_f32
);
492 test_a_f64_z_extF80(slow_f64_to_extF80M
, qemu_f64_to_extF80M
);
495 test_a_f64_z_f128(slow_f64_to_f128M
, qemu_f64_to_f128M
);
498 test_az_f64_rx(slow_f64_roundToInt
, qemu_f64_roundToInt
, rmode
, exact
);
501 true_abz_f64
= slow_f64_add
;
502 subj_abz_f64
= qemu_f64_add
;
505 true_abz_f64
= slow_f64_sub
;
506 subj_abz_f64
= qemu_f64_sub
;
509 true_abz_f64
= slow_f64_mul
;
510 subj_abz_f64
= qemu_f64_mul
;
513 true_abz_f64
= slow_f64_div
;
514 subj_abz_f64
= qemu_f64_div
;
517 true_abz_f64
= slow_f64_rem
;
518 subj_abz_f64
= qemu_f64_rem
;
520 test_abz_f64(true_abz_f64
, subj_abz_f64
);
523 test_abcz_f64(slow_f64_mulAdd
, qemu_f64_mulAdd
);
526 test_az_f64(slow_f64_sqrt
, qemu_f64_sqrt
);
529 true_ab_f64_z_bool
= slow_f64_eq
;
530 subj_ab_f64_z_bool
= qemu_f64_eq
;
531 goto test_ab_f64_z_bool
;
533 true_ab_f64_z_bool
= slow_f64_le
;
534 subj_ab_f64_z_bool
= qemu_f64_le
;
535 goto test_ab_f64_z_bool
;
537 true_ab_f64_z_bool
= slow_f64_lt
;
538 subj_ab_f64_z_bool
= qemu_f64_lt
;
539 goto test_ab_f64_z_bool
;
540 case F64_EQ_SIGNALING
:
541 true_ab_f64_z_bool
= slow_f64_eq_signaling
;
542 subj_ab_f64_z_bool
= qemu_f64_eq_signaling
;
543 goto test_ab_f64_z_bool
;
545 true_ab_f64_z_bool
= slow_f64_le_quiet
;
546 subj_ab_f64_z_bool
= qemu_f64_le_quiet
;
547 goto test_ab_f64_z_bool
;
549 true_ab_f64_z_bool
= slow_f64_lt_quiet
;
550 subj_ab_f64_z_bool
= qemu_f64_lt_quiet
;
552 test_ab_f64_z_bool(true_ab_f64_z_bool
, subj_ab_f64_z_bool
);
561 test_a_extF80_z_i32_rx(slow_extF80M_to_i32
, qemu_extF80M_to_i32
, rmode
,
565 test_a_extF80_z_i64_rx(slow_extF80M_to_i64
, qemu_extF80M_to_i64
, rmode
,
568 case EXTF80_TO_UI32_R_MINMAG
:
571 case EXTF80_TO_UI64_R_MINMAG
:
574 case EXTF80_TO_I32_R_MINMAG
:
575 test_a_extF80_z_i32_x(slow_extF80M_to_i32_r_minMag
,
576 qemu_extF80M_to_i32_r_minMag
, exact
);
578 case EXTF80_TO_I64_R_MINMAG
:
579 test_a_extF80_z_i64_x(slow_extF80M_to_i64_r_minMag
,
580 qemu_extF80M_to_i64_r_minMag
, exact
);
586 test_a_extF80_z_f32(slow_extF80M_to_f32
, qemu_extF80M_to_f32
);
589 test_a_extF80_z_f64(slow_extF80M_to_f64
, qemu_extF80M_to_f64
);
592 test_a_extF80_z_f128(slow_extF80M_to_f128M
, qemu_extF80M_to_f128M
);
594 case EXTF80_ROUNDTOINT
:
595 test_az_extF80_rx(slow_extF80M_roundToInt
, qemu_extF80M_roundToInt
,
599 true_abz_extF80M
= slow_extF80M_add
;
600 subj_abz_extF80M
= qemu_extF80M_add
;
601 goto test_abz_extF80
;
603 true_abz_extF80M
= slow_extF80M_sub
;
604 subj_abz_extF80M
= qemu_extF80M_sub
;
605 goto test_abz_extF80
;
607 true_abz_extF80M
= slow_extF80M_mul
;
608 subj_abz_extF80M
= qemu_extF80M_mul
;
609 goto test_abz_extF80
;
611 true_abz_extF80M
= slow_extF80M_div
;
612 subj_abz_extF80M
= qemu_extF80M_div
;
613 goto test_abz_extF80
;
615 true_abz_extF80M
= slow_extF80M_rem
;
616 subj_abz_extF80M
= qemu_extF80M_rem
;
618 test_abz_extF80(true_abz_extF80M
, subj_abz_extF80M
);
621 test_az_extF80(slow_extF80M_sqrt
, qemu_extF80M_sqrt
);
624 true_ab_extF80M_z_bool
= slow_extF80M_eq
;
625 subj_ab_extF80M_z_bool
= qemu_extF80M_eq
;
626 goto test_ab_extF80_z_bool
;
628 true_ab_extF80M_z_bool
= slow_extF80M_le
;
629 subj_ab_extF80M_z_bool
= qemu_extF80M_le
;
630 goto test_ab_extF80_z_bool
;
632 true_ab_extF80M_z_bool
= slow_extF80M_lt
;
633 subj_ab_extF80M_z_bool
= qemu_extF80M_lt
;
634 goto test_ab_extF80_z_bool
;
635 case EXTF80_EQ_SIGNALING
:
636 true_ab_extF80M_z_bool
= slow_extF80M_eq_signaling
;
637 subj_ab_extF80M_z_bool
= qemu_extF80M_eq_signaling
;
638 goto test_ab_extF80_z_bool
;
639 case EXTF80_LE_QUIET
:
640 true_ab_extF80M_z_bool
= slow_extF80M_le_quiet
;
641 subj_ab_extF80M_z_bool
= qemu_extF80M_le_quiet
;
642 goto test_ab_extF80_z_bool
;
643 case EXTF80_LT_QUIET
:
644 true_ab_extF80M_z_bool
= slow_extF80M_lt_quiet
;
645 subj_ab_extF80M_z_bool
= qemu_extF80M_lt_quiet
;
646 test_ab_extF80_z_bool
:
647 test_ab_extF80_z_bool(true_ab_extF80M_z_bool
, subj_ab_extF80M_z_bool
);
650 test_a_f128_z_ui32_rx(slow_f128M_to_ui32
, qemu_f128M_to_ui32
, rmode
,
654 test_a_f128_z_ui64_rx(slow_f128M_to_ui64
, qemu_f128M_to_ui64
, rmode
,
658 test_a_f128_z_i32_rx(slow_f128M_to_i32
, qemu_f128M_to_i32
, rmode
,
662 test_a_f128_z_i64_rx(slow_f128M_to_i64
, qemu_f128M_to_i64
, rmode
,
665 case F128_TO_UI32_R_MINMAG
:
666 test_a_f128_z_ui32_x(slow_f128M_to_ui32_r_minMag
,
667 qemu_f128M_to_ui32_r_minMag
, exact
);
669 case F128_TO_UI64_R_MINMAG
:
670 test_a_f128_z_ui64_x(slow_f128M_to_ui64_r_minMag
,
671 qemu_f128M_to_ui64_r_minMag
, exact
);
673 case F128_TO_I32_R_MINMAG
:
674 test_a_f128_z_i32_x(slow_f128M_to_i32_r_minMag
,
675 qemu_f128M_to_i32_r_minMag
, exact
);
677 case F128_TO_I64_R_MINMAG
:
678 test_a_f128_z_i64_x(slow_f128M_to_i64_r_minMag
,
679 qemu_f128M_to_i64_r_minMag
, exact
);
685 test_a_f128_z_f32(slow_f128M_to_f32
, qemu_f128M_to_f32
);
688 test_a_f128_z_f64(slow_f128M_to_f64
, qemu_f128M_to_f64
);
691 test_a_f128_z_extF80(slow_f128M_to_extF80M
, qemu_f128M_to_extF80M
);
693 case F128_ROUNDTOINT
:
694 test_az_f128_rx(slow_f128M_roundToInt
, qemu_f128M_roundToInt
, rmode
,
698 true_abz_f128M
= slow_f128M_add
;
699 subj_abz_f128M
= qemu_f128M_add
;
702 true_abz_f128M
= slow_f128M_sub
;
703 subj_abz_f128M
= qemu_f128M_sub
;
706 true_abz_f128M
= slow_f128M_mul
;
707 subj_abz_f128M
= qemu_f128M_mul
;
710 true_abz_f128M
= slow_f128M_div
;
711 subj_abz_f128M
= qemu_f128M_div
;
714 true_abz_f128M
= slow_f128M_rem
;
715 subj_abz_f128M
= qemu_f128M_rem
;
717 test_abz_f128(true_abz_f128M
, subj_abz_f128M
);
720 test_abcz_f128(slow_f128M_mulAdd
, qemu_f128M_mulAdd
);
723 test_az_f128(slow_f128M_sqrt
, qemu_f128M_sqrt
);
726 true_ab_f128M_z_bool
= slow_f128M_eq
;
727 subj_ab_f128M_z_bool
= qemu_f128M_eq
;
728 goto test_ab_f128_z_bool
;
730 true_ab_f128M_z_bool
= slow_f128M_le
;
731 subj_ab_f128M_z_bool
= qemu_f128M_le
;
732 goto test_ab_f128_z_bool
;
734 true_ab_f128M_z_bool
= slow_f128M_lt
;
735 subj_ab_f128M_z_bool
= qemu_f128M_lt
;
736 goto test_ab_f128_z_bool
;
737 case F128_EQ_SIGNALING
:
738 true_ab_f128M_z_bool
= slow_f128M_eq_signaling
;
739 subj_ab_f128M_z_bool
= qemu_f128M_eq_signaling
;
740 goto test_ab_f128_z_bool
;
742 true_ab_f128M_z_bool
= slow_f128M_le_quiet
;
743 subj_ab_f128M_z_bool
= qemu_f128M_le_quiet
;
744 goto test_ab_f128_z_bool
;
746 true_ab_f128M_z_bool
= slow_f128M_lt_quiet
;
747 subj_ab_f128M_z_bool
= qemu_f128M_lt_quiet
;
749 test_ab_f128_z_bool(true_ab_f128M_z_bool
, subj_ab_f128M_z_bool
);
752 if ((verCases_errorStop
&& verCases_anyErrors
)) {
753 verCases_exitWithStatus();
757 static unsigned int test_name_to_op(const char *arg
)
761 /* counting begins at 1 */
762 for (i
= 1; i
< NUM_FUNCTIONS
; i
++) {
763 const char *name
= functionInfos
[i
].namePtr
;
765 if (name
&& !strcmp(name
, arg
)) {
772 static unsigned int round_name_to_mode(const char *name
)
776 /* counting begins at 1 */
777 for (i
= 1; i
< NUM_ROUNDINGMODES
; i
++) {
778 if (!strcmp(round_mode_names
[i
], name
)) {
785 static int set_init_flags(const char *flags
)
789 for (p
= flags
; *p
!= '\0'; p
++) {
792 slow_init_flags
|= softfloat_flag_invalid
;
793 qemu_init_flags
|= float_flag_invalid
;
796 slow_init_flags
|= softfloat_flag_infinite
;
797 qemu_init_flags
|= float_flag_divbyzero
;
800 slow_init_flags
|= softfloat_flag_overflow
;
801 qemu_init_flags
|= float_flag_overflow
;
804 slow_init_flags
|= softfloat_flag_underflow
;
805 qemu_init_flags
|= float_flag_underflow
;
808 slow_init_flags
|= softfloat_flag_inexact
;
809 qemu_init_flags
|= float_flag_inexact
;
818 static uint_fast8_t slow_clear_flags(void)
820 uint8_t prev
= slowfloat_exceptionFlags
;
822 slowfloat_exceptionFlags
= slow_init_flags
;
826 static uint_fast8_t qemu_clear_flags(void)
828 uint8_t prev
= qemu_flags_to_sf(qsf
.float_exception_flags
);
830 qsf
.float_exception_flags
= qemu_init_flags
;
834 static void parse_args(int argc
, char *argv
[])
840 c
= getopt(argc
, argv
, "he:f:l:r:s");
846 usage_complete(argc
, argv
);
849 if (qemu_strtoui(optarg
, NULL
, 0, &n_max_errors
)) {
850 fprintf(stderr
, "fatal: invalid max error count\n");
855 if (set_init_flags(optarg
)) {
856 fprintf(stderr
, "fatal: flags must be a subset of 'vioux'\n");
861 if (qemu_strtoi(optarg
, NULL
, 0, &test_level
)) {
862 fprintf(stderr
, "fatal: invalid test level\n");
867 if (!strcmp(optarg
, "all")) {
870 test_round_mode
= round_name_to_mode(optarg
);
871 if (test_round_mode
== 0) {
872 fprintf(stderr
, "fatal: invalid rounding mode\n");
878 verCases_errorStop
= true;
881 /* invalid option or missing argument; getopt prints error info */
886 /* set rounding modes */
887 if (test_round_mode
== 0) {
888 /* test all rounding modes; note that counting begins at 1 */
889 n_round_modes
= NUM_ROUNDINGMODES
- 1;
890 round_modes
= g_malloc_n(n_round_modes
, sizeof(*round_modes
));
891 for (i
= 0; i
< n_round_modes
; i
++) {
892 round_modes
[i
] = i
+ 1;
896 round_modes
= g_malloc(sizeof(*round_modes
));
897 round_modes
[0] = test_round_mode
;
901 if (optind
== argc
) {
902 /* test all ops; note that counting begins at 1 */
903 n_test_ops
= NUM_FUNCTIONS
- 1;
904 test_ops
= g_malloc_n(n_test_ops
, sizeof(*test_ops
));
905 for (i
= 0; i
< n_test_ops
; i
++) {
909 n_test_ops
= argc
- optind
;
910 test_ops
= g_malloc_n(n_test_ops
, sizeof(*test_ops
));
911 for (i
= 0; i
< n_test_ops
; i
++) {
912 const char *name
= argv
[i
+ optind
];
913 unsigned int op
= test_name_to_op(name
);
916 fprintf(stderr
, "fatal: invalid op '%s'\n", name
);
924 static void QEMU_NORETURN
run_test(void)
928 genCases_setLevel(test_level
);
929 verCases_maxErrorCount
= n_max_errors
;
931 testLoops_trueFlagsFunction
= slow_clear_flags
;
932 testLoops_subjFlagsFunction
= qemu_clear_flags
;
934 for (i
= 0; i
< n_test_ops
; i
++) {
935 unsigned int op
= test_ops
[i
];
938 if (functionInfos
[op
].namePtr
== NULL
) {
941 verCases_functionNamePtr
= functionInfos
[op
].namePtr
;
943 for (j
= 0; j
< n_round_modes
; j
++) {
944 int attrs
= functionInfos
[op
].attribs
;
945 int round
= round_modes
[j
];
946 int rmode
= roundingModes
[round
];
949 verCases_roundingCode
= 0;
950 slowfloat_roundingMode
= rmode
;
951 qsf
.float_rounding_mode
= sf_rounding_to_qemu(rmode
);
953 if (attrs
& (FUNC_ARG_ROUNDINGMODE
| FUNC_EFF_ROUNDINGMODE
)) {
954 /* print rounding mode if the op is affected by it */
955 verCases_roundingCode
= round
;
957 /* if the op is not sensitive to rounding, move on */
961 /* QEMU doesn't have !exact */
962 verCases_exact
= true;
963 verCases_usesExact
= !!(attrs
& FUNC_ARG_EXACT
);
965 for (k
= 0; k
< 3; k
++) {
966 FloatX80RoundPrec qsf_prec80
= floatx80_precision_x
;
972 qsf_prec80
= floatx80_precision_d
;
975 qsf_prec80
= floatx80_precision_s
;
978 verCases_roundingPrecision
= 0;
979 slow_extF80_roundingPrecision
= prec80
;
980 qsf
.floatx80_rounding_precision
= qsf_prec80
;
982 if (attrs
& FUNC_EFF_ROUNDINGPRECISION
) {
983 verCases_roundingPrecision
= prec80
;
985 /* if the op is not sensitive to prec80, move on */
989 /* note: the count begins at 1 */
990 for (l
= 1; l
< NUM_TININESSMODES
; l
++) {
991 int tmode
= tininessModes
[l
];
993 verCases_tininessCode
= 0;
994 slowfloat_detectTininess
= tmode
;
995 qsf
.tininess_before_rounding
= sf_tininess_to_qemu(tmode
);
997 if (attrs
& FUNC_EFF_TININESSMODE
||
998 ((attrs
& FUNC_EFF_TININESSMODE_REDUCEDPREC
) &&
999 prec80
&& prec80
< 80)) {
1000 verCases_tininessCode
= l
;
1002 /* if the op is not sensitive to tininess, move on */
1006 do_testfloat(op
, rmode
, true);
1011 verCases_exitWithStatus();
1012 /* old compilers might miss that we exited */
1013 g_assert_not_reached();
1016 int main(int argc
, char *argv
[])
1018 parse_args(argc
, argv
);
1019 fail_programName
= argv
[0];
1020 run_test(); /* does not return */