diff --git a/src/stage1/ir.cpp b/src/stage1/ir.cpp index 864f2615f9..ea760bb1f3 100644 --- a/src/stage1/ir.cpp +++ b/src/stage1/ir.cpp @@ -17,6 +17,7 @@ #include "util.hpp" #include "mem_list.hpp" #include "all_types.hpp" +#include "zigendian.h" #include #include @@ -11403,7 +11404,7 @@ static void float_negate(ZigValue *out_val, ZigValue *op) { } } -void float_write_ieee597(ZigValue *op, uint8_t *buf, bool is_big_endian) { +void float_write_ieee597(ZigValue *op, uint8_t *buf, bool target_is_big_endian) { if (op->type->id != ZigTypeIdFloat) zig_unreachable(); @@ -11427,8 +11428,8 @@ void float_write_ieee597(ZigValue *op, uint8_t *buf, bool is_big_endian) { zig_unreachable(); } - if (is_big_endian) { - // Byteswap in place if needed + // Byteswap if system endianness != target endianness + if (native_is_big_endian != target_is_big_endian) { for (size_t i = 0; i < n / 2; i++) { uint8_t u = buf[i]; buf[i] = buf[n - 1 - i]; @@ -11437,7 +11438,7 @@ void float_write_ieee597(ZigValue *op, uint8_t *buf, bool is_big_endian) { } } -void float_read_ieee597(ZigValue *val, uint8_t *buf, bool is_big_endian) { +void float_read_ieee597(ZigValue *val, uint8_t *buf, bool target_is_big_endian) { if (val->type->id != ZigTypeIdFloat) zig_unreachable(); @@ -11447,10 +11448,9 @@ void float_read_ieee597(ZigValue *val, uint8_t *buf, bool is_big_endian) { uint8_t tmp[16]; uint8_t *ptr = buf; - if (is_big_endian) { + // Byteswap if system endianness != target endianness + if (native_is_big_endian != target_is_big_endian) { memcpy(tmp, buf, n); - - // Byteswap if needed for (size_t i = 0; i < n / 2; i++) { uint8_t u = tmp[i]; tmp[i] = tmp[n - 1 - i]; diff --git a/src/stage1/parse_f128.c b/src/stage1/parse_f128.c index 59750f2129..ea6acc73d0 100644 --- a/src/stage1/parse_f128.c +++ b/src/stage1/parse_f128.c @@ -3,6 +3,7 @@ #include "parse_f128.h" #include "softfloat.h" +#include "zigendian.h" #include #include #include @@ -10,28 +11,6 @@ #include #include -// Every OSes seem to define endianness macros in different files. -#if defined(__APPLE__) - #include - #define ZIG_BIG_ENDIAN BIG_ENDIAN - #define ZIG_LITTLE_ENDIAN LITTLE_ENDIAN - #define ZIG_BYTE_ORDER BYTE_ORDER -#elif defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) - #include - #define ZIG_BIG_ENDIAN _BIG_ENDIAN - #define ZIG_LITTLE_ENDIAN _LITTLE_ENDIAN - #define ZIG_BYTE_ORDER _BYTE_ORDER -#elif defined(_WIN32) || defined(_WIN64) - // Assume that Windows installations are always little endian. - #define ZIG_LITTLE_ENDIAN 1 - #define ZIG_BYTE_ORDER ZIG_LITTLE_ENDIAN -#else // Linux - #include - #define ZIG_BIG_ENDIAN __BIG_ENDIAN - #define ZIG_LITTLE_ENDIAN __LITTLE_ENDIAN - #define ZIG_BYTE_ORDER __BYTE_ORDER -#endif - #define shcnt(f) ((f)->shcnt + ((f)->rpos - (f)->buf)) #define shlim(f, lim) __shlim((f), (lim)) #define shgetc(f) (((f)->rpos != (f)->shend) ? *(f)->rpos++ : __shgetc(f)) @@ -783,7 +762,7 @@ static float128_t decfloat(struct MuslFILE *f, int c, int bits, int emin, int si } if ((e2+LDBL_MANT_DIG & INT_MAX) > emax-5) { - //if (fabsf128(y) >= 0x1p113) + //if (fabsf128(y) >= 0x1p113) float128_t abs_y = fabsf128(y); float128_t mant_f128 = make_f128(0x4070000000000000, 0x0000000000000000); if (!f128M_lt(&abs_y, &mant_f128)) { diff --git a/src/stage1/zigendian.h b/src/stage1/zigendian.h new file mode 100644 index 0000000000..0a4f6a6ad2 --- /dev/null +++ b/src/stage1/zigendian.h @@ -0,0 +1,34 @@ +#ifndef ZIG_ENDIAN_H +#define ZIG_ENDIAN_H + +// Every OSes seem to define endianness macros in different files. +#if defined(__APPLE__) + #include + #define ZIG_BIG_ENDIAN BIG_ENDIAN + #define ZIG_LITTLE_ENDIAN LITTLE_ENDIAN + #define ZIG_BYTE_ORDER BYTE_ORDER +#elif defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) + #include + #define ZIG_BIG_ENDIAN _BIG_ENDIAN + #define ZIG_LITTLE_ENDIAN _LITTLE_ENDIAN + #define ZIG_BYTE_ORDER _BYTE_ORDER +#elif defined(_WIN32) || defined(_WIN64) + // Assume that Windows installations are always little endian. + #define ZIG_LITTLE_ENDIAN 1 + #define ZIG_BYTE_ORDER ZIG_LITTLE_ENDIAN +#else // Linux + #include + #define ZIG_BIG_ENDIAN __BIG_ENDIAN + #define ZIG_LITTLE_ENDIAN __LITTLE_ENDIAN + #define ZIG_BYTE_ORDER __BYTE_ORDER +#endif + +#if defined(ZIG_BYTE_ORDER) && ZIG_BYTE_ORDER == ZIG_LITTLE_ENDIAN + const bool native_is_big_endian = false; +#elif defined(ZIG_BYTE_ORDER) && ZIG_BYTE_ORDER == ZIG_BIG_ENDIAN + const bool native_is_big_endian = true; +#else + #error Unsupported endian +#endif + +#endif // ZIG_ENDIAN_H