Wire the t-float128 fragment into the FreeBSD powerpc64 configuration so
the KFmode soft-float functions are built.

On glibc the plain __*kf* entry points are exported from libgcc_s.so by
the float128 IFUNC in t-float128-hw.  That fragment is unusable on
FreeBSD (its runtime dispatch needs the Linux AT_PLATFORM auxv entry), so
t-float128 alone puts the software functions only into the static
libgcc.a via LIB2ADD_ST, and hidden.  A gcc-built shared object such as
libstdc++.so then references e.g. __eqkf2 (for IEEE-128 long double) with
no shared provider, and linking an executable against it fails with
"hidden symbol `__eqkf2' ... is referenced by DSO".

Add a FreeBSD-only t-float128-freebsd fragment that routes the software
functions into libgcc_s.so (LIB2ADD) and a version script that exports
them under GCC_7.0.0.  __mulkc3/__divkc3 are excluded from the shared
addition: under -mabi=ieeelongdouble libgcc2.c's __multc3/__divtc3 are
already mangled to those names, so the version script just exports the
libgcc2.c copies.

libgcc/ChangeLog:

        * config.host (powerpc64*-*-freebsd*): Add rs6000/t-float128 and
        rs6000/t-float128-freebsd to tmake_file when float128 is supported,
        and rs6000/t-float128-hw when hardware float128 is supported.
        * config/rs6000/t-float128-freebsd: New file.
        * config/rs6000/libgcc-freebsd-float128.ver: New file.

Signed-off-by: Piotr Kubaj <[email protected]>
---
 libgcc/config.host                               | 6 ++++++
 libgcc/config/rs6000/t-float128-freebsd          | 15 +++++++++++++++
 libgcc/config/rs6000/libgcc-freebsd-float128.ver | 35 
+++++++++++++++++++++++++++++++++++
 3 files changed, 56 insertions(+)

diff --git a/libgcc/config.host b/libgcc/config.host
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -1230,6 +1230,12 @@
        powerpc64*)
          tmake_file="${tmake_file} rs6000/t-freebsd64"
          md_unwind_header=rs6000/freebsd-unwind.h
+         if test $libgcc_cv_powerpc_float128 = yes; then
+           tmake_file="${tmake_file} rs6000/t-float128 
rs6000/t-float128-freebsd"
+         fi
+         if test $libgcc_cv_powerpc_float128_hw = yes; then
+           tmake_file="${tmake_file} rs6000/t-float128-hw"
+         fi
          ;;
        esac
        ;;
diff --git a/libgcc/config/rs6000/t-float128-freebsd 
b/libgcc/config/rs6000/t-float128-freebsd
new file mode 100644
--- /dev/null
+++ b/libgcc/config/rs6000/t-float128-freebsd
@@ -0,0 +1,15 @@
+# On FreeBSD there is no float128 IFUNC (rs6000/t-float128-hw needs the Linux
+# AT_PLATFORM auxv entry, absent on FreeBSD), so the software __float128/KFmode
+# helpers built by rs6000/t-float128 would only land in the static libgcc.a
+# (hidden) via LIB2ADD_ST.  Put them in the shared libgcc_s.so and export them
+# (see libgcc-freebsd-float128.ver) so gcc-built DSOs -- notably libstdc++.so,
+# which references e.g. __eqkf2 for IEEE-128 long double -- resolve them.
+#
+# Exclude __mulkc3/__divkc3: under -mabi=ieeelongdouble libgcc2.c's __multc3/
+# __divtc3 are already mangled to those names in libgcc_s.so, so adding 
rs6000's
+# own copies to the shared library would multiply-define them.  They stay
+# static-only; the .ver exports the libgcc2.c-provided ones.
+fp128_shared_src := $(filter-out %/_mulkc3.c %/_divkc3.c,$(fp128_src))
+LIB2ADD_ST := $(filter-out $(fp128_shared_src),$(LIB2ADD_ST))
+LIB2ADD += $(fp128_shared_src)
+SHLIB_MAPFILES += $(srcdir)/config/rs6000/libgcc-freebsd-float128.ver
diff --git a/libgcc/config/rs6000/libgcc-freebsd-float128.ver 
b/libgcc/config/rs6000/libgcc-freebsd-float128.ver
new file mode 100644
--- /dev/null
+++ b/libgcc/config/rs6000/libgcc-freebsd-float128.ver
@@ -0,0 +1,35 @@
+# IEEE-128 (__float128 / KFmode) software helpers exported from libgcc_s.so on
+# FreeBSD, where there is no float128 IFUNC.  Attached to GCC_7.0.0, the 
version
+# where PowerPC __float128 support was introduced.
+GCC_7.0.0 {
+  __addkf3
+  __subkf3
+  __mulkf3
+  __divkf3
+  __negkf2
+  __unordkf2
+  __eqkf2
+  __gekf2
+  __lekf2
+  __extendsfkf2
+  __extenddfkf2
+  __trunckfsf2
+  __trunckfdf2
+  __fixkfsi
+  __fixkfdi
+  __fixunskfsi
+  __fixunskfdi
+  __floatsikf
+  __floatdikf
+  __floatunsikf
+  __floatundikf
+  __floattikf
+  __floatuntikf
+  __fixkfti
+  __fixunskfti
+  __extendkftf2
+  __trunctfkf2
+  __mulkc3
+  __divkc3
+  __powikf2
+}

-- 
2.49.0

Reply via email to