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.c.inc" 120 121 static void not_implemented(void) 122 { 123 fprintf(stderr, "Not implemented.\n"); 124 } 125 126 static bool is_allowed(unsigned op, int rmode) 127 { 128 /* odd has not been implemented for any 80-bit ops */ 129 if (rmode == softfloat_round_odd) { 130 switch (op) { 131 case EXTF80_TO_UI32: 132 case EXTF80_TO_UI64: 133 case EXTF80_TO_I32: 134 case EXTF80_TO_I64: 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: 139 case EXTF80_TO_F16: 140 case EXTF80_TO_F32: 141 case EXTF80_TO_F64: 142 case EXTF80_TO_F128: 143 case EXTF80_ROUNDTOINT: 144 case EXTF80_ADD: 145 case EXTF80_SUB: 146 case EXTF80_MUL: 147 case EXTF80_DIV: 148 case EXTF80_REM: 149 case EXTF80_SQRT: 150 case EXTF80_EQ: 151 case EXTF80_LE: 152 case EXTF80_LT: 153 case EXTF80_EQ_SIGNALING: 154 case EXTF80_LE_QUIET: 155 case EXTF80_LT_QUIET: 156 case UI32_TO_EXTF80: 157 case UI64_TO_EXTF80: 158 case I32_TO_EXTF80: 159 case I64_TO_EXTF80: 160 case F16_TO_EXTF80: 161 case F32_TO_EXTF80: 162 case F64_TO_EXTF80: 163 case F128_TO_EXTF80: 164 return false; 165 } 166 } 167 return true; 168 } 169 170 static void do_testfloat(int op, int rmode, bool exact) 171 { 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; 192 193 fputs(">> Testing ", stderr); 194 verCases_writeFunctionName(stderr); 195 fputs("\n", stderr); 196 197 if (!is_allowed(op, rmode)) { 198 not_implemented(); 199 return; 200 } 201 202 switch (op) { 203 case UI32_TO_F16: 204 test_a_ui32_z_f16(slow_ui32_to_f16, qemu_ui32_to_f16); 205 break; 206 case UI32_TO_F32: 207 test_a_ui32_z_f32(slow_ui32_to_f32, qemu_ui32_to_f32); 208 break; 209 case UI32_TO_F64: 210 test_a_ui32_z_f64(slow_ui32_to_f64, qemu_ui32_to_f64); 211 break; 212 case UI32_TO_EXTF80: 213 not_implemented(); 214 break; 215 case UI32_TO_F128: 216 not_implemented(); 217 break; 218 case UI64_TO_F16: 219 test_a_ui64_z_f16(slow_ui64_to_f16, qemu_ui64_to_f16); 220 break; 221 case UI64_TO_F32: 222 test_a_ui64_z_f32(slow_ui64_to_f32, qemu_ui64_to_f32); 223 break; 224 case UI64_TO_F64: 225 test_a_ui64_z_f64(slow_ui64_to_f64, qemu_ui64_to_f64); 226 break; 227 case UI64_TO_EXTF80: 228 not_implemented(); 229 break; 230 case UI64_TO_F128: 231 test_a_ui64_z_f128(slow_ui64_to_f128M, qemu_ui64_to_f128M); 232 break; 233 case I32_TO_F16: 234 test_a_i32_z_f16(slow_i32_to_f16, qemu_i32_to_f16); 235 break; 236 case I32_TO_F32: 237 test_a_i32_z_f32(slow_i32_to_f32, qemu_i32_to_f32); 238 break; 239 case I32_TO_F64: 240 test_a_i32_z_f64(slow_i32_to_f64, qemu_i32_to_f64); 241 break; 242 case I32_TO_EXTF80: 243 test_a_i32_z_extF80(slow_i32_to_extF80M, qemu_i32_to_extF80M); 244 break; 245 case I32_TO_F128: 246 test_a_i32_z_f128(slow_i32_to_f128M, qemu_i32_to_f128M); 247 break; 248 case I64_TO_F16: 249 test_a_i64_z_f16(slow_i64_to_f16, qemu_i64_to_f16); 250 break; 251 case I64_TO_F32: 252 test_a_i64_z_f32(slow_i64_to_f32, qemu_i64_to_f32); 253 break; 254 case I64_TO_F64: 255 test_a_i64_z_f64(slow_i64_to_f64, qemu_i64_to_f64); 256 break; 257 case I64_TO_EXTF80: 258 test_a_i64_z_extF80(slow_i64_to_extF80M, qemu_i64_to_extF80M); 259 break; 260 case I64_TO_F128: 261 test_a_i64_z_f128(slow_i64_to_f128M, qemu_i64_to_f128M); 262 break; 263 case F16_TO_UI32: 264 test_a_f16_z_ui32_rx(slow_f16_to_ui32, qemu_f16_to_ui32, rmode, exact); 265 break; 266 case F16_TO_UI64: 267 test_a_f16_z_ui64_rx(slow_f16_to_ui64, qemu_f16_to_ui64, rmode, exact); 268 break; 269 case F16_TO_I32: 270 test_a_f16_z_i32_rx(slow_f16_to_i32, qemu_f16_to_i32, rmode, exact); 271 break; 272 case F16_TO_I64: 273 test_a_f16_z_i64_rx(slow_f16_to_i64, qemu_f16_to_i64, rmode, exact); 274 break; 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); 278 break; 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); 282 break; 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, 285 exact); 286 break; 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, 289 exact); 290 break; 291 case F16_TO_F32: 292 test_a_f16_z_f32(slow_f16_to_f32, qemu_f16_to_f32); 293 break; 294 case F16_TO_F64: 295 test_a_f16_z_f64(slow_f16_to_f64, qemu_f16_to_f64); 296 break; 297 case F16_TO_EXTF80: 298 not_implemented(); 299 break; 300 case F16_TO_F128: 301 not_implemented(); 302 break; 303 case F16_ROUNDTOINT: 304 test_az_f16_rx(slow_f16_roundToInt, qemu_f16_roundToInt, rmode, exact); 305 break; 306 case F16_ADD: 307 true_abz_f16 = slow_f16_add; 308 subj_abz_f16 = qemu_f16_add; 309 goto test_abz_f16; 310 case F16_SUB: 311 true_abz_f16 = slow_f16_sub; 312 subj_abz_f16 = qemu_f16_sub; 313 goto test_abz_f16; 314 case F16_MUL: 315 true_abz_f16 = slow_f16_mul; 316 subj_abz_f16 = qemu_f16_mul; 317 goto test_abz_f16; 318 case F16_DIV: 319 true_abz_f16 = slow_f16_div; 320 subj_abz_f16 = qemu_f16_div; 321 goto test_abz_f16; 322 case F16_REM: 323 not_implemented(); 324 break; 325 test_abz_f16: 326 test_abz_f16(true_abz_f16, subj_abz_f16); 327 break; 328 case F16_MULADD: 329 test_abcz_f16(slow_f16_mulAdd, qemu_f16_mulAdd); 330 break; 331 case F16_SQRT: 332 test_az_f16(slow_f16_sqrt, qemu_f16_sqrt); 333 break; 334 case F16_EQ: 335 true_f16_z_bool = slow_f16_eq; 336 subj_f16_z_bool = qemu_f16_eq; 337 goto test_ab_f16_z_bool; 338 case F16_LE: 339 true_f16_z_bool = slow_f16_le; 340 subj_f16_z_bool = qemu_f16_le; 341 goto test_ab_f16_z_bool; 342 case F16_LT: 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; 350 case F16_LE_QUIET: 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; 354 case F16_LT_QUIET: 355 true_f16_z_bool = slow_f16_lt_quiet; 356 subj_f16_z_bool = qemu_f16_lt_quiet; 357 test_ab_f16_z_bool: 358 test_ab_f16_z_bool(true_f16_z_bool, subj_f16_z_bool); 359 break; 360 case F32_TO_UI32: 361 test_a_f32_z_ui32_rx(slow_f32_to_ui32, qemu_f32_to_ui32, rmode, exact); 362 break; 363 case F32_TO_UI64: 364 test_a_f32_z_ui64_rx(slow_f32_to_ui64, qemu_f32_to_ui64, rmode, exact); 365 break; 366 case F32_TO_I32: 367 test_a_f32_z_i32_rx(slow_f32_to_i32, qemu_f32_to_i32, rmode, exact); 368 break; 369 case F32_TO_I64: 370 test_a_f32_z_i64_rx(slow_f32_to_i64, qemu_f32_to_i64, rmode, exact); 371 break; 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); 375 break; 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); 379 break; 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, 382 exact); 383 break; 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, 386 exact); 387 break; 388 case F32_TO_F16: 389 test_a_f32_z_f16(slow_f32_to_f16, qemu_f32_to_f16); 390 break; 391 case F32_TO_F64: 392 test_a_f32_z_f64(slow_f32_to_f64, qemu_f32_to_f64); 393 break; 394 case F32_TO_EXTF80: 395 test_a_f32_z_extF80(slow_f32_to_extF80M, qemu_f32_to_extF80M); 396 break; 397 case F32_TO_F128: 398 test_a_f32_z_f128(slow_f32_to_f128M, qemu_f32_to_f128M); 399 break; 400 case F32_ROUNDTOINT: 401 test_az_f32_rx(slow_f32_roundToInt, qemu_f32_roundToInt, rmode, exact); 402 break; 403 case F32_ADD: 404 true_abz_f32 = slow_f32_add; 405 subj_abz_f32 = qemu_f32_add; 406 goto test_abz_f32; 407 case F32_SUB: 408 true_abz_f32 = slow_f32_sub; 409 subj_abz_f32 = qemu_f32_sub; 410 goto test_abz_f32; 411 case F32_MUL: 412 true_abz_f32 = slow_f32_mul; 413 subj_abz_f32 = qemu_f32_mul; 414 goto test_abz_f32; 415 case F32_DIV: 416 true_abz_f32 = slow_f32_div; 417 subj_abz_f32 = qemu_f32_div; 418 goto test_abz_f32; 419 case F32_REM: 420 true_abz_f32 = slow_f32_rem; 421 subj_abz_f32 = qemu_f32_rem; 422 test_abz_f32: 423 test_abz_f32(true_abz_f32, subj_abz_f32); 424 break; 425 case F32_MULADD: 426 test_abcz_f32(slow_f32_mulAdd, qemu_f32_mulAdd); 427 break; 428 case F32_SQRT: 429 test_az_f32(slow_f32_sqrt, qemu_f32_sqrt); 430 break; 431 case F32_EQ: 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; 435 case F32_LE: 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; 439 case F32_LT: 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; 447 case F32_LE_QUIET: 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; 451 case F32_LT_QUIET: 452 true_ab_f32_z_bool = slow_f32_lt_quiet; 453 subj_ab_f32_z_bool = qemu_f32_lt_quiet; 454 test_ab_f32_z_bool: 455 test_ab_f32_z_bool(true_ab_f32_z_bool, subj_ab_f32_z_bool); 456 break; 457 case F64_TO_UI32: 458 test_a_f64_z_ui32_rx(slow_f64_to_ui32, qemu_f64_to_ui32, rmode, exact); 459 break; 460 case F64_TO_UI64: 461 test_a_f64_z_ui64_rx(slow_f64_to_ui64, qemu_f64_to_ui64, rmode, exact); 462 break; 463 case F64_TO_I32: 464 test_a_f64_z_i32_rx(slow_f64_to_i32, qemu_f64_to_i32, rmode, exact); 465 break; 466 case F64_TO_I64: 467 test_a_f64_z_i64_rx(slow_f64_to_i64, qemu_f64_to_i64, rmode, exact); 468 break; 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); 472 break; 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); 476 break; 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, 479 exact); 480 break; 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, 483 exact); 484 break; 485 case F64_TO_F16: 486 test_a_f64_z_f16(slow_f64_to_f16, qemu_f64_to_f16); 487 break; 488 case F64_TO_F32: 489 test_a_f64_z_f32(slow_f64_to_f32, qemu_f64_to_f32); 490 break; 491 case F64_TO_EXTF80: 492 test_a_f64_z_extF80(slow_f64_to_extF80M, qemu_f64_to_extF80M); 493 break; 494 case F64_TO_F128: 495 test_a_f64_z_f128(slow_f64_to_f128M, qemu_f64_to_f128M); 496 break; 497 case F64_ROUNDTOINT: 498 test_az_f64_rx(slow_f64_roundToInt, qemu_f64_roundToInt, rmode, exact); 499 break; 500 case F64_ADD: 501 true_abz_f64 = slow_f64_add; 502 subj_abz_f64 = qemu_f64_add; 503 goto test_abz_f64; 504 case F64_SUB: 505 true_abz_f64 = slow_f64_sub; 506 subj_abz_f64 = qemu_f64_sub; 507 goto test_abz_f64; 508 case F64_MUL: 509 true_abz_f64 = slow_f64_mul; 510 subj_abz_f64 = qemu_f64_mul; 511 goto test_abz_f64; 512 case F64_DIV: 513 true_abz_f64 = slow_f64_div; 514 subj_abz_f64 = qemu_f64_div; 515 goto test_abz_f64; 516 case F64_REM: 517 true_abz_f64 = slow_f64_rem; 518 subj_abz_f64 = qemu_f64_rem; 519 test_abz_f64: 520 test_abz_f64(true_abz_f64, subj_abz_f64); 521 break; 522 case F64_MULADD: 523 test_abcz_f64(slow_f64_mulAdd, qemu_f64_mulAdd); 524 break; 525 case F64_SQRT: 526 test_az_f64(slow_f64_sqrt, qemu_f64_sqrt); 527 break; 528 case F64_EQ: 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; 532 case F64_LE: 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; 536 case F64_LT: 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; 544 case F64_LE_QUIET: 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; 548 case F64_LT_QUIET: 549 true_ab_f64_z_bool = slow_f64_lt_quiet; 550 subj_ab_f64_z_bool = qemu_f64_lt_quiet; 551 test_ab_f64_z_bool: 552 test_ab_f64_z_bool(true_ab_f64_z_bool, subj_ab_f64_z_bool); 553 break; 554 case EXTF80_TO_UI32: 555 not_implemented(); 556 break; 557 case EXTF80_TO_UI64: 558 not_implemented(); 559 break; 560 case EXTF80_TO_I32: 561 test_a_extF80_z_i32_rx(slow_extF80M_to_i32, qemu_extF80M_to_i32, rmode, 562 exact); 563 break; 564 case EXTF80_TO_I64: 565 test_a_extF80_z_i64_rx(slow_extF80M_to_i64, qemu_extF80M_to_i64, rmode, 566 exact); 567 break; 568 case EXTF80_TO_UI32_R_MINMAG: 569 not_implemented(); 570 break; 571 case EXTF80_TO_UI64_R_MINMAG: 572 not_implemented(); 573 break; 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); 577 break; 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); 581 break; 582 case EXTF80_TO_F16: 583 not_implemented(); 584 break; 585 case EXTF80_TO_F32: 586 test_a_extF80_z_f32(slow_extF80M_to_f32, qemu_extF80M_to_f32); 587 break; 588 case EXTF80_TO_F64: 589 test_a_extF80_z_f64(slow_extF80M_to_f64, qemu_extF80M_to_f64); 590 break; 591 case EXTF80_TO_F128: 592 test_a_extF80_z_f128(slow_extF80M_to_f128M, qemu_extF80M_to_f128M); 593 break; 594 case EXTF80_ROUNDTOINT: 595 test_az_extF80_rx(slow_extF80M_roundToInt, qemu_extF80M_roundToInt, 596 rmode, exact); 597 break; 598 case EXTF80_ADD: 599 true_abz_extF80M = slow_extF80M_add; 600 subj_abz_extF80M = qemu_extF80M_add; 601 goto test_abz_extF80; 602 case EXTF80_SUB: 603 true_abz_extF80M = slow_extF80M_sub; 604 subj_abz_extF80M = qemu_extF80M_sub; 605 goto test_abz_extF80; 606 case EXTF80_MUL: 607 true_abz_extF80M = slow_extF80M_mul; 608 subj_abz_extF80M = qemu_extF80M_mul; 609 goto test_abz_extF80; 610 case EXTF80_DIV: 611 true_abz_extF80M = slow_extF80M_div; 612 subj_abz_extF80M = qemu_extF80M_div; 613 goto test_abz_extF80; 614 case EXTF80_REM: 615 true_abz_extF80M = slow_extF80M_rem; 616 subj_abz_extF80M = qemu_extF80M_rem; 617 test_abz_extF80: 618 test_abz_extF80(true_abz_extF80M, subj_abz_extF80M); 619 break; 620 case EXTF80_SQRT: 621 test_az_extF80(slow_extF80M_sqrt, qemu_extF80M_sqrt); 622 break; 623 case EXTF80_EQ: 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; 627 case EXTF80_LE: 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; 631 case EXTF80_LT: 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); 648 break; 649 case F128_TO_UI32: 650 test_a_f128_z_ui32_rx(slow_f128M_to_ui32, qemu_f128M_to_ui32, rmode, 651 exact); 652 break; 653 case F128_TO_UI64: 654 test_a_f128_z_ui64_rx(slow_f128M_to_ui64, qemu_f128M_to_ui64, rmode, 655 exact); 656 break; 657 case F128_TO_I32: 658 test_a_f128_z_i32_rx(slow_f128M_to_i32, qemu_f128M_to_i32, rmode, 659 exact); 660 break; 661 case F128_TO_I64: 662 test_a_f128_z_i64_rx(slow_f128M_to_i64, qemu_f128M_to_i64, rmode, 663 exact); 664 break; 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); 668 break; 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); 672 break; 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); 676 break; 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); 680 break; 681 case F128_TO_F16: 682 not_implemented(); 683 break; 684 case F128_TO_F32: 685 test_a_f128_z_f32(slow_f128M_to_f32, qemu_f128M_to_f32); 686 break; 687 case F128_TO_F64: 688 test_a_f128_z_f64(slow_f128M_to_f64, qemu_f128M_to_f64); 689 break; 690 case F128_TO_EXTF80: 691 test_a_f128_z_extF80(slow_f128M_to_extF80M, qemu_f128M_to_extF80M); 692 break; 693 case F128_ROUNDTOINT: 694 test_az_f128_rx(slow_f128M_roundToInt, qemu_f128M_roundToInt, rmode, 695 exact); 696 break; 697 case F128_ADD: 698 true_abz_f128M = slow_f128M_add; 699 subj_abz_f128M = qemu_f128M_add; 700 goto test_abz_f128; 701 case F128_SUB: 702 true_abz_f128M = slow_f128M_sub; 703 subj_abz_f128M = qemu_f128M_sub; 704 goto test_abz_f128; 705 case F128_MUL: 706 true_abz_f128M = slow_f128M_mul; 707 subj_abz_f128M = qemu_f128M_mul; 708 goto test_abz_f128; 709 case F128_DIV: 710 true_abz_f128M = slow_f128M_div; 711 subj_abz_f128M = qemu_f128M_div; 712 goto test_abz_f128; 713 case F128_REM: 714 true_abz_f128M = slow_f128M_rem; 715 subj_abz_f128M = qemu_f128M_rem; 716 test_abz_f128: 717 test_abz_f128(true_abz_f128M, subj_abz_f128M); 718 break; 719 case F128_MULADD: 720 test_abcz_f128(slow_f128M_mulAdd, qemu_f128M_mulAdd); 721 break; 722 case F128_SQRT: 723 test_az_f128(slow_f128M_sqrt, qemu_f128M_sqrt); 724 break; 725 case F128_EQ: 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; 729 case F128_LE: 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; 733 case F128_LT: 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; 741 case F128_LE_QUIET: 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; 745 case F128_LT_QUIET: 746 true_ab_f128M_z_bool = slow_f128M_lt_quiet; 747 subj_ab_f128M_z_bool = qemu_f128M_lt_quiet; 748 test_ab_f128_z_bool: 749 test_ab_f128_z_bool(true_ab_f128M_z_bool, subj_ab_f128M_z_bool); 750 break; 751 } 752 if ((verCases_errorStop && verCases_anyErrors)) { 753 verCases_exitWithStatus(); 754 } 755 } 756 757 static unsigned int test_name_to_op(const char *arg) 758 { 759 unsigned int i; 760 761 /* counting begins at 1 */ 762 for (i = 1; i < NUM_FUNCTIONS; i++) { 763 const char *name = functionInfos[i].namePtr; 764 765 if (name && !strcmp(name, arg)) { 766 return i; 767 } 768 } 769 return 0; 770 } 771 772 static unsigned int round_name_to_mode(const char *name) 773 { 774 int i; 775 776 /* counting begins at 1 */ 777 for (i = 1; i < NUM_ROUNDINGMODES; i++) { 778 if (!strcmp(round_mode_names[i], name)) { 779 return i; 780 } 781 } 782 return 0; 783 } 784 785 static int set_init_flags(const char *flags) 786 { 787 const char *p; 788 789 for (p = flags; *p != '\0'; p++) { 790 switch (*p) { 791 case 'v': 792 slow_init_flags |= softfloat_flag_invalid; 793 qemu_init_flags |= float_flag_invalid; 794 break; 795 case 'i': 796 slow_init_flags |= softfloat_flag_infinite; 797 qemu_init_flags |= float_flag_divbyzero; 798 break; 799 case 'o': 800 slow_init_flags |= softfloat_flag_overflow; 801 qemu_init_flags |= float_flag_overflow; 802 break; 803 case 'u': 804 slow_init_flags |= softfloat_flag_underflow; 805 qemu_init_flags |= float_flag_underflow; 806 break; 807 case 'x': 808 slow_init_flags |= softfloat_flag_inexact; 809 qemu_init_flags |= float_flag_inexact; 810 break; 811 default: 812 return 1; 813 } 814 } 815 return 0; 816 } 817 818 static uint_fast8_t slow_clear_flags(void) 819 { 820 uint8_t prev = slowfloat_exceptionFlags; 821 822 slowfloat_exceptionFlags = slow_init_flags; 823 return prev; 824 } 825 826 static uint_fast8_t qemu_clear_flags(void) 827 { 828 uint8_t prev = qemu_flags_to_sf(qsf.float_exception_flags); 829 830 qsf.float_exception_flags = qemu_init_flags; 831 return prev; 832 } 833 834 static void parse_args(int argc, char *argv[]) 835 { 836 unsigned int i; 837 int c; 838 839 for (;;) { 840 c = getopt(argc, argv, "he:f:l:r:s"); 841 if (c < 0) { 842 break; 843 } 844 switch (c) { 845 case 'h': 846 usage_complete(argc, argv); 847 exit(EXIT_SUCCESS); 848 case 'e': 849 if (qemu_strtoui(optarg, NULL, 0, &n_max_errors)) { 850 fprintf(stderr, "fatal: invalid max error count\n"); 851 exit(EXIT_FAILURE); 852 } 853 break; 854 case 'f': 855 if (set_init_flags(optarg)) { 856 fprintf(stderr, "fatal: flags must be a subset of 'vioux'\n"); 857 exit(EXIT_FAILURE); 858 } 859 break; 860 case 'l': 861 if (qemu_strtoi(optarg, NULL, 0, &test_level)) { 862 fprintf(stderr, "fatal: invalid test level\n"); 863 exit(EXIT_FAILURE); 864 } 865 break; 866 case 'r': 867 if (!strcmp(optarg, "all")) { 868 test_round_mode = 0; 869 } else { 870 test_round_mode = round_name_to_mode(optarg); 871 if (test_round_mode == 0) { 872 fprintf(stderr, "fatal: invalid rounding mode\n"); 873 exit(EXIT_FAILURE); 874 } 875 } 876 break; 877 case 's': 878 verCases_errorStop = true; 879 break; 880 case '?': 881 /* invalid option or missing argument; getopt prints error info */ 882 exit(EXIT_FAILURE); 883 } 884 } 885 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; 893 } 894 } else { 895 n_round_modes = 1; 896 round_modes = g_malloc(sizeof(*round_modes)); 897 round_modes[0] = test_round_mode; 898 } 899 900 /* set test ops */ 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++) { 906 test_ops[i] = i + 1; 907 } 908 } else { 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); 914 915 if (op == 0) { 916 fprintf(stderr, "fatal: invalid op '%s'\n", name); 917 exit(EXIT_FAILURE); 918 } 919 test_ops[i] = op; 920 } 921 } 922 } 923 924 static G_NORETURN 925 void run_test(void) 926 { 927 unsigned int i; 928 929 genCases_setLevel(test_level); 930 verCases_maxErrorCount = n_max_errors; 931 932 testLoops_trueFlagsFunction = slow_clear_flags; 933 testLoops_subjFlagsFunction = qemu_clear_flags; 934 935 for (i = 0; i < n_test_ops; i++) { 936 unsigned int op = test_ops[i]; 937 int j; 938 939 if (functionInfos[op].namePtr == NULL) { 940 continue; 941 } 942 verCases_functionNamePtr = functionInfos[op].namePtr; 943 944 for (j = 0; j < n_round_modes; j++) { 945 int attrs = functionInfos[op].attribs; 946 int round = round_modes[j]; 947 int rmode = roundingModes[round]; 948 int k; 949 950 verCases_roundingCode = 0; 951 slowfloat_roundingMode = rmode; 952 qsf.float_rounding_mode = sf_rounding_to_qemu(rmode); 953 954 if (attrs & (FUNC_ARG_ROUNDINGMODE | FUNC_EFF_ROUNDINGMODE)) { 955 /* print rounding mode if the op is affected by it */ 956 verCases_roundingCode = round; 957 } else if (j > 0) { 958 /* if the op is not sensitive to rounding, move on */ 959 break; 960 } 961 962 /* QEMU doesn't have !exact */ 963 verCases_exact = true; 964 verCases_usesExact = !!(attrs & FUNC_ARG_EXACT); 965 966 for (k = 0; k < 3; k++) { 967 FloatX80RoundPrec qsf_prec80 = floatx80_precision_x; 968 int prec80 = 80; 969 int l; 970 971 if (k == 1) { 972 prec80 = 64; 973 qsf_prec80 = floatx80_precision_d; 974 } else if (k == 2) { 975 prec80 = 32; 976 qsf_prec80 = floatx80_precision_s; 977 } 978 979 verCases_roundingPrecision = 0; 980 slow_extF80_roundingPrecision = prec80; 981 qsf.floatx80_rounding_precision = qsf_prec80; 982 983 if (attrs & FUNC_EFF_ROUNDINGPRECISION) { 984 verCases_roundingPrecision = prec80; 985 } else if (k > 0) { 986 /* if the op is not sensitive to prec80, move on */ 987 break; 988 } 989 990 /* note: the count begins at 1 */ 991 for (l = 1; l < NUM_TININESSMODES; l++) { 992 int tmode = tininessModes[l]; 993 994 verCases_tininessCode = 0; 995 slowfloat_detectTininess = tmode; 996 qsf.tininess_before_rounding = sf_tininess_to_qemu(tmode); 997 998 if (attrs & FUNC_EFF_TININESSMODE || 999 ((attrs & FUNC_EFF_TININESSMODE_REDUCEDPREC) && 1000 prec80 && prec80 < 80)) { 1001 verCases_tininessCode = l; 1002 } else if (l > 1) { 1003 /* if the op is not sensitive to tininess, move on */ 1004 break; 1005 } 1006 1007 do_testfloat(op, rmode, true); 1008 } 1009 } 1010 } 1011 } 1012 verCases_exitWithStatus(); 1013 /* old compilers might miss that we exited */ 1014 g_assert_not_reached(); 1015 } 1016 1017 int main(int argc, char *argv[]) 1018 { 1019 parse_args(argc, argv); 1020 fail_programName = argv[0]; 1021 run_test(); /* does not return */ 1022 } 1023