authorgravatar for koachan@protonmail.comKoakuma <koachan@protonmail.com> 2021-01-17 23:29:16+07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-01-25 10:40:23-08:00
log09450419d3bfe990b4e34f85f673615ae601b0d3
tree325e78a380786bcdf125a7dd23436f0ca4e8fc1a
parente23bc1f76af298e7ba0140e442858c1faa98e379

Fix f128 NaN check on big-endian hosts

On big-endian hosts, zig_f128_isNaN() takes the high and low halves from the wrong element, resulting in buggy NaN detection behavior. This fixes it.

1 files changed, 16 insertions(+), 2 deletions(-)

src/stage1/softfloat.hpp+16-2
...@@ -12,6 +12,8 @@ extern "C" {...@@ -12,6 +12,8 @@ extern "C" {
12#include "softfloat.h"12#include "softfloat.h"
13}13}
1414
15#include "zigendian.h"
16
15static inline float16_t zig_double_to_f16(double x) {17static inline float16_t zig_double_to_f16(double x) {
16 float64_t y;18 float64_t y;
17 static_assert(sizeof(x) == sizeof(y), "");19 static_assert(sizeof(x) == sizeof(y), "");
...@@ -36,10 +38,22 @@ static inline bool zig_f16_isNaN(float16_t a) {...@@ -36,10 +38,22 @@ static inline bool zig_f16_isNaN(float16_t a) {
36}38}
3739
38static inline bool zig_f128_isNaN(float128_t *aPtr) {40static inline bool zig_f128_isNaN(float128_t *aPtr) {
39 uint64_t absA64 = aPtr->v[1] & UINT64_C(0x7FFFFFFFFFFFFFFF);41 uint64_t hi, lo;
42
43 #if defined(ZIG_BYTE_ORDER) && ZIG_BYTE_ORDER == ZIG_LITTLE_ENDIAN
44 hi = aPtr->v[1];
45 lo = aPtr->v[0];
46 #elif defined(ZIG_BYTE_ORDER) && ZIG_BYTE_ORDER == ZIG_BIG_ENDIAN
47 hi = aPtr->v[0];
48 lo = aPtr->v[1];
49 #else
50 #error Unsupported endian
51 #endif
52
53 uint64_t absA64 = hi & UINT64_C(0x7FFFFFFFFFFFFFFF);
40 return54 return
41 (UINT64_C(0x7FFF000000000000) < absA64)55 (UINT64_C(0x7FFF000000000000) < absA64)
42 || ((absA64 == UINT64_C(0x7FFF000000000000)) && aPtr->v[0]);56 || ((absA64 == UINT64_C(0x7FFF000000000000)) && lo);
43}57}
4458
45#endif59#endif