mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
float_*_ieee597: only swap bytes when targeting different endianness than native
float_*_ieee597 functions should fill the buffer with the target endianness, instead of always filling it in LE ordering.
This commit is contained in:
parent
1d3ceac770
commit
588e828759
@ -17,6 +17,7 @@
|
||||
#include "util.hpp"
|
||||
#include "mem_list.hpp"
|
||||
#include "all_types.hpp"
|
||||
#include "zigendian.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
@ -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];
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
|
||||
#include "parse_f128.h"
|
||||
#include "softfloat.h"
|
||||
#include "zigendian.h"
|
||||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
@ -10,28 +11,6 @@
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
// Every OSes seem to define endianness macros in different files.
|
||||
#if defined(__APPLE__)
|
||||
#include <machine/endian.h>
|
||||
#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 <sys/endian.h>
|
||||
#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 <endian.h>
|
||||
#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)) {
|
||||
|
||||
34
src/stage1/zigendian.h
Normal file
34
src/stage1/zigendian.h
Normal file
@ -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 <machine/endian.h>
|
||||
#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 <sys/endian.h>
|
||||
#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 <endian.h>
|
||||
#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
|
||||
Loading…
x
Reference in New Issue
Block a user