8 #ifdef COMPILER_RT_HAS_FLOAT16
9 #define TYPE_FP16 _Float16
11 #define TYPE_FP16 uint16_t
14 enum EXPECTED_RESULT
{
15 LESS_0
, LESS_EQUAL_0
, EQUAL_0
, GREATER_0
, GREATER_EQUAL_0
, NEQUAL_0
18 static inline TYPE_FP16
fromRep16(uint16_t x
)
20 #ifdef COMPILER_RT_HAS_FLOAT16
22 memcpy(&ret
, &x
, sizeof(ret
));
29 static inline float fromRep32(uint32_t x
)
36 static inline double fromRep64(uint64_t x
)
43 #if defined(CRT_HAS_TF_MODE)
44 static inline tf_float
fromRep128(uint64_t hi
, uint64_t lo
) {
45 __uint128_t x
= ((__uint128_t
)hi
<< 64) + lo
;
52 static inline uint16_t toRep16(TYPE_FP16 x
)
54 #ifdef COMPILER_RT_HAS_FLOAT16
56 memcpy(&ret
, &x
, sizeof(ret
));
63 static inline uint32_t toRep32(float x
)
70 static inline uint64_t toRep64(double x
)
77 #if defined(CRT_HAS_TF_MODE)
78 static inline __uint128_t
toRep128(tf_float x
) {
85 static inline int compareResultH(TYPE_FP16 result
,
88 uint16_t rep
= toRep16(result
);
93 // test other possible NaN representation(signal NaN)
94 else if (expected
== 0x7e00U
){
95 if ((rep
& 0x7c00U
) == 0x7c00U
&&
103 static inline int compareResultF(float result
,
106 uint32_t rep
= toRep32(result
);
108 if (rep
== expected
){
111 // test other possible NaN representation(signal NaN)
112 else if (expected
== 0x7fc00000U
){
113 if ((rep
& 0x7f800000U
) == 0x7f800000U
&&
114 (rep
& 0x7fffffU
) > 0){
121 static inline int compareResultD(double result
,
124 uint64_t rep
= toRep64(result
);
126 if (rep
== expected
){
129 // test other possible NaN representation(signal NaN)
130 else if (expected
== 0x7ff8000000000000UL
){
131 if ((rep
& 0x7ff0000000000000UL
) == 0x7ff0000000000000UL
&&
132 (rep
& 0xfffffffffffffUL
) > 0){
139 #if defined(CRT_HAS_TF_MODE)
141 // use two 64-bit integers instead of one 128-bit integer
142 // because 128-bit integer constant can't be assigned directly
143 static inline int compareResultF128(tf_float result
, uint64_t expectedHi
,
144 uint64_t expectedLo
) {
145 __uint128_t rep
= toRep128(result
);
146 uint64_t hi
= rep
>> 64;
149 if (hi
== expectedHi
&& lo
== expectedLo
) {
152 // test other possible NaN representation(signal NaN)
153 else if (expectedHi
== 0x7fff800000000000UL
&& expectedLo
== 0x0UL
) {
154 if ((hi
& 0x7fff000000000000UL
) == 0x7fff000000000000UL
&&
155 ((hi
& 0xffffffffffffUL
) > 0 || lo
> 0)) {
163 static inline int compareResultCMP(int result
,
164 enum EXPECTED_RESULT expected
)
183 case GREATER_EQUAL_0
:
197 static inline char *expectedStr(enum EXPECTED_RESULT expected
)
208 case GREATER_EQUAL_0
:
218 static inline TYPE_FP16
makeQNaN16(void)
220 return fromRep16(0x7e00U
);
223 static inline float makeQNaN32(void)
225 return fromRep32(0x7fc00000U
);
228 static inline double makeQNaN64(void)
230 return fromRep64(0x7ff8000000000000UL
);
233 #if __LDBL_MANT_DIG__ == 64 && defined(__x86_64__)
234 static inline long double F80FromRep128(uint64_t hi
, uint64_t lo
) {
235 __uint128_t x
= ((__uint128_t
)hi
<< 64) + lo
;
237 memcpy(&ret
, &x
, 16);
241 static inline __uint128_t
F80ToRep128(long double x
) {
243 memcpy(&ret
, &x
, 16);
247 static inline int compareResultF80(long double result
, uint64_t expectedHi
,
248 uint64_t expectedLo
) {
249 __uint128_t rep
= F80ToRep128(result
);
250 // F80 occupies the lower 80 bits of __uint128_t.
251 uint64_t hi
= (rep
>> 64) & ((1UL << (80 - 64)) - 1);
253 return !(hi
== expectedHi
&& lo
== expectedLo
);
256 static inline long double makeQNaN80(void) {
257 return F80FromRep128(0x7fffUL
, 0xc000000000000000UL
);
260 static inline long double makeNaN80(uint64_t rand
) {
261 return F80FromRep128(0x7fffUL
,
262 0x8000000000000000 | (rand
& 0x3fffffffffffffff));
265 static inline long double makeInf80(void) {
266 return F80FromRep128(0x7fffUL
, 0x8000000000000000UL
);
270 #if defined(CRT_HAS_TF_MODE)
271 static inline tf_float
makeQNaN128(void) {
272 return fromRep128(0x7fff800000000000UL
, 0x0UL
);
276 static inline TYPE_FP16
makeNaN16(uint16_t rand
)
278 return fromRep16(0x7c00U
| (rand
& 0x7fffU
));
281 static inline float makeNaN32(uint32_t rand
)
283 return fromRep32(0x7f800000U
| (rand
& 0x7fffffU
));
286 static inline double makeNaN64(uint64_t rand
)
288 return fromRep64(0x7ff0000000000000UL
| (rand
& 0xfffffffffffffUL
));
291 #if defined(CRT_HAS_TF_MODE)
292 static inline tf_float
makeNaN128(uint64_t rand
) {
293 return fromRep128(0x7fff000000000000UL
| (rand
& 0xffffffffffffUL
), 0x0UL
);
297 static inline TYPE_FP16
makeInf16(void)
299 return fromRep16(0x7c00U
);
302 static inline float makeInf32(void)
304 return fromRep32(0x7f800000U
);
307 static inline float makeNegativeInf32(void)
309 return fromRep32(0xff800000U
);
312 static inline double makeInf64(void)
314 return fromRep64(0x7ff0000000000000UL
);
317 static inline double makeNegativeInf64(void)
319 return fromRep64(0xfff0000000000000UL
);
322 #if defined(CRT_HAS_TF_MODE)
323 static inline tf_float
makeInf128(void) {
324 return fromRep128(0x7fff000000000000UL
, 0x0UL
);
327 static inline tf_float
makeNegativeInf128(void) {
328 return fromRep128(0xffff000000000000UL
, 0x0UL
);