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