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 
     18 enum EXPECTED_RESULT {
     19     LESS_0, LESS_EQUAL_0, EQUAL_0, GREATER_0, GREATER_EQUAL_0, NEQUAL_0
     20 };
     21 
     22 static inline float fromRep32(uint32_t x)
     23 {
     24     float ret;
     25     memcpy(&ret, &x, 4);
     26     return ret;
     27 }
     28 
     29 static inline double fromRep64(uint64_t x)
     30 {
     31     double ret;
     32     memcpy(&ret, &x, 8);
     33     return ret;
     34 }
     35 
     36 static inline long double fromRep128(uint64_t hi, uint64_t lo)
     37 {
     38     __uint128_t x = ((__uint128_t)hi << 64) + lo;
     39     long double ret;
     40     memcpy(&ret, &x, 16);
     41     return ret;
     42 }
     43 
     44 static inline uint32_t toRep32(float x)
     45 {
     46     uint32_t ret;
     47     memcpy(&ret, &x, 4);
     48     return ret;
     49 }
     50 
     51 static inline uint64_t toRep64(double x)
     52 {
     53     uint64_t ret;
     54     memcpy(&ret, &x, 8);
     55     return ret;
     56 }
     57 
     58 static inline __uint128_t toRep128(long double x)
     59 {
     60     __uint128_t ret;
     61     memcpy(&ret, &x, 16);
     62     return ret;
     63 }
     64 
     65 static inline int compareResultF(float result,
     66                                  uint32_t expected)
     67 {
     68     uint32_t rep = toRep32(result);
     69 
     70     if (rep == expected){
     71         return 0;
     72     }
     73     // test other posible NaN representation(signal NaN)
     74     else if (expected == 0x7fc00000U){
     75         if ((rep & 0x7f800000U) == 0x7f800000U &&
     76             (rep & 0x7fffffU) > 0){
     77             return 0;
     78         }
     79     }
     80     return 1;
     81 }
     82 
     83 static inline int compareResultD(double result,
     84                                  uint64_t expected)
     85 {
     86     uint64_t rep = toRep64(result);
     87 
     88     if (rep == expected){
     89         return 0;
     90     }
     91     // test other posible NaN representation(signal NaN)
     92     else if (expected == 0x7ff8000000000000UL){
     93         if ((rep & 0x7ff0000000000000UL) == 0x7ff0000000000000UL &&
     94             (rep & 0xfffffffffffffUL) > 0){
     95             return 0;
     96         }
     97     }
     98     return 1;
     99 }
    100 
    101 // return 0 if equal
    102 // use two 64-bit integers intead of one 128-bit integer
    103 // because 128-bit integer constant can't be assigned directly
    104 static inline int compareResultLD(long double result,
    105                                   uint64_t expectedHi,
    106                                   uint64_t expectedLo)
    107 {
    108     __uint128_t rep = toRep128(result);
    109     uint64_t hi = rep >> 64;
    110     uint64_t lo = rep;
    111 
    112     if (hi == expectedHi && lo == expectedLo){
    113         return 0;
    114     }
    115     // test other posible NaN representation(signal NaN)
    116     else if (expectedHi == 0x7fff800000000000UL && expectedLo == 0x0UL){
    117         if ((hi & 0x7fff000000000000UL) == 0x7fff000000000000UL &&
    118             ((hi & 0xffffffffffffUL) > 0 || lo > 0)){
    119             return 0;
    120         }
    121     }
    122     return 1;
    123 }
    124 
    125 static inline int compareResultCMP(int result,
    126                                    enum EXPECTED_RESULT expected)
    127 {
    128     switch(expected){
    129         case LESS_0:
    130             if (result < 0)
    131                 return 0;
    132             break;
    133         case LESS_EQUAL_0:
    134             if (result <= 0)
    135                 return 0;
    136             break;
    137         case EQUAL_0:
    138             if (result == 0)
    139                 return 0;
    140             break;
    141         case NEQUAL_0:
    142             if (result != 0)
    143                 return 0;
    144             break;
    145         case GREATER_EQUAL_0:
    146             if (result >= 0)
    147                 return 0;
    148             break;
    149         case GREATER_0:
    150             if (result > 0)
    151                 return 0;
    152             break;
    153         default:
    154             return 1;
    155     }
    156     return 1;
    157 }
    158 
    159 static inline char *expectedStr(enum EXPECTED_RESULT expected)
    160 {
    161     switch(expected){
    162         case LESS_0:
    163             return "<0";
    164         case LESS_EQUAL_0:
    165             return "<=0";
    166         case EQUAL_0:
    167             return "=0";
    168         case NEQUAL_0:
    169             return "!=0";
    170         case GREATER_EQUAL_0:
    171             return ">=0";
    172         case GREATER_0:
    173             return ">0";
    174         default:
    175             return "";
    176     }
    177     return "";
    178 }
    179 
    180 static inline float makeQNaN32()
    181 {
    182     return fromRep32(0x7fc00000U);
    183 }
    184 
    185 static inline double makeQNaN64()
    186 {
    187     return fromRep64(0x7ff8000000000000UL);
    188 }
    189 
    190 static inline long double makeQNaN128()
    191 {
    192     return fromRep128(0x7fff800000000000UL, 0x0UL);
    193 }
    194 
    195 static inline float makeNaN32(uint32_t rand)
    196 {
    197     return fromRep32(0x7f800000U | (rand & 0x7fffffU));
    198 }
    199 
    200 static inline double makeNaN64(uint64_t rand)
    201 {
    202     return fromRep64(0x7ff0000000000000UL | (rand & 0xfffffffffffffUL));
    203 }
    204 
    205 static inline long double makeNaN128(uint64_t rand)
    206 {
    207     return fromRep128(0x7fff000000000000UL | (rand & 0xffffffffffffUL), 0x0UL);
    208 }
    209 
    210 static inline float makeInf32()
    211 {
    212     return fromRep32(0x7f800000U);
    213 }
    214 
    215 static inline double makeInf64()
    216 {
    217     return fromRep64(0x7ff0000000000000UL);
    218 }
    219 
    220 static inline long double makeInf128()
    221 {
    222     return fromRep128(0x7fff000000000000UL, 0x0UL);
    223 }
    224