Home | History | Annotate | Download | only in rtest
      1 /*
      2  * semi.c: test implementations of mathlib seminumerical functions
      3  *
      4  * Copyright (c) 1999-2018, Arm Limited.
      5  * SPDX-License-Identifier: MIT
      6  */
      7 
      8 #include <stdio.h>
      9 #include "semi.h"
     10 
     11 static void test_rint(uint32 *in, uint32 *out,
     12                        int isfloor, int isceil) {
     13     int sign = in[0] & 0x80000000;
     14     int roundup = (isfloor && sign) || (isceil && !sign);
     15     uint32 xh, xl, roundword;
     16     int ex = (in[0] >> 20) & 0x7FF;    /* exponent */
     17     int i;
     18 
     19     if ((ex > 0x3ff + 52 - 1) ||     /* things this big can't be fractional */
     20         ((in[0] & 0x7FFFFFFF) == 0 && in[1] == 0)) {   /* zero */
     21         /* NaN, Inf, a large integer, or zero: just return the input */
     22         out[0] = in[0];
     23         out[1] = in[1];
     24         return;
     25     }
     26 
     27     /*
     28      * Special case: ex < 0x3ff, ie our number is in (0,1). Return
     29      * 1 or 0 according to roundup.
     30      */
     31     if (ex < 0x3ff) {
     32         out[0] = sign | (roundup ? 0x3FF00000 : 0);
     33         out[1] = 0;
     34         return;
     35     }
     36 
     37     /*
     38      * We're not short of time here, so we'll do this the hideously
     39      * inefficient way. Shift bit by bit so that the units place is
     40      * somewhere predictable, round, and shift back again.
     41      */
     42     xh = in[0];
     43     xl = in[1];
     44     roundword = 0;
     45     for (i = ex; i < 0x3ff + 52; i++) {
     46         if (roundword & 1)
     47             roundword |= 2;            /* preserve sticky bit */
     48         roundword = (roundword >> 1) | ((xl & 1) << 31);
     49         xl = (xl >> 1) | ((xh & 1) << 31);
     50         xh = xh >> 1;
     51     }
     52     if (roundword && roundup) {
     53         xl++;
     54         xh += (xl==0);
     55     }
     56     for (i = ex; i < 0x3ff + 52; i++) {
     57         xh = (xh << 1) | ((xl >> 31) & 1);
     58         xl = (xl & 0x7FFFFFFF) << 1;
     59     }
     60     out[0] = xh;
     61     out[1] = xl;
     62 }
     63 
     64 char *test_ceil(uint32 *in, uint32 *out) {
     65     test_rint(in, out, 0, 1);
     66     return NULL;
     67 }
     68 
     69 char *test_floor(uint32 *in, uint32 *out) {
     70     test_rint(in, out, 1, 0);
     71     return NULL;
     72 }
     73 
     74 static void test_rintf(uint32 *in, uint32 *out,
     75                        int isfloor, int isceil) {
     76     int sign = *in & 0x80000000;
     77     int roundup = (isfloor && sign) || (isceil && !sign);
     78     uint32 x, roundword;
     79     int ex = (*in >> 23) & 0xFF;       /* exponent */
     80     int i;
     81 
     82     if ((ex > 0x7f + 23 - 1) ||      /* things this big can't be fractional */
     83         (*in & 0x7FFFFFFF) == 0) {     /* zero */
     84         /* NaN, Inf, a large integer, or zero: just return the input */
     85         *out = *in;
     86         return;
     87     }
     88 
     89     /*
     90      * Special case: ex < 0x7f, ie our number is in (0,1). Return
     91      * 1 or 0 according to roundup.
     92      */
     93     if (ex < 0x7f) {
     94         *out = sign | (roundup ? 0x3F800000 : 0);
     95         return;
     96     }
     97 
     98     /*
     99      * We're not short of time here, so we'll do this the hideously
    100      * inefficient way. Shift bit by bit so that the units place is
    101      * somewhere predictable, round, and shift back again.
    102      */
    103     x = *in;
    104     roundword = 0;
    105     for (i = ex; i < 0x7F + 23; i++) {
    106         if (roundword & 1)
    107             roundword |= 2;            /* preserve sticky bit */
    108         roundword = (roundword >> 1) | ((x & 1) << 31);
    109         x = x >> 1;
    110     }
    111     if (roundword && roundup) {
    112         x++;
    113     }
    114     for (i = ex; i < 0x7F + 23; i++) {
    115         x = x << 1;
    116     }
    117     *out = x;
    118 }
    119 
    120 char *test_ceilf(uint32 *in, uint32 *out) {
    121     test_rintf(in, out, 0, 1);
    122     return NULL;
    123 }
    124 
    125 char *test_floorf(uint32 *in, uint32 *out) {
    126     test_rintf(in, out, 1, 0);
    127     return NULL;
    128 }
    129 
    130 char *test_fmod(uint32 *a, uint32 *b, uint32 *out) {
    131     int sign;
    132     int32 aex, bex;
    133     uint32 am[2], bm[2];
    134 
    135     if (((a[0] & 0x7FFFFFFF) << 1) + !!a[1] > 0xFFE00000 ||
    136         ((b[0] & 0x7FFFFFFF) << 1) + !!b[1] > 0xFFE00000) {
    137         /* a or b is NaN: return QNaN, optionally with IVO */
    138         uint32 an, bn;
    139         out[0] = 0x7ff80000;
    140         out[1] = 1;
    141         an = ((a[0] & 0x7FFFFFFF) << 1) + !!a[1];
    142         bn = ((b[0] & 0x7FFFFFFF) << 1) + !!b[1];
    143         if ((an > 0xFFE00000 && an < 0xFFF00000) ||
    144             (bn > 0xFFE00000 && bn < 0xFFF00000))
    145             return "i";                /* at least one SNaN: IVO */
    146         else
    147             return NULL;               /* no SNaNs, but at least 1 QNaN */
    148     }
    149     if ((b[0] & 0x7FFFFFFF) == 0 && b[1] == 0) {   /* b==0: EDOM */
    150         out[0] = 0x7ff80000;
    151         out[1] = 1;
    152         return "EDOM status=i";
    153     }
    154     if ((a[0] & 0x7FF00000) == 0x7FF00000) {   /* a==Inf: EDOM */
    155         out[0] = 0x7ff80000;
    156         out[1] = 1;
    157         return "EDOM status=i";
    158     }
    159     if ((b[0] & 0x7FF00000) == 0x7FF00000) {   /* b==Inf: return a */
    160         out[0] = a[0];
    161         out[1] = a[1];
    162         return NULL;
    163     }
    164     if ((a[0] & 0x7FFFFFFF) == 0 && a[1] == 0) {   /* a==0: return a */
    165         out[0] = a[0];
    166         out[1] = a[1];
    167         return NULL;
    168     }
    169 
    170     /*
    171      * OK. That's the special cases cleared out of the way. Now we
    172      * have finite (though not necessarily normal) a and b.
    173      */
    174     sign = a[0] & 0x80000000;          /* we discard sign of b */
    175     test_frexp(a, am, (uint32 *)&aex);
    176     test_frexp(b, bm, (uint32 *)&bex);
    177     am[0] &= 0xFFFFF, am[0] |= 0x100000;
    178     bm[0] &= 0xFFFFF, bm[0] |= 0x100000;
    179 
    180     while (aex >= bex) {
    181         if (am[0] > bm[0] || (am[0] == bm[0] && am[1] >= bm[1])) {
    182             am[1] -= bm[1];
    183             am[0] = am[0] - bm[0] - (am[1] > ~bm[1]);
    184         }
    185         if (aex > bex) {
    186             am[0] = (am[0] << 1) | ((am[1] & 0x80000000) >> 31);
    187             am[1] <<= 1;
    188             aex--;
    189         } else
    190             break;
    191     }
    192 
    193     /*
    194      * Renormalise final result; this can be cunningly done by
    195      * passing a denormal to ldexp.
    196      */
    197     aex += 0x3fd;
    198     am[0] |= sign;
    199     test_ldexp(am, (uint32 *)&aex, out);
    200 
    201     return NULL;                       /* FIXME */
    202 }
    203 
    204 char *test_fmodf(uint32 *a, uint32 *b, uint32 *out) {
    205     int sign;
    206     int32 aex, bex;
    207     uint32 am, bm;
    208 
    209     if ((*a & 0x7FFFFFFF) > 0x7F800000 ||
    210         (*b & 0x7FFFFFFF) > 0x7F800000) {
    211         /* a or b is NaN: return QNaN, optionally with IVO */
    212         uint32 an, bn;
    213         *out = 0x7fc00001;
    214         an = *a & 0x7FFFFFFF;
    215         bn = *b & 0x7FFFFFFF;
    216         if ((an > 0x7f800000 && an < 0x7fc00000) ||
    217             (bn > 0x7f800000 && bn < 0x7fc00000))
    218             return "i";                /* at least one SNaN: IVO */
    219         else
    220             return NULL;               /* no SNaNs, but at least 1 QNaN */
    221     }
    222     if ((*b & 0x7FFFFFFF) == 0) {      /* b==0: EDOM */
    223         *out = 0x7fc00001;
    224         return "EDOM status=i";
    225     }
    226     if ((*a & 0x7F800000) == 0x7F800000) {   /* a==Inf: EDOM */
    227         *out = 0x7fc00001;
    228         return "EDOM status=i";
    229     }
    230     if ((*b & 0x7F800000) == 0x7F800000) {   /* b==Inf: return a */
    231         *out = *a;
    232         return NULL;
    233     }
    234     if ((*a & 0x7FFFFFFF) == 0) {      /* a==0: return a */
    235         *out = *a;
    236         return NULL;
    237     }
    238 
    239     /*
    240      * OK. That's the special cases cleared out of the way. Now we
    241      * have finite (though not necessarily normal) a and b.
    242      */
    243     sign = a[0] & 0x80000000;          /* we discard sign of b */
    244     test_frexpf(a, &am, (uint32 *)&aex);
    245     test_frexpf(b, &bm, (uint32 *)&bex);
    246     am &= 0x7FFFFF, am |= 0x800000;
    247     bm &= 0x7FFFFF, bm |= 0x800000;
    248 
    249     while (aex >= bex) {
    250         if (am >= bm) {
    251             am -= bm;
    252         }
    253         if (aex > bex) {
    254             am <<= 1;
    255             aex--;
    256         } else
    257             break;
    258     }
    259 
    260     /*
    261      * Renormalise final result; this can be cunningly done by
    262      * passing a denormal to ldexp.
    263      */
    264     aex += 0x7d;
    265     am |= sign;
    266     test_ldexpf(&am, (uint32 *)&aex, out);
    267 
    268     return NULL;                       /* FIXME */
    269 }
    270 
    271 char *test_ldexp(uint32 *x, uint32 *np, uint32 *out) {
    272     int n = *np;
    273     int32 n2;
    274     uint32 y[2];
    275     int ex = (x[0] >> 20) & 0x7FF;     /* exponent */
    276     int sign = x[0] & 0x80000000;
    277 
    278     if (ex == 0x7FF) {                 /* inf/NaN; just return x */
    279         out[0] = x[0];
    280         out[1] = x[1];
    281         return NULL;
    282     }
    283     if ((x[0] & 0x7FFFFFFF) == 0 && x[1] == 0) {   /* zero: return x */
    284         out[0] = x[0];
    285         out[1] = x[1];
    286         return NULL;
    287     }
    288 
    289     test_frexp(x, y, (uint32 *)&n2);
    290     ex = n + n2;
    291     if (ex > 0x400) {                  /* overflow */
    292         out[0] = sign | 0x7FF00000;
    293         out[1] = 0;
    294         return "overflow";
    295     }
    296     /*
    297      * Underflow. 2^-1074 is 00000000.00000001; so if ex == -1074
    298      * then we have something [2^-1075,2^-1074). Under round-to-
    299      * nearest-even, this whole interval rounds up to 2^-1074,
    300      * except for the bottom endpoint which rounds to even and is
    301      * an underflow condition.
    302      *
    303      * So, ex < -1074 is definite underflow, and ex == -1074 is
    304      * underflow iff all mantissa bits are zero.
    305      */
    306     if (ex < -1074 || (ex == -1074 && (y[0] & 0xFFFFF) == 0 && y[1] == 0)) {
    307         out[0] = sign;                 /* underflow: correctly signed zero */
    308         out[1] = 0;
    309         return "underflow";
    310     }
    311 
    312     /*
    313      * No overflow or underflow; should be nice and simple, unless
    314      * we have to denormalise and round the result.
    315      */
    316     if (ex < -1021) {                  /* denormalise and round */
    317         uint32 roundword;
    318         y[0] &= 0x000FFFFF;
    319         y[0] |= 0x00100000;            /* set leading bit */
    320         roundword = 0;
    321         while (ex < -1021) {
    322             if (roundword & 1)
    323                 roundword |= 2;        /* preserve sticky bit */
    324             roundword = (roundword >> 1) | ((y[1] & 1) << 31);
    325             y[1] = (y[1] >> 1) | ((y[0] & 1) << 31);
    326             y[0] = y[0] >> 1;
    327             ex++;
    328         }
    329         if (roundword > 0x80000000 ||  /* round up */
    330             (roundword == 0x80000000 && (y[1] & 1))) {  /* round up to even */
    331             y[1]++;
    332             y[0] += (y[1] == 0);
    333         }
    334         out[0] = sign | y[0];
    335         out[1] = y[1];
    336         /* Proper ERANGE underflow was handled earlier, but we still
    337          * expect an IEEE Underflow exception if this partially
    338          * underflowed result is not exact. */
    339         if (roundword)
    340             return "u";
    341         return NULL;                   /* underflow was handled earlier */
    342     } else {
    343         out[0] = y[0] + (ex << 20);
    344         out[1] = y[1];
    345         return NULL;
    346     }
    347 }
    348 
    349 char *test_ldexpf(uint32 *x, uint32 *np, uint32 *out) {
    350     int n = *np;
    351     int32 n2;
    352     uint32 y;
    353     int ex = (*x >> 23) & 0xFF;     /* exponent */
    354     int sign = *x & 0x80000000;
    355 
    356     if (ex == 0xFF) {                 /* inf/NaN; just return x */
    357         *out = *x;
    358         return NULL;
    359     }
    360     if ((*x & 0x7FFFFFFF) == 0) {      /* zero: return x */
    361         *out = *x;
    362         return NULL;
    363     }
    364 
    365     test_frexpf(x, &y, (uint32 *)&n2);
    366     ex = n + n2;
    367     if (ex > 0x80) {                  /* overflow */
    368         *out = sign | 0x7F800000;
    369         return "overflow";
    370     }
    371     /*
    372      * Underflow. 2^-149 is 00000001; so if ex == -149 then we have
    373      * something [2^-150,2^-149). Under round-to- nearest-even,
    374      * this whole interval rounds up to 2^-149, except for the
    375      * bottom endpoint which rounds to even and is an underflow
    376      * condition.
    377      *
    378      * So, ex < -149 is definite underflow, and ex == -149 is
    379      * underflow iff all mantissa bits are zero.
    380      */
    381     if (ex < -149 || (ex == -149 && (y & 0x7FFFFF) == 0)) {
    382         *out = sign;                 /* underflow: correctly signed zero */
    383         return "underflow";
    384     }
    385 
    386     /*
    387      * No overflow or underflow; should be nice and simple, unless
    388      * we have to denormalise and round the result.
    389      */
    390     if (ex < -125) {                  /* denormalise and round */
    391         uint32 roundword;
    392         y &= 0x007FFFFF;
    393         y |= 0x00800000;               /* set leading bit */
    394         roundword = 0;
    395         while (ex < -125) {
    396             if (roundword & 1)
    397                 roundword |= 2;        /* preserve sticky bit */
    398             roundword = (roundword >> 1) | ((y & 1) << 31);
    399             y = y >> 1;
    400             ex++;
    401         }
    402         if (roundword > 0x80000000 ||  /* round up */
    403             (roundword == 0x80000000 && (y & 1))) {  /* round up to even */
    404             y++;
    405         }
    406         *out = sign | y;
    407         /* Proper ERANGE underflow was handled earlier, but we still
    408          * expect an IEEE Underflow exception if this partially
    409          * underflowed result is not exact. */
    410         if (roundword)
    411             return "u";
    412         return NULL;                   /* underflow was handled earlier */
    413     } else {
    414         *out = y + (ex << 23);
    415         return NULL;
    416     }
    417 }
    418 
    419 char *test_frexp(uint32 *x, uint32 *out, uint32 *nout) {
    420     int ex = (x[0] >> 20) & 0x7FF;     /* exponent */
    421     if (ex == 0x7FF) {                 /* inf/NaN; return x/0 */
    422         out[0] = x[0];
    423         out[1] = x[1];
    424         nout[0] = 0;
    425         return NULL;
    426     }
    427     if (ex == 0) {                     /* denormals/zeros */
    428         int sign;
    429         uint32 xh, xl;
    430         if ((x[0] & 0x7FFFFFFF) == 0 && x[1] == 0) {
    431             /* zero: return x/0 */
    432             out[0] = x[0];
    433             out[1] = x[1];
    434             nout[0] = 0;
    435             return NULL;
    436         }
    437         sign = x[0] & 0x80000000;
    438         xh = x[0] & 0x7FFFFFFF;
    439         xl = x[1];
    440         ex = 1;
    441         while (!(xh & 0x100000)) {
    442             ex--;
    443             xh = (xh << 1) | ((xl >> 31) & 1);
    444             xl = (xl & 0x7FFFFFFF) << 1;
    445         }
    446         out[0] = sign | 0x3FE00000 | (xh & 0xFFFFF);
    447         out[1] = xl;
    448         nout[0] = ex - 0x3FE;
    449         return NULL;
    450     }
    451     out[0] = 0x3FE00000 | (x[0] & 0x800FFFFF);
    452     out[1] = x[1];
    453     nout[0] = ex - 0x3FE;
    454     return NULL;                       /* ordinary number; no error */
    455 }
    456 
    457 char *test_frexpf(uint32 *x, uint32 *out, uint32 *nout) {
    458     int ex = (*x >> 23) & 0xFF;        /* exponent */
    459     if (ex == 0xFF) {                  /* inf/NaN; return x/0 */
    460         *out = *x;
    461         nout[0] = 0;
    462         return NULL;
    463     }
    464     if (ex == 0) {                     /* denormals/zeros */
    465         int sign;
    466         uint32 xv;
    467         if ((*x & 0x7FFFFFFF) == 0) {
    468             /* zero: return x/0 */
    469             *out = *x;
    470             nout[0] = 0;
    471             return NULL;
    472         }
    473         sign = *x & 0x80000000;
    474         xv = *x & 0x7FFFFFFF;
    475         ex = 1;
    476         while (!(xv & 0x800000)) {
    477             ex--;
    478             xv = xv << 1;
    479         }
    480         *out = sign | 0x3F000000 | (xv & 0x7FFFFF);
    481         nout[0] = ex - 0x7E;
    482         return NULL;
    483     }
    484     *out = 0x3F000000 | (*x & 0x807FFFFF);
    485     nout[0] = ex - 0x7E;
    486     return NULL;                       /* ordinary number; no error */
    487 }
    488 
    489 char *test_modf(uint32 *x, uint32 *fout, uint32 *iout) {
    490     int ex = (x[0] >> 20) & 0x7FF;     /* exponent */
    491     int sign = x[0] & 0x80000000;
    492     uint32 fh, fl;
    493 
    494     if (((x[0] & 0x7FFFFFFF) | (!!x[1])) > 0x7FF00000) {
    495         /*
    496          * NaN input: return the same in _both_ outputs.
    497          */
    498         fout[0] = iout[0] = x[0];
    499         fout[1] = iout[1] = x[1];
    500         return NULL;
    501     }
    502 
    503     test_rint(x, iout, 0, 0);
    504     fh = x[0] - iout[0];
    505     fl = x[1] - iout[1];
    506     if (!fh && !fl) {                  /* no fraction part */
    507         fout[0] = sign;
    508         fout[1] = 0;
    509         return NULL;
    510     }
    511     if (!(iout[0] & 0x7FFFFFFF) && !iout[1]) {   /* no integer part */
    512         fout[0] = x[0];
    513         fout[1] = x[1];
    514         return NULL;
    515     }
    516     while (!(fh & 0x100000)) {
    517         ex--;
    518         fh = (fh << 1) | ((fl >> 31) & 1);
    519         fl = (fl & 0x7FFFFFFF) << 1;
    520     }
    521     fout[0] = sign | (ex << 20) | (fh & 0xFFFFF);
    522     fout[1] = fl;
    523     return NULL;
    524 }
    525 
    526 char *test_modff(uint32 *x, uint32 *fout, uint32 *iout) {
    527     int ex = (*x >> 23) & 0xFF;        /* exponent */
    528     int sign = *x & 0x80000000;
    529     uint32 f;
    530 
    531     if ((*x & 0x7FFFFFFF) > 0x7F800000) {
    532         /*
    533          * NaN input: return the same in _both_ outputs.
    534          */
    535         *fout = *iout = *x;
    536         return NULL;
    537     }
    538 
    539     test_rintf(x, iout, 0, 0);
    540     f = *x - *iout;
    541     if (!f) {                          /* no fraction part */
    542         *fout = sign;
    543         return NULL;
    544     }
    545     if (!(*iout & 0x7FFFFFFF)) {       /* no integer part */
    546         *fout = *x;
    547         return NULL;
    548     }
    549     while (!(f & 0x800000)) {
    550         ex--;
    551         f = f << 1;
    552     }
    553     *fout = sign | (ex << 23) | (f & 0x7FFFFF);
    554     return NULL;
    555 }
    556 
    557 char *test_copysign(uint32 *x, uint32 *y, uint32 *out)
    558 {
    559     int ysign = y[0] & 0x80000000;
    560     int xhigh = x[0] & 0x7fffffff;
    561 
    562     out[0] = ysign | xhigh;
    563     out[1] = x[1];
    564 
    565     /* There can be no error */
    566     return NULL;
    567 }
    568 
    569 char *test_copysignf(uint32 *x, uint32 *y, uint32 *out)
    570 {
    571     int ysign = y[0] & 0x80000000;
    572     int xhigh = x[0] & 0x7fffffff;
    573 
    574     out[0] = ysign | xhigh;
    575 
    576     /* There can be no error */
    577     return NULL;
    578 }
    579 
    580 char *test_isfinite(uint32 *x, uint32 *out)
    581 {
    582     int xhigh = x[0];
    583     /* Being finite means that the exponent is not 0x7ff */
    584     if ((xhigh & 0x7ff00000) == 0x7ff00000) out[0] = 0;
    585     else out[0] = 1;
    586     return NULL;
    587 }
    588 
    589 char *test_isfinitef(uint32 *x, uint32 *out)
    590 {
    591     /* Being finite means that the exponent is not 0xff */
    592     if ((x[0] & 0x7f800000) == 0x7f800000) out[0] = 0;
    593     else out[0] = 1;
    594     return NULL;
    595 }
    596 
    597 char *test_isinff(uint32 *x, uint32 *out)
    598 {
    599     /* Being infinite means that our bottom 30 bits equate to 0x7f800000 */
    600     if ((x[0] & 0x7fffffff) == 0x7f800000) out[0] = 1;
    601     else out[0] = 0;
    602     return NULL;
    603 }
    604 
    605 char *test_isinf(uint32 *x, uint32 *out)
    606 {
    607     int xhigh = x[0];
    608     int xlow = x[1];
    609     /* Being infinite means that our fraction is zero and exponent is 0x7ff */
    610     if (((xhigh & 0x7fffffff) == 0x7ff00000) && (xlow == 0)) out[0] = 1;
    611     else out[0] = 0;
    612     return NULL;
    613 }
    614 
    615 char *test_isnanf(uint32 *x, uint32 *out)
    616 {
    617     /* Being NaN means that our exponent is 0xff and non-0 fraction */
    618     int exponent = x[0] & 0x7f800000;
    619     int fraction = x[0] & 0x007fffff;
    620     if ((exponent == 0x7f800000) && (fraction != 0)) out[0] = 1;
    621     else out[0] = 0;
    622     return NULL;
    623 }
    624 
    625 char *test_isnan(uint32 *x, uint32 *out)
    626 {
    627     /* Being NaN means that our exponent is 0x7ff and non-0 fraction */
    628     int exponent = x[0] & 0x7ff00000;
    629     int fractionhigh = x[0] & 0x000fffff;
    630     if ((exponent == 0x7ff00000) && ((fractionhigh != 0) || x[1] != 0))
    631         out[0] = 1;
    632     else out[0] = 0;
    633     return NULL;
    634 }
    635 
    636 char *test_isnormalf(uint32 *x, uint32 *out)
    637 {
    638     /* Being normal means exponent is not 0 and is not 0xff */
    639     int exponent = x[0] & 0x7f800000;
    640     if (exponent == 0x7f800000) out[0] = 0;
    641     else if (exponent == 0) out[0] = 0;
    642     else out[0] = 1;
    643     return NULL;
    644 }
    645 
    646 char *test_isnormal(uint32 *x, uint32 *out)
    647 {
    648     /* Being normal means exponent is not 0 and is not 0x7ff */
    649     int exponent = x[0] & 0x7ff00000;
    650     if (exponent == 0x7ff00000) out[0] = 0;
    651     else if (exponent == 0) out[0] = 0;
    652     else out[0] = 1;
    653     return NULL;
    654 }
    655 
    656 char *test_signbitf(uint32 *x, uint32 *out)
    657 {
    658     /* Sign bit is bit 31 */
    659     out[0] = (x[0] >> 31) & 1;
    660     return NULL;
    661 }
    662 
    663 char *test_signbit(uint32 *x, uint32 *out)
    664 {
    665     /* Sign bit is bit 31 */
    666     out[0] = (x[0] >> 31) & 1;
    667     return NULL;
    668 }
    669 
    670 char *test_fpclassify(uint32 *x, uint32 *out)
    671 {
    672     int exponent = (x[0] & 0x7ff00000) >> 20;
    673     int fraction = (x[0] & 0x000fffff) | x[1];
    674 
    675     if ((exponent == 0x00) && (fraction == 0)) out[0] = 0;
    676     else if ((exponent == 0x00) && (fraction != 0)) out[0] = 4;
    677     else if ((exponent == 0x7ff) && (fraction == 0)) out[0] = 3;
    678     else if ((exponent == 0x7ff) && (fraction != 0)) out[0] = 7;
    679     else out[0] = 5;
    680     return NULL;
    681 }
    682 
    683 char *test_fpclassifyf(uint32 *x, uint32 *out)
    684 {
    685     int exponent = (x[0] & 0x7f800000) >> 23;
    686     int fraction = x[0] & 0x007fffff;
    687 
    688     if ((exponent == 0x000) && (fraction == 0)) out[0] = 0;
    689     else if ((exponent == 0x000) && (fraction != 0)) out[0] = 4;
    690     else if ((exponent == 0xff) && (fraction == 0)) out[0] = 3;
    691     else if ((exponent == 0xff) && (fraction != 0)) out[0] = 7;
    692     else out[0] = 5;
    693     return NULL;
    694 }
    695 
    696 /*
    697  * Internal function that compares doubles in x & y and returns -3, -2, -1, 0,
    698  * 1 if they compare to be signaling, unordered, less than, equal or greater
    699  * than.
    700  */
    701 static int fpcmp4(uint32 *x, uint32 *y)
    702 {
    703     int result = 0;
    704 
    705     /*
    706      * Sort out whether results are ordered or not to begin with
    707      * NaNs have exponent 0x7ff, and non-zero fraction. Signaling NaNs take
    708      * higher priority than quiet ones.
    709      */
    710     if ((x[0] & 0x7fffffff) >= 0x7ff80000) result = -2;
    711     else if ((x[0] & 0x7fffffff) > 0x7ff00000) result = -3;
    712     else if (((x[0] & 0x7fffffff) == 0x7ff00000) && (x[1] != 0)) result = -3;
    713     if ((y[0] & 0x7fffffff) >= 0x7ff80000 && result != -3) result = -2;
    714     else if ((y[0] & 0x7fffffff) > 0x7ff00000) result = -3;
    715     else if (((y[0] & 0x7fffffff) == 0x7ff00000) && (y[1] != 0)) result = -3;
    716     if (result != 0) return result;
    717 
    718     /*
    719      * The two forms of zero are equal
    720      */
    721     if (((x[0] & 0x7fffffff) == 0) && x[1] == 0 &&
    722         ((y[0] & 0x7fffffff) == 0) && y[1] == 0)
    723         return 0;
    724 
    725     /*
    726      * If x and y have different signs we can tell that they're not equal
    727      * If x is +ve we have x > y return 1 - otherwise y is +ve return -1
    728      */
    729     if ((x[0] >> 31) != (y[0] >> 31))
    730         return ((x[0] >> 31) == 0) - ((y[0] >> 31) == 0);
    731 
    732     /*
    733      * Now we have both signs the same, let's do an initial compare of the
    734      * values.
    735      *
    736      * Whoever designed IEEE754's floating point formats is very clever and
    737      * earns my undying admiration.  Once you remove the sign-bit, the
    738      * floating point numbers can be ordered using the standard <, ==, >
    739      * operators will treating the fp-numbers as integers with that bit-
    740      * pattern.
    741      */
    742     if ((x[0] & 0x7fffffff) < (y[0] & 0x7fffffff)) result = -1;
    743     else if ((x[0] & 0x7fffffff) > (y[0] & 0x7fffffff)) result = 1;
    744     else if (x[1] < y[1]) result = -1;
    745     else if (x[1] > y[1]) result = 1;
    746     else result = 0;
    747 
    748     /*
    749      * Now we return the result - is x is positive (and therefore so is y) we
    750      * return the plain result - otherwise we negate it and return.
    751      */
    752     if ((x[0] >> 31) == 0) return result;
    753     else return -result;
    754 }
    755 
    756 /*
    757  * Internal function that compares floats in x & y and returns -3, -2, -1, 0,
    758  * 1 if they compare to be signaling, unordered, less than, equal or greater
    759  * than.
    760  */
    761 static int fpcmp4f(uint32 *x, uint32 *y)
    762 {
    763     int result = 0;
    764 
    765     /*
    766      * Sort out whether results are ordered or not to begin with
    767      * NaNs have exponent 0xff, and non-zero fraction - we have to handle all
    768      * signaling cases over the quiet ones
    769      */
    770     if ((x[0] & 0x7fffffff) >= 0x7fc00000) result = -2;
    771     else if ((x[0] & 0x7fffffff) > 0x7f800000) result = -3;
    772     if ((y[0] & 0x7fffffff) >= 0x7fc00000 && result != -3) result = -2;
    773     else if ((y[0] & 0x7fffffff) > 0x7f800000) result = -3;
    774     if (result != 0) return result;
    775 
    776     /*
    777      * The two forms of zero are equal
    778      */
    779     if (((x[0] & 0x7fffffff) == 0) && ((y[0] & 0x7fffffff) == 0))
    780         return 0;
    781 
    782     /*
    783      * If x and y have different signs we can tell that they're not equal
    784      * If x is +ve we have x > y return 1 - otherwise y is +ve return -1
    785      */
    786     if ((x[0] >> 31) != (y[0] >> 31))
    787         return ((x[0] >> 31) == 0) - ((y[0] >> 31) == 0);
    788 
    789     /*
    790      * Now we have both signs the same, let's do an initial compare of the
    791      * values.
    792      *
    793      * Whoever designed IEEE754's floating point formats is very clever and
    794      * earns my undying admiration.  Once you remove the sign-bit, the
    795      * floating point numbers can be ordered using the standard <, ==, >
    796      * operators will treating the fp-numbers as integers with that bit-
    797      * pattern.
    798      */
    799     if ((x[0] & 0x7fffffff) < (y[0] & 0x7fffffff)) result = -1;
    800     else if ((x[0] & 0x7fffffff) > (y[0] & 0x7fffffff)) result = 1;
    801     else result = 0;
    802 
    803     /*
    804      * Now we return the result - is x is positive (and therefore so is y) we
    805      * return the plain result - otherwise we negate it and return.
    806      */
    807     if ((x[0] >> 31) == 0) return result;
    808     else return -result;
    809 }
    810 
    811 char *test_isgreater(uint32 *x, uint32 *y, uint32 *out)
    812 {
    813     int result = fpcmp4(x, y);
    814     *out = (result == 1);
    815     return result == -3 ? "i" : NULL;
    816 }
    817 
    818 char *test_isgreaterequal(uint32 *x, uint32 *y, uint32 *out)
    819 {
    820     int result = fpcmp4(x, y);
    821     *out = (result >= 0);
    822     return result == -3 ? "i" : NULL;
    823 }
    824 
    825 char *test_isless(uint32 *x, uint32 *y, uint32 *out)
    826 {
    827     int result = fpcmp4(x, y);
    828     *out = (result == -1);
    829     return result == -3 ? "i" : NULL;
    830 }
    831 
    832 char *test_islessequal(uint32 *x, uint32 *y, uint32 *out)
    833 {
    834     int result = fpcmp4(x, y);
    835     *out = (result == -1) || (result == 0);
    836     return result == -3 ? "i" : NULL;
    837 }
    838 
    839 char *test_islessgreater(uint32 *x, uint32 *y, uint32 *out)
    840 {
    841     int result = fpcmp4(x, y);
    842     *out = (result == -1) || (result == 1);
    843     return result == -3 ? "i" : NULL;
    844 }
    845 
    846 char *test_isunordered(uint32 *x, uint32 *y, uint32 *out)
    847 {
    848     int normal = 0;
    849     int result = fpcmp4(x, y);
    850 
    851     test_isnormal(x, out);
    852     normal |= *out;
    853     test_isnormal(y, out);
    854     normal |= *out;
    855     *out = (result == -2) || (result == -3);
    856     return result == -3 ? "i" : NULL;
    857 }
    858 
    859 char *test_isgreaterf(uint32 *x, uint32 *y, uint32 *out)
    860 {
    861     int result = fpcmp4f(x, y);
    862     *out = (result == 1);
    863     return result == -3 ? "i" : NULL;
    864 }
    865 
    866 char *test_isgreaterequalf(uint32 *x, uint32 *y, uint32 *out)
    867 {
    868     int result = fpcmp4f(x, y);
    869     *out = (result >= 0);
    870     return result == -3 ? "i" : NULL;
    871 }
    872 
    873 char *test_islessf(uint32 *x, uint32 *y, uint32 *out)
    874 {
    875     int result = fpcmp4f(x, y);
    876     *out = (result == -1);
    877     return result == -3 ? "i" : NULL;
    878 }
    879 
    880 char *test_islessequalf(uint32 *x, uint32 *y, uint32 *out)
    881 {
    882     int result = fpcmp4f(x, y);
    883     *out = (result == -1) || (result == 0);
    884     return result == -3 ? "i" : NULL;
    885 }
    886 
    887 char *test_islessgreaterf(uint32 *x, uint32 *y, uint32 *out)
    888 {
    889     int result = fpcmp4f(x, y);
    890     *out = (result == -1) || (result == 1);
    891     return result == -3 ? "i" : NULL;
    892 }
    893 
    894 char *test_isunorderedf(uint32 *x, uint32 *y, uint32 *out)
    895 {
    896     int normal = 0;
    897     int result = fpcmp4f(x, y);
    898 
    899     test_isnormalf(x, out);
    900     normal |= *out;
    901     test_isnormalf(y, out);
    902     normal |= *out;
    903     *out = (result == -2) || (result == -3);
    904     return result == -3 ? "i" : NULL;
    905 }
    906