9 #ifdef COMPILER_RT_HAS_FLOAT16
10 #define TYPE_FP16 _Float16
12 #define TYPE_FP16 uint16_t
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
23 memcpy(&ret
, &x
, sizeof(ret
));
30 static inline float fromRep32(uint32_t x
)
37 static inline double fromRep64(uint64_t x
)
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
;
53 static inline uint16_t toRep16(TYPE_FP16 x
)
55 #ifdef COMPILER_RT_HAS_FLOAT16
57 memcpy(&ret
, &x
, sizeof(ret
));
64 static inline uint32_t toRep32(float x
)
71 static inline uint64_t toRep64(double x
)
78 #if defined(CRT_HAS_TF_MODE)
79 static inline __uint128_t
toRep128(tf_float x
) {
86 static inline int compareResultH(TYPE_FP16 result
,
89 uint16_t rep
= toRep16(result
);
94 // test other possible NaN representation(signal NaN)
95 else if (expected
== 0x7e00U
){
96 if ((rep
& 0x7c00U
) == 0x7c00U
&&
104 static inline int compareResultF(float result
,
107 uint32_t rep
= toRep32(result
);
109 if (rep
== expected
){
112 // test other possible NaN representation(signal NaN)
113 else if (expected
== 0x7fc00000U
){
114 if ((rep
& 0x7f800000U
) == 0x7f800000U
&&
115 (rep
& 0x7fffffU
) > 0){
122 static inline int compareResultD(double result
,
125 uint64_t rep
= toRep64(result
);
127 if (rep
== expected
){
130 // test other possible NaN representation(signal NaN)
131 else if (expected
== 0x7ff8000000000000UL
){
132 if ((rep
& 0x7ff0000000000000UL
) == 0x7ff0000000000000UL
&&
133 (rep
& 0xfffffffffffffUL
) > 0){
140 #if defined(CRT_HAS_TF_MODE)
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;
150 if (hi
== expectedHi
&& lo
== expectedLo
) {
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)) {
164 static inline int compareResultCMP(int result
,
165 enum EXPECTED_RESULT expected
)
184 case GREATER_EQUAL_0
:
198 static inline char *expectedStr(enum EXPECTED_RESULT expected
)
209 case GREATER_EQUAL_0
:
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
) {
240 static_assert(sizeof(xf_float
) <= sizeof(uqwords
), "wrong representation");
241 memcpy(&ret
, &bits
, sizeof(ret
));
245 static inline uqwords
F80ToRep80(xf_float x
) {
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
;
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
);
280 #if defined(CRT_HAS_TF_MODE)
281 static inline tf_float
makeQNaN128(void) {
282 return fromRep128(0x7fff800000000000UL
, 0x0UL
);
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
);
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
);