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