Skip to content

Commit

Permalink
define long double math only if sizeof long double > sizeof double
Browse files Browse the repository at this point in the history
- the gcc-5.5.0 toolchain cross-compiled for mips is built without
  long double math functions (acosl, roundl, etc. are unavailable)

- this lead to libstdc++ disabling support for C99_MATH_TR1 funcs
  _fully_ during its configure (glibcxx_cv_c99_math_tr1=no)

-> Enable the subset (float, double) of C99_MATH_TR1 funcs, by
   masking long double math functions IF long double size equals
   that of double, for now (if long double is greater, assume
   that acosl, roundl are indeed implemented)

Freetz uses the toolchain with soft-float and the o32 mips abi.
Consequently gcc/config/mips/mips.h sets long double size = 64 (bits).
[1]

The t-softfp-tf tetra float support on mips is enabled conditionally.
It is only enabled if ac_cv_sizeof_long_double = 16 (bytes), which
is true for mips_abi == ABI_N32 || mips_abi == ABI_64 (TARGET_NEWABI).
[2]

Thus to have long double math support backed by soft-float an ABI
change is necessary.  This is impractical since freetz often modifies
(instead of replacing) an existing firmware, the ABI of which is
factory-preset.  Some compilers treat using long double with O32 ABI
(i.e. "old 32" abi) an error, not so gcc, because the abi spec did
not consider long double types.
[3]

Long story short, having acosl, roundl, etc. builtins backed by a
gcc soft-float emulation lib in TFmode won't work without ABI change.
Violating O32 ABI using -mlong-double-128 qualifies as such (e.g. a
lib on the target /may/ have used long-double-64 in function defs,
demanding for recompilation of all target executables).
[4], [5]

Unfortunately llvm/clang add to the confusion, since comments in
their target calling convention definitions say N32 ABI long double
is equivalent to double. This is inconsistent with [1], [3].
[6]

There's added commented lines in uclibc.mk that show how to enable
long double within the scope of uclibc only - this actually builds
with a long double size of 8 (bytes) as well, if aliasing double.

UCLIBC_HAS_LONG_DOUBLE should be consistent with the setting of
UCLIBCXX_HAS_LONG_DOUBLE and with long double support in GLIBCXX
(i.e. in libstdc++), so this is inactive/commented work not only
for the fact that we cannot/should not use it with O32 ABI.

The approach of this patch is thus to separate long_double and
non-long_double math support in cmath headers, as to enable the
latter for c++11 applications in O32 ABI soft-float environments,
(which somewhat violates c++11 since the spec demands presence of
long double specializations), and enable both in NEWABI envs.

In its current form it may work for gcc-4.8.x and gcc-4.9.x as well,
adapt toolchain/make/target/gcc/5/850*.patch and copy to gcc/4.8 or
gcc/4.9 patch directories to try (not tested here as 5.5.0 tc works).

[1] https://github.com/gcc-mirror/gcc/blob/561e857cd34210c92a41e540d33f104665533859/gcc/config/mips/mips.h#L1572
[2] https://github.com/gcc-mirror/gcc/blob/a5a22b4fd40aec08398ab45c6b33a698789f0d29/libgcc/config.host#L151
[3] ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/MIPS-N32-ABI-Handbook.pdf (page 20)
[4] https://gcc.gnu.org/onlinedocs/gccint/Soft-float-library-routines.html
[5] https://gcc.gnu.org/onlinedocs/gccint/Machine-Modes.html
[6] https://github.com/Microsoft/llvm/blob/71f3f90b04c63182b7ba28d0f33cd6bdda56d95a/lib/Target/Mips/MipsCallingConv.td#L197
  • Loading branch information
cm8 committed Jun 23, 2018
1 parent 46e7cda commit 41d97c3
Show file tree
Hide file tree
Showing 2 changed files with 736 additions and 0 deletions.

0 comments on commit 41d97c3

Please sign in to comment.