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.inc.c"
121 static void not_implemented(void)
123 fprintf(stderr
, "Not implemented.\n");
126 static bool blacklisted(unsigned op
, int rmode
)
128 /* odd has only been implemented for a few 128-bit ops */
129 if (rmode
== softfloat_round_odd
) {
145 static void do_testfloat(int op
, int rmode
, bool exact
)
147 abz_f16 true_abz_f16
;
148 abz_f16 subj_abz_f16
;
149 ab_f16_z_bool true_f16_z_bool
;
150 ab_f16_z_bool subj_f16_z_bool
;
151 abz_f32 true_abz_f32
;
152 abz_f32 subj_abz_f32
;
153 ab_f32_z_bool true_ab_f32_z_bool
;
154 ab_f32_z_bool subj_ab_f32_z_bool
;
155 abz_f64 true_abz_f64
;
156 abz_f64 subj_abz_f64
;
157 ab_f64_z_bool true_ab_f64_z_bool
;
158 ab_f64_z_bool subj_ab_f64_z_bool
;
159 abz_extF80M true_abz_extF80M
;
160 abz_extF80M subj_abz_extF80M
;
161 ab_extF80M_z_bool true_ab_extF80M_z_bool
;
162 ab_extF80M_z_bool subj_ab_extF80M_z_bool
;
163 abz_f128M true_abz_f128M
;
164 abz_f128M subj_abz_f128M
;
165 ab_f128M_z_bool true_ab_f128M_z_bool
;
166 ab_f128M_z_bool subj_ab_f128M_z_bool
;
168 fputs(">> Testing ", stderr
);
169 verCases_writeFunctionName(stderr
);
172 if (blacklisted(op
, rmode
)) {
179 test_a_ui32_z_f16(slow_ui32_to_f16
, qemu_ui32_to_f16
);
182 test_a_ui32_z_f32(slow_ui32_to_f32
, qemu_ui32_to_f32
);
185 test_a_ui32_z_f64(slow_ui32_to_f64
, qemu_ui32_to_f64
);
194 test_a_ui64_z_f16(slow_ui64_to_f16
, qemu_ui64_to_f16
);
197 test_a_ui64_z_f32(slow_ui64_to_f32
, qemu_ui64_to_f32
);
200 test_a_ui64_z_f64(slow_ui64_to_f64
, qemu_ui64_to_f64
);
206 test_a_ui64_z_f128(slow_ui64_to_f128M
, qemu_ui64_to_f128M
);
209 test_a_i32_z_f16(slow_i32_to_f16
, qemu_i32_to_f16
);
212 test_a_i32_z_f32(slow_i32_to_f32
, qemu_i32_to_f32
);
215 test_a_i32_z_f64(slow_i32_to_f64
, qemu_i32_to_f64
);
218 test_a_i32_z_extF80(slow_i32_to_extF80M
, qemu_i32_to_extF80M
);
221 test_a_i32_z_f128(slow_i32_to_f128M
, qemu_i32_to_f128M
);
224 test_a_i64_z_f16(slow_i64_to_f16
, qemu_i64_to_f16
);
227 test_a_i64_z_f32(slow_i64_to_f32
, qemu_i64_to_f32
);
230 test_a_i64_z_f64(slow_i64_to_f64
, qemu_i64_to_f64
);
233 test_a_i64_z_extF80(slow_i64_to_extF80M
, qemu_i64_to_extF80M
);
236 test_a_i64_z_f128(slow_i64_to_f128M
, qemu_i64_to_f128M
);
239 test_a_f16_z_ui32_rx(slow_f16_to_ui32
, qemu_f16_to_ui32
, rmode
, exact
);
242 test_a_f16_z_ui64_rx(slow_f16_to_ui64
, qemu_f16_to_ui64
, rmode
, exact
);
245 test_a_f16_z_i32_rx(slow_f16_to_i32
, qemu_f16_to_i32
, rmode
, exact
);
248 test_a_f16_z_i64_rx(slow_f16_to_i64
, qemu_f16_to_i64
, rmode
, exact
);
250 case F16_TO_UI32_R_MINMAG
:
251 test_a_f16_z_ui32_x(slow_f16_to_ui32_r_minMag
,
252 qemu_f16_to_ui32_r_minMag
, exact
);
254 case F16_TO_UI64_R_MINMAG
:
255 test_a_f16_z_ui64_x(slow_f16_to_ui64_r_minMag
,
256 qemu_f16_to_ui64_r_minMag
, exact
);
258 case F16_TO_I32_R_MINMAG
:
259 test_a_f16_z_i32_x(slow_f16_to_i32_r_minMag
, qemu_f16_to_i32_r_minMag
,
262 case F16_TO_I64_R_MINMAG
:
263 test_a_f16_z_i64_x(slow_f16_to_i64_r_minMag
, qemu_f16_to_i64_r_minMag
,
267 test_a_f16_z_f32(slow_f16_to_f32
, qemu_f16_to_f32
);
270 test_a_f16_z_f64(slow_f16_to_f64
, qemu_f16_to_f64
);
279 test_az_f16_rx(slow_f16_roundToInt
, qemu_f16_roundToInt
, rmode
, exact
);
282 true_abz_f16
= slow_f16_add
;
283 subj_abz_f16
= qemu_f16_add
;
286 true_abz_f16
= slow_f16_sub
;
287 subj_abz_f16
= qemu_f16_sub
;
290 true_abz_f16
= slow_f16_mul
;
291 subj_abz_f16
= qemu_f16_mul
;
294 true_abz_f16
= slow_f16_div
;
295 subj_abz_f16
= qemu_f16_div
;
301 test_abz_f16(true_abz_f16
, subj_abz_f16
);
304 test_abcz_f16(slow_f16_mulAdd
, qemu_f16_mulAdd
);
307 test_az_f16(slow_f16_sqrt
, qemu_f16_sqrt
);
310 true_f16_z_bool
= slow_f16_eq
;
311 subj_f16_z_bool
= qemu_f16_eq
;
312 goto test_ab_f16_z_bool
;
314 true_f16_z_bool
= slow_f16_le
;
315 subj_f16_z_bool
= qemu_f16_le
;
316 goto test_ab_f16_z_bool
;
318 true_f16_z_bool
= slow_f16_lt
;
319 subj_f16_z_bool
= qemu_f16_lt
;
320 goto test_ab_f16_z_bool
;
321 case F16_EQ_SIGNALING
:
322 true_f16_z_bool
= slow_f16_eq_signaling
;
323 subj_f16_z_bool
= qemu_f16_eq_signaling
;
324 goto test_ab_f16_z_bool
;
326 true_f16_z_bool
= slow_f16_le_quiet
;
327 subj_f16_z_bool
= qemu_f16_le_quiet
;
328 goto test_ab_f16_z_bool
;
330 true_f16_z_bool
= slow_f16_lt_quiet
;
331 subj_f16_z_bool
= qemu_f16_lt_quiet
;
333 test_ab_f16_z_bool(true_f16_z_bool
, subj_f16_z_bool
);
336 test_a_f32_z_ui32_rx(slow_f32_to_ui32
, qemu_f32_to_ui32
, rmode
, exact
);
339 test_a_f32_z_ui64_rx(slow_f32_to_ui64
, qemu_f32_to_ui64
, rmode
, exact
);
342 test_a_f32_z_i32_rx(slow_f32_to_i32
, qemu_f32_to_i32
, rmode
, exact
);
345 test_a_f32_z_i64_rx(slow_f32_to_i64
, qemu_f32_to_i64
, rmode
, exact
);
347 case F32_TO_UI32_R_MINMAG
:
348 test_a_f32_z_ui32_x(slow_f32_to_ui32_r_minMag
,
349 qemu_f32_to_ui32_r_minMag
, exact
);
351 case F32_TO_UI64_R_MINMAG
:
352 test_a_f32_z_ui64_x(slow_f32_to_ui64_r_minMag
,
353 qemu_f32_to_ui64_r_minMag
, exact
);
355 case F32_TO_I32_R_MINMAG
:
356 test_a_f32_z_i32_x(slow_f32_to_i32_r_minMag
, qemu_f32_to_i32_r_minMag
,
359 case F32_TO_I64_R_MINMAG
:
360 test_a_f32_z_i64_x(slow_f32_to_i64_r_minMag
, qemu_f32_to_i64_r_minMag
,
364 test_a_f32_z_f16(slow_f32_to_f16
, qemu_f32_to_f16
);
367 test_a_f32_z_f64(slow_f32_to_f64
, qemu_f32_to_f64
);
370 test_a_f32_z_extF80(slow_f32_to_extF80M
, qemu_f32_to_extF80M
);
373 test_a_f32_z_f128(slow_f32_to_f128M
, qemu_f32_to_f128M
);
376 test_az_f32_rx(slow_f32_roundToInt
, qemu_f32_roundToInt
, rmode
, exact
);
379 true_abz_f32
= slow_f32_add
;
380 subj_abz_f32
= qemu_f32_add
;
383 true_abz_f32
= slow_f32_sub
;
384 subj_abz_f32
= qemu_f32_sub
;
387 true_abz_f32
= slow_f32_mul
;
388 subj_abz_f32
= qemu_f32_mul
;
391 true_abz_f32
= slow_f32_div
;
392 subj_abz_f32
= qemu_f32_div
;
395 true_abz_f32
= slow_f32_rem
;
396 subj_abz_f32
= qemu_f32_rem
;
398 test_abz_f32(true_abz_f32
, subj_abz_f32
);
401 test_abcz_f32(slow_f32_mulAdd
, qemu_f32_mulAdd
);
404 test_az_f32(slow_f32_sqrt
, qemu_f32_sqrt
);
407 true_ab_f32_z_bool
= slow_f32_eq
;
408 subj_ab_f32_z_bool
= qemu_f32_eq
;
409 goto test_ab_f32_z_bool
;
411 true_ab_f32_z_bool
= slow_f32_le
;
412 subj_ab_f32_z_bool
= qemu_f32_le
;
413 goto test_ab_f32_z_bool
;
415 true_ab_f32_z_bool
= slow_f32_lt
;
416 subj_ab_f32_z_bool
= qemu_f32_lt
;
417 goto test_ab_f32_z_bool
;
418 case F32_EQ_SIGNALING
:
419 true_ab_f32_z_bool
= slow_f32_eq_signaling
;
420 subj_ab_f32_z_bool
= qemu_f32_eq_signaling
;
421 goto test_ab_f32_z_bool
;
423 true_ab_f32_z_bool
= slow_f32_le_quiet
;
424 subj_ab_f32_z_bool
= qemu_f32_le_quiet
;
425 goto test_ab_f32_z_bool
;
427 true_ab_f32_z_bool
= slow_f32_lt_quiet
;
428 subj_ab_f32_z_bool
= qemu_f32_lt_quiet
;
430 test_ab_f32_z_bool(true_ab_f32_z_bool
, subj_ab_f32_z_bool
);
433 test_a_f64_z_ui32_rx(slow_f64_to_ui32
, qemu_f64_to_ui32
, rmode
, exact
);
436 test_a_f64_z_ui64_rx(slow_f64_to_ui64
, qemu_f64_to_ui64
, rmode
, exact
);
439 test_a_f64_z_i32_rx(slow_f64_to_i32
, qemu_f64_to_i32
, rmode
, exact
);
442 test_a_f64_z_i64_rx(slow_f64_to_i64
, qemu_f64_to_i64
, rmode
, exact
);
444 case F64_TO_UI32_R_MINMAG
:
445 test_a_f64_z_ui32_x(slow_f64_to_ui32_r_minMag
,
446 qemu_f64_to_ui32_r_minMag
, exact
);
448 case F64_TO_UI64_R_MINMAG
:
449 test_a_f64_z_ui64_x(slow_f64_to_ui64_r_minMag
,
450 qemu_f64_to_ui64_r_minMag
, exact
);
452 case F64_TO_I32_R_MINMAG
:
453 test_a_f64_z_i32_x(slow_f64_to_i32_r_minMag
, qemu_f64_to_i32_r_minMag
,
456 case F64_TO_I64_R_MINMAG
:
457 test_a_f64_z_i64_x(slow_f64_to_i64_r_minMag
, qemu_f64_to_i64_r_minMag
,
461 test_a_f64_z_f16(slow_f64_to_f16
, qemu_f64_to_f16
);
464 test_a_f64_z_f32(slow_f64_to_f32
, qemu_f64_to_f32
);
467 test_a_f64_z_extF80(slow_f64_to_extF80M
, qemu_f64_to_extF80M
);
470 test_a_f64_z_f128(slow_f64_to_f128M
, qemu_f64_to_f128M
);
473 test_az_f64_rx(slow_f64_roundToInt
, qemu_f64_roundToInt
, rmode
, exact
);
476 true_abz_f64
= slow_f64_add
;
477 subj_abz_f64
= qemu_f64_add
;
480 true_abz_f64
= slow_f64_sub
;
481 subj_abz_f64
= qemu_f64_sub
;
484 true_abz_f64
= slow_f64_mul
;
485 subj_abz_f64
= qemu_f64_mul
;
488 true_abz_f64
= slow_f64_div
;
489 subj_abz_f64
= qemu_f64_div
;
492 true_abz_f64
= slow_f64_rem
;
493 subj_abz_f64
= qemu_f64_rem
;
495 test_abz_f64(true_abz_f64
, subj_abz_f64
);
498 test_abcz_f64(slow_f64_mulAdd
, qemu_f64_mulAdd
);
501 test_az_f64(slow_f64_sqrt
, qemu_f64_sqrt
);
504 true_ab_f64_z_bool
= slow_f64_eq
;
505 subj_ab_f64_z_bool
= qemu_f64_eq
;
506 goto test_ab_f64_z_bool
;
508 true_ab_f64_z_bool
= slow_f64_le
;
509 subj_ab_f64_z_bool
= qemu_f64_le
;
510 goto test_ab_f64_z_bool
;
512 true_ab_f64_z_bool
= slow_f64_lt
;
513 subj_ab_f64_z_bool
= qemu_f64_lt
;
514 goto test_ab_f64_z_bool
;
515 case F64_EQ_SIGNALING
:
516 true_ab_f64_z_bool
= slow_f64_eq_signaling
;
517 subj_ab_f64_z_bool
= qemu_f64_eq_signaling
;
518 goto test_ab_f64_z_bool
;
520 true_ab_f64_z_bool
= slow_f64_le_quiet
;
521 subj_ab_f64_z_bool
= qemu_f64_le_quiet
;
522 goto test_ab_f64_z_bool
;
524 true_ab_f64_z_bool
= slow_f64_lt_quiet
;
525 subj_ab_f64_z_bool
= qemu_f64_lt_quiet
;
527 test_ab_f64_z_bool(true_ab_f64_z_bool
, subj_ab_f64_z_bool
);
536 test_a_extF80_z_i32_rx(slow_extF80M_to_i32
, qemu_extF80M_to_i32
, rmode
,
540 test_a_extF80_z_i64_rx(slow_extF80M_to_i64
, qemu_extF80M_to_i64
, rmode
,
543 case EXTF80_TO_UI32_R_MINMAG
:
546 case EXTF80_TO_UI64_R_MINMAG
:
549 case EXTF80_TO_I32_R_MINMAG
:
550 test_a_extF80_z_i32_x(slow_extF80M_to_i32_r_minMag
,
551 qemu_extF80M_to_i32_r_minMag
, exact
);
553 case EXTF80_TO_I64_R_MINMAG
:
554 test_a_extF80_z_i64_x(slow_extF80M_to_i64_r_minMag
,
555 qemu_extF80M_to_i64_r_minMag
, exact
);
561 test_a_extF80_z_f32(slow_extF80M_to_f32
, qemu_extF80M_to_f32
);
564 test_a_extF80_z_f64(slow_extF80M_to_f64
, qemu_extF80M_to_f64
);
567 test_a_extF80_z_f128(slow_extF80M_to_f128M
, qemu_extF80M_to_f128M
);
569 case EXTF80_ROUNDTOINT
:
570 test_az_extF80_rx(slow_extF80M_roundToInt
, qemu_extF80M_roundToInt
,
574 true_abz_extF80M
= slow_extF80M_add
;
575 subj_abz_extF80M
= qemu_extF80M_add
;
576 goto test_abz_extF80
;
578 true_abz_extF80M
= slow_extF80M_sub
;
579 subj_abz_extF80M
= qemu_extF80M_sub
;
580 goto test_abz_extF80
;
582 true_abz_extF80M
= slow_extF80M_mul
;
583 subj_abz_extF80M
= qemu_extF80M_mul
;
584 goto test_abz_extF80
;
586 true_abz_extF80M
= slow_extF80M_div
;
587 subj_abz_extF80M
= qemu_extF80M_div
;
588 goto test_abz_extF80
;
590 true_abz_extF80M
= slow_extF80M_rem
;
591 subj_abz_extF80M
= qemu_extF80M_rem
;
593 test_abz_extF80(true_abz_extF80M
, subj_abz_extF80M
);
596 test_az_extF80(slow_extF80M_sqrt
, qemu_extF80M_sqrt
);
599 true_ab_extF80M_z_bool
= slow_extF80M_eq
;
600 subj_ab_extF80M_z_bool
= qemu_extF80M_eq
;
601 goto test_ab_extF80_z_bool
;
603 true_ab_extF80M_z_bool
= slow_extF80M_le
;
604 subj_ab_extF80M_z_bool
= qemu_extF80M_le
;
605 goto test_ab_extF80_z_bool
;
607 true_ab_extF80M_z_bool
= slow_extF80M_lt
;
608 subj_ab_extF80M_z_bool
= qemu_extF80M_lt
;
609 goto test_ab_extF80_z_bool
;
610 case EXTF80_EQ_SIGNALING
:
611 true_ab_extF80M_z_bool
= slow_extF80M_eq_signaling
;
612 subj_ab_extF80M_z_bool
= qemu_extF80M_eq_signaling
;
613 goto test_ab_extF80_z_bool
;
614 case EXTF80_LE_QUIET
:
615 true_ab_extF80M_z_bool
= slow_extF80M_le_quiet
;
616 subj_ab_extF80M_z_bool
= qemu_extF80M_le_quiet
;
617 goto test_ab_extF80_z_bool
;
618 case EXTF80_LT_QUIET
:
619 true_ab_extF80M_z_bool
= slow_extF80M_lt_quiet
;
620 subj_ab_extF80M_z_bool
= qemu_extF80M_lt_quiet
;
621 test_ab_extF80_z_bool
:
622 test_ab_extF80_z_bool(true_ab_extF80M_z_bool
, subj_ab_extF80M_z_bool
);
628 test_a_f128_z_ui64_rx(slow_f128M_to_ui64
, qemu_f128M_to_ui64
, rmode
,
632 test_a_f128_z_i32_rx(slow_f128M_to_i32
, qemu_f128M_to_i32
, rmode
,
636 test_a_f128_z_i64_rx(slow_f128M_to_i64
, qemu_f128M_to_i64
, rmode
,
639 case F128_TO_UI32_R_MINMAG
:
640 test_a_f128_z_ui32_x(slow_f128M_to_ui32_r_minMag
,
641 qemu_f128M_to_ui32_r_minMag
, exact
);
643 case F128_TO_UI64_R_MINMAG
:
644 test_a_f128_z_ui64_x(slow_f128M_to_ui64_r_minMag
,
645 qemu_f128M_to_ui64_r_minMag
, exact
);
647 case F128_TO_I32_R_MINMAG
:
648 test_a_f128_z_i32_x(slow_f128M_to_i32_r_minMag
,
649 qemu_f128M_to_i32_r_minMag
, exact
);
651 case F128_TO_I64_R_MINMAG
:
652 test_a_f128_z_i64_x(slow_f128M_to_i64_r_minMag
,
653 qemu_f128M_to_i64_r_minMag
, exact
);
659 test_a_f128_z_f32(slow_f128M_to_f32
, qemu_f128M_to_f32
);
662 test_a_f128_z_f64(slow_f128M_to_f64
, qemu_f128M_to_f64
);
665 test_a_f128_z_extF80(slow_f128M_to_extF80M
, qemu_f128M_to_extF80M
);
667 case F128_ROUNDTOINT
:
668 test_az_f128_rx(slow_f128M_roundToInt
, qemu_f128M_roundToInt
, rmode
,
672 true_abz_f128M
= slow_f128M_add
;
673 subj_abz_f128M
= qemu_f128M_add
;
676 true_abz_f128M
= slow_f128M_sub
;
677 subj_abz_f128M
= qemu_f128M_sub
;
680 true_abz_f128M
= slow_f128M_mul
;
681 subj_abz_f128M
= qemu_f128M_mul
;
684 true_abz_f128M
= slow_f128M_div
;
685 subj_abz_f128M
= qemu_f128M_div
;
688 true_abz_f128M
= slow_f128M_rem
;
689 subj_abz_f128M
= qemu_f128M_rem
;
691 test_abz_f128(true_abz_f128M
, subj_abz_f128M
);
697 test_az_f128(slow_f128M_sqrt
, qemu_f128M_sqrt
);
700 true_ab_f128M_z_bool
= slow_f128M_eq
;
701 subj_ab_f128M_z_bool
= qemu_f128M_eq
;
702 goto test_ab_f128_z_bool
;
704 true_ab_f128M_z_bool
= slow_f128M_le
;
705 subj_ab_f128M_z_bool
= qemu_f128M_le
;
706 goto test_ab_f128_z_bool
;
708 true_ab_f128M_z_bool
= slow_f128M_lt
;
709 subj_ab_f128M_z_bool
= qemu_f128M_lt
;
710 goto test_ab_f128_z_bool
;
711 case F128_EQ_SIGNALING
:
712 true_ab_f128M_z_bool
= slow_f128M_eq_signaling
;
713 subj_ab_f128M_z_bool
= qemu_f128M_eq_signaling
;
714 goto test_ab_f128_z_bool
;
716 true_ab_f128M_z_bool
= slow_f128M_le_quiet
;
717 subj_ab_f128M_z_bool
= qemu_f128M_le_quiet
;
718 goto test_ab_f128_z_bool
;
720 true_ab_f128M_z_bool
= slow_f128M_lt_quiet
;
721 subj_ab_f128M_z_bool
= qemu_f128M_lt_quiet
;
723 test_ab_f128_z_bool(true_ab_f128M_z_bool
, subj_ab_f128M_z_bool
);
726 if ((verCases_errorStop
&& verCases_anyErrors
)) {
727 verCases_exitWithStatus();
731 static unsigned int test_name_to_op(const char *arg
)
735 /* counting begins at 1 */
736 for (i
= 1; i
< NUM_FUNCTIONS
; i
++) {
737 const char *name
= functionInfos
[i
].namePtr
;
739 if (name
&& !strcmp(name
, arg
)) {
746 static unsigned int round_name_to_mode(const char *name
)
750 /* counting begins at 1 */
751 for (i
= 1; i
< NUM_ROUNDINGMODES
; i
++) {
752 if (!strcmp(round_mode_names
[i
], name
)) {
759 static int set_init_flags(const char *flags
)
763 for (p
= flags
; *p
!= '\0'; p
++) {
766 slow_init_flags
|= softfloat_flag_invalid
;
767 qemu_init_flags
|= float_flag_invalid
;
770 slow_init_flags
|= softfloat_flag_infinite
;
771 qemu_init_flags
|= float_flag_divbyzero
;
774 slow_init_flags
|= softfloat_flag_overflow
;
775 qemu_init_flags
|= float_flag_overflow
;
778 slow_init_flags
|= softfloat_flag_underflow
;
779 qemu_init_flags
|= float_flag_underflow
;
782 slow_init_flags
|= softfloat_flag_inexact
;
783 qemu_init_flags
|= float_flag_inexact
;
792 static uint8_t slow_clear_flags(void)
794 uint8_t prev
= slowfloat_exceptionFlags
;
796 slowfloat_exceptionFlags
= slow_init_flags
;
800 static uint8_t qemu_clear_flags(void)
802 uint8_t prev
= qemu_flags_to_sf(qsf
.float_exception_flags
);
804 qsf
.float_exception_flags
= qemu_init_flags
;
808 static void parse_args(int argc
, char *argv
[])
814 c
= getopt(argc
, argv
, "he:f:l:r:s");
820 usage_complete(argc
, argv
);
823 if (qemu_strtoui(optarg
, NULL
, 0, &n_max_errors
)) {
824 fprintf(stderr
, "fatal: invalid max error count\n");
829 if (set_init_flags(optarg
)) {
830 fprintf(stderr
, "fatal: flags must be a subset of 'vioux'\n");
835 if (qemu_strtoi(optarg
, NULL
, 0, &test_level
)) {
836 fprintf(stderr
, "fatal: invalid test level\n");
841 if (!strcmp(optarg
, "all")) {
844 test_round_mode
= round_name_to_mode(optarg
);
845 if (test_round_mode
== 0) {
846 fprintf(stderr
, "fatal: invalid rounding mode\n");
852 verCases_errorStop
= true;
855 /* invalid option or missing argument; getopt prints error info */
860 /* set rounding modes */
861 if (test_round_mode
== 0) {
862 /* test all rounding modes; note that counting begins at 1 */
863 n_round_modes
= NUM_ROUNDINGMODES
- 1;
864 round_modes
= g_malloc_n(n_round_modes
, sizeof(*round_modes
));
865 for (i
= 0; i
< n_round_modes
; i
++) {
866 round_modes
[i
] = i
+ 1;
870 round_modes
= g_malloc(sizeof(*round_modes
));
871 round_modes
[0] = test_round_mode
;
875 if (optind
== argc
) {
876 /* test all ops; note that counting begins at 1 */
877 n_test_ops
= NUM_FUNCTIONS
- 1;
878 test_ops
= g_malloc_n(n_test_ops
, sizeof(*test_ops
));
879 for (i
= 0; i
< n_test_ops
; i
++) {
883 n_test_ops
= argc
- optind
;
884 test_ops
= g_malloc_n(n_test_ops
, sizeof(*test_ops
));
885 for (i
= 0; i
< n_test_ops
; i
++) {
886 const char *name
= argv
[i
+ optind
];
887 unsigned int op
= test_name_to_op(name
);
890 fprintf(stderr
, "fatal: invalid op '%s'\n", name
);
898 static void QEMU_NORETURN
run_test(void)
902 genCases_setLevel(test_level
);
903 verCases_maxErrorCount
= n_max_errors
;
905 testLoops_trueFlagsFunction
= slow_clear_flags
;
906 testLoops_subjFlagsFunction
= qemu_clear_flags
;
908 for (i
= 0; i
< n_test_ops
; i
++) {
909 unsigned int op
= test_ops
[i
];
912 if (functionInfos
[op
].namePtr
== NULL
) {
915 verCases_functionNamePtr
= functionInfos
[op
].namePtr
;
917 for (j
= 0; j
< n_round_modes
; j
++) {
918 int attrs
= functionInfos
[op
].attribs
;
919 int round
= round_modes
[j
];
920 int rmode
= roundingModes
[round
];
923 verCases_roundingCode
= 0;
924 slowfloat_roundingMode
= rmode
;
925 qsf
.float_rounding_mode
= sf_rounding_to_qemu(rmode
);
927 if (attrs
& (FUNC_ARG_ROUNDINGMODE
| FUNC_EFF_ROUNDINGMODE
)) {
928 /* print rounding mode if the op is affected by it */
929 verCases_roundingCode
= round
;
931 /* if the op is not sensitive to rounding, move on */
935 /* QEMU doesn't have !exact */
936 verCases_exact
= true;
937 verCases_usesExact
= !!(attrs
& FUNC_ARG_EXACT
);
939 for (k
= 0; k
< 3; k
++) {
949 verCases_roundingPrecision
= 0;
950 slow_extF80_roundingPrecision
= prec80
;
951 qsf
.floatx80_rounding_precision
= prec80
;
953 if (attrs
& FUNC_EFF_ROUNDINGPRECISION
) {
954 verCases_roundingPrecision
= prec80
;
956 /* if the op is not sensitive to prec80, move on */
960 /* note: the count begins at 1 */
961 for (l
= 1; l
< NUM_TININESSMODES
; l
++) {
962 int tmode
= tininessModes
[l
];
964 verCases_tininessCode
= 0;
965 slowfloat_detectTininess
= tmode
;
966 qsf
.float_detect_tininess
= sf_tininess_to_qemu(tmode
);
968 if (attrs
& FUNC_EFF_TININESSMODE
||
969 ((attrs
& FUNC_EFF_TININESSMODE_REDUCEDPREC
) &&
970 prec80
&& prec80
< 80)) {
971 verCases_tininessCode
= l
;
973 /* if the op is not sensitive to tininess, move on */
977 do_testfloat(op
, rmode
, true);
982 verCases_exitWithStatus();
983 /* old compilers might miss that we exited */
984 g_assert_not_reached();
987 int main(int argc
, char *argv
[])
989 parse_args(argc
, argv
);
990 fail_programName
= argv
[0];
991 run_test(); /* does not return */