1 /* 2 * Copyright(c) 2020-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 /* 19 * This test checks various FP operations performed on Hexagon 20 */ 21 22 #include <stdio.h> 23 24 const int FPINVF_BIT = 1; /* Invalid */ 25 const int FPINVF = 1 << FPINVF_BIT; 26 const int FPDBZF_BIT = 2; /* Divide by zero */ 27 const int FPDBZF = 1 << FPDBZF_BIT; 28 const int FPOVFF_BIT = 3; /* Overflow */ 29 const int FPOVFF = 1 << FPOVFF_BIT; 30 const int FPUNFF_BIT = 4; /* Underflow */ 31 const int FPUNFF = 1 << FPUNFF_BIT; 32 const int FPINPF_BIT = 5; /* Inexact */ 33 const int FPINPF = 1 << FPINPF_BIT; 34 35 const int SF_ZERO = 0x00000000; 36 const int SF_NaN = 0x7fc00000; 37 const int SF_NaN_special = 0x7f800001; 38 const int SF_ANY = 0x3f800000; 39 const int SF_HEX_NAN = 0xffffffff; 40 const int SF_small_neg = 0xab98fba8; 41 42 const long long DF_NaN = 0x7ff8000000000000ULL; 43 const long long DF_ANY = 0x3f80000000000000ULL; 44 const long long DF_HEX_NAN = 0xffffffffffffffffULL; 45 const long long DF_small_neg = 0xbd731f7500000000ULL; 46 47 int err; 48 49 #define CLEAR_FPSTATUS \ 50 "r2 = usr\n\t" \ 51 "r2 = clrbit(r2, #1)\n\t" \ 52 "r2 = clrbit(r2, #2)\n\t" \ 53 "r2 = clrbit(r2, #3)\n\t" \ 54 "r2 = clrbit(r2, #4)\n\t" \ 55 "r2 = clrbit(r2, #5)\n\t" \ 56 "usr = r2\n\t" 57 58 static void check_fpstatus_bit(int usr, int expect, int flag, const char *n) 59 { 60 int bit = 1 << flag; 61 if ((usr & bit) != (expect & bit)) { 62 printf("ERROR %s: usr = %d, expect = %d\n", n, 63 (usr >> flag) & 1, (expect >> flag) & 1); 64 err++; 65 } 66 } 67 68 static void check_fpstatus(int usr, int expect) 69 { 70 check_fpstatus_bit(usr, expect, FPINVF_BIT, "Invalid"); 71 check_fpstatus_bit(usr, expect, FPDBZF_BIT, "Div by zero"); 72 check_fpstatus_bit(usr, expect, FPOVFF_BIT, "Overflow"); 73 check_fpstatus_bit(usr, expect, FPUNFF_BIT, "Underflow"); 74 check_fpstatus_bit(usr, expect, FPINPF_BIT, "Inexact"); 75 } 76 77 static void check32(int val, int expect) 78 { 79 if (val != expect) { 80 printf("ERROR: 0x%x != 0x%x\n", val, expect); 81 err++; 82 } 83 } 84 static void check64(unsigned long long val, unsigned long long expect) 85 { 86 if (val != expect) { 87 printf("ERROR: 0x%llx != 0x%llx\n", val, expect); 88 err++; 89 } 90 } 91 92 static void check_compare_exception(void) 93 { 94 int cmp; 95 int usr; 96 97 /* Check that FP compares are quiet (don't raise any execptions) */ 98 asm (CLEAR_FPSTATUS 99 "p0 = sfcmp.eq(%2, %3)\n\t" 100 "%0 = p0\n\t" 101 "%1 = usr\n\t" 102 : "=r"(cmp), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) 103 : "r2", "p0", "usr"); 104 check32(cmp, 0); 105 check_fpstatus(usr, 0); 106 107 asm (CLEAR_FPSTATUS 108 "p0 = sfcmp.gt(%2, %3)\n\t" 109 "%0 = p0\n\t" 110 "%1 = usr\n\t" 111 : "=r"(cmp), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) 112 : "r2", "p0", "usr"); 113 check32(cmp, 0); 114 check_fpstatus(usr, 0); 115 116 asm (CLEAR_FPSTATUS 117 "p0 = sfcmp.ge(%2, %3)\n\t" 118 "%0 = p0\n\t" 119 "%1 = usr\n\t" 120 : "=r"(cmp), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) 121 : "r2", "p0", "usr"); 122 check32(cmp, 0); 123 check_fpstatus(usr, 0); 124 125 asm (CLEAR_FPSTATUS 126 "p0 = dfcmp.eq(%2, %3)\n\t" 127 "%0 = p0\n\t" 128 "%1 = usr\n\t" 129 : "=r"(cmp), "=r"(usr) : "r"(DF_NaN), "r"(DF_ANY) 130 : "r2", "p0", "usr"); 131 check32(cmp, 0); 132 check_fpstatus(usr, 0); 133 134 asm (CLEAR_FPSTATUS 135 "p0 = dfcmp.gt(%2, %3)\n\t" 136 "%0 = p0\n\t" 137 "%1 = usr\n\t" 138 : "=r"(cmp), "=r"(usr) : "r"(DF_NaN), "r"(DF_ANY) 139 : "r2", "p0", "usr"); 140 check32(cmp, 0); 141 check_fpstatus(usr, 0); 142 143 asm (CLEAR_FPSTATUS 144 "p0 = dfcmp.ge(%2, %3)\n\t" 145 "%0 = p0\n\t" 146 "%1 = usr\n\t" 147 : "=r"(cmp), "=r"(usr) : "r"(DF_NaN), "r"(DF_ANY) 148 : "r2", "p0", "usr"); 149 check32(cmp, 0); 150 check_fpstatus(usr, 0); 151 } 152 153 static void check_sfminmax(void) 154 { 155 int minmax; 156 int usr; 157 158 /* 159 * Execute sfmin/sfmax instructions with one operand as NaN 160 * Check that 161 * Result is the other operand 162 * Invalid bit in USR is not set 163 */ 164 asm (CLEAR_FPSTATUS 165 "%0 = sfmin(%2, %3)\n\t" 166 "%1 = usr\n\t" 167 : "=r"(minmax), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) 168 : "r2", "usr"); 169 check64(minmax, SF_ANY); 170 check_fpstatus(usr, 0); 171 172 asm (CLEAR_FPSTATUS 173 "%0 = sfmax(%2, %3)\n\t" 174 "%1 = usr\n\t" 175 : "=r"(minmax), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) 176 : "r2", "usr"); 177 check64(minmax, SF_ANY); 178 check_fpstatus(usr, 0); 179 180 /* 181 * Execute sfmin/sfmax instructions with both operands NaN 182 * Check that 183 * Result is SF_HEX_NAN 184 * Invalid bit in USR is set 185 */ 186 asm (CLEAR_FPSTATUS 187 "%0 = sfmin(%2, %3)\n\t" 188 "%1 = usr\n\t" 189 : "=r"(minmax), "=r"(usr) : "r"(SF_NaN), "r"(SF_NaN) 190 : "r2", "usr"); 191 check64(minmax, SF_HEX_NAN); 192 check_fpstatus(usr, 0); 193 194 asm (CLEAR_FPSTATUS 195 "%0 = sfmax(%2, %3)\n\t" 196 "%1 = usr\n\t" 197 : "=r"(minmax), "=r"(usr) : "r"(SF_NaN), "r"(SF_NaN) 198 : "r2", "usr"); 199 check64(minmax, SF_HEX_NAN); 200 check_fpstatus(usr, 0); 201 } 202 203 static void check_dfminmax(void) 204 { 205 unsigned long long minmax; 206 int usr; 207 208 /* 209 * Execute dfmin/dfmax instructions with one operand as NaN 210 * Check that 211 * Result is the other operand 212 * Invalid bit in USR is set 213 */ 214 asm (CLEAR_FPSTATUS 215 "%0 = dfmin(%2, %3)\n\t" 216 "%1 = usr\n\t" 217 : "=r"(minmax), "=r"(usr) : "r"(DF_NaN), "r"(DF_ANY) 218 : "r2", "usr"); 219 check64(minmax, DF_ANY); 220 check_fpstatus(usr, FPINVF); 221 222 asm (CLEAR_FPSTATUS 223 "%0 = dfmax(%2, %3)\n\t" 224 "%1 = usr\n\t" 225 : "=r"(minmax), "=r"(usr) : "r"(DF_NaN), "r"(DF_ANY) 226 : "r2", "usr"); 227 check64(minmax, DF_ANY); 228 check_fpstatus(usr, FPINVF); 229 230 /* 231 * Execute dfmin/dfmax instructions with both operands NaN 232 * Check that 233 * Result is DF_HEX_NAN 234 * Invalid bit in USR is set 235 */ 236 asm (CLEAR_FPSTATUS 237 "%0 = dfmin(%2, %3)\n\t" 238 "%1 = usr\n\t" 239 : "=r"(minmax), "=r"(usr) : "r"(DF_NaN), "r"(DF_NaN) 240 : "r2", "usr"); 241 check64(minmax, DF_HEX_NAN); 242 check_fpstatus(usr, FPINVF); 243 244 asm (CLEAR_FPSTATUS 245 "%0 = dfmax(%2, %3)\n\t" 246 "%1 = usr\n\t" 247 : "=r"(minmax), "=r"(usr) : "r"(DF_NaN), "r"(DF_NaN) 248 : "r2", "usr"); 249 check64(minmax, DF_HEX_NAN); 250 check_fpstatus(usr, FPINVF); 251 } 252 253 static void check_recip_exception(void) 254 { 255 int result; 256 int usr; 257 258 /* 259 * Check that sfrecipa doesn't set status bits when 260 * a NaN with bit 22 non-zero is passed 261 */ 262 asm (CLEAR_FPSTATUS 263 "%0,p0 = sfrecipa(%2, %3)\n\t" 264 "%1 = usr\n\t" 265 : "=r"(result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) 266 : "r2", "p0", "usr"); 267 check32(result, SF_HEX_NAN); 268 check_fpstatus(usr, 0); 269 270 asm (CLEAR_FPSTATUS 271 "%0,p0 = sfrecipa(%2, %3)\n\t" 272 "%1 = usr\n\t" 273 : "=r"(result), "=r"(usr) : "r"(SF_ANY), "r"(SF_NaN) 274 : "r2", "p0", "usr"); 275 check32(result, SF_HEX_NAN); 276 check_fpstatus(usr, 0); 277 278 asm (CLEAR_FPSTATUS 279 "%0,p0 = sfrecipa(%2, %2)\n\t" 280 "%1 = usr\n\t" 281 : "=r"(result), "=r"(usr) : "r"(SF_NaN) 282 : "r2", "p0", "usr"); 283 check32(result, SF_HEX_NAN); 284 check_fpstatus(usr, 0); 285 286 /* 287 * Check that sfrecipa doesn't set status bits when 288 * a NaN with bit 22 zero is passed 289 */ 290 asm (CLEAR_FPSTATUS 291 "%0,p0 = sfrecipa(%2, %3)\n\t" 292 "%1 = usr\n\t" 293 : "=r"(result), "=r"(usr) : "r"(SF_NaN_special), "r"(SF_ANY) 294 : "r2", "p0", "usr"); 295 check32(result, SF_HEX_NAN); 296 check_fpstatus(usr, FPINVF); 297 298 asm (CLEAR_FPSTATUS 299 "%0,p0 = sfrecipa(%2, %3)\n\t" 300 "%1 = usr\n\t" 301 : "=r"(result), "=r"(usr) : "r"(SF_ANY), "r"(SF_NaN_special) 302 : "r2", "p0", "usr"); 303 check32(result, SF_HEX_NAN); 304 check_fpstatus(usr, FPINVF); 305 306 asm (CLEAR_FPSTATUS 307 "%0,p0 = sfrecipa(%2, %2)\n\t" 308 "%1 = usr\n\t" 309 : "=r"(result), "=r"(usr) : "r"(SF_NaN_special) 310 : "r2", "p0", "usr"); 311 check32(result, SF_HEX_NAN); 312 check_fpstatus(usr, FPINVF); 313 314 /* 315 * Check that sfrecipa properly sets divid-by-zero 316 */ 317 asm (CLEAR_FPSTATUS 318 "%0,p0 = sfrecipa(%2, %3)\n\t" 319 "%1 = usr\n\t" 320 : "=r"(result), "=r"(usr) : "r"(0x885dc960), "r"(0x80000000) 321 : "r2", "p0", "usr"); 322 check32(result, 0x3f800000); 323 check_fpstatus(usr, FPDBZF); 324 325 asm (CLEAR_FPSTATUS 326 "%0,p0 = sfrecipa(%2, %3)\n\t" 327 "%1 = usr\n\t" 328 : "=r"(result), "=r"(usr) : "r"(0x7f800000), "r"(SF_ZERO) 329 : "r2", "p0", "usr"); 330 check32(result, 0x3f800000); 331 check_fpstatus(usr, 0); 332 } 333 334 static void check_canonical_NaN(void) 335 { 336 int sf_result; 337 unsigned long long df_result; 338 int usr; 339 340 /* Check that each FP instruction properly returns SF_HEX_NAN/DF_HEX_NAN */ 341 asm(CLEAR_FPSTATUS 342 "%0 = sfadd(%2, %3)\n\t" 343 "%1 = usr\n\t" 344 : "=r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) 345 : "r2", "usr"); 346 check32(sf_result, SF_HEX_NAN); 347 check_fpstatus(usr, 0); 348 349 asm(CLEAR_FPSTATUS 350 "%0 = sfsub(%2, %3)\n\t" 351 "%1 = usr\n\t" 352 : "=r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) 353 : "r2", "usr"); 354 check32(sf_result, SF_HEX_NAN); 355 check_fpstatus(usr, 0); 356 357 asm(CLEAR_FPSTATUS 358 "%0 = sfmpy(%2, %3)\n\t" 359 "%1 = usr\n\t" 360 : "=r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) 361 : "r2", "usr"); 362 check32(sf_result, SF_HEX_NAN); 363 check_fpstatus(usr, 0); 364 365 sf_result = SF_ZERO; 366 asm(CLEAR_FPSTATUS 367 "%0 += sfmpy(%2, %3)\n\t" 368 "%1 = usr\n\t" 369 : "+r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) 370 : "r2", "usr"); 371 check32(sf_result, SF_HEX_NAN); 372 check_fpstatus(usr, 0); 373 374 sf_result = SF_ZERO; 375 asm(CLEAR_FPSTATUS 376 "p0 = !cmp.eq(r0, r0)\n\t" 377 "%0 += sfmpy(%2, %3, p0):scale\n\t" 378 "%1 = usr\n\t" 379 : "+r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) 380 : "r2", "usr", "p0"); 381 check32(sf_result, SF_HEX_NAN); 382 check_fpstatus(usr, 0); 383 384 sf_result = SF_ZERO; 385 asm(CLEAR_FPSTATUS 386 "%0 -= sfmpy(%2, %3)\n\t" 387 "%1 = usr\n\t" 388 : "+r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) 389 : "r2", "usr"); 390 check32(sf_result, SF_HEX_NAN); 391 check_fpstatus(usr, 0); 392 393 sf_result = SF_ZERO; 394 asm(CLEAR_FPSTATUS 395 "%0 += sfmpy(%2, %3):lib\n\t" 396 "%1 = usr\n\t" 397 : "+r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) 398 : "r2", "usr"); 399 check32(sf_result, SF_HEX_NAN); 400 check_fpstatus(usr, 0); 401 402 sf_result = SF_ZERO; 403 asm(CLEAR_FPSTATUS 404 "%0 -= sfmpy(%2, %3):lib\n\t" 405 "%1 = usr\n\t" 406 : "+r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) 407 : "r2", "usr"); 408 check32(sf_result, SF_HEX_NAN); 409 check_fpstatus(usr, 0); 410 411 asm(CLEAR_FPSTATUS 412 "%0 = convert_df2sf(%2)\n\t" 413 "%1 = usr\n\t" 414 : "=r"(sf_result), "=r"(usr) : "r"(DF_NaN) 415 : "r2", "usr"); 416 check32(sf_result, SF_HEX_NAN); 417 check_fpstatus(usr, 0); 418 419 asm(CLEAR_FPSTATUS 420 "%0 = dfadd(%2, %3)\n\t" 421 "%1 = usr\n\t" 422 : "=r"(df_result), "=r"(usr) : "r"(DF_NaN), "r"(DF_ANY) 423 : "r2", "usr"); 424 check64(df_result, DF_HEX_NAN); 425 check_fpstatus(usr, 0); 426 427 asm(CLEAR_FPSTATUS 428 "%0 = dfsub(%2, %3)\n\t" 429 "%1 = usr\n\t" 430 : "=r"(df_result), "=r"(usr) : "r"(DF_NaN), "r"(DF_ANY) 431 : "r2", "usr"); 432 check64(df_result, DF_HEX_NAN); 433 check_fpstatus(usr, 0); 434 435 asm(CLEAR_FPSTATUS 436 "%0 = convert_sf2df(%2)\n\t" 437 "%1 = usr\n\t" 438 : "=r"(df_result), "=r"(usr) : "r"(SF_NaN) 439 : "r2", "usr"); 440 check64(df_result, DF_HEX_NAN); 441 check_fpstatus(usr, 0); 442 } 443 444 static void check_invsqrta(void) 445 { 446 int result; 447 int predval; 448 449 asm volatile("%0,p0 = sfinvsqrta(%2)\n\t" 450 "%1 = p0\n\t" 451 : "+r"(result), "=r"(predval) 452 : "r"(0x7f800000) 453 : "p0"); 454 check32(result, 0xff800000); 455 check32(predval, 0x0); 456 } 457 458 static void check_float2int_convs() 459 { 460 int res32; 461 long long res64; 462 int usr; 463 464 /* 465 * Check that the various forms of float-to-unsigned 466 * check sign before rounding 467 */ 468 asm(CLEAR_FPSTATUS 469 "%0 = convert_sf2uw(%2)\n\t" 470 "%1 = usr\n\t" 471 : "=r"(res32), "=r"(usr) : "r"(SF_small_neg) 472 : "r2", "usr"); 473 check32(res32, 0); 474 check_fpstatus(usr, FPINVF); 475 476 asm(CLEAR_FPSTATUS 477 "%0 = convert_sf2uw(%2):chop\n\t" 478 "%1 = usr\n\t" 479 : "=r"(res32), "=r"(usr) : "r"(SF_small_neg) 480 : "r2", "usr"); 481 check32(res32, 0); 482 check_fpstatus(usr, FPINVF); 483 484 asm(CLEAR_FPSTATUS 485 "%0 = convert_sf2ud(%2)\n\t" 486 "%1 = usr\n\t" 487 : "=r"(res64), "=r"(usr) : "r"(SF_small_neg) 488 : "r2", "usr"); 489 check64(res64, 0); 490 check_fpstatus(usr, FPINVF); 491 492 asm(CLEAR_FPSTATUS 493 "%0 = convert_sf2ud(%2):chop\n\t" 494 "%1 = usr\n\t" 495 : "=r"(res64), "=r"(usr) : "r"(SF_small_neg) 496 : "r2", "usr"); 497 check64(res64, 0); 498 check_fpstatus(usr, FPINVF); 499 500 asm(CLEAR_FPSTATUS 501 "%0 = convert_df2uw(%2)\n\t" 502 "%1 = usr\n\t" 503 : "=r"(res32), "=r"(usr) : "r"(DF_small_neg) 504 : "r2", "usr"); 505 check32(res32, 0); 506 check_fpstatus(usr, FPINVF); 507 508 asm(CLEAR_FPSTATUS 509 "%0 = convert_df2uw(%2):chop\n\t" 510 "%1 = usr\n\t" 511 : "=r"(res32), "=r"(usr) : "r"(DF_small_neg) 512 : "r2", "usr"); 513 check32(res32, 0); 514 check_fpstatus(usr, FPINVF); 515 516 asm(CLEAR_FPSTATUS 517 "%0 = convert_df2ud(%2)\n\t" 518 "%1 = usr\n\t" 519 : "=r"(res64), "=r"(usr) : "r"(DF_small_neg) 520 : "r2", "usr"); 521 check64(res64, 0); 522 check_fpstatus(usr, FPINVF); 523 524 asm(CLEAR_FPSTATUS 525 "%0 = convert_df2ud(%2):chop\n\t" 526 "%1 = usr\n\t" 527 : "=r"(res64), "=r"(usr) : "r"(DF_small_neg) 528 : "r2", "usr"); 529 check64(res64, 0); 530 check_fpstatus(usr, FPINVF); 531 532 /* 533 * Check that the various forms of float-to-signed return -1 for NaN 534 */ 535 asm(CLEAR_FPSTATUS 536 "%0 = convert_sf2w(%2)\n\t" 537 "%1 = usr\n\t" 538 : "=r"(res32), "=r"(usr) : "r"(SF_NaN) 539 : "r2", "usr"); 540 check32(res32, -1); 541 check_fpstatus(usr, FPINVF); 542 543 asm(CLEAR_FPSTATUS 544 "%0 = convert_sf2w(%2):chop\n\t" 545 "%1 = usr\n\t" 546 : "=r"(res32), "=r"(usr) : "r"(SF_NaN) 547 : "r2", "usr"); 548 check32(res32, -1); 549 check_fpstatus(usr, FPINVF); 550 551 asm(CLEAR_FPSTATUS 552 "%0 = convert_sf2d(%2)\n\t" 553 "%1 = usr\n\t" 554 : "=r"(res64), "=r"(usr) : "r"(SF_NaN) 555 : "r2", "usr"); 556 check64(res64, -1); 557 check_fpstatus(usr, FPINVF); 558 559 asm(CLEAR_FPSTATUS 560 "%0 = convert_sf2d(%2):chop\n\t" 561 "%1 = usr\n\t" 562 : "=r"(res64), "=r"(usr) : "r"(SF_NaN) 563 : "r2", "usr"); 564 check64(res64, -1); 565 check_fpstatus(usr, FPINVF); 566 567 asm(CLEAR_FPSTATUS 568 "%0 = convert_df2w(%2)\n\t" 569 "%1 = usr\n\t" 570 : "=r"(res32), "=r"(usr) : "r"(DF_NaN) 571 : "r2", "usr"); 572 check32(res32, -1); 573 check_fpstatus(usr, FPINVF); 574 575 asm(CLEAR_FPSTATUS 576 "%0 = convert_df2w(%2):chop\n\t" 577 "%1 = usr\n\t" 578 : "=r"(res32), "=r"(usr) : "r"(DF_NaN) 579 : "r2", "usr"); 580 check32(res32, -1); 581 check_fpstatus(usr, FPINVF); 582 583 asm(CLEAR_FPSTATUS 584 "%0 = convert_df2d(%2)\n\t" 585 "%1 = usr\n\t" 586 : "=r"(res64), "=r"(usr) : "r"(DF_NaN) 587 : "r2", "usr"); 588 check64(res64, -1); 589 check_fpstatus(usr, FPINVF); 590 591 asm(CLEAR_FPSTATUS 592 "%0 = convert_df2d(%2):chop\n\t" 593 "%1 = usr\n\t" 594 : "=r"(res64), "=r"(usr) : "r"(DF_NaN) 595 : "r2", "usr"); 596 check64(res64, -1); 597 check_fpstatus(usr, FPINVF); 598 } 599 600 int main() 601 { 602 check_compare_exception(); 603 check_sfminmax(); 604 check_dfminmax(); 605 check_recip_exception(); 606 check_canonical_NaN(); 607 check_invsqrta(); 608 check_float2int_convs(); 609 610 puts(err ? "FAIL" : "PASS"); 611 return err ? 1 : 0; 612 } 613