Skip to content

Commit

Permalink
Merge pull request #1145 from netbsduser/big-endian-ldbl
Browse files Browse the repository at this point in the history
options/internal: fix 80-bit long doubles on big endian arches
  • Loading branch information
mintsuki authored Oct 13, 2024
2 parents 777f4cd + e0df194 commit e67666e
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 5 deletions.
12 changes: 10 additions & 2 deletions options/ansi/musl-generic-math/__fpclassifyl.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,18 @@ int __fpclassifyl(long double x)
int msb = u.i.m>>63;
if (!e && !msb)
return u.i.m ? FP_SUBNORMAL : FP_ZERO;
if (e == 0x7fff) {
/* The x86 variant of 80-bit extended precision only admits
* one representation of each infinity, with the mantissa msb
* necessarily set. The version with it clear is invalid/nan.
* The m68k variant, however, allows either, and tooling uses
* the version with it clear. */
if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ && !msb)
return FP_NAN;
return u.i.m << 1 ? FP_NAN : FP_INFINITE;
}
if (!msb)
return FP_NAN;
if (e == 0x7fff)
return u.i.m << 1 ? FP_NAN : FP_INFINITE;
return FP_NORMAL;
}
#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
Expand Down
17 changes: 14 additions & 3 deletions options/ansi/musl-generic-math/libm.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,26 @@
#include <math.h>

#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN
#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
union ldshape {
long double f;
struct {
uint64_t m;
uint16_t se;
} i;
};
#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN
#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
/* This is the m68k variant of 80-bit long double, and this definition only works
* on archs where the alignment requirement of uint64_t is <= 4. */
union ldshape {
long double f;
struct {
uint16_t se;
uint16_t pad;
uint64_t m;
} i;
};
#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
union ldshape {
long double f;
struct {
Expand All @@ -40,7 +51,7 @@ union ldshape {
uint64_t hi;
} i2;
};
#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __BIG_ENDIAN
#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
union ldshape {
long double f;
struct {
Expand Down

0 comments on commit e67666e

Please sign in to comment.