1 /* 2 * Copyright(c) 2020-2022 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 const int SF_denorm = 0x00000001; 42 const int SF_random = 0x346001d6; 43 44 const long long DF_QNaN = 0x7ff8000000000000ULL; 45 const long long DF_SNaN = 0x7ff7000000000000ULL; 46 const long long DF_ANY = 0x3f80000000000000ULL; 47 const long long DF_HEX_NAN = 0xffffffffffffffffULL; 48 const long long DF_small_neg = 0xbd731f7500000000ULL; 49 50 int err; 51 52 #define CLEAR_FPSTATUS \ 53 "r2 = usr\n\t" \ 54 "r2 = clrbit(r2, #1)\n\t" \ 55 "r2 = clrbit(r2, #2)\n\t" \ 56 "r2 = clrbit(r2, #3)\n\t" \ 57 "r2 = clrbit(r2, #4)\n\t" \ 58 "r2 = clrbit(r2, #5)\n\t" \ 59 "usr = r2\n\t" 60 61 static void check_fpstatus_bit(int usr, int expect, int flag, const char *n) 62 { 63 int bit = 1 << flag; 64 if ((usr & bit) != (expect & bit)) { 65 printf("ERROR %s: usr = %d, expect = %d\n", n, 66 (usr >> flag) & 1, (expect >> flag) & 1); 67 err++; 68 } 69 } 70 71 static void check_fpstatus(int usr, int expect) 72 { 73 check_fpstatus_bit(usr, expect, FPINVF_BIT, "Invalid"); 74 check_fpstatus_bit(usr, expect, FPDBZF_BIT, "Div by zero"); 75 check_fpstatus_bit(usr, expect, FPOVFF_BIT, "Overflow"); 76 check_fpstatus_bit(usr, expect, FPUNFF_BIT, "Underflow"); 77 check_fpstatus_bit(usr, expect, FPINPF_BIT, "Inexact"); 78 } 79 80 static void check32(int val, int expect) 81 { 82 if (val != expect) { 83 printf("ERROR: 0x%x != 0x%x\n", val, expect); 84 err++; 85 } 86 } 87 static void check64(unsigned long long val, unsigned long long expect) 88 { 89 if (val != expect) { 90 printf("ERROR: 0x%llx != 0x%llx\n", val, expect); 91 err++; 92 } 93 } 94 95 static void check_compare_exception(void) 96 { 97 int cmp; 98 int usr; 99 100 /* Check that FP compares are quiet (don't raise any execptions) */ 101 asm (CLEAR_FPSTATUS 102 "p0 = sfcmp.eq(%2, %3)\n\t" 103 "%0 = p0\n\t" 104 "%1 = usr\n\t" 105 : "=r"(cmp), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) 106 : "r2", "p0", "usr"); 107 check32(cmp, 0); 108 check_fpstatus(usr, 0); 109 110 asm (CLEAR_FPSTATUS 111 "p0 = sfcmp.gt(%2, %3)\n\t" 112 "%0 = p0\n\t" 113 "%1 = usr\n\t" 114 : "=r"(cmp), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) 115 : "r2", "p0", "usr"); 116 check32(cmp, 0); 117 check_fpstatus(usr, 0); 118 119 asm (CLEAR_FPSTATUS 120 "p0 = sfcmp.ge(%2, %3)\n\t" 121 "%0 = p0\n\t" 122 "%1 = usr\n\t" 123 : "=r"(cmp), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) 124 : "r2", "p0", "usr"); 125 check32(cmp, 0); 126 check_fpstatus(usr, 0); 127 128 asm (CLEAR_FPSTATUS 129 "p0 = dfcmp.eq(%2, %3)\n\t" 130 "%0 = p0\n\t" 131 "%1 = usr\n\t" 132 : "=r"(cmp), "=r"(usr) : "r"(DF_QNaN), "r"(DF_ANY) 133 : "r2", "p0", "usr"); 134 check32(cmp, 0); 135 check_fpstatus(usr, 0); 136 137 asm (CLEAR_FPSTATUS 138 "p0 = dfcmp.gt(%2, %3)\n\t" 139 "%0 = p0\n\t" 140 "%1 = usr\n\t" 141 : "=r"(cmp), "=r"(usr) : "r"(DF_QNaN), "r"(DF_ANY) 142 : "r2", "p0", "usr"); 143 check32(cmp, 0); 144 check_fpstatus(usr, 0); 145 146 asm (CLEAR_FPSTATUS 147 "p0 = dfcmp.ge(%2, %3)\n\t" 148 "%0 = p0\n\t" 149 "%1 = usr\n\t" 150 : "=r"(cmp), "=r"(usr) : "r"(DF_QNaN), "r"(DF_ANY) 151 : "r2", "p0", "usr"); 152 check32(cmp, 0); 153 check_fpstatus(usr, 0); 154 } 155 156 static void check_sfminmax(void) 157 { 158 int minmax; 159 int usr; 160 161 /* 162 * Execute sfmin/sfmax instructions with one operand as NaN 163 * Check that 164 * Result is the other operand 165 * Invalid bit in USR is not set 166 */ 167 asm (CLEAR_FPSTATUS 168 "%0 = sfmin(%2, %3)\n\t" 169 "%1 = usr\n\t" 170 : "=r"(minmax), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) 171 : "r2", "usr"); 172 check64(minmax, SF_ANY); 173 check_fpstatus(usr, 0); 174 175 asm (CLEAR_FPSTATUS 176 "%0 = sfmax(%2, %3)\n\t" 177 "%1 = usr\n\t" 178 : "=r"(minmax), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) 179 : "r2", "usr"); 180 check64(minmax, SF_ANY); 181 check_fpstatus(usr, 0); 182 183 /* 184 * Execute sfmin/sfmax instructions with both operands NaN 185 * Check that 186 * Result is SF_HEX_NAN 187 * Invalid bit in USR is set 188 */ 189 asm (CLEAR_FPSTATUS 190 "%0 = sfmin(%2, %3)\n\t" 191 "%1 = usr\n\t" 192 : "=r"(minmax), "=r"(usr) : "r"(SF_NaN), "r"(SF_NaN) 193 : "r2", "usr"); 194 check64(minmax, SF_HEX_NAN); 195 check_fpstatus(usr, 0); 196 197 asm (CLEAR_FPSTATUS 198 "%0 = sfmax(%2, %3)\n\t" 199 "%1 = usr\n\t" 200 : "=r"(minmax), "=r"(usr) : "r"(SF_NaN), "r"(SF_NaN) 201 : "r2", "usr"); 202 check64(minmax, SF_HEX_NAN); 203 check_fpstatus(usr, 0); 204 } 205 206 static void check_dfminmax(void) 207 { 208 unsigned long long minmax; 209 int usr; 210 211 /* 212 * Execute dfmin/dfmax instructions with one operand as SNaN 213 * Check that 214 * Result is the other operand 215 * Invalid bit in USR is set 216 */ 217 asm (CLEAR_FPSTATUS 218 "%0 = dfmin(%2, %3)\n\t" 219 "%1 = usr\n\t" 220 : "=r"(minmax), "=r"(usr) : "r"(DF_SNaN), "r"(DF_ANY) 221 : "r2", "usr"); 222 check64(minmax, DF_ANY); 223 check_fpstatus(usr, FPINVF); 224 225 asm (CLEAR_FPSTATUS 226 "%0 = dfmax(%2, %3)\n\t" 227 "%1 = usr\n\t" 228 : "=r"(minmax), "=r"(usr) : "r"(DF_SNaN), "r"(DF_ANY) 229 : "r2", "usr"); 230 check64(minmax, DF_ANY); 231 check_fpstatus(usr, FPINVF); 232 233 /* 234 * Execute dfmin/dfmax instructions with one operand as QNaN 235 * Check that 236 * Result is the other operand 237 * No bit in USR is set 238 */ 239 asm (CLEAR_FPSTATUS 240 "%0 = dfmin(%2, %3)\n\t" 241 "%1 = usr\n\t" 242 : "=r"(minmax), "=r"(usr) : "r"(DF_QNaN), "r"(DF_ANY) 243 : "r2", "usr"); 244 check64(minmax, DF_ANY); 245 check_fpstatus(usr, 0); 246 247 asm (CLEAR_FPSTATUS 248 "%0 = dfmax(%2, %3)\n\t" 249 "%1 = usr\n\t" 250 : "=r"(minmax), "=r"(usr) : "r"(DF_QNaN), "r"(DF_ANY) 251 : "r2", "usr"); 252 check64(minmax, DF_ANY); 253 check_fpstatus(usr, 0); 254 255 /* 256 * Execute dfmin/dfmax instructions with both operands SNaN 257 * Check that 258 * Result is DF_HEX_NAN 259 * Invalid bit in USR is set 260 */ 261 asm (CLEAR_FPSTATUS 262 "%0 = dfmin(%2, %3)\n\t" 263 "%1 = usr\n\t" 264 : "=r"(minmax), "=r"(usr) : "r"(DF_SNaN), "r"(DF_SNaN) 265 : "r2", "usr"); 266 check64(minmax, DF_HEX_NAN); 267 check_fpstatus(usr, FPINVF); 268 269 asm (CLEAR_FPSTATUS 270 "%0 = dfmax(%2, %3)\n\t" 271 "%1 = usr\n\t" 272 : "=r"(minmax), "=r"(usr) : "r"(DF_SNaN), "r"(DF_SNaN) 273 : "r2", "usr"); 274 check64(minmax, DF_HEX_NAN); 275 check_fpstatus(usr, FPINVF); 276 277 /* 278 * Execute dfmin/dfmax instructions with both operands QNaN 279 * Check that 280 * Result is DF_HEX_NAN 281 * No bit in USR is set 282 */ 283 asm (CLEAR_FPSTATUS 284 "%0 = dfmin(%2, %3)\n\t" 285 "%1 = usr\n\t" 286 : "=r"(minmax), "=r"(usr) : "r"(DF_QNaN), "r"(DF_QNaN) 287 : "r2", "usr"); 288 check64(minmax, DF_HEX_NAN); 289 check_fpstatus(usr, 0); 290 291 asm (CLEAR_FPSTATUS 292 "%0 = dfmax(%2, %3)\n\t" 293 "%1 = usr\n\t" 294 : "=r"(minmax), "=r"(usr) : "r"(DF_QNaN), "r"(DF_QNaN) 295 : "r2", "usr"); 296 check64(minmax, DF_HEX_NAN); 297 check_fpstatus(usr, 0); 298 } 299 300 static void check_sfrecipa(void) 301 { 302 int result; 303 int usr; 304 int pred; 305 306 /* 307 * Check that sfrecipa doesn't set status bits when 308 * a NaN with bit 22 non-zero is passed 309 */ 310 asm (CLEAR_FPSTATUS 311 "%0,p0 = sfrecipa(%2, %3)\n\t" 312 "%1 = usr\n\t" 313 : "=r"(result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) 314 : "r2", "p0", "usr"); 315 check32(result, SF_HEX_NAN); 316 check_fpstatus(usr, 0); 317 318 asm (CLEAR_FPSTATUS 319 "%0,p0 = sfrecipa(%2, %3)\n\t" 320 "%1 = usr\n\t" 321 : "=r"(result), "=r"(usr) : "r"(SF_ANY), "r"(SF_NaN) 322 : "r2", "p0", "usr"); 323 check32(result, SF_HEX_NAN); 324 check_fpstatus(usr, 0); 325 326 asm (CLEAR_FPSTATUS 327 "%0,p0 = sfrecipa(%2, %2)\n\t" 328 "%1 = usr\n\t" 329 : "=r"(result), "=r"(usr) : "r"(SF_NaN) 330 : "r2", "p0", "usr"); 331 check32(result, SF_HEX_NAN); 332 check_fpstatus(usr, 0); 333 334 /* 335 * Check that sfrecipa doesn't set status bits when 336 * a NaN with bit 22 zero is passed 337 */ 338 asm (CLEAR_FPSTATUS 339 "%0,p0 = sfrecipa(%2, %3)\n\t" 340 "%1 = usr\n\t" 341 : "=r"(result), "=r"(usr) : "r"(SF_NaN_special), "r"(SF_ANY) 342 : "r2", "p0", "usr"); 343 check32(result, SF_HEX_NAN); 344 check_fpstatus(usr, FPINVF); 345 346 asm (CLEAR_FPSTATUS 347 "%0,p0 = sfrecipa(%2, %3)\n\t" 348 "%1 = usr\n\t" 349 : "=r"(result), "=r"(usr) : "r"(SF_ANY), "r"(SF_NaN_special) 350 : "r2", "p0", "usr"); 351 check32(result, SF_HEX_NAN); 352 check_fpstatus(usr, FPINVF); 353 354 asm (CLEAR_FPSTATUS 355 "%0,p0 = sfrecipa(%2, %2)\n\t" 356 "%1 = usr\n\t" 357 : "=r"(result), "=r"(usr) : "r"(SF_NaN_special) 358 : "r2", "p0", "usr"); 359 check32(result, SF_HEX_NAN); 360 check_fpstatus(usr, FPINVF); 361 362 /* 363 * Check that sfrecipa properly sets divid-by-zero 364 */ 365 asm (CLEAR_FPSTATUS 366 "%0,p0 = sfrecipa(%2, %3)\n\t" 367 "%1 = usr\n\t" 368 : "=r"(result), "=r"(usr) : "r"(0x885dc960), "r"(0x80000000) 369 : "r2", "p0", "usr"); 370 check32(result, 0x3f800000); 371 check_fpstatus(usr, FPDBZF); 372 373 asm (CLEAR_FPSTATUS 374 "%0,p0 = sfrecipa(%2, %3)\n\t" 375 "%1 = usr\n\t" 376 : "=r"(result), "=r"(usr) : "r"(0x7f800000), "r"(SF_ZERO) 377 : "r2", "p0", "usr"); 378 check32(result, 0x3f800000); 379 check_fpstatus(usr, 0); 380 381 /* 382 * Check that sfrecipa properly handles denorm 383 */ 384 asm (CLEAR_FPSTATUS 385 "%0,p0 = sfrecipa(%2, %3)\n\t" 386 "%1 = p0\n\t" 387 : "=r"(result), "=r"(pred) : "r"(SF_denorm), "r"(SF_random) 388 : "p0", "usr"); 389 check32(result, 0x6a920001); 390 check32(pred, 0x80); 391 } 392 393 static void check_canonical_NaN(void) 394 { 395 int sf_result; 396 unsigned long long df_result; 397 int usr; 398 399 /* Check that each FP instruction properly returns SF_HEX_NAN/DF_HEX_NAN */ 400 asm(CLEAR_FPSTATUS 401 "%0 = sfadd(%2, %3)\n\t" 402 "%1 = usr\n\t" 403 : "=r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) 404 : "r2", "usr"); 405 check32(sf_result, SF_HEX_NAN); 406 check_fpstatus(usr, 0); 407 408 asm(CLEAR_FPSTATUS 409 "%0 = sfsub(%2, %3)\n\t" 410 "%1 = usr\n\t" 411 : "=r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) 412 : "r2", "usr"); 413 check32(sf_result, SF_HEX_NAN); 414 check_fpstatus(usr, 0); 415 416 asm(CLEAR_FPSTATUS 417 "%0 = sfmpy(%2, %3)\n\t" 418 "%1 = usr\n\t" 419 : "=r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) 420 : "r2", "usr"); 421 check32(sf_result, SF_HEX_NAN); 422 check_fpstatus(usr, 0); 423 424 sf_result = SF_ZERO; 425 asm(CLEAR_FPSTATUS 426 "%0 += sfmpy(%2, %3)\n\t" 427 "%1 = usr\n\t" 428 : "+r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) 429 : "r2", "usr"); 430 check32(sf_result, SF_HEX_NAN); 431 check_fpstatus(usr, 0); 432 433 sf_result = SF_ZERO; 434 asm(CLEAR_FPSTATUS 435 "p0 = !cmp.eq(r0, r0)\n\t" 436 "%0 += sfmpy(%2, %3, p0):scale\n\t" 437 "%1 = usr\n\t" 438 : "+r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) 439 : "r2", "usr", "p0"); 440 check32(sf_result, SF_HEX_NAN); 441 check_fpstatus(usr, 0); 442 443 sf_result = SF_ZERO; 444 asm(CLEAR_FPSTATUS 445 "%0 -= sfmpy(%2, %3)\n\t" 446 "%1 = usr\n\t" 447 : "+r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) 448 : "r2", "usr"); 449 check32(sf_result, SF_HEX_NAN); 450 check_fpstatus(usr, 0); 451 452 sf_result = SF_ZERO; 453 asm(CLEAR_FPSTATUS 454 "%0 += sfmpy(%2, %3):lib\n\t" 455 "%1 = usr\n\t" 456 : "+r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) 457 : "r2", "usr"); 458 check32(sf_result, SF_HEX_NAN); 459 check_fpstatus(usr, 0); 460 461 sf_result = SF_ZERO; 462 asm(CLEAR_FPSTATUS 463 "%0 -= sfmpy(%2, %3):lib\n\t" 464 "%1 = usr\n\t" 465 : "+r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY) 466 : "r2", "usr"); 467 check32(sf_result, SF_HEX_NAN); 468 check_fpstatus(usr, 0); 469 470 asm(CLEAR_FPSTATUS 471 "%0 = convert_df2sf(%2)\n\t" 472 "%1 = usr\n\t" 473 : "=r"(sf_result), "=r"(usr) : "r"(DF_QNaN) 474 : "r2", "usr"); 475 check32(sf_result, SF_HEX_NAN); 476 check_fpstatus(usr, 0); 477 478 asm(CLEAR_FPSTATUS 479 "%0 = dfadd(%2, %3)\n\t" 480 "%1 = usr\n\t" 481 : "=r"(df_result), "=r"(usr) : "r"(DF_QNaN), "r"(DF_ANY) 482 : "r2", "usr"); 483 check64(df_result, DF_HEX_NAN); 484 check_fpstatus(usr, 0); 485 486 asm(CLEAR_FPSTATUS 487 "%0 = dfsub(%2, %3)\n\t" 488 "%1 = usr\n\t" 489 : "=r"(df_result), "=r"(usr) : "r"(DF_QNaN), "r"(DF_ANY) 490 : "r2", "usr"); 491 check64(df_result, DF_HEX_NAN); 492 check_fpstatus(usr, 0); 493 494 asm(CLEAR_FPSTATUS 495 "%0 = convert_sf2df(%2)\n\t" 496 "%1 = usr\n\t" 497 : "=r"(df_result), "=r"(usr) : "r"(SF_NaN) 498 : "r2", "usr"); 499 check64(df_result, DF_HEX_NAN); 500 check_fpstatus(usr, 0); 501 } 502 503 static void check_invsqrta(void) 504 { 505 int result; 506 int predval; 507 508 asm volatile("%0,p0 = sfinvsqrta(%2)\n\t" 509 "%1 = p0\n\t" 510 : "+r"(result), "=r"(predval) 511 : "r"(0x7f800000) 512 : "p0"); 513 check32(result, 0xff800000); 514 check32(predval, 0x0); 515 } 516 517 static void check_sffixupn(void) 518 { 519 int result; 520 521 /* Check that sffixupn properly deals with denorm */ 522 asm volatile("%0 = sffixupn(%1, %2)\n\t" 523 : "=r"(result) 524 : "r"(SF_random), "r"(SF_denorm)); 525 check32(result, 0x246001d6); 526 } 527 528 static void check_sffixupd(void) 529 { 530 int result; 531 532 /* Check that sffixupd properly deals with denorm */ 533 asm volatile("%0 = sffixupd(%1, %2)\n\t" 534 : "=r"(result) 535 : "r"(SF_denorm), "r"(SF_random)); 536 check32(result, 0x146001d6); 537 } 538 539 static void check_float2int_convs() 540 { 541 int res32; 542 long long res64; 543 int usr; 544 545 /* 546 * Check that the various forms of float-to-unsigned 547 * check sign before rounding 548 */ 549 asm(CLEAR_FPSTATUS 550 "%0 = convert_sf2uw(%2)\n\t" 551 "%1 = usr\n\t" 552 : "=r"(res32), "=r"(usr) : "r"(SF_small_neg) 553 : "r2", "usr"); 554 check32(res32, 0); 555 check_fpstatus(usr, FPINVF); 556 557 asm(CLEAR_FPSTATUS 558 "%0 = convert_sf2uw(%2):chop\n\t" 559 "%1 = usr\n\t" 560 : "=r"(res32), "=r"(usr) : "r"(SF_small_neg) 561 : "r2", "usr"); 562 check32(res32, 0); 563 check_fpstatus(usr, FPINVF); 564 565 asm(CLEAR_FPSTATUS 566 "%0 = convert_sf2ud(%2)\n\t" 567 "%1 = usr\n\t" 568 : "=r"(res64), "=r"(usr) : "r"(SF_small_neg) 569 : "r2", "usr"); 570 check64(res64, 0); 571 check_fpstatus(usr, FPINVF); 572 573 asm(CLEAR_FPSTATUS 574 "%0 = convert_sf2ud(%2):chop\n\t" 575 "%1 = usr\n\t" 576 : "=r"(res64), "=r"(usr) : "r"(SF_small_neg) 577 : "r2", "usr"); 578 check64(res64, 0); 579 check_fpstatus(usr, FPINVF); 580 581 asm(CLEAR_FPSTATUS 582 "%0 = convert_df2uw(%2)\n\t" 583 "%1 = usr\n\t" 584 : "=r"(res32), "=r"(usr) : "r"(DF_small_neg) 585 : "r2", "usr"); 586 check32(res32, 0); 587 check_fpstatus(usr, FPINVF); 588 589 asm(CLEAR_FPSTATUS 590 "%0 = convert_df2uw(%2):chop\n\t" 591 "%1 = usr\n\t" 592 : "=r"(res32), "=r"(usr) : "r"(DF_small_neg) 593 : "r2", "usr"); 594 check32(res32, 0); 595 check_fpstatus(usr, FPINVF); 596 597 asm(CLEAR_FPSTATUS 598 "%0 = convert_df2ud(%2)\n\t" 599 "%1 = usr\n\t" 600 : "=r"(res64), "=r"(usr) : "r"(DF_small_neg) 601 : "r2", "usr"); 602 check64(res64, 0); 603 check_fpstatus(usr, FPINVF); 604 605 asm(CLEAR_FPSTATUS 606 "%0 = convert_df2ud(%2):chop\n\t" 607 "%1 = usr\n\t" 608 : "=r"(res64), "=r"(usr) : "r"(DF_small_neg) 609 : "r2", "usr"); 610 check64(res64, 0); 611 check_fpstatus(usr, FPINVF); 612 613 /* 614 * Check that the various forms of float-to-signed return -1 for NaN 615 */ 616 asm(CLEAR_FPSTATUS 617 "%0 = convert_sf2w(%2)\n\t" 618 "%1 = usr\n\t" 619 : "=r"(res32), "=r"(usr) : "r"(SF_NaN) 620 : "r2", "usr"); 621 check32(res32, -1); 622 check_fpstatus(usr, FPINVF); 623 624 asm(CLEAR_FPSTATUS 625 "%0 = convert_sf2w(%2):chop\n\t" 626 "%1 = usr\n\t" 627 : "=r"(res32), "=r"(usr) : "r"(SF_NaN) 628 : "r2", "usr"); 629 check32(res32, -1); 630 check_fpstatus(usr, FPINVF); 631 632 asm(CLEAR_FPSTATUS 633 "%0 = convert_sf2d(%2)\n\t" 634 "%1 = usr\n\t" 635 : "=r"(res64), "=r"(usr) : "r"(SF_NaN) 636 : "r2", "usr"); 637 check64(res64, -1); 638 check_fpstatus(usr, FPINVF); 639 640 asm(CLEAR_FPSTATUS 641 "%0 = convert_sf2d(%2):chop\n\t" 642 "%1 = usr\n\t" 643 : "=r"(res64), "=r"(usr) : "r"(SF_NaN) 644 : "r2", "usr"); 645 check64(res64, -1); 646 check_fpstatus(usr, FPINVF); 647 648 asm(CLEAR_FPSTATUS 649 "%0 = convert_df2w(%2)\n\t" 650 "%1 = usr\n\t" 651 : "=r"(res32), "=r"(usr) : "r"(DF_QNaN) 652 : "r2", "usr"); 653 check32(res32, -1); 654 check_fpstatus(usr, FPINVF); 655 656 asm(CLEAR_FPSTATUS 657 "%0 = convert_df2w(%2):chop\n\t" 658 "%1 = usr\n\t" 659 : "=r"(res32), "=r"(usr) : "r"(DF_QNaN) 660 : "r2", "usr"); 661 check32(res32, -1); 662 check_fpstatus(usr, FPINVF); 663 664 asm(CLEAR_FPSTATUS 665 "%0 = convert_df2d(%2)\n\t" 666 "%1 = usr\n\t" 667 : "=r"(res64), "=r"(usr) : "r"(DF_QNaN) 668 : "r2", "usr"); 669 check64(res64, -1); 670 check_fpstatus(usr, FPINVF); 671 672 asm(CLEAR_FPSTATUS 673 "%0 = convert_df2d(%2):chop\n\t" 674 "%1 = usr\n\t" 675 : "=r"(res64), "=r"(usr) : "r"(DF_QNaN) 676 : "r2", "usr"); 677 check64(res64, -1); 678 check_fpstatus(usr, FPINVF); 679 } 680 681 int main() 682 { 683 check_compare_exception(); 684 check_sfminmax(); 685 check_dfminmax(); 686 check_sfrecipa(); 687 check_canonical_NaN(); 688 check_invsqrta(); 689 check_sffixupn(); 690 check_sffixupd(); 691 check_float2int_convs(); 692 693 puts(err ? "FAIL" : "PASS"); 694 return err ? 1 : 0; 695 } 696