fp_test.h revision 2d1fdb26e458c4ddc04155c1d421bced3ba90cd0
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 float fromRep32(uint32_t x) 23{ 24 float ret; 25 memcpy(&ret, &x, 4); 26 return ret; 27} 28 29static inline double fromRep64(uint64_t x) 30{ 31 double ret; 32 memcpy(&ret, &x, 8); 33 return ret; 34} 35 36static 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 44static inline uint32_t toRep32(float x) 45{ 46 uint32_t ret; 47 memcpy(&ret, &x, 4); 48 return ret; 49} 50 51static inline uint64_t toRep64(double x) 52{ 53 uint64_t ret; 54 memcpy(&ret, &x, 8); 55 return ret; 56} 57 58static inline __uint128_t toRep128(long double x) 59{ 60 __uint128_t ret; 61 memcpy(&ret, &x, 16); 62 return ret; 63} 64 65static 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 83static 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 104static 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 125static 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 159static 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 180static inline float makeQNaN32() 181{ 182 return fromRep32(0x7fc00000U); 183} 184 185static inline double makeQNaN64() 186{ 187 return fromRep64(0x7ff8000000000000UL); 188} 189 190static inline long double makeQNaN128() 191{ 192 return fromRep128(0x7fff800000000000UL, 0x0UL); 193} 194 195static inline float makeNaN32(uint32_t rand) 196{ 197 return fromRep32(0x7f800000U | (rand & 0x7fffffU)); 198} 199 200static inline double makeNaN64(uint64_t rand) 201{ 202 return fromRep64(0x7ff0000000000000UL | (rand & 0xfffffffffffffUL)); 203} 204 205static inline long double makeNaN128(uint64_t rand) 206{ 207 return fromRep128(0x7fff000000000000UL | (rand & 0xffffffffffffUL), 0x0UL); 208} 209 210static inline float makeInf32() 211{ 212 return fromRep32(0x7f800000U); 213} 214 215static inline double makeInf64() 216{ 217 return fromRep64(0x7ff0000000000000UL); 218} 219 220static inline long double makeInf128() 221{ 222 return fromRep128(0x7fff000000000000UL, 0x0UL); 223} 224