Home | History | Annotate | Download | only in Unit
      1 //===--------------------------- fp_test.h - ------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is dual licensed under the MIT and the University of Illinois Open
      6 // Source Licenses. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file defines shared functions for the test.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include <stdlib.h>
     15 #include <limits.h>
     16 #include <string.h>
     17 #include <stdint.h>
     18 
     19 enum EXPECTED_RESULT {
     20     LESS_0, LESS_EQUAL_0, EQUAL_0, GREATER_0, GREATER_EQUAL_0, NEQUAL_0
     21 };
     22 
     23 static inline uint16_t fromRep16(uint16_t x)
     24 {
     25     return x;
     26 }
     27 
     28 static inline float fromRep32(uint32_t x)
     29 {
     30     float ret;
     31     memcpy(&ret, &x, 4);
     32     return ret;
     33 }
     34 
     35 static inline double fromRep64(uint64_t x)
     36 {
     37     double ret;
     38     memcpy(&ret, &x, 8);
     39     return ret;
     40 }
     41 
     42 #if __LDBL_MANT_DIG__ == 113
     43 static inline long double fromRep128(uint64_t hi, uint64_t lo)
     44 {
     45     __uint128_t x = ((__uint128_t)hi << 64) + lo;
     46     long double ret;
     47     memcpy(&ret, &x, 16);
     48     return ret;
     49 }
     50 #endif
     51 
     52 static inline uint16_t toRep16(uint16_t x)
     53 {
     54     return x;
     55 }
     56 
     57 static inline uint32_t toRep32(float x)
     58 {
     59     uint32_t ret;
     60     memcpy(&ret, &x, 4);
     61     return ret;
     62 }
     63 
     64 static inline uint64_t toRep64(double x)
     65 {
     66     uint64_t ret;
     67     memcpy(&ret, &x, 8);
     68     return ret;
     69 }
     70 
     71 #if __LDBL_MANT_DIG__ == 113
     72 static inline __uint128_t toRep128(long double x)
     73 {
     74     __uint128_t ret;
     75     memcpy(&ret, &x, 16);
     76     return ret;
     77 }
     78 #endif
     79 
     80 static inline int compareResultH(uint16_t result,
     81                                  uint16_t expected)
     82 {
     83     uint16_t rep = toRep16(result);
     84 
     85     if (rep == expected){
     86         return 0;
     87     }
     88     // test other posible NaN representation(signal NaN)
     89     else if (expected == 0x7e00U){
     90         if ((rep & 0x7c00U) == 0x7c00U &&
     91             (rep & 0x3ffU) > 0){
     92             return 0;
     93         }
     94     }
     95     return 1;
     96 }
     97 
     98 static inline int compareResultF(float result,
     99                                  uint32_t expected)
    100 {
    101     uint32_t rep = toRep32(result);
    102 
    103     if (rep == expected){
    104         return 0;
    105     }
    106     // test other posible NaN representation(signal NaN)
    107     else if (expected == 0x7fc00000U){
    108         if ((rep & 0x7f800000U) == 0x7f800000U &&
    109             (rep & 0x7fffffU) > 0){
    110             return 0;
    111         }
    112     }
    113     return 1;
    114 }
    115 
    116 static inline int compareResultD(double result,
    117                                  uint64_t expected)
    118 {
    119     uint64_t rep = toRep64(result);
    120 
    121     if (rep == expected){
    122         return 0;
    123     }
    124     // test other posible NaN representation(signal NaN)
    125     else if (expected == 0x7ff8000000000000UL){
    126         if ((rep & 0x7ff0000000000000UL) == 0x7ff0000000000000UL &&
    127             (rep & 0xfffffffffffffUL) > 0){
    128             return 0;
    129         }
    130     }
    131     return 1;
    132 }
    133 
    134 #if __LDBL_MANT_DIG__ == 113
    135 // return 0 if equal
    136 // use two 64-bit integers intead of one 128-bit integer
    137 // because 128-bit integer constant can't be assigned directly
    138 static inline int compareResultLD(long double result,
    139                                   uint64_t expectedHi,
    140                                   uint64_t expectedLo)
    141 {
    142     __uint128_t rep = toRep128(result);
    143     uint64_t hi = rep >> 64;
    144     uint64_t lo = rep;
    145 
    146     if (hi == expectedHi && lo == expectedLo){
    147         return 0;
    148     }
    149     // test other posible NaN representation(signal NaN)
    150     else if (expectedHi == 0x7fff800000000000UL && expectedLo == 0x0UL){
    151         if ((hi & 0x7fff000000000000UL) == 0x7fff000000000000UL &&
    152             ((hi & 0xffffffffffffUL) > 0 || lo > 0)){
    153             return 0;
    154         }
    155     }
    156     return 1;
    157 }
    158 #endif
    159 
    160 static inline int compareResultCMP(int result,
    161                                    enum EXPECTED_RESULT expected)
    162 {
    163     switch(expected){
    164         case LESS_0:
    165             if (result < 0)
    166                 return 0;
    167             break;
    168         case LESS_EQUAL_0:
    169             if (result <= 0)
    170                 return 0;
    171             break;
    172         case EQUAL_0:
    173             if (result == 0)
    174                 return 0;
    175             break;
    176         case NEQUAL_0:
    177             if (result != 0)
    178                 return 0;
    179             break;
    180         case GREATER_EQUAL_0:
    181             if (result >= 0)
    182                 return 0;
    183             break;
    184         case GREATER_0:
    185             if (result > 0)
    186                 return 0;
    187             break;
    188         default:
    189             return 1;
    190     }
    191     return 1;
    192 }
    193 
    194 static inline char *expectedStr(enum EXPECTED_RESULT expected)
    195 {
    196     switch(expected){
    197         case LESS_0:
    198             return "<0";
    199         case LESS_EQUAL_0:
    200             return "<=0";
    201         case EQUAL_0:
    202             return "=0";
    203         case NEQUAL_0:
    204             return "!=0";
    205         case GREATER_EQUAL_0:
    206             return ">=0";
    207         case GREATER_0:
    208             return ">0";
    209         default:
    210             return "";
    211     }
    212     return "";
    213 }
    214 
    215 static inline uint16_t makeQNaN16()
    216 {
    217     return fromRep16(0x7e00U);
    218 }
    219 
    220 static inline float makeQNaN32()
    221 {
    222     return fromRep32(0x7fc00000U);
    223 }
    224 
    225 static inline double makeQNaN64()
    226 {
    227     return fromRep64(0x7ff8000000000000UL);
    228 }
    229 
    230 #if __LDBL_MANT_DIG__ == 113
    231 static inline long double makeQNaN128()
    232 {
    233     return fromRep128(0x7fff800000000000UL, 0x0UL);
    234 }
    235 #endif
    236 
    237 static inline uint16_t makeNaN16(uint16_t rand)
    238 {
    239     return fromRep16(0x7c00U | (rand & 0x7fffU));
    240 }
    241 
    242 static inline float makeNaN32(uint32_t rand)
    243 {
    244     return fromRep32(0x7f800000U | (rand & 0x7fffffU));
    245 }
    246 
    247 static inline double makeNaN64(uint64_t rand)
    248 {
    249     return fromRep64(0x7ff0000000000000UL | (rand & 0xfffffffffffffUL));
    250 }
    251 
    252 #if __LDBL_MANT_DIG__ == 113
    253 static inline long double makeNaN128(uint64_t rand)
    254 {
    255     return fromRep128(0x7fff000000000000UL | (rand & 0xffffffffffffUL), 0x0UL);
    256 }
    257 #endif
    258 
    259 static inline uint16_t makeInf16()
    260 {
    261     return fromRep16(0x7c00U);
    262 }
    263 
    264 static inline float makeInf32()
    265 {
    266     return fromRep32(0x7f800000U);
    267 }
    268 
    269 static inline double makeInf64()
    270 {
    271     return fromRep64(0x7ff0000000000000UL);
    272 }
    273 
    274 #if __LDBL_MANT_DIG__ == 113
    275 static inline long double makeInf128()
    276 {
    277     return fromRep128(0x7fff000000000000UL, 0x0UL);
    278 }
    279 #endif
    280