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 uint16_t toRep16(uint16_t x)
     58 {
     59     return x;
     60 }
     61 
     62 static inline uint32_t toRep32(float x)
     63 {
     64     uint32_t ret;
     65     memcpy(&ret, &x, 4);
     66     return ret;
     67 }
     68 
     69 static inline uint64_t toRep64(double x)
     70 {
     71     uint64_t ret;
     72     memcpy(&ret, &x, 8);
     73     return ret;
     74 }
     75 
     76 #if __LDBL_MANT_DIG__ == 113
     77 static inline __uint128_t toRep128(long double x)
     78 {
     79     __uint128_t ret;
     80     memcpy(&ret, &x, 16);
     81     return ret;
     82 }
     83 #endif
     84 
     85 static inline int compareResultH(uint16_t result,
     86                                  uint16_t expected)
     87 {
     88     uint16_t rep = toRep16(result);
     89 
     90     if (rep == expected){
     91         return 0;
     92     }
     93     // test other posible NaN representation(signal NaN)
     94     else if (expected == 0x7e00U){
     95         if ((rep & 0x7c00U) == 0x7c00U &&
     96             (rep & 0x3ffU) > 0){
     97             return 0;
     98         }
     99     }
    100     return 1;
    101 }
    102 
    103 static inline int compareResultH(uint16_t result,
    104                                  uint16_t expected)
    105 {
    106     uint16_t rep = toRep16(result);
    107 
    108     if (rep == expected){
    109         return 0;
    110     }
    111     // test other posible NaN representation(signal NaN)
    112     else if (expected == 0x7e00U){
    113         if ((rep & 0x7c00U) == 0x7c00U &&
    114             (rep & 0x3ffU) > 0){
    115             return 0;
    116         }
    117     }
    118     return 1;
    119 }
    120 
    121 static inline int compareResultF(float result,
    122                                  uint32_t expected)
    123 {
    124     uint32_t rep = toRep32(result);
    125 
    126     if (rep == expected){
    127         return 0;
    128     }
    129     // test other posible NaN representation(signal NaN)
    130     else if (expected == 0x7fc00000U){
    131         if ((rep & 0x7f800000U) == 0x7f800000U &&
    132             (rep & 0x7fffffU) > 0){
    133             return 0;
    134         }
    135     }
    136     return 1;
    137 }
    138 
    139 static inline int compareResultD(double result,
    140                                  uint64_t expected)
    141 {
    142     uint64_t rep = toRep64(result);
    143 
    144     if (rep == expected){
    145         return 0;
    146     }
    147     // test other posible NaN representation(signal NaN)
    148     else if (expected == 0x7ff8000000000000UL){
    149         if ((rep & 0x7ff0000000000000UL) == 0x7ff0000000000000UL &&
    150             (rep & 0xfffffffffffffUL) > 0){
    151             return 0;
    152         }
    153     }
    154     return 1;
    155 }
    156 
    157 #if __LDBL_MANT_DIG__ == 113
    158 // return 0 if equal
    159 // use two 64-bit integers intead of one 128-bit integer
    160 // because 128-bit integer constant can't be assigned directly
    161 static inline int compareResultLD(long double result,
    162                                   uint64_t expectedHi,
    163                                   uint64_t expectedLo)
    164 {
    165     __uint128_t rep = toRep128(result);
    166     uint64_t hi = rep >> 64;
    167     uint64_t lo = rep;
    168 
    169     if (hi == expectedHi && lo == expectedLo){
    170         return 0;
    171     }
    172     // test other posible NaN representation(signal NaN)
    173     else if (expectedHi == 0x7fff800000000000UL && expectedLo == 0x0UL){
    174         if ((hi & 0x7fff000000000000UL) == 0x7fff000000000000UL &&
    175             ((hi & 0xffffffffffffUL) > 0 || lo > 0)){
    176             return 0;
    177         }
    178     }
    179     return 1;
    180 }
    181 #endif
    182 
    183 static inline int compareResultCMP(int result,
    184                                    enum EXPECTED_RESULT expected)
    185 {
    186     switch(expected){
    187         case LESS_0:
    188             if (result < 0)
    189                 return 0;
    190             break;
    191         case LESS_EQUAL_0:
    192             if (result <= 0)
    193                 return 0;
    194             break;
    195         case EQUAL_0:
    196             if (result == 0)
    197                 return 0;
    198             break;
    199         case NEQUAL_0:
    200             if (result != 0)
    201                 return 0;
    202             break;
    203         case GREATER_EQUAL_0:
    204             if (result >= 0)
    205                 return 0;
    206             break;
    207         case GREATER_0:
    208             if (result > 0)
    209                 return 0;
    210             break;
    211         default:
    212             return 1;
    213     }
    214     return 1;
    215 }
    216 
    217 static inline char *expectedStr(enum EXPECTED_RESULT expected)
    218 {
    219     switch(expected){
    220         case LESS_0:
    221             return "<0";
    222         case LESS_EQUAL_0:
    223             return "<=0";
    224         case EQUAL_0:
    225             return "=0";
    226         case NEQUAL_0:
    227             return "!=0";
    228         case GREATER_EQUAL_0:
    229             return ">=0";
    230         case GREATER_0:
    231             return ">0";
    232         default:
    233             return "";
    234     }
    235     return "";
    236 }
    237 
    238 static inline uint16_t makeQNaN16()
    239 {
    240     return fromRep16(0x7e00U);
    241 }
    242 
    243 static inline float makeQNaN32()
    244 {
    245     return fromRep32(0x7fc00000U);
    246 }
    247 
    248 static inline double makeQNaN64()
    249 {
    250     return fromRep64(0x7ff8000000000000UL);
    251 }
    252 
    253 #if __LDBL_MANT_DIG__ == 113
    254 static inline long double makeQNaN128()
    255 {
    256     return fromRep128(0x7fff800000000000UL, 0x0UL);
    257 }
    258 #endif
    259 
    260 static inline uint16_t makeNaN16(uint16_t rand)
    261 {
    262     return fromRep16(0x7c00U | (rand & 0x7fffU));
    263 }
    264 
    265 static inline uint16_t makeNaN16(uint16_t rand)
    266 {
    267     return fromRep16(0x7c00U | (rand & 0x7fffU));
    268 }
    269 
    270 static inline float makeNaN32(uint32_t rand)
    271 {
    272     return fromRep32(0x7f800000U | (rand & 0x7fffffU));
    273 }
    274 
    275 static inline double makeNaN64(uint64_t rand)
    276 {
    277     return fromRep64(0x7ff0000000000000UL | (rand & 0xfffffffffffffUL));
    278 }
    279 
    280 #if __LDBL_MANT_DIG__ == 113
    281 static inline long double makeNaN128(uint64_t rand)
    282 {
    283     return fromRep128(0x7fff000000000000UL | (rand & 0xffffffffffffUL), 0x0UL);
    284 }
    285 #endif
    286 
    287 static inline uint16_t makeInf16()
    288 {
    289     return fromRep16(0x7c00U);
    290 }
    291 
    292 static inline uint16_t makeInf16()
    293 {
    294     return fromRep16(0x7c00U);
    295 }
    296 
    297 static inline float makeInf32()
    298 {
    299     return fromRep32(0x7f800000U);
    300 }
    301 
    302 static inline double makeInf64()
    303 {
    304     return fromRep64(0x7ff0000000000000UL);
    305 }
    306 
    307 #if __LDBL_MANT_DIG__ == 113
    308 static inline long double makeInf128()
    309 {
    310     return fromRep128(0x7fff000000000000UL, 0x0UL);
    311 }
    312 #endif
    313