qemu

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

test_fclass.c (5234B)


      1 #include <stdio.h>
      2 
      3 /* float class */
      4 #define FLOAT_CLASS_SIGNALING_NAN      0x001
      5 #define FLOAT_CLASS_QUIET_NAN          0x002
      6 #define FLOAT_CLASS_NEGATIVE_INFINITY  0x004
      7 #define FLOAT_CLASS_NEGATIVE_NORMAL    0x008
      8 #define FLOAT_CLASS_NEGATIVE_SUBNORMAL 0x010
      9 #define FLOAT_CLASS_NEGATIVE_ZERO      0x020
     10 #define FLOAT_CLASS_POSITIVE_INFINITY  0x040
     11 #define FLOAT_CLASS_POSITIVE_NORMAL    0x080
     12 #define FLOAT_CLASS_POSITIVE_SUBNORMAL 0x100
     13 #define FLOAT_CLASS_POSITIVE_ZERO      0x200
     14 
     15 #define TEST_FCLASS(N)                            \
     16 void test_fclass_##N(long s)                      \
     17 {                                                 \
     18     double fd;                                    \
     19     long rd;                                      \
     20                                                   \
     21     asm volatile("fclass."#N" %0, %2\n\t"         \
     22                  "movfr2gr."#N" %1, %2\n\t"       \
     23                     : "=f"(fd), "=r"(rd)          \
     24                     : "f"(s)                      \
     25                     : );                          \
     26     switch (rd) {                                 \
     27     case FLOAT_CLASS_SIGNALING_NAN:               \
     28     case FLOAT_CLASS_QUIET_NAN:                   \
     29     case FLOAT_CLASS_NEGATIVE_INFINITY:           \
     30     case FLOAT_CLASS_NEGATIVE_NORMAL:             \
     31     case FLOAT_CLASS_NEGATIVE_SUBNORMAL:          \
     32     case FLOAT_CLASS_NEGATIVE_ZERO:               \
     33     case FLOAT_CLASS_POSITIVE_INFINITY:           \
     34     case FLOAT_CLASS_POSITIVE_NORMAL:             \
     35     case FLOAT_CLASS_POSITIVE_SUBNORMAL:          \
     36     case FLOAT_CLASS_POSITIVE_ZERO:               \
     37         break;                                    \
     38     default:                                      \
     39         printf("fclass."#N" test failed.\n");     \
     40         break;                                    \
     41     }                                             \
     42 }
     43 
     44 /*
     45  *  float format
     46  *  type     |    S  | Exponent  |  Fraction    |  example value
     47  *                31 | 30 --23   | 22  | 21 --0 |
     48  *                               | bit |
     49  *  SNAN         0/1 |   0xFF    | 0   |  !=0   |  0x7FBFFFFF
     50  *  QNAN         0/1 |   0xFF    | 1   |        |  0x7FCFFFFF
     51  *  -infinity     1  |   0xFF    |     0        |  0xFF800000
     52  *  -normal       1  | [1, 0xFE] | [0, 0x7FFFFF]|  0xFF7FFFFF
     53  *  -subnormal    1  |    0      |    !=0       |  0x807FFFFF
     54  *  -0            1  |    0      |     0        |  0x80000000
     55  *  +infinity     0  |   0xFF    |     0        |  0x7F800000
     56  *  +normal       0  | [1, 0xFE] | [0, 0x7FFFFF]|  0x7F7FFFFF
     57  *  +subnormal    0  |    0      |    !=0       |  0x007FFFFF
     58  *  +0            0  |    0      |     0        |  0x00000000
     59  */
     60 
     61 long float_snan = 0x7FBFFFFF;
     62 long float_qnan = 0x7FCFFFFF;
     63 long float_neg_infinity = 0xFF800000;
     64 long float_neg_normal = 0xFF7FFFFF;
     65 long float_neg_subnormal = 0x807FFFFF;
     66 long float_neg_zero = 0x80000000;
     67 long float_post_infinity = 0x7F800000;
     68 long float_post_normal = 0x7F7FFFFF;
     69 long float_post_subnormal = 0x007FFFFF;
     70 long float_post_zero = 0x00000000;
     71 
     72 /*
     73  * double format
     74  *  type     |    S  | Exponent  |  Fraction     |  example value
     75  *                63 | 62  -- 52 | 51  | 50 -- 0 |
     76  *                               | bit |
     77  *  SNAN         0/1 |  0x7FF    | 0   |  !=0    | 0x7FF7FFFFFFFFFFFF
     78  *  QNAN         0/1 |  0x7FF    | 1   |         | 0x7FFFFFFFFFFFFFFF
     79  * -infinity      1  |  0x7FF    |    0          | 0xFFF0000000000000
     80  * -normal        1  |[1, 0x7FE] |               | 0xFFEFFFFFFFFFFFFF
     81  * -subnormal     1  |   0       |   !=0         | 0x8007FFFFFFFFFFFF
     82  * -0             1  |   0       |    0          | 0x8000000000000000
     83  * +infinity      0  |  0x7FF    |    0          | 0x7FF0000000000000
     84  * +normal        0  |[1, 0x7FE] |               | 0x7FEFFFFFFFFFFFFF
     85  * +subnormal     0  |  0        |   !=0         | 0x000FFFFFFFFFFFFF
     86  * +0             0  |  0        |   0           | 0x0000000000000000
     87  */
     88 
     89 long double_snan = 0x7FF7FFFFFFFFFFFF;
     90 long double_qnan = 0x7FFFFFFFFFFFFFFF;
     91 long double_neg_infinity = 0xFFF0000000000000;
     92 long double_neg_normal = 0xFFEFFFFFFFFFFFFF;
     93 long double_neg_subnormal = 0x8007FFFFFFFFFFFF;
     94 long double_neg_zero = 0x8000000000000000;
     95 long double_post_infinity = 0x7FF0000000000000;
     96 long double_post_normal = 0x7FEFFFFFFFFFFFFF;
     97 long double_post_subnormal = 0x000FFFFFFFFFFFFF;
     98 long double_post_zero = 0x0000000000000000;
     99 
    100 TEST_FCLASS(s)
    101 TEST_FCLASS(d)
    102 
    103 int main()
    104 {
    105     /* fclass.s */
    106     test_fclass_s(float_snan);
    107     test_fclass_s(float_qnan);
    108     test_fclass_s(float_neg_infinity);
    109     test_fclass_s(float_neg_normal);
    110     test_fclass_s(float_neg_subnormal);
    111     test_fclass_s(float_neg_zero);
    112     test_fclass_s(float_post_infinity);
    113     test_fclass_s(float_post_normal);
    114     test_fclass_s(float_post_subnormal);
    115     test_fclass_s(float_post_zero);
    116 
    117     /* fclass.d */
    118     test_fclass_d(double_snan);
    119     test_fclass_d(double_qnan);
    120     test_fclass_d(double_neg_infinity);
    121     test_fclass_d(double_neg_normal);
    122     test_fclass_d(double_neg_subnormal);
    123     test_fclass_d(double_neg_zero);
    124     test_fclass_d(double_post_infinity);
    125     test_fclass_d(double_post_normal);
    126     test_fclass_d(double_post_subnormal);
    127     test_fclass_d(double_post_zero);
    128 
    129     return 0;
    130 }