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