qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

fpstuff.c (19573B)


      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 }