From 09450419d3bfe990b4e34f85f673615ae601b0d3 Mon Sep 17 00:00:00 2001 From: Koakuma Date: Sun, 17 Jan 2021 23:29:16 +0700 Subject: [PATCH] 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. --- src/stage1/softfloat.hpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/stage1/softfloat.hpp b/src/stage1/softfloat.hpp index 57e60a5fc0..0d43292c4d 100644 --- a/src/stage1/softfloat.hpp +++ b/src/stage1/softfloat.hpp @@ -12,6 +12,8 @@ extern "C" { #include "softfloat.h" } +#include "zigendian.h" + static inline float16_t zig_double_to_f16(double x) { float64_t y; static_assert(sizeof(x) == sizeof(y), ""); @@ -36,10 +38,22 @@ static inline bool zig_f16_isNaN(float16_t a) { } static inline bool zig_f128_isNaN(float128_t *aPtr) { - uint64_t absA64 = aPtr->v[1] & UINT64_C(0x7FFFFFFFFFFFFFFF); + uint64_t hi, lo; + + #if defined(ZIG_BYTE_ORDER) && ZIG_BYTE_ORDER == ZIG_LITTLE_ENDIAN + hi = aPtr->v[1]; + lo = aPtr->v[0]; + #elif defined(ZIG_BYTE_ORDER) && ZIG_BYTE_ORDER == ZIG_BIG_ENDIAN + hi = aPtr->v[0]; + lo = aPtr->v[1]; + #else + #error Unsupported endian + #endif + + uint64_t absA64 = hi & UINT64_C(0x7FFFFFFFFFFFFFFF); return (UINT64_C(0x7FFF000000000000) < absA64) - || ((absA64 == UINT64_C(0x7FFF000000000000)) && aPtr->v[0]); + || ((absA64 == UINT64_C(0x7FFF000000000000)) && lo); } #endif