1 /* 2 * fp-test.c - test QEMU's softfloat implementation using Berkeley's Testfloat 3 * 4 * Copyright (C) 2018, Emilio G. Cota <cota@braap.org> 5 * 6 * License: GNU GPL, version 2 or later. 7 * See the COPYING file in the top-level directory. 8 * 9 * This file is derived from testfloat/source/testsoftfloat.c. Its copyright 10 * info follows: 11 * 12 * Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the 13 * University of California. All rights reserved. 14 * 15 * Redistribution and use in source and binary forms, with or without 16 * modification, are permitted provided that the following conditions are met: 17 * 18 * 1. Redistributions of source code must retain the above copyright notice, 19 * this list of conditions, and the following disclaimer. 20 * 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. 24 * 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. 28 * 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. 39 */ 40 #ifndef HW_POISON_H 41 #error Must define HW_POISON_H to work around TARGET_* poisoning 42 #endif 43 44 #include "qemu/osdep.h" 45 #include "qemu/cutils.h" 46 #include <math.h> 47 #include "fpu/softfloat.h" 48 #include "platform.h" 49 50 #include "fail.h" 51 #include "slowfloat.h" 52 #include "functions.h" 53 #include "genCases.h" 54 #include "verCases.h" 55 #include "writeCase.h" 56 #include "testLoops.h" 57 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 *, 65 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 *); 69 70 static const char * const round_mode_names[] = { 71 [ROUND_NEAR_EVEN] = "even", 72 [ROUND_MINMAG] = "zero", 73 [ROUND_MIN] = "down", 74 [ROUND_MAX] = "up", 75 [ROUND_NEAR_MAXMAG] = "tieaway", 76 [ROUND_ODD] = "odd", 77 }; 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; 87 88 /* qemu softfloat status */ 89 static float_status qsf; 90 91 static const char commands_string[] = 92 "operations:\n" 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" 99 " <float>_sqrt\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" 103 "options:\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"; 110 111 static void usage_complete(int argc, char *argv[]) 112 { 113 fprintf(stderr, "Usage: %s [options] [operation1 ...]\n", argv[0]); 114 fprintf(stderr, "%s\n", commands_string); 115 exit(EXIT_FAILURE); 116 } 117 118 /* keep wrappers separate but do not bother defining headers for all of them */ 119 #include "wrap.inc.c" 120 121 static void not_implemented(void) 122 { 123 fprintf(stderr, "Not implemented.\n"); 124 } 125 126 static bool blacklisted(unsigned op, int rmode) 127 { 128 /* odd has only been implemented for a few 128-bit ops */ 129 if (rmode == softfloat_round_odd) { 130 switch (op) { 131 case F128_ADD: 132 case F128_SUB: 133 case F128_MUL: 134 case F128_DIV: 135 case F128_TO_F64: 136 case F128_SQRT: 137 return false; 138 default: 139 return true; 140 } 141 } 142 return false; 143 } 144 145 static void do_testfloat(int op, int rmode, bool exact) 146 { 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; 167 168 fputs(">> Testing ", stderr); 169 verCases_writeFunctionName(stderr); 170 fputs("\n", stderr); 171 172 if (blacklisted(op, rmode)) { 173 not_implemented(); 174 return; 175 } 176 177 switch (op) { 178 case UI32_TO_F16: 179 test_a_ui32_z_f16(slow_ui32_to_f16, qemu_ui32_to_f16); 180 break; 181 case UI32_TO_F32: 182 test_a_ui32_z_f32(slow_ui32_to_f32, qemu_ui32_to_f32); 183 break; 184 case UI32_TO_F64: 185 test_a_ui32_z_f64(slow_ui32_to_f64, qemu_ui32_to_f64); 186 break; 187 case UI32_TO_EXTF80: 188 not_implemented(); 189 break; 190 case UI32_TO_F128: 191 not_implemented(); 192 break; 193 case UI64_TO_F16: 194 test_a_ui64_z_f16(slow_ui64_to_f16, qemu_ui64_to_f16); 195 break; 196 case UI64_TO_F32: 197 test_a_ui64_z_f32(slow_ui64_to_f32, qemu_ui64_to_f32); 198 break; 199 case UI64_TO_F64: 200 test_a_ui64_z_f64(slow_ui64_to_f64, qemu_ui64_to_f64); 201 break; 202 case UI64_TO_EXTF80: 203 not_implemented(); 204 break; 205 case UI64_TO_F128: 206 test_a_ui64_z_f128(slow_ui64_to_f128M, qemu_ui64_to_f128M); 207 break; 208 case I32_TO_F16: 209 test_a_i32_z_f16(slow_i32_to_f16, qemu_i32_to_f16); 210 break; 211 case I32_TO_F32: 212 test_a_i32_z_f32(slow_i32_to_f32, qemu_i32_to_f32); 213 break; 214 case I32_TO_F64: 215 test_a_i32_z_f64(slow_i32_to_f64, qemu_i32_to_f64); 216 break; 217 case I32_TO_EXTF80: 218 test_a_i32_z_extF80(slow_i32_to_extF80M, qemu_i32_to_extF80M); 219 break; 220 case I32_TO_F128: 221 test_a_i32_z_f128(slow_i32_to_f128M, qemu_i32_to_f128M); 222 break; 223 case I64_TO_F16: 224 test_a_i64_z_f16(slow_i64_to_f16, qemu_i64_to_f16); 225 break; 226 case I64_TO_F32: 227 test_a_i64_z_f32(slow_i64_to_f32, qemu_i64_to_f32); 228 break; 229 case I64_TO_F64: 230 test_a_i64_z_f64(slow_i64_to_f64, qemu_i64_to_f64); 231 break; 232 case I64_TO_EXTF80: 233 test_a_i64_z_extF80(slow_i64_to_extF80M, qemu_i64_to_extF80M); 234 break; 235 case I64_TO_F128: 236 test_a_i64_z_f128(slow_i64_to_f128M, qemu_i64_to_f128M); 237 break; 238 case F16_TO_UI32: 239 test_a_f16_z_ui32_rx(slow_f16_to_ui32, qemu_f16_to_ui32, rmode, exact); 240 break; 241 case F16_TO_UI64: 242 test_a_f16_z_ui64_rx(slow_f16_to_ui64, qemu_f16_to_ui64, rmode, exact); 243 break; 244 case F16_TO_I32: 245 test_a_f16_z_i32_rx(slow_f16_to_i32, qemu_f16_to_i32, rmode, exact); 246 break; 247 case F16_TO_I64: 248 test_a_f16_z_i64_rx(slow_f16_to_i64, qemu_f16_to_i64, rmode, exact); 249 break; 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); 253 break; 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); 257 break; 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, 260 exact); 261 break; 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, 264 exact); 265 break; 266 case F16_TO_F32: 267 test_a_f16_z_f32(slow_f16_to_f32, qemu_f16_to_f32); 268 break; 269 case F16_TO_F64: 270 test_a_f16_z_f64(slow_f16_to_f64, qemu_f16_to_f64); 271 break; 272 case F16_TO_EXTF80: 273 not_implemented(); 274 break; 275 case F16_TO_F128: 276 not_implemented(); 277 break; 278 case F16_ROUNDTOINT: 279 test_az_f16_rx(slow_f16_roundToInt, qemu_f16_roundToInt, rmode, exact); 280 break; 281 case F16_ADD: 282 true_abz_f16 = slow_f16_add; 283 subj_abz_f16 = qemu_f16_add; 284 goto test_abz_f16; 285 case F16_SUB: 286 true_abz_f16 = slow_f16_sub; 287 subj_abz_f16 = qemu_f16_sub; 288 goto test_abz_f16; 289 case F16_MUL: 290 true_abz_f16 = slow_f16_mul; 291 subj_abz_f16 = qemu_f16_mul; 292 goto test_abz_f16; 293 case F16_DIV: 294 true_abz_f16 = slow_f16_div; 295 subj_abz_f16 = qemu_f16_div; 296 goto test_abz_f16; 297 case F16_REM: 298 not_implemented(); 299 break; 300 test_abz_f16: 301 test_abz_f16(true_abz_f16, subj_abz_f16); 302 break; 303 case F16_MULADD: 304 test_abcz_f16(slow_f16_mulAdd, qemu_f16_mulAdd); 305 break; 306 case F16_SQRT: 307 test_az_f16(slow_f16_sqrt, qemu_f16_sqrt); 308 break; 309 case F16_EQ: 310 true_f16_z_bool = slow_f16_eq; 311 subj_f16_z_bool = qemu_f16_eq; 312 goto test_ab_f16_z_bool; 313 case F16_LE: 314 true_f16_z_bool = slow_f16_le; 315 subj_f16_z_bool = qemu_f16_le; 316 goto test_ab_f16_z_bool; 317 case F16_LT: 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; 325 case F16_LE_QUIET: 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; 329 case F16_LT_QUIET: 330 true_f16_z_bool = slow_f16_lt_quiet; 331 subj_f16_z_bool = qemu_f16_lt_quiet; 332 test_ab_f16_z_bool: 333 test_ab_f16_z_bool(true_f16_z_bool, subj_f16_z_bool); 334 break; 335 case F32_TO_UI32: 336 test_a_f32_z_ui32_rx(slow_f32_to_ui32, qemu_f32_to_ui32, rmode, exact); 337 break; 338 case F32_TO_UI64: 339 test_a_f32_z_ui64_rx(slow_f32_to_ui64, qemu_f32_to_ui64, rmode, exact); 340 break; 341 case F32_TO_I32: 342 test_a_f32_z_i32_rx(slow_f32_to_i32, qemu_f32_to_i32, rmode, exact); 343 break; 344 case F32_TO_I64: 345 test_a_f32_z_i64_rx(slow_f32_to_i64, qemu_f32_to_i64, rmode, exact); 346 break; 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); 350 break; 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); 354 break; 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, 357 exact); 358 break; 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, 361 exact); 362 break; 363 case F32_TO_F16: 364 test_a_f32_z_f16(slow_f32_to_f16, qemu_f32_to_f16); 365 break; 366 case F32_TO_F64: 367 test_a_f32_z_f64(slow_f32_to_f64, qemu_f32_to_f64); 368 break; 369 case F32_TO_EXTF80: 370 test_a_f32_z_extF80(slow_f32_to_extF80M, qemu_f32_to_extF80M); 371 break; 372 case F32_TO_F128: 373 test_a_f32_z_f128(slow_f32_to_f128M, qemu_f32_to_f128M); 374 break; 375 case F32_ROUNDTOINT: 376 test_az_f32_rx(slow_f32_roundToInt, qemu_f32_roundToInt, rmode, exact); 377 break; 378 case F32_ADD: 379 true_abz_f32 = slow_f32_add; 380 subj_abz_f32 = qemu_f32_add; 381 goto test_abz_f32; 382 case F32_SUB: 383 true_abz_f32 = slow_f32_sub; 384 subj_abz_f32 = qemu_f32_sub; 385 goto test_abz_f32; 386 case F32_MUL: 387 true_abz_f32 = slow_f32_mul; 388 subj_abz_f32 = qemu_f32_mul; 389 goto test_abz_f32; 390 case F32_DIV: 391 true_abz_f32 = slow_f32_div; 392 subj_abz_f32 = qemu_f32_div; 393 goto test_abz_f32; 394 case F32_REM: 395 true_abz_f32 = slow_f32_rem; 396 subj_abz_f32 = qemu_f32_rem; 397 test_abz_f32: 398 test_abz_f32(true_abz_f32, subj_abz_f32); 399 break; 400 case F32_MULADD: 401 test_abcz_f32(slow_f32_mulAdd, qemu_f32_mulAdd); 402 break; 403 case F32_SQRT: 404 test_az_f32(slow_f32_sqrt, qemu_f32_sqrt); 405 break; 406 case F32_EQ: 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; 410 case F32_LE: 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; 414 case F32_LT: 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; 422 case F32_LE_QUIET: 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; 426 case F32_LT_QUIET: 427 true_ab_f32_z_bool = slow_f32_lt_quiet; 428 subj_ab_f32_z_bool = qemu_f32_lt_quiet; 429 test_ab_f32_z_bool: 430 test_ab_f32_z_bool(true_ab_f32_z_bool, subj_ab_f32_z_bool); 431 break; 432 case F64_TO_UI32: 433 test_a_f64_z_ui32_rx(slow_f64_to_ui32, qemu_f64_to_ui32, rmode, exact); 434 break; 435 case F64_TO_UI64: 436 test_a_f64_z_ui64_rx(slow_f64_to_ui64, qemu_f64_to_ui64, rmode, exact); 437 break; 438 case F64_TO_I32: 439 test_a_f64_z_i32_rx(slow_f64_to_i32, qemu_f64_to_i32, rmode, exact); 440 break; 441 case F64_TO_I64: 442 test_a_f64_z_i64_rx(slow_f64_to_i64, qemu_f64_to_i64, rmode, exact); 443 break; 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); 447 break; 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); 451 break; 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, 454 exact); 455 break; 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, 458 exact); 459 break; 460 case F64_TO_F16: 461 test_a_f64_z_f16(slow_f64_to_f16, qemu_f64_to_f16); 462 break; 463 case F64_TO_F32: 464 test_a_f64_z_f32(slow_f64_to_f32, qemu_f64_to_f32); 465 break; 466 case F64_TO_EXTF80: 467 test_a_f64_z_extF80(slow_f64_to_extF80M, qemu_f64_to_extF80M); 468 break; 469 case F64_TO_F128: 470 test_a_f64_z_f128(slow_f64_to_f128M, qemu_f64_to_f128M); 471 break; 472 case F64_ROUNDTOINT: 473 test_az_f64_rx(slow_f64_roundToInt, qemu_f64_roundToInt, rmode, exact); 474 break; 475 case F64_ADD: 476 true_abz_f64 = slow_f64_add; 477 subj_abz_f64 = qemu_f64_add; 478 goto test_abz_f64; 479 case F64_SUB: 480 true_abz_f64 = slow_f64_sub; 481 subj_abz_f64 = qemu_f64_sub; 482 goto test_abz_f64; 483 case F64_MUL: 484 true_abz_f64 = slow_f64_mul; 485 subj_abz_f64 = qemu_f64_mul; 486 goto test_abz_f64; 487 case F64_DIV: 488 true_abz_f64 = slow_f64_div; 489 subj_abz_f64 = qemu_f64_div; 490 goto test_abz_f64; 491 case F64_REM: 492 true_abz_f64 = slow_f64_rem; 493 subj_abz_f64 = qemu_f64_rem; 494 test_abz_f64: 495 test_abz_f64(true_abz_f64, subj_abz_f64); 496 break; 497 case F64_MULADD: 498 test_abcz_f64(slow_f64_mulAdd, qemu_f64_mulAdd); 499 break; 500 case F64_SQRT: 501 test_az_f64(slow_f64_sqrt, qemu_f64_sqrt); 502 break; 503 case F64_EQ: 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; 507 case F64_LE: 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; 511 case F64_LT: 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; 519 case F64_LE_QUIET: 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; 523 case F64_LT_QUIET: 524 true_ab_f64_z_bool = slow_f64_lt_quiet; 525 subj_ab_f64_z_bool = qemu_f64_lt_quiet; 526 test_ab_f64_z_bool: 527 test_ab_f64_z_bool(true_ab_f64_z_bool, subj_ab_f64_z_bool); 528 break; 529 case EXTF80_TO_UI32: 530 not_implemented(); 531 break; 532 case EXTF80_TO_UI64: 533 not_implemented(); 534 break; 535 case EXTF80_TO_I32: 536 test_a_extF80_z_i32_rx(slow_extF80M_to_i32, qemu_extF80M_to_i32, rmode, 537 exact); 538 break; 539 case EXTF80_TO_I64: 540 test_a_extF80_z_i64_rx(slow_extF80M_to_i64, qemu_extF80M_to_i64, rmode, 541 exact); 542 break; 543 case EXTF80_TO_UI32_R_MINMAG: 544 not_implemented(); 545 break; 546 case EXTF80_TO_UI64_R_MINMAG: 547 not_implemented(); 548 break; 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); 552 break; 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); 556 break; 557 case EXTF80_TO_F16: 558 not_implemented(); 559 break; 560 case EXTF80_TO_F32: 561 test_a_extF80_z_f32(slow_extF80M_to_f32, qemu_extF80M_to_f32); 562 break; 563 case EXTF80_TO_F64: 564 test_a_extF80_z_f64(slow_extF80M_to_f64, qemu_extF80M_to_f64); 565 break; 566 case EXTF80_TO_F128: 567 test_a_extF80_z_f128(slow_extF80M_to_f128M, qemu_extF80M_to_f128M); 568 break; 569 case EXTF80_ROUNDTOINT: 570 test_az_extF80_rx(slow_extF80M_roundToInt, qemu_extF80M_roundToInt, 571 rmode, exact); 572 break; 573 case EXTF80_ADD: 574 true_abz_extF80M = slow_extF80M_add; 575 subj_abz_extF80M = qemu_extF80M_add; 576 goto test_abz_extF80; 577 case EXTF80_SUB: 578 true_abz_extF80M = slow_extF80M_sub; 579 subj_abz_extF80M = qemu_extF80M_sub; 580 goto test_abz_extF80; 581 case EXTF80_MUL: 582 true_abz_extF80M = slow_extF80M_mul; 583 subj_abz_extF80M = qemu_extF80M_mul; 584 goto test_abz_extF80; 585 case EXTF80_DIV: 586 true_abz_extF80M = slow_extF80M_div; 587 subj_abz_extF80M = qemu_extF80M_div; 588 goto test_abz_extF80; 589 case EXTF80_REM: 590 true_abz_extF80M = slow_extF80M_rem; 591 subj_abz_extF80M = qemu_extF80M_rem; 592 test_abz_extF80: 593 test_abz_extF80(true_abz_extF80M, subj_abz_extF80M); 594 break; 595 case EXTF80_SQRT: 596 test_az_extF80(slow_extF80M_sqrt, qemu_extF80M_sqrt); 597 break; 598 case EXTF80_EQ: 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; 602 case EXTF80_LE: 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; 606 case EXTF80_LT: 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); 623 break; 624 case F128_TO_UI32: 625 not_implemented(); 626 break; 627 case F128_TO_UI64: 628 test_a_f128_z_ui64_rx(slow_f128M_to_ui64, qemu_f128M_to_ui64, rmode, 629 exact); 630 break; 631 case F128_TO_I32: 632 test_a_f128_z_i32_rx(slow_f128M_to_i32, qemu_f128M_to_i32, rmode, 633 exact); 634 break; 635 case F128_TO_I64: 636 test_a_f128_z_i64_rx(slow_f128M_to_i64, qemu_f128M_to_i64, rmode, 637 exact); 638 break; 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); 642 break; 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); 646 break; 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); 650 break; 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); 654 break; 655 case F128_TO_F16: 656 not_implemented(); 657 break; 658 case F128_TO_F32: 659 test_a_f128_z_f32(slow_f128M_to_f32, qemu_f128M_to_f32); 660 break; 661 case F128_TO_F64: 662 test_a_f128_z_f64(slow_f128M_to_f64, qemu_f128M_to_f64); 663 break; 664 case F128_TO_EXTF80: 665 test_a_f128_z_extF80(slow_f128M_to_extF80M, qemu_f128M_to_extF80M); 666 break; 667 case F128_ROUNDTOINT: 668 test_az_f128_rx(slow_f128M_roundToInt, qemu_f128M_roundToInt, rmode, 669 exact); 670 break; 671 case F128_ADD: 672 true_abz_f128M = slow_f128M_add; 673 subj_abz_f128M = qemu_f128M_add; 674 goto test_abz_f128; 675 case F128_SUB: 676 true_abz_f128M = slow_f128M_sub; 677 subj_abz_f128M = qemu_f128M_sub; 678 goto test_abz_f128; 679 case F128_MUL: 680 true_abz_f128M = slow_f128M_mul; 681 subj_abz_f128M = qemu_f128M_mul; 682 goto test_abz_f128; 683 case F128_DIV: 684 true_abz_f128M = slow_f128M_div; 685 subj_abz_f128M = qemu_f128M_div; 686 goto test_abz_f128; 687 case F128_REM: 688 true_abz_f128M = slow_f128M_rem; 689 subj_abz_f128M = qemu_f128M_rem; 690 test_abz_f128: 691 test_abz_f128(true_abz_f128M, subj_abz_f128M); 692 break; 693 case F128_MULADD: 694 not_implemented(); 695 break; 696 case F128_SQRT: 697 test_az_f128(slow_f128M_sqrt, qemu_f128M_sqrt); 698 break; 699 case F128_EQ: 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; 703 case F128_LE: 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; 707 case F128_LT: 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; 715 case F128_LE_QUIET: 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; 719 case F128_LT_QUIET: 720 true_ab_f128M_z_bool = slow_f128M_lt_quiet; 721 subj_ab_f128M_z_bool = qemu_f128M_lt_quiet; 722 test_ab_f128_z_bool: 723 test_ab_f128_z_bool(true_ab_f128M_z_bool, subj_ab_f128M_z_bool); 724 break; 725 } 726 if ((verCases_errorStop && verCases_anyErrors)) { 727 verCases_exitWithStatus(); 728 } 729 } 730 731 static unsigned int test_name_to_op(const char *arg) 732 { 733 unsigned int i; 734 735 /* counting begins at 1 */ 736 for (i = 1; i < NUM_FUNCTIONS; i++) { 737 const char *name = functionInfos[i].namePtr; 738 739 if (name && !strcmp(name, arg)) { 740 return i; 741 } 742 } 743 return 0; 744 } 745 746 static unsigned int round_name_to_mode(const char *name) 747 { 748 int i; 749 750 /* counting begins at 1 */ 751 for (i = 1; i < NUM_ROUNDINGMODES; i++) { 752 if (!strcmp(round_mode_names[i], name)) { 753 return i; 754 } 755 } 756 return 0; 757 } 758 759 static int set_init_flags(const char *flags) 760 { 761 const char *p; 762 763 for (p = flags; *p != '\0'; p++) { 764 switch (*p) { 765 case 'v': 766 slow_init_flags |= softfloat_flag_invalid; 767 qemu_init_flags |= float_flag_invalid; 768 break; 769 case 'i': 770 slow_init_flags |= softfloat_flag_infinite; 771 qemu_init_flags |= float_flag_divbyzero; 772 break; 773 case 'o': 774 slow_init_flags |= softfloat_flag_overflow; 775 qemu_init_flags |= float_flag_overflow; 776 break; 777 case 'u': 778 slow_init_flags |= softfloat_flag_underflow; 779 qemu_init_flags |= float_flag_underflow; 780 break; 781 case 'x': 782 slow_init_flags |= softfloat_flag_inexact; 783 qemu_init_flags |= float_flag_inexact; 784 break; 785 default: 786 return 1; 787 } 788 } 789 return 0; 790 } 791 792 static uint_fast8_t slow_clear_flags(void) 793 { 794 uint8_t prev = slowfloat_exceptionFlags; 795 796 slowfloat_exceptionFlags = slow_init_flags; 797 return prev; 798 } 799 800 static uint_fast8_t qemu_clear_flags(void) 801 { 802 uint8_t prev = qemu_flags_to_sf(qsf.float_exception_flags); 803 804 qsf.float_exception_flags = qemu_init_flags; 805 return prev; 806 } 807 808 static void parse_args(int argc, char *argv[]) 809 { 810 unsigned int i; 811 int c; 812 813 for (;;) { 814 c = getopt(argc, argv, "he:f:l:r:s"); 815 if (c < 0) { 816 break; 817 } 818 switch (c) { 819 case 'h': 820 usage_complete(argc, argv); 821 exit(EXIT_SUCCESS); 822 case 'e': 823 if (qemu_strtoui(optarg, NULL, 0, &n_max_errors)) { 824 fprintf(stderr, "fatal: invalid max error count\n"); 825 exit(EXIT_FAILURE); 826 } 827 break; 828 case 'f': 829 if (set_init_flags(optarg)) { 830 fprintf(stderr, "fatal: flags must be a subset of 'vioux'\n"); 831 exit(EXIT_FAILURE); 832 } 833 break; 834 case 'l': 835 if (qemu_strtoi(optarg, NULL, 0, &test_level)) { 836 fprintf(stderr, "fatal: invalid test level\n"); 837 exit(EXIT_FAILURE); 838 } 839 break; 840 case 'r': 841 if (!strcmp(optarg, "all")) { 842 test_round_mode = 0; 843 } else { 844 test_round_mode = round_name_to_mode(optarg); 845 if (test_round_mode == 0) { 846 fprintf(stderr, "fatal: invalid rounding mode\n"); 847 exit(EXIT_FAILURE); 848 } 849 } 850 break; 851 case 's': 852 verCases_errorStop = true; 853 break; 854 case '?': 855 /* invalid option or missing argument; getopt prints error info */ 856 exit(EXIT_FAILURE); 857 } 858 } 859 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; 867 } 868 } else { 869 n_round_modes = 1; 870 round_modes = g_malloc(sizeof(*round_modes)); 871 round_modes[0] = test_round_mode; 872 } 873 874 /* set test ops */ 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++) { 880 test_ops[i] = i + 1; 881 } 882 } else { 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); 888 889 if (op == 0) { 890 fprintf(stderr, "fatal: invalid op '%s'\n", name); 891 exit(EXIT_FAILURE); 892 } 893 test_ops[i] = op; 894 } 895 } 896 } 897 898 static void QEMU_NORETURN run_test(void) 899 { 900 unsigned int i; 901 902 genCases_setLevel(test_level); 903 verCases_maxErrorCount = n_max_errors; 904 905 testLoops_trueFlagsFunction = slow_clear_flags; 906 testLoops_subjFlagsFunction = qemu_clear_flags; 907 908 for (i = 0; i < n_test_ops; i++) { 909 unsigned int op = test_ops[i]; 910 int j; 911 912 if (functionInfos[op].namePtr == NULL) { 913 continue; 914 } 915 verCases_functionNamePtr = functionInfos[op].namePtr; 916 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]; 921 int k; 922 923 verCases_roundingCode = 0; 924 slowfloat_roundingMode = rmode; 925 qsf.float_rounding_mode = sf_rounding_to_qemu(rmode); 926 927 if (attrs & (FUNC_ARG_ROUNDINGMODE | FUNC_EFF_ROUNDINGMODE)) { 928 /* print rounding mode if the op is affected by it */ 929 verCases_roundingCode = round; 930 } else if (j > 0) { 931 /* if the op is not sensitive to rounding, move on */ 932 break; 933 } 934 935 /* QEMU doesn't have !exact */ 936 verCases_exact = true; 937 verCases_usesExact = !!(attrs & FUNC_ARG_EXACT); 938 939 for (k = 0; k < 3; k++) { 940 int prec80 = 32; 941 int l; 942 943 if (k == 1) { 944 prec80 = 64; 945 } else if (k == 2) { 946 prec80 = 80; 947 } 948 949 verCases_roundingPrecision = 0; 950 slow_extF80_roundingPrecision = prec80; 951 qsf.floatx80_rounding_precision = prec80; 952 953 if (attrs & FUNC_EFF_ROUNDINGPRECISION) { 954 verCases_roundingPrecision = prec80; 955 } else if (k > 0) { 956 /* if the op is not sensitive to prec80, move on */ 957 break; 958 } 959 960 /* note: the count begins at 1 */ 961 for (l = 1; l < NUM_TININESSMODES; l++) { 962 int tmode = tininessModes[l]; 963 964 verCases_tininessCode = 0; 965 slowfloat_detectTininess = tmode; 966 qsf.float_detect_tininess = sf_tininess_to_qemu(tmode); 967 968 if (attrs & FUNC_EFF_TININESSMODE || 969 ((attrs & FUNC_EFF_TININESSMODE_REDUCEDPREC) && 970 prec80 && prec80 < 80)) { 971 verCases_tininessCode = l; 972 } else if (l > 1) { 973 /* if the op is not sensitive to tininess, move on */ 974 break; 975 } 976 977 do_testfloat(op, rmode, true); 978 } 979 } 980 } 981 } 982 verCases_exitWithStatus(); 983 /* old compilers might miss that we exited */ 984 g_assert_not_reached(); 985 } 986 987 int main(int argc, char *argv[]) 988 { 989 parse_args(argc, argv); 990 fail_programName = argv[0]; 991 run_test(); /* does not return */ 992 } 993