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 19enum EXPECTED_RESULT { 20 LESS_0, LESS_EQUAL_0, EQUAL_0, GREATER_0, GREATER_EQUAL_0, NEQUAL_0 21}; 22 23static inline uint16_t fromRep16(uint16_t x) 24{ 25 return x; 26} 27 28static inline float fromRep32(uint32_t x) 29{ 30 float ret; 31 memcpy(&ret, &x, 4); 32 return ret; 33} 34 35static 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 43static 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 52static inline uint16_t toRep16(uint16_t x) 53{ 54 return x; 55} 56 57static inline uint32_t toRep32(float x) 58{ 59 uint32_t ret; 60 memcpy(&ret, &x, 4); 61 return ret; 62} 63 64static 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 72static inline __uint128_t toRep128(long double x) 73{ 74 __uint128_t ret; 75 memcpy(&ret, &x, 16); 76 return ret; 77} 78#endif 79 80static 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 98static 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 116static 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 138static 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 160static 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 194static 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 215static inline uint16_t makeQNaN16() 216{ 217 return fromRep16(0x7e00U); 218} 219 220static inline float makeQNaN32() 221{ 222 return fromRep32(0x7fc00000U); 223} 224 225static inline double makeQNaN64() 226{ 227 return fromRep64(0x7ff8000000000000UL); 228} 229 230#if __LDBL_MANT_DIG__ == 113 231static inline long double makeQNaN128() 232{ 233 return fromRep128(0x7fff800000000000UL, 0x0UL); 234} 235#endif 236 237static inline uint16_t makeNaN16(uint16_t rand) 238{ 239 return fromRep16(0x7c00U | (rand & 0x7fffU)); 240} 241 242static inline float makeNaN32(uint32_t rand) 243{ 244 return fromRep32(0x7f800000U | (rand & 0x7fffffU)); 245} 246 247static inline double makeNaN64(uint64_t rand) 248{ 249 return fromRep64(0x7ff0000000000000UL | (rand & 0xfffffffffffffUL)); 250} 251 252#if __LDBL_MANT_DIG__ == 113 253static inline long double makeNaN128(uint64_t rand) 254{ 255 return fromRep128(0x7fff000000000000UL | (rand & 0xffffffffffffUL), 0x0UL); 256} 257#endif 258 259static inline uint16_t makeInf16() 260{ 261 return fromRep16(0x7c00U); 262} 263 264static inline float makeInf32() 265{ 266 return fromRep32(0x7f800000U); 267} 268 269static inline double makeInf64() 270{ 271 return fromRep64(0x7ff0000000000000UL); 272} 273 274#if __LDBL_MANT_DIG__ == 113 275static inline long double makeInf128() 276{ 277 return fromRep128(0x7fff000000000000UL, 0x0UL); 278} 279#endif 280