On Sat, Jan 08, 2022 at 12:10:56PM +0100, Jakub Jelinek via Gcc-patches wrote:
> One reason for that is that neither conversion is lossless, neither format
> is a subset or superset of the other.  Yes, IEEE quad has both much bigger
> exponent range (-16382..16383 vs. -1022..1023) and slightly bigger fixed
> precision (113 vs. 106 bits).
> But IBM extended has that weirdo numerically awful flexible precision where
> certain numbers can have much bigger precision than those 106 bits, up to
> 2048+52 or so.  So there is rounding in both directions.
> So, after distros switch to -mabi=ieeelongdouble by default or when people
> use -mabi=ieeelongdouble on their programs, they'd better store that format
> into data files by default, without the need of some magic CONVERT= options,
> env vars or command line options.  Only in the case where they need to
> interact with -mabi=ibmlongdouble environments, they need to take some
> action.

Note, as for byteswapping, apparently it wasn't ever working right fox
the IBM extended real(kind=16) and complex(kind=16).
Because unlike IEEE extended or integral types, it seems powerpc*-*-*
doesn't actually fully byteswap those between little and big endian.
Proof:
long double a = 
0.3333333333333333333333333333333333333333333333333333333333333333333333333333L;
compiled little endian IBM long double:
        .size   a, 16
a:
        .long   1431655765
        .long   1070945621
        .long   1431655766
        .long   1014322517
compiled big endian IBM long double:
        .size   a, 16
a:
        .long   1070945621
        .long   1431655765
        .long   1014322517
        .long   1431655766
compiled little endian IEEE long double:
        .size   a, 16
a:
        .long   1431655765
        .long   1431655765
        .long   1431655765
        .long   1073567061
compiled big endian IEEE long double:
        .size   a, 16
a:
        .long   1073567061
        .long   1431655765
        .long   1431655765
        .long   1431655765
where the numbers in .long arguments are 32-bit numbers stored in the
selected endianity.  Compiled with -mlong-double-64 little endian:
        .size   a, 8
a:
        .long   1431655765
        .long   1070945621
and big endian:
        .size   a, 8
a:
        .long   1070945621
        .long   1431655765
Unless I'm misreading this, for IEEE long double, or double (and I bet float
too) byteswapping the whole numbers is what is needed for interoperability
between powerpc64{,le}-linux, for IBM long double we'd actually want to
byteswap it as 2 real(kind=8) numbers and not one real(kind=16) one, i.e.
the numbers are always stored as the more significant double followed by
less significant double in memory.

        Jakub

Reply via email to