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