[AMDGPU] Remove s_wakeup_barrier instruction (#122277)
[llvm-project.git] / compiler-rt / test / builtins / Unit / fp_test.h
blob3a8968a9660448307697bad7356da861b9c5fe74
1 #include <assert.h>
2 #include <limits.h>
3 #include <stdint.h>
4 #include <stdlib.h>
5 #include <string.h>
7 #include "int_types.h"
9 #ifdef COMPILER_RT_HAS_FLOAT16
10 #define TYPE_FP16 _Float16
11 #else
12 #define TYPE_FP16 uint16_t
13 #endif
15 enum EXPECTED_RESULT {
16 LESS_0, LESS_EQUAL_0, EQUAL_0, GREATER_0, GREATER_EQUAL_0, NEQUAL_0
19 static inline TYPE_FP16 fromRep16(uint16_t x)
21 #ifdef COMPILER_RT_HAS_FLOAT16
22 TYPE_FP16 ret;
23 memcpy(&ret, &x, sizeof(ret));
24 return ret;
25 #else
26 return x;
27 #endif
30 static inline float fromRep32(uint32_t x)
32 float ret;
33 memcpy(&ret, &x, 4);
34 return ret;
37 static inline double fromRep64(uint64_t x)
39 double ret;
40 memcpy(&ret, &x, 8);
41 return ret;
44 #if defined(CRT_HAS_TF_MODE)
45 static inline tf_float fromRep128(uint64_t hi, uint64_t lo) {
46 __uint128_t x = ((__uint128_t)hi << 64) + lo;
47 tf_float ret;
48 memcpy(&ret, &x, 16);
49 return ret;
51 #endif
53 static inline uint16_t toRep16(TYPE_FP16 x)
55 #ifdef COMPILER_RT_HAS_FLOAT16
56 uint16_t ret;
57 memcpy(&ret, &x, sizeof(ret));
58 return ret;
59 #else
60 return x;
61 #endif
64 static inline uint32_t toRep32(float x)
66 uint32_t ret;
67 memcpy(&ret, &x, 4);
68 return ret;
71 static inline uint64_t toRep64(double x)
73 uint64_t ret;
74 memcpy(&ret, &x, 8);
75 return ret;
78 #if defined(CRT_HAS_TF_MODE)
79 static inline __uint128_t toRep128(tf_float x) {
80 __uint128_t ret;
81 memcpy(&ret, &x, 16);
82 return ret;
84 #endif
86 static inline int compareResultH(TYPE_FP16 result,
87 uint16_t expected)
89 uint16_t rep = toRep16(result);
91 if (rep == expected){
92 return 0;
94 // test other possible NaN representation(signal NaN)
95 else if (expected == 0x7e00U){
96 if ((rep & 0x7c00U) == 0x7c00U &&
97 (rep & 0x3ffU) > 0){
98 return 0;
101 return 1;
104 static inline int compareResultF(float result,
105 uint32_t expected)
107 uint32_t rep = toRep32(result);
109 if (rep == expected){
110 return 0;
112 // test other possible NaN representation(signal NaN)
113 else if (expected == 0x7fc00000U){
114 if ((rep & 0x7f800000U) == 0x7f800000U &&
115 (rep & 0x7fffffU) > 0){
116 return 0;
119 return 1;
122 static inline int compareResultD(double result,
123 uint64_t expected)
125 uint64_t rep = toRep64(result);
127 if (rep == expected){
128 return 0;
130 // test other possible NaN representation(signal NaN)
131 else if (expected == 0x7ff8000000000000UL){
132 if ((rep & 0x7ff0000000000000UL) == 0x7ff0000000000000UL &&
133 (rep & 0xfffffffffffffUL) > 0){
134 return 0;
137 return 1;
140 #if defined(CRT_HAS_TF_MODE)
141 // return 0 if equal
142 // use two 64-bit integers instead of one 128-bit integer
143 // because 128-bit integer constant can't be assigned directly
144 static inline int compareResultF128(tf_float result, uint64_t expectedHi,
145 uint64_t expectedLo) {
146 __uint128_t rep = toRep128(result);
147 uint64_t hi = rep >> 64;
148 uint64_t lo = rep;
150 if (hi == expectedHi && lo == expectedLo) {
151 return 0;
153 // test other possible NaN representation(signal NaN)
154 else if (expectedHi == 0x7fff800000000000UL && expectedLo == 0x0UL) {
155 if ((hi & 0x7fff000000000000UL) == 0x7fff000000000000UL &&
156 ((hi & 0xffffffffffffUL) > 0 || lo > 0)) {
157 return 0;
160 return 1;
162 #endif
164 static inline int compareResultCMP(int result,
165 enum EXPECTED_RESULT expected)
167 switch(expected){
168 case LESS_0:
169 if (result < 0)
170 return 0;
171 break;
172 case LESS_EQUAL_0:
173 if (result <= 0)
174 return 0;
175 break;
176 case EQUAL_0:
177 if (result == 0)
178 return 0;
179 break;
180 case NEQUAL_0:
181 if (result != 0)
182 return 0;
183 break;
184 case GREATER_EQUAL_0:
185 if (result >= 0)
186 return 0;
187 break;
188 case GREATER_0:
189 if (result > 0)
190 return 0;
191 break;
192 default:
193 return 1;
195 return 1;
198 static inline char *expectedStr(enum EXPECTED_RESULT expected)
200 switch(expected){
201 case LESS_0:
202 return "<0";
203 case LESS_EQUAL_0:
204 return "<=0";
205 case EQUAL_0:
206 return "=0";
207 case NEQUAL_0:
208 return "!=0";
209 case GREATER_EQUAL_0:
210 return ">=0";
211 case GREATER_0:
212 return ">0";
213 default:
214 return "";
216 return "";
219 static inline TYPE_FP16 makeQNaN16(void)
221 return fromRep16(0x7e00U);
224 static inline float makeQNaN32(void)
226 return fromRep32(0x7fc00000U);
229 static inline double makeQNaN64(void)
231 return fromRep64(0x7ff8000000000000UL);
234 #if HAS_80_BIT_LONG_DOUBLE
235 static inline xf_float F80FromRep80(uint16_t hi, uint64_t lo) {
236 uqwords bits;
237 bits.high.all = hi;
238 bits.low.all = lo;
239 xf_float ret;
240 static_assert(sizeof(xf_float) <= sizeof(uqwords), "wrong representation");
241 memcpy(&ret, &bits, sizeof(ret));
242 return ret;
245 static inline uqwords F80ToRep80(xf_float x) {
246 uqwords ret;
247 memset(&ret, 0, sizeof(ret));
248 memcpy(&ret, &x, sizeof(x));
249 // Any bits beyond the first 16 in high are undefined.
250 ret.high.all = (uint16_t)ret.high.all;
251 return ret;
254 static inline int compareResultF80(xf_float result, uint16_t expectedHi,
255 uint64_t expectedLo) {
256 uqwords rep = F80ToRep80(result);
257 // F80 high occupies the lower 16 bits of high.
258 assert((uint64_t)(uint16_t)rep.high.all == rep.high.all);
259 return !(rep.high.all == expectedHi && rep.low.all == expectedLo);
262 static inline xf_float makeQNaN80(void) {
263 return F80FromRep80(0x7fffu, 0xc000000000000000UL);
266 static inline xf_float makeNaN80(uint64_t rand) {
267 return F80FromRep80(0x7fffu,
268 0x8000000000000000 | (rand & 0x3fffffffffffffff));
271 static inline xf_float makeInf80(void) {
272 return F80FromRep80(0x7fffu, 0x8000000000000000UL);
275 static inline xf_float makeNegativeInf80(void) {
276 return F80FromRep80(0xffffu, 0x8000000000000000UL);
278 #endif
280 #if defined(CRT_HAS_TF_MODE)
281 static inline tf_float makeQNaN128(void) {
282 return fromRep128(0x7fff800000000000UL, 0x0UL);
284 #endif
286 static inline TYPE_FP16 makeNaN16(uint16_t rand)
288 return fromRep16(0x7c00U | (rand & 0x7fffU));
291 static inline float makeNaN32(uint32_t rand)
293 return fromRep32(0x7f800000U | (rand & 0x7fffffU));
296 static inline double makeNaN64(uint64_t rand)
298 return fromRep64(0x7ff0000000000000UL | (rand & 0xfffffffffffffUL));
301 #if defined(CRT_HAS_TF_MODE)
302 static inline tf_float makeNaN128(uint64_t rand) {
303 return fromRep128(0x7fff000000000000UL | (rand & 0xffffffffffffUL), 0x0UL);
305 #endif
307 static inline TYPE_FP16 makeInf16(void)
309 return fromRep16(0x7c00U);
312 static inline TYPE_FP16 makeNegativeInf16(void) { return fromRep16(0xfc00U); }
314 static inline float makeInf32(void)
316 return fromRep32(0x7f800000U);
319 static inline float makeNegativeInf32(void)
321 return fromRep32(0xff800000U);
324 static inline double makeInf64(void)
326 return fromRep64(0x7ff0000000000000UL);
329 static inline double makeNegativeInf64(void)
331 return fromRep64(0xfff0000000000000UL);
334 #if defined(CRT_HAS_TF_MODE)
335 static inline tf_float makeInf128(void) {
336 return fromRep128(0x7fff000000000000UL, 0x0UL);
339 static inline tf_float makeNegativeInf128(void) {
340 return fromRep128(0xffff000000000000UL, 0x0UL);
342 #endif