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