Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gcc: if hostPlatform.isPower64, configure with "--with-long-double-64" #170402

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
This patch is included upstream in gcc 11.1.0 and later:

https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=cda41ce0e8414aec59e6b9fbe645d96e6e8193e2

From cda41ce0e8414aec59e6b9fbe645d96e6e8193e2 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@redhat.com>
Date: Sat, 3 Apr 2021 10:05:32 +0200
Subject: [PATCH] rs6000: Fix up libgcc ABI when built with
--with-long-double-format=ieee [PR97653]

__floatunditf and __fixtfdi and a couple of other libgcc{.a,_s.so}
entrypoints for backwards compatibility should mean IBM double double
handling (i.e. IFmode), gcc emits such calls for that format and
form IEEE long double emits *kf* instead.
When gcc is configured without --with-long-double-format=ieee ,
everything is fine, but when it is not, we need to compile those
libgcc sources with -mno-gnu-attribute -mabi=ibmlongdouble.
The following snippet in libgcc/config/rs6000/t-linux was attempting
to ensure that, and for some routines it works fine (e.g. for _powitf2).
But, due to 4 different types of bugs it doesn't work for most of those
functions, which means that in --with-long-double-format=ieee
configured gcc those *tf* entrypoints instead handle the long double
arguments as if they were KFmode.

The bugs are:
1) the first few objs properly use $(objext) as suffix, but
several other contain a typo and use $(object) instead,
which is a variable that isn't set to anything, so we don't
add .o etc. extensions
2) while unsigned fix are properly called _fixuns*, unsigned float
are called _floatun* (without s), but the var was using there
the extra s and so didn't match
3) the variable didn't cover any of the TF <-> TI conversions,
only TF <-> DI conversions
4) nothing in libgcc_s.so was handled, as those object files are
called *_s.o rather than *.o and IBM128_SHARED_OBJS used wrong
syntax of the GNU make substitution reference, which should be
$(var:a=b) standing for $(patsubst a,b,$(var)) but it used
$(var:a:b) instead

2021-04-03 Jakub Jelinek <jakub@redhat.com>

PR target/97653
* config/rs6000/t-linux (IBM128_STATIC_OBJS): Fix spelling, use
$(objext) instead of $(object). Use _floatunditf instead of
_floatunsditf. Add tf <-> ti conversion objects.
(IBM128_SHARED_OBJS): Use proper substitution reference syntax.
---
libgcc/config/rs6000/t-linux | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/libgcc/config/rs6000/t-linux b/libgcc/config/rs6000/t-linux
index 72e9c2770a6..500210ddaf2 100644
--- a/libgcc/config/rs6000/t-linux
+++ b/libgcc/config/rs6000/t-linux
@@ -11,10 +11,12 @@ HOST_LIBGCC2_CFLAGS += -mno-minimal-toc
# the IBM extended double format. Also turn off gnu attributes on the static
# modules.
IBM128_STATIC_OBJS = ibm-ldouble$(objext) _powitf2$(objext) \
- ppc64-fp$(objext) _divtc3$(object) _multc3$(object) \
- _fixtfdi$(object) _fixunstfdi$(object) \
- _floatditf$(objext) _floatunsditf$(objext)
-IBM128_SHARED_OBJS = $(IBM128_STATIC_OBJS:$(objext):_s$(objext))
+ ppc64-fp$(objext) _divtc3$(objext) _multc3$(objext) \
+ _fixtfdi$(objext) _fixunstfdi$(objext) \
+ _floatditf$(objext) _floatunditf$(objext) \
+ _fixtfti$(objext) _fixunstfti$(objext) \
+ _floattitf$(objext) _floatuntitf$(objext)
+IBM128_SHARED_OBJS = $(IBM128_STATIC_OBJS:$(objext)=_s$(objext))
IBM128_OBJS = $(IBM128_STATIC_OBJS) $(IBM128_SHARED_OBJS)

IBM128_CFLAGS = -Wno-psabi -mabi=ibmlongdouble -mno-gnu-attribute
--
2.27.0

1 change: 1 addition & 0 deletions pkgs/development/compilers/gcc/10/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ let majorVersion = "10";
++ optional langAda ../gnat-cflags.patch
++ optional langFortran ../gfortran-driving.patch
++ optional (targetPlatform.libc == "musl" && targetPlatform.isPower) ../ppc-musl.patch
++ optional (targetPlatform.isMusl && targetPlatform.isPower64) ./backport-libgcc-fix-PR97653.patch

# Obtain latest patch with ../update-mcfgthread-patches.sh
++ optional (!crossStageStatic && targetPlatform.isMinGW) ./Added-mcf-thread-model-support-from-mcfgthread.patch
Expand Down
52 changes: 49 additions & 3 deletions pkgs/development/compilers/gcc/common/platform-flags.nix
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,53 @@ in lib.concatLists [
(lib.optional (p ? fpu) "--with-fpu=${p.fpu}")
(lib.optional (p ? float) "--with-float=${p.float}")
(lib.optional (p ? mode) "--with-mode=${p.mode}")
(lib.optional
(let tp = targetPlatform; in tp.isPower && tp.libc == "glibc" && tp.is64bit)
"--with-long-double-128")

# The powerpc64 ABI has an IBM-specific, non-IEEE "long double" type
# which causes many some test failures. GCC and glibc have been
# working on migrating to 128-bit IEEE long doubles using a complex
# "fat binary" scheme that avoids having a new multiarch tuple.
# Progress with this scheme has been exceptionally slow: Fedora has
# been trying to "flip the switch" since Fedora 31 without success.
#
# As of version 2.34 glibc refuses to build using *only* the IEEE
# standard long-double type, and implementation of the "fat binary"
# scheme to support both IEEE and IBM long doubles simultaneously is
# troublesome and unreliable. Therefore, we use the same approach
# with glibc that musl uses: simply have `long double` be the same
# size as `double`: 64 bits. This is already the case on
# aarch64-darwin, 32-bit ARM, 32-bit MIPS, and Microsoft's C/C++
# compiler for both 64-bit ARM and 32-bit x86, so it is
# well-supported by the build scripts for essentially everything in
# nixpkgs.
#
# Musl specifically checks for non-IEEE `long double`s on powerpc
# and will refuse to build if they are found to be present:
#
# https://git.musl-libc.org/cgit/musl/tree/configure#n732
#
# This has saved musl as great deal of trouble that glibc is
# currently struggling with. By using the same approach for both
# musl and glibc we avoid a lot of headaches that come up when
# "cross-compiling" from *-linux-gnu to *-linux-musl due to the
# libgcc bundled into *-linux-gnu's being linked with the emitted
# binaries.
#
# More details:
#
# https://gcc.gnu.org/wiki/Ieee128PowerPC
# https://gcc.gnu.org/onlinedocs/gcc/Floating-Types.html
# https://fedoraproject.org/wiki/Changes/PPC64LE_Float128_Transition
# https://en.m.wikipedia.org/wiki/Long_double
# https://gcc.gnu.org/install/configure.html
#
# Below are the three possible valid combinations of options, with
# two commented out:
#
(lib.optionals targetPlatform.isPower64 [ "--with-long-double-64" ])
#
# glibc gets very unhappy with these flags:
#(lib.optionals targetPlatform.isPower64 [ "--with-long-double-128" "--with-long-double-format=ieee" ])
#
# this is the default; should be equivalent to not adding any flags at all:
#(lib.optionals targetPlatform.isPower64 [ "--with-long-double-128" "--with-long-double-format=ibm" ])
]