Proposal to switch powerpc64le to IEEE-754 binary128

From: Piotr Kubaj <pkubaj_at_FreeBSD.org>
Date: Tue, 02 Jun 2026 19:16:43 UTC
Hello,

as you may know, FreeBSD currently uses 64-bit long double. Since plain
double is also 64-bit, long double actually gives no advantage over
double and is actually the same type.

However, we can do better, at least on powerpc64le. On Linux with glibc,
many distros have already switched to IEEE-754 binary128, which is
128-bit long double. On FreeBSD, aarch64 and riscv64 already use 128-bit
long double.
Apart from the arguments "others do it", 128-bit long double provides
obviously better precision - it's analogous to float vs double.
Operations on long doubles are also slower and variables take twice as
much memory, but that's expected of bigger types.

Upgrades are another issue: LLVM uses different functions for operations
on 64-bit long doubles and on binary128. This means that after upgrades,
software using long doubles will need to be rebuilt. Otherwise, there's
a risk of strange issues. I have verified that bootstraps for all the
major languages work fine (rust, ghc, sbcl, openjdk), but I assume that
some scientific software may have issues.

The current patchset is at: https://reviews.freebsd.org/D57388

Some ports will probably also need to be patched, but that's another
issue.

If you have some spare system for testing, I recommend a try and a
report, straight "make buildworld installworld" is expected to work.

I have a powerpc64le VM where it works:
root@ieeeldbl:~ # echo | cc -dM -E - | grep LDBL
#define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__
#define __LDBL_DECIMAL_DIG__ 36
#define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L
#define __LDBL_DIG__ 33
#define __LDBL_EPSILON__ 1.92592994438723585305597794258492732e-34L
#define __LDBL_HAS_DENORM__ 1
#define __LDBL_HAS_INFINITY__ 1
#define __LDBL_HAS_QUIET_NAN__ 1
#define __LDBL_MANT_DIG__ 113
#define __LDBL_MAX_10_EXP__ 4932
#define __LDBL_MAX_EXP__ 16384
#define __LDBL_MAX__ 1.18973149535723176508575932662800702e+4932L
#define __LDBL_MIN_10_EXP__ (-4931)
#define __LDBL_MIN_EXP__ (-16381)
#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L
#define __LDBL_NORM_MAX__ 1.18973149535723176508575932662800702e+4932L

On a system with the current default, 64-bit long double, the following
will be reported:
root@blackbird:~ # echo | cc -dM -E - | grep LDBL
#define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__
#define __LDBL_DECIMAL_DIG__ 17
#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
#define __LDBL_DIG__ 15
#define __LDBL_EPSILON__ 2.2204460492503131e-16L
#define __LDBL_HAS_DENORM__ 1
#define __LDBL_HAS_INFINITY__ 1
#define __LDBL_HAS_QUIET_NAN__ 1
#define __LDBL_MANT_DIG__ 53
#define __LDBL_MAX_10_EXP__ 308
#define __LDBL_MAX_EXP__ 1024
#define __LDBL_MAX__ 1.7976931348623157e+308L
#define __LDBL_MIN_10_EXP__ (-307)
#define __LDBL_MIN_EXP__ (-1021)
#define __LDBL_MIN__ 2.2250738585072014e-308L
#define __LDBL_NORM_MAX__ 1.7976931348623157e+308L