Page MenuHomeFreeBSD

D58116.id.diff
No OneTemporary

D58116.id.diff

diff --git a/lang/gcc12/files/patch-gcc_config_rs6000_rs6000.cc b/lang/gcc12/files/patch-gcc_config_rs6000_rs6000.cc
new file mode 100644
--- /dev/null
+++ b/lang/gcc12/files/patch-gcc_config_rs6000_rs6000.cc
@@ -0,0 +1,10 @@
+--- gcc/config/rs6000/rs6000.cc.orig
++++ gcc/config/rs6000/rs6000.cc
+@@ -28124,6 +28124,7 @@
+
+ /* Map long double built-in functions if long double is IEEE 128-bit. */
+ if (TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
++ && glibc_supports_ieee_128bit ()
+ && TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_IS_UNDECLARED_BUILTIN (decl)
+ && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
diff --git a/lang/gcc12/files/patch-gcc_fortran_trans-types.cc b/lang/gcc12/files/patch-gcc_fortran_trans-types.cc
new file mode 100644
--- /dev/null
+++ b/lang/gcc12/files/patch-gcc_fortran_trans-types.cc
@@ -0,0 +1,12 @@
+--- gcc/fortran/trans-types.cc.orig
++++ gcc/fortran/trans-types.cc
+@@ -512,7 +512,8 @@
+ precision. For libgfortran calls pretend the IEEE 754 quad TFmode has
+ kind 17 rather than 16 and use kind 16 for the IBM extended format
+ TFmode. */
+- if (composite_mode != QImode && saw_r16 && !MODE_COMPOSITE_P (r16_mode))
++ if (composite_mode != QImode && saw_r16 && !MODE_COMPOSITE_P (r16_mode)
++ && TARGET_GLIBC_MAJOR >= 2)
+ {
+ for (int i = 0; i < r_index; ++i)
+ if (gfc_real_kinds[i].kind == 16)
diff --git a/lang/gcc12/files/patch-libgcc_config.host b/lang/gcc12/files/patch-libgcc_config.host
--- a/lang/gcc12/files/patch-libgcc_config.host
+++ b/lang/gcc12/files/patch-libgcc_config.host
@@ -5,7 +5,7 @@
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"
++ 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"
diff --git a/lang/gcc12/files/patch-libgcc_config_rs6000_freebsd-tc-alias.c b/lang/gcc12/files/patch-libgcc_config_rs6000_freebsd-tc-alias.c
new file mode 100644
--- /dev/null
+++ b/lang/gcc12/files/patch-libgcc_config_rs6000_freebsd-tc-alias.c
@@ -0,0 +1,32 @@
+--- /dev/null
++++ libgcc/config/rs6000/freebsd-tc-alias.c
+@@ -0,0 +1,29 @@
++/* clang emits __multc3/__divtc3 (TCmode) for complex IEEE-128 long double,
++ where gcc uses the KCmode names __mulkc3/__divkc3. Provide TCmode forwarders
++ so clang-built shared libraries that link gcc's libgcc_s (e.g. USES=fortran
++ ports mixing a clang C compile with gfortran) resolve them. These are real
++ symbols, so mkmap-symver keeps them in the exported version map -- unlike a
++ link-time --defsym alias. The __asm__ names are not rewritten: the rs6000
++ IEEE-128 name mangling is disabled on FreeBSD, and only libgcc2.c's own
++ mode-based naming turns its __multc3/__divtc3 into __mulkc3/__divkc3. */
++
++extern _Complex long double __mulkc3 (_Complex long double, _Complex long double);
++extern _Complex long double __divkc3 (_Complex long double, _Complex long double);
++
++__attribute__ ((visibility ("default")))
++_Complex long double __freebsd_multc3 (_Complex long double, _Complex long double) __asm__ ("__multc3");
++
++_Complex long double
++__freebsd_multc3 (_Complex long double a, _Complex long double b)
++{
++ return __mulkc3 (a, b);
++}
++
++__attribute__ ((visibility ("default")))
++_Complex long double __freebsd_divtc3 (_Complex long double, _Complex long double) __asm__ ("__divtc3");
++
++_Complex long double
++__freebsd_divtc3 (_Complex long double a, _Complex long double b)
++{
++ return __divkc3 (a, b);
++}
diff --git a/lang/gcc14/files/patch-libgcc_config_rs6000_freebsd-unwind.h b/lang/gcc12/files/patch-libgcc_config_rs6000_freebsd-unwind.h
copy from lang/gcc14/files/patch-libgcc_config_rs6000_freebsd-unwind.h
copy to lang/gcc12/files/patch-libgcc_config_rs6000_freebsd-unwind.h
--- a/lang/gcc14/files/patch-libgcc_config_rs6000_freebsd-unwind.h
+++ b/lang/gcc12/files/patch-libgcc_config_rs6000_freebsd-unwind.h
@@ -1,30 +1,37 @@
---- libgcc/config/rs6000/freebsd-unwind.h.orig
+--- libgcc/config/rs6000/freebsd-unwind.h.orig 2026-04-30 08:33:28 UTC
+++ libgcc/config/rs6000/freebsd-unwind.h
-@@ -33,6 +33,11 @@
- const unsigned int *pc = (const unsigned int *) context->ra;
+@@ -24,6 +24,14 @@
- #ifdef __powerpc64__
+ #define R_LR 65
+
++#ifdef __powerpc64__
+#if _CALL_ELF == 2
-+#define TOC_SAVE_SLOT 24
++#define TOC_SAVE_SLOT 24
+#else
-+#define TOC_SAVE_SLOT 40
++#define TOC_SAVE_SLOT 40
++#endif
+#endif
- if (fs->regs.how[2] == REG_UNSAVED)
- {
- /* If the current unwind info (FS) does not contain explicit info
-@@ -40,9 +45,9 @@
++
+ #define MD_FROB_UPDATE_CONTEXT frob_update_context
+
+ static void
+@@ -40,9 +48,13 @@ frob_update_context (struct _Unwind_Context *context,
figure out if it was saved. The big problem here is that the
code that does the save/restore is generated by the linker, so
we have no good way to determine at compile time what to do. */
- if (pc[0] == 0xF8410028
+ if (pc[0] == 0xF8410000 + TOC_SAVE_SLOT
++#if _CALL_ELF != 2
++ /* The ELFv2 linker never generates the old PLT stub form. */
|| ((pc[0] & 0xFFFF0000) == 0x3D820000
- && pc[1] == 0xF8410028))
-+ && pc[1] == 0xF8410000 + TOC_SAVE_SLOT))
++ && pc[1] == 0xF8410000 + TOC_SAVE_SLOT)
++#endif
++ )
{
/* We are in a plt call stub or r2 adjusting long branch stub,
before r2 has been saved. Keep REG_UNSAVED. */
-@@ -51,17 +56,17 @@
+@@ -51,18 +63,21 @@ frob_update_context (struct _Unwind_Context *context,
{
unsigned int *insn
= (unsigned int *) _Unwind_GetGR (context, R_LR);
@@ -32,6 +39,8 @@
- _Unwind_SetGRPtr (context, 2, context->cfa + 40);
+ if (insn && *insn == 0xE8410000 + TOC_SAVE_SLOT)
+ _Unwind_SetGRPtr (context, 2, context->cfa + TOC_SAVE_SLOT);
++#if _CALL_ELF != 2
++ /* ELFv2 does not use this function pointer call sequence. */
else if (pc[0] == 0x4E800421
- && pc[1] == 0xE8410028)
+ && pc[1] == 0xE8410000 + TOC_SAVE_SLOT)
@@ -44,5 +53,7 @@
- _Unwind_SetGRPtr (context, 2, (void *)(sp + 40));
+ _Unwind_SetGRPtr (context, 2, (void *)(sp + TOC_SAVE_SLOT));
}
++#endif
}
}
+ #endif
diff --git a/lang/gcc12/files/patch-libgcc_config_rs6000_libgcc-freebsd-float128.ver b/lang/gcc12/files/patch-libgcc_config_rs6000_libgcc-freebsd-float128.ver
new file mode 100644
--- /dev/null
+++ b/lang/gcc12/files/patch-libgcc_config_rs6000_libgcc-freebsd-float128.ver
@@ -0,0 +1,40 @@
+--- /dev/null
++++ libgcc/config/rs6000/libgcc-freebsd-float128.ver
+@@ -0,0 +1,37 @@
++# 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
++ __multc3
++ __divtc3
++ __powikf2
++}
diff --git a/lang/gcc12/files/patch-libgcc_config_rs6000_t-float128-freebsd b/lang/gcc12/files/patch-libgcc_config_rs6000_t-float128-freebsd
new file mode 100644
--- /dev/null
+++ b/lang/gcc12/files/patch-libgcc_config_rs6000_t-float128-freebsd
@@ -0,0 +1,25 @@
+--- /dev/null
++++ libgcc/config/rs6000/t-float128-freebsd
+@@ -0,0 +1,22 @@
++# 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
++
++# clang emits the complex IEEE-128 helpers as __multc3/__divtc3 (TCmode) where
++# gcc names them __mulkc3/__divkc3 (KCmode). Provide real TCmode forwarders
++# (freebsd-tc-alias.c) so clang-built DSOs that link gcc's libgcc_s -- e.g.
++# USES=fortran ports mixing clang C with gfortran -- resolve them. Real symbols
++# survive mkmap-symver's map generation where a --defsym link alias would not.
++LIB2ADD += $(srcdir)/config/rs6000/freebsd-tc-alias.c
diff --git a/lang/gcc12/files/patch-libgcc_configure b/lang/gcc12/files/patch-libgcc_configure
new file mode 100644
--- /dev/null
+++ b/lang/gcc12/files/patch-libgcc_configure
@@ -0,0 +1,19 @@
+--- libgcc/configure.orig
++++ libgcc/configure
+@@ -5216,7 +5216,7 @@
+ # check if we have VSX (ISA 2.06) support to build the software libraries, and
+ # whether the assembler can handle xsaddqp for hardware support. Also check if
+ # a new glibc is being used so that __builtin_cpu_supports can be used.
+-powerpc*-*-linux*)
++powerpc*-*-linux* | powerpc*-*-freebsd*)
+ saved_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -mabi=altivec -mvsx -mfloat128"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PowerPC ISA 2.06 to build __float128 libraries" >&5
+@@ -5227,6 +5227,7 @@
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ vector double dadd (vector double a, vector double b) { return a + b; }
++__ibm128 conftest_ibm128;
+ _ACEOF
+ if ac_fn_c_try_compile "$LINENO"; then :
+ libgcc_cv_powerpc_float128=yes
diff --git a/lang/gcc13/files/patch-gcc_config_rs6000_rs6000.cc b/lang/gcc13/files/patch-gcc_config_rs6000_rs6000.cc
new file mode 100644
--- /dev/null
+++ b/lang/gcc13/files/patch-gcc_config_rs6000_rs6000.cc
@@ -0,0 +1,10 @@
+--- gcc/config/rs6000/rs6000.cc.orig
++++ gcc/config/rs6000/rs6000.cc
+@@ -28283,6 +28283,7 @@
+
+ /* Map long double built-in functions if long double is IEEE 128-bit. */
+ if (TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
++ && glibc_supports_ieee_128bit ()
+ && TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_IS_UNDECLARED_BUILTIN (decl)
+ && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
diff --git a/lang/gcc13/files/patch-gcc_fortran_trans-types.cc b/lang/gcc13/files/patch-gcc_fortran_trans-types.cc
new file mode 100644
--- /dev/null
+++ b/lang/gcc13/files/patch-gcc_fortran_trans-types.cc
@@ -0,0 +1,12 @@
+--- gcc/fortran/trans-types.cc.orig
++++ gcc/fortran/trans-types.cc
+@@ -513,7 +513,8 @@
+ precision. For libgfortran calls pretend the IEEE 754 quad TFmode has
+ kind 17 rather than 16 and use kind 16 for the IBM extended format
+ TFmode. */
+- if (composite_mode != QImode && saw_r16 && !MODE_COMPOSITE_P (r16_mode))
++ if (composite_mode != QImode && saw_r16 && !MODE_COMPOSITE_P (r16_mode)
++ && TARGET_GLIBC_MAJOR >= 2)
+ {
+ for (int i = 0; i < r_index; ++i)
+ if (gfc_real_kinds[i].kind == 16)
diff --git a/lang/gcc13/files/patch-libgcc_config.host b/lang/gcc13/files/patch-libgcc_config.host
--- a/lang/gcc13/files/patch-libgcc_config.host
+++ b/lang/gcc13/files/patch-libgcc_config.host
@@ -5,7 +5,7 @@
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"
++ 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"
diff --git a/lang/gcc13/files/patch-libgcc_config_rs6000_freebsd-tc-alias.c b/lang/gcc13/files/patch-libgcc_config_rs6000_freebsd-tc-alias.c
new file mode 100644
--- /dev/null
+++ b/lang/gcc13/files/patch-libgcc_config_rs6000_freebsd-tc-alias.c
@@ -0,0 +1,32 @@
+--- /dev/null
++++ libgcc/config/rs6000/freebsd-tc-alias.c
+@@ -0,0 +1,29 @@
++/* clang emits __multc3/__divtc3 (TCmode) for complex IEEE-128 long double,
++ where gcc uses the KCmode names __mulkc3/__divkc3. Provide TCmode forwarders
++ so clang-built shared libraries that link gcc's libgcc_s (e.g. USES=fortran
++ ports mixing a clang C compile with gfortran) resolve them. These are real
++ symbols, so mkmap-symver keeps them in the exported version map -- unlike a
++ link-time --defsym alias. The __asm__ names are not rewritten: the rs6000
++ IEEE-128 name mangling is disabled on FreeBSD, and only libgcc2.c's own
++ mode-based naming turns its __multc3/__divtc3 into __mulkc3/__divkc3. */
++
++extern _Complex long double __mulkc3 (_Complex long double, _Complex long double);
++extern _Complex long double __divkc3 (_Complex long double, _Complex long double);
++
++__attribute__ ((visibility ("default")))
++_Complex long double __freebsd_multc3 (_Complex long double, _Complex long double) __asm__ ("__multc3");
++
++_Complex long double
++__freebsd_multc3 (_Complex long double a, _Complex long double b)
++{
++ return __mulkc3 (a, b);
++}
++
++__attribute__ ((visibility ("default")))
++_Complex long double __freebsd_divtc3 (_Complex long double, _Complex long double) __asm__ ("__divtc3");
++
++_Complex long double
++__freebsd_divtc3 (_Complex long double a, _Complex long double b)
++{
++ return __divkc3 (a, b);
++}
diff --git a/lang/gcc14/files/patch-libgcc_config_rs6000_freebsd-unwind.h b/lang/gcc13/files/patch-libgcc_config_rs6000_freebsd-unwind.h
copy from lang/gcc14/files/patch-libgcc_config_rs6000_freebsd-unwind.h
copy to lang/gcc13/files/patch-libgcc_config_rs6000_freebsd-unwind.h
--- a/lang/gcc14/files/patch-libgcc_config_rs6000_freebsd-unwind.h
+++ b/lang/gcc13/files/patch-libgcc_config_rs6000_freebsd-unwind.h
@@ -1,30 +1,37 @@
---- libgcc/config/rs6000/freebsd-unwind.h.orig
+--- libgcc/config/rs6000/freebsd-unwind.h.orig 2026-04-30 08:33:28 UTC
+++ libgcc/config/rs6000/freebsd-unwind.h
-@@ -33,6 +33,11 @@
- const unsigned int *pc = (const unsigned int *) context->ra;
+@@ -24,6 +24,14 @@
- #ifdef __powerpc64__
+ #define R_LR 65
+
++#ifdef __powerpc64__
+#if _CALL_ELF == 2
-+#define TOC_SAVE_SLOT 24
++#define TOC_SAVE_SLOT 24
+#else
-+#define TOC_SAVE_SLOT 40
++#define TOC_SAVE_SLOT 40
++#endif
+#endif
- if (fs->regs.how[2] == REG_UNSAVED)
- {
- /* If the current unwind info (FS) does not contain explicit info
-@@ -40,9 +45,9 @@
++
+ #define MD_FROB_UPDATE_CONTEXT frob_update_context
+
+ static void
+@@ -40,9 +48,13 @@ frob_update_context (struct _Unwind_Context *context,
figure out if it was saved. The big problem here is that the
code that does the save/restore is generated by the linker, so
we have no good way to determine at compile time what to do. */
- if (pc[0] == 0xF8410028
+ if (pc[0] == 0xF8410000 + TOC_SAVE_SLOT
++#if _CALL_ELF != 2
++ /* The ELFv2 linker never generates the old PLT stub form. */
|| ((pc[0] & 0xFFFF0000) == 0x3D820000
- && pc[1] == 0xF8410028))
-+ && pc[1] == 0xF8410000 + TOC_SAVE_SLOT))
++ && pc[1] == 0xF8410000 + TOC_SAVE_SLOT)
++#endif
++ )
{
/* We are in a plt call stub or r2 adjusting long branch stub,
before r2 has been saved. Keep REG_UNSAVED. */
-@@ -51,17 +56,17 @@
+@@ -51,18 +63,21 @@ frob_update_context (struct _Unwind_Context *context,
{
unsigned int *insn
= (unsigned int *) _Unwind_GetGR (context, R_LR);
@@ -32,6 +39,8 @@
- _Unwind_SetGRPtr (context, 2, context->cfa + 40);
+ if (insn && *insn == 0xE8410000 + TOC_SAVE_SLOT)
+ _Unwind_SetGRPtr (context, 2, context->cfa + TOC_SAVE_SLOT);
++#if _CALL_ELF != 2
++ /* ELFv2 does not use this function pointer call sequence. */
else if (pc[0] == 0x4E800421
- && pc[1] == 0xE8410028)
+ && pc[1] == 0xE8410000 + TOC_SAVE_SLOT)
@@ -44,5 +53,7 @@
- _Unwind_SetGRPtr (context, 2, (void *)(sp + 40));
+ _Unwind_SetGRPtr (context, 2, (void *)(sp + TOC_SAVE_SLOT));
}
++#endif
}
}
+ #endif
diff --git a/lang/gcc13/files/patch-libgcc_config_rs6000_libgcc-freebsd-float128.ver b/lang/gcc13/files/patch-libgcc_config_rs6000_libgcc-freebsd-float128.ver
new file mode 100644
--- /dev/null
+++ b/lang/gcc13/files/patch-libgcc_config_rs6000_libgcc-freebsd-float128.ver
@@ -0,0 +1,40 @@
+--- /dev/null
++++ libgcc/config/rs6000/libgcc-freebsd-float128.ver
+@@ -0,0 +1,37 @@
++# 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
++ __multc3
++ __divtc3
++ __powikf2
++}
diff --git a/lang/gcc13/files/patch-libgcc_config_rs6000_t-float128-freebsd b/lang/gcc13/files/patch-libgcc_config_rs6000_t-float128-freebsd
new file mode 100644
--- /dev/null
+++ b/lang/gcc13/files/patch-libgcc_config_rs6000_t-float128-freebsd
@@ -0,0 +1,25 @@
+--- /dev/null
++++ libgcc/config/rs6000/t-float128-freebsd
+@@ -0,0 +1,22 @@
++# 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
++
++# clang emits the complex IEEE-128 helpers as __multc3/__divtc3 (TCmode) where
++# gcc names them __mulkc3/__divkc3 (KCmode). Provide real TCmode forwarders
++# (freebsd-tc-alias.c) so clang-built DSOs that link gcc's libgcc_s -- e.g.
++# USES=fortran ports mixing clang C with gfortran -- resolve them. Real symbols
++# survive mkmap-symver's map generation where a --defsym link alias would not.
++LIB2ADD += $(srcdir)/config/rs6000/freebsd-tc-alias.c
diff --git a/lang/gcc13/files/patch-libgcc_configure b/lang/gcc13/files/patch-libgcc_configure
new file mode 100644
--- /dev/null
+++ b/lang/gcc13/files/patch-libgcc_configure
@@ -0,0 +1,19 @@
+--- libgcc/configure.orig
++++ libgcc/configure
+@@ -5217,7 +5217,7 @@
+ # check if we have VSX (ISA 2.06) support to build the software libraries, and
+ # whether the assembler can handle xsaddqp for hardware support. Also check if
+ # a new glibc is being used so that __builtin_cpu_supports can be used.
+-powerpc*-*-linux*)
++powerpc*-*-linux* | powerpc*-*-freebsd*)
+ saved_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -mabi=altivec -mvsx -mfloat128"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PowerPC ISA 2.06 to build __float128 libraries" >&5
+@@ -5228,6 +5228,7 @@
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ vector double dadd (vector double a, vector double b) { return a + b; }
++__ibm128 conftest_ibm128;
+ _ACEOF
+ if ac_fn_c_try_compile "$LINENO"; then :
+ libgcc_cv_powerpc_float128=yes
diff --git a/lang/gcc14/files/patch-gcc_config_rs6000_rs6000.cc b/lang/gcc14/files/patch-gcc_config_rs6000_rs6000.cc
new file mode 100644
--- /dev/null
+++ b/lang/gcc14/files/patch-gcc_config_rs6000_rs6000.cc
@@ -0,0 +1,10 @@
+--- gcc/config/rs6000/rs6000.cc.orig
++++ gcc/config/rs6000/rs6000.cc
+@@ -28563,6 +28563,7 @@
+
+ /* Map long double built-in functions if long double is IEEE 128-bit. */
+ if (TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
++ && glibc_supports_ieee_128bit ()
+ && TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_IS_UNDECLARED_BUILTIN (decl)
+ && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
diff --git a/lang/gcc14/files/patch-gcc_fortran_trans-types.cc b/lang/gcc14/files/patch-gcc_fortran_trans-types.cc
new file mode 100644
--- /dev/null
+++ b/lang/gcc14/files/patch-gcc_fortran_trans-types.cc
@@ -0,0 +1,12 @@
+--- gcc/fortran/trans-types.cc.orig
++++ gcc/fortran/trans-types.cc
+@@ -513,7 +513,8 @@
+ precision. For libgfortran calls pretend the IEEE 754 quad TFmode has
+ kind 17 rather than 16 and use kind 16 for the IBM extended format
+ TFmode. */
+- if (composite_mode != QImode && saw_r16 && !MODE_COMPOSITE_P (r16_mode))
++ if (composite_mode != QImode && saw_r16 && !MODE_COMPOSITE_P (r16_mode)
++ && TARGET_GLIBC_MAJOR >= 2)
+ {
+ for (int i = 0; i < r_index; ++i)
+ if (gfc_real_kinds[i].kind == 16)
diff --git a/lang/gcc14/files/patch-libgcc_config.host b/lang/gcc14/files/patch-libgcc_config.host
--- a/lang/gcc14/files/patch-libgcc_config.host
+++ b/lang/gcc14/files/patch-libgcc_config.host
@@ -5,7 +5,7 @@
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"
++ 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"
diff --git a/lang/gcc14/files/patch-libgcc_config_rs6000_freebsd-tc-alias.c b/lang/gcc14/files/patch-libgcc_config_rs6000_freebsd-tc-alias.c
new file mode 100644
--- /dev/null
+++ b/lang/gcc14/files/patch-libgcc_config_rs6000_freebsd-tc-alias.c
@@ -0,0 +1,32 @@
+--- /dev/null
++++ libgcc/config/rs6000/freebsd-tc-alias.c
+@@ -0,0 +1,29 @@
++/* clang emits __multc3/__divtc3 (TCmode) for complex IEEE-128 long double,
++ where gcc uses the KCmode names __mulkc3/__divkc3. Provide TCmode forwarders
++ so clang-built shared libraries that link gcc's libgcc_s (e.g. USES=fortran
++ ports mixing a clang C compile with gfortran) resolve them. These are real
++ symbols, so mkmap-symver keeps them in the exported version map -- unlike a
++ link-time --defsym alias. The __asm__ names are not rewritten: the rs6000
++ IEEE-128 name mangling is disabled on FreeBSD, and only libgcc2.c's own
++ mode-based naming turns its __multc3/__divtc3 into __mulkc3/__divkc3. */
++
++extern _Complex long double __mulkc3 (_Complex long double, _Complex long double);
++extern _Complex long double __divkc3 (_Complex long double, _Complex long double);
++
++__attribute__ ((visibility ("default")))
++_Complex long double __freebsd_multc3 (_Complex long double, _Complex long double) __asm__ ("__multc3");
++
++_Complex long double
++__freebsd_multc3 (_Complex long double a, _Complex long double b)
++{
++ return __mulkc3 (a, b);
++}
++
++__attribute__ ((visibility ("default")))
++_Complex long double __freebsd_divtc3 (_Complex long double, _Complex long double) __asm__ ("__divtc3");
++
++_Complex long double
++__freebsd_divtc3 (_Complex long double a, _Complex long double b)
++{
++ return __divkc3 (a, b);
++}
diff --git a/lang/gcc14/files/patch-libgcc_config_rs6000_freebsd-unwind.h b/lang/gcc14/files/patch-libgcc_config_rs6000_freebsd-unwind.h
--- a/lang/gcc14/files/patch-libgcc_config_rs6000_freebsd-unwind.h
+++ b/lang/gcc14/files/patch-libgcc_config_rs6000_freebsd-unwind.h
@@ -1,30 +1,37 @@
---- libgcc/config/rs6000/freebsd-unwind.h.orig
+--- libgcc/config/rs6000/freebsd-unwind.h.orig 2026-04-30 08:33:28 UTC
+++ libgcc/config/rs6000/freebsd-unwind.h
-@@ -33,6 +33,11 @@
- const unsigned int *pc = (const unsigned int *) context->ra;
+@@ -24,6 +24,14 @@
- #ifdef __powerpc64__
+ #define R_LR 65
+
++#ifdef __powerpc64__
+#if _CALL_ELF == 2
-+#define TOC_SAVE_SLOT 24
++#define TOC_SAVE_SLOT 24
+#else
-+#define TOC_SAVE_SLOT 40
++#define TOC_SAVE_SLOT 40
++#endif
+#endif
- if (fs->regs.how[2] == REG_UNSAVED)
- {
- /* If the current unwind info (FS) does not contain explicit info
-@@ -40,9 +45,9 @@
++
+ #define MD_FROB_UPDATE_CONTEXT frob_update_context
+
+ static void
+@@ -40,9 +48,13 @@ frob_update_context (struct _Unwind_Context *context,
figure out if it was saved. The big problem here is that the
code that does the save/restore is generated by the linker, so
we have no good way to determine at compile time what to do. */
- if (pc[0] == 0xF8410028
+ if (pc[0] == 0xF8410000 + TOC_SAVE_SLOT
++#if _CALL_ELF != 2
++ /* The ELFv2 linker never generates the old PLT stub form. */
|| ((pc[0] & 0xFFFF0000) == 0x3D820000
- && pc[1] == 0xF8410028))
-+ && pc[1] == 0xF8410000 + TOC_SAVE_SLOT))
++ && pc[1] == 0xF8410000 + TOC_SAVE_SLOT)
++#endif
++ )
{
/* We are in a plt call stub or r2 adjusting long branch stub,
before r2 has been saved. Keep REG_UNSAVED. */
-@@ -51,17 +56,17 @@
+@@ -51,18 +63,21 @@ frob_update_context (struct _Unwind_Context *context,
{
unsigned int *insn
= (unsigned int *) _Unwind_GetGR (context, R_LR);
@@ -32,6 +39,8 @@
- _Unwind_SetGRPtr (context, 2, context->cfa + 40);
+ if (insn && *insn == 0xE8410000 + TOC_SAVE_SLOT)
+ _Unwind_SetGRPtr (context, 2, context->cfa + TOC_SAVE_SLOT);
++#if _CALL_ELF != 2
++ /* ELFv2 does not use this function pointer call sequence. */
else if (pc[0] == 0x4E800421
- && pc[1] == 0xE8410028)
+ && pc[1] == 0xE8410000 + TOC_SAVE_SLOT)
@@ -44,5 +53,7 @@
- _Unwind_SetGRPtr (context, 2, (void *)(sp + 40));
+ _Unwind_SetGRPtr (context, 2, (void *)(sp + TOC_SAVE_SLOT));
}
++#endif
}
}
+ #endif
diff --git a/lang/gcc14/files/patch-libgcc_config_rs6000_libgcc-freebsd-float128.ver b/lang/gcc14/files/patch-libgcc_config_rs6000_libgcc-freebsd-float128.ver
new file mode 100644
--- /dev/null
+++ b/lang/gcc14/files/patch-libgcc_config_rs6000_libgcc-freebsd-float128.ver
@@ -0,0 +1,40 @@
+--- /dev/null
++++ libgcc/config/rs6000/libgcc-freebsd-float128.ver
+@@ -0,0 +1,37 @@
++# 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
++ __multc3
++ __divtc3
++ __powikf2
++}
diff --git a/lang/gcc14/files/patch-libgcc_config_rs6000_t-float128-freebsd b/lang/gcc14/files/patch-libgcc_config_rs6000_t-float128-freebsd
new file mode 100644
--- /dev/null
+++ b/lang/gcc14/files/patch-libgcc_config_rs6000_t-float128-freebsd
@@ -0,0 +1,25 @@
+--- /dev/null
++++ libgcc/config/rs6000/t-float128-freebsd
+@@ -0,0 +1,22 @@
++# 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
++
++# clang emits the complex IEEE-128 helpers as __multc3/__divtc3 (TCmode) where
++# gcc names them __mulkc3/__divkc3 (KCmode). Provide real TCmode forwarders
++# (freebsd-tc-alias.c) so clang-built DSOs that link gcc's libgcc_s -- e.g.
++# USES=fortran ports mixing clang C with gfortran -- resolve them. Real symbols
++# survive mkmap-symver's map generation where a --defsym link alias would not.
++LIB2ADD += $(srcdir)/config/rs6000/freebsd-tc-alias.c
diff --git a/lang/gcc14/files/patch-libgcc_configure b/lang/gcc14/files/patch-libgcc_configure
new file mode 100644
--- /dev/null
+++ b/lang/gcc14/files/patch-libgcc_configure
@@ -0,0 +1,19 @@
+--- libgcc/configure.orig
++++ libgcc/configure
+@@ -5216,7 +5216,7 @@
+ # check if we have VSX (ISA 2.06) support to build the software libraries, and
+ # whether the assembler can handle xsaddqp for hardware support. Also check if
+ # a new glibc is being used so that __builtin_cpu_supports can be used.
+-powerpc*-*-linux*)
++powerpc*-*-linux* | powerpc*-*-freebsd*)
+ saved_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -mabi=altivec -mvsx -mfloat128"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PowerPC ISA 2.06 to build __float128 libraries" >&5
+@@ -5227,6 +5227,7 @@
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ vector double dadd (vector double a, vector double b) { return a + b; }
++__ibm128 conftest_ibm128;
+ _ACEOF
+ if ac_fn_c_try_compile "$LINENO"; then :
+ libgcc_cv_powerpc_float128=yes
diff --git a/lang/gcc15/files/patch-gcc_config_rs6000_rs6000.cc b/lang/gcc15/files/patch-gcc_config_rs6000_rs6000.cc
new file mode 100644
--- /dev/null
+++ b/lang/gcc15/files/patch-gcc_config_rs6000_rs6000.cc
@@ -0,0 +1,10 @@
+--- gcc/config/rs6000/rs6000.cc.orig
++++ gcc/config/rs6000/rs6000.cc
+@@ -28581,6 +28581,7 @@
+
+ /* Map long double built-in functions if long double is IEEE 128-bit. */
+ if (TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
++ && glibc_supports_ieee_128bit ()
+ && TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_IS_UNDECLARED_BUILTIN (decl)
+ && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
diff --git a/lang/gcc15/files/patch-gcc_fortran_trans-types.cc b/lang/gcc15/files/patch-gcc_fortran_trans-types.cc
new file mode 100644
--- /dev/null
+++ b/lang/gcc15/files/patch-gcc_fortran_trans-types.cc
@@ -0,0 +1,12 @@
+--- gcc/fortran/trans-types.cc.orig
++++ gcc/fortran/trans-types.cc
+@@ -595,7 +595,8 @@
+ precision. For libgfortran calls pretend the IEEE 754 quad TFmode has
+ kind 17 rather than 16 and use kind 16 for the IBM extended format
+ TFmode. */
+- if (composite_mode != QImode && saw_r16 && !MODE_COMPOSITE_P (r16_mode))
++ if (composite_mode != QImode && saw_r16 && !MODE_COMPOSITE_P (r16_mode)
++ && TARGET_GLIBC_MAJOR >= 2)
+ {
+ for (int i = 0; i < r_index; ++i)
+ if (gfc_real_kinds[i].kind == 16)
diff --git a/lang/gcc15/files/patch-libgcc_config.host b/lang/gcc15/files/patch-libgcc_config.host
--- a/lang/gcc15/files/patch-libgcc_config.host
+++ b/lang/gcc15/files/patch-libgcc_config.host
@@ -5,7 +5,7 @@
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"
++ 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"
diff --git a/lang/gcc15/files/patch-libgcc_config_rs6000_freebsd-tc-alias.c b/lang/gcc15/files/patch-libgcc_config_rs6000_freebsd-tc-alias.c
new file mode 100644
--- /dev/null
+++ b/lang/gcc15/files/patch-libgcc_config_rs6000_freebsd-tc-alias.c
@@ -0,0 +1,32 @@
+--- /dev/null
++++ libgcc/config/rs6000/freebsd-tc-alias.c
+@@ -0,0 +1,29 @@
++/* clang emits __multc3/__divtc3 (TCmode) for complex IEEE-128 long double,
++ where gcc uses the KCmode names __mulkc3/__divkc3. Provide TCmode forwarders
++ so clang-built shared libraries that link gcc's libgcc_s (e.g. USES=fortran
++ ports mixing a clang C compile with gfortran) resolve them. These are real
++ symbols, so mkmap-symver keeps them in the exported version map -- unlike a
++ link-time --defsym alias. The __asm__ names are not rewritten: the rs6000
++ IEEE-128 name mangling is disabled on FreeBSD, and only libgcc2.c's own
++ mode-based naming turns its __multc3/__divtc3 into __mulkc3/__divkc3. */
++
++extern _Complex long double __mulkc3 (_Complex long double, _Complex long double);
++extern _Complex long double __divkc3 (_Complex long double, _Complex long double);
++
++__attribute__ ((visibility ("default")))
++_Complex long double __freebsd_multc3 (_Complex long double, _Complex long double) __asm__ ("__multc3");
++
++_Complex long double
++__freebsd_multc3 (_Complex long double a, _Complex long double b)
++{
++ return __mulkc3 (a, b);
++}
++
++__attribute__ ((visibility ("default")))
++_Complex long double __freebsd_divtc3 (_Complex long double, _Complex long double) __asm__ ("__divtc3");
++
++_Complex long double
++__freebsd_divtc3 (_Complex long double a, _Complex long double b)
++{
++ return __divkc3 (a, b);
++}
diff --git a/lang/gcc14/files/patch-libgcc_config_rs6000_freebsd-unwind.h b/lang/gcc15/files/patch-libgcc_config_rs6000_freebsd-unwind.h
copy from lang/gcc14/files/patch-libgcc_config_rs6000_freebsd-unwind.h
copy to lang/gcc15/files/patch-libgcc_config_rs6000_freebsd-unwind.h
--- a/lang/gcc14/files/patch-libgcc_config_rs6000_freebsd-unwind.h
+++ b/lang/gcc15/files/patch-libgcc_config_rs6000_freebsd-unwind.h
@@ -1,30 +1,37 @@
---- libgcc/config/rs6000/freebsd-unwind.h.orig
+--- libgcc/config/rs6000/freebsd-unwind.h.orig 2026-04-30 08:33:28 UTC
+++ libgcc/config/rs6000/freebsd-unwind.h
-@@ -33,6 +33,11 @@
- const unsigned int *pc = (const unsigned int *) context->ra;
+@@ -24,6 +24,14 @@
- #ifdef __powerpc64__
+ #define R_LR 65
+
++#ifdef __powerpc64__
+#if _CALL_ELF == 2
-+#define TOC_SAVE_SLOT 24
++#define TOC_SAVE_SLOT 24
+#else
-+#define TOC_SAVE_SLOT 40
++#define TOC_SAVE_SLOT 40
++#endif
+#endif
- if (fs->regs.how[2] == REG_UNSAVED)
- {
- /* If the current unwind info (FS) does not contain explicit info
-@@ -40,9 +45,9 @@
++
+ #define MD_FROB_UPDATE_CONTEXT frob_update_context
+
+ static void
+@@ -40,9 +48,13 @@ frob_update_context (struct _Unwind_Context *context,
figure out if it was saved. The big problem here is that the
code that does the save/restore is generated by the linker, so
we have no good way to determine at compile time what to do. */
- if (pc[0] == 0xF8410028
+ if (pc[0] == 0xF8410000 + TOC_SAVE_SLOT
++#if _CALL_ELF != 2
++ /* The ELFv2 linker never generates the old PLT stub form. */
|| ((pc[0] & 0xFFFF0000) == 0x3D820000
- && pc[1] == 0xF8410028))
-+ && pc[1] == 0xF8410000 + TOC_SAVE_SLOT))
++ && pc[1] == 0xF8410000 + TOC_SAVE_SLOT)
++#endif
++ )
{
/* We are in a plt call stub or r2 adjusting long branch stub,
before r2 has been saved. Keep REG_UNSAVED. */
-@@ -51,17 +56,17 @@
+@@ -51,18 +63,21 @@ frob_update_context (struct _Unwind_Context *context,
{
unsigned int *insn
= (unsigned int *) _Unwind_GetGR (context, R_LR);
@@ -32,6 +39,8 @@
- _Unwind_SetGRPtr (context, 2, context->cfa + 40);
+ if (insn && *insn == 0xE8410000 + TOC_SAVE_SLOT)
+ _Unwind_SetGRPtr (context, 2, context->cfa + TOC_SAVE_SLOT);
++#if _CALL_ELF != 2
++ /* ELFv2 does not use this function pointer call sequence. */
else if (pc[0] == 0x4E800421
- && pc[1] == 0xE8410028)
+ && pc[1] == 0xE8410000 + TOC_SAVE_SLOT)
@@ -44,5 +53,7 @@
- _Unwind_SetGRPtr (context, 2, (void *)(sp + 40));
+ _Unwind_SetGRPtr (context, 2, (void *)(sp + TOC_SAVE_SLOT));
}
++#endif
}
}
+ #endif
diff --git a/lang/gcc15/files/patch-libgcc_config_rs6000_libgcc-freebsd-float128.ver b/lang/gcc15/files/patch-libgcc_config_rs6000_libgcc-freebsd-float128.ver
new file mode 100644
--- /dev/null
+++ b/lang/gcc15/files/patch-libgcc_config_rs6000_libgcc-freebsd-float128.ver
@@ -0,0 +1,40 @@
+--- /dev/null
++++ libgcc/config/rs6000/libgcc-freebsd-float128.ver
+@@ -0,0 +1,37 @@
++# 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
++ __multc3
++ __divtc3
++ __powikf2
++}
diff --git a/lang/gcc15/files/patch-libgcc_config_rs6000_t-float128-freebsd b/lang/gcc15/files/patch-libgcc_config_rs6000_t-float128-freebsd
new file mode 100644
--- /dev/null
+++ b/lang/gcc15/files/patch-libgcc_config_rs6000_t-float128-freebsd
@@ -0,0 +1,25 @@
+--- /dev/null
++++ libgcc/config/rs6000/t-float128-freebsd
+@@ -0,0 +1,22 @@
++# 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
++
++# clang emits the complex IEEE-128 helpers as __multc3/__divtc3 (TCmode) where
++# gcc names them __mulkc3/__divkc3 (KCmode). Provide real TCmode forwarders
++# (freebsd-tc-alias.c) so clang-built DSOs that link gcc's libgcc_s -- e.g.
++# USES=fortran ports mixing clang C with gfortran -- resolve them. Real symbols
++# survive mkmap-symver's map generation where a --defsym link alias would not.
++LIB2ADD += $(srcdir)/config/rs6000/freebsd-tc-alias.c
diff --git a/lang/gcc15/files/patch-libgcc_configure b/lang/gcc15/files/patch-libgcc_configure
new file mode 100644
--- /dev/null
+++ b/lang/gcc15/files/patch-libgcc_configure
@@ -0,0 +1,19 @@
+--- libgcc/configure.orig
++++ libgcc/configure
+@@ -5185,7 +5185,7 @@
+ # check if we have VSX (ISA 2.06) support to build the software libraries, and
+ # whether the assembler can handle xsaddqp for hardware support. Also check if
+ # a new glibc is being used so that __builtin_cpu_supports can be used.
+-powerpc*-*-linux*)
++powerpc*-*-linux* | powerpc*-*-freebsd*)
+ saved_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -mabi=altivec -mvsx -mfloat128"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PowerPC ISA 2.06 to build __float128 libraries" >&5
+@@ -5196,6 +5196,7 @@
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ vector double dadd (vector double a, vector double b) { return a + b; }
++__ibm128 conftest_ibm128;
+ _ACEOF
+ if ac_fn_c_try_compile "$LINENO"; then :
+ libgcc_cv_powerpc_float128=yes
diff --git a/lang/gcc16/files/patch-gcc_config_rs6000_rs6000.cc b/lang/gcc16/files/patch-gcc_config_rs6000_rs6000.cc
new file mode 100644
--- /dev/null
+++ b/lang/gcc16/files/patch-gcc_config_rs6000_rs6000.cc
@@ -0,0 +1,10 @@
+--- gcc/config/rs6000/rs6000.cc.orig 2026-04-30 08:33:20 UTC
++++ gcc/config/rs6000/rs6000.cc
+@@ -28608,6 +28608,7 @@ rs6000_mangle_decl_assembler_name (tree decl, tree id)
+
+ /* Map long double built-in functions if long double is IEEE 128-bit. */
+ if (TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
++ && glibc_supports_ieee_128bit ()
+ && TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_IS_UNDECLARED_BUILTIN (decl)
+ && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
diff --git a/lang/gcc16/files/patch-gcc_fortran_trans-types.cc b/lang/gcc16/files/patch-gcc_fortran_trans-types.cc
new file mode 100644
--- /dev/null
+++ b/lang/gcc16/files/patch-gcc_fortran_trans-types.cc
@@ -0,0 +1,12 @@
+--- gcc/fortran/trans-types.cc.orig 2026-04-30 08:33:20 UTC
++++ gcc/fortran/trans-types.cc
+@@ -595,7 +595,8 @@ gfc_init_kinds (void)
+ precision. For libgfortran calls pretend the IEEE 754 quad TFmode has
+ kind 17 rather than 16 and use kind 16 for the IBM extended format
+ TFmode. */
+- if (composite_mode != QImode && saw_r16 && !MODE_COMPOSITE_P (r16_mode))
++ if (composite_mode != QImode && saw_r16 && !MODE_COMPOSITE_P (r16_mode)
++ && TARGET_GLIBC_MAJOR >= 2)
+ {
+ for (int i = 0; i < r_index; ++i)
+ if (gfc_real_kinds[i].kind == 16)
diff --git a/lang/gcc16/files/patch-libgcc_config.host b/lang/gcc16/files/patch-libgcc_config.host
--- a/lang/gcc16/files/patch-libgcc_config.host
+++ b/lang/gcc16/files/patch-libgcc_config.host
@@ -1,11 +1,11 @@
---- libgcc/config.host.orig
+--- libgcc/config.host.orig 2026-04-30 08:33:28 UTC
+++ libgcc/config.host
-@@ -1234,6 +1234,12 @@
+@@ -1234,6 +1234,12 @@ powerpc*-*-freebsd*)
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"
++ 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"
diff --git a/lang/gcc16/files/patch-libgcc_config_rs6000_freebsd-tc-alias.c b/lang/gcc16/files/patch-libgcc_config_rs6000_freebsd-tc-alias.c
new file mode 100644
--- /dev/null
+++ b/lang/gcc16/files/patch-libgcc_config_rs6000_freebsd-tc-alias.c
@@ -0,0 +1,32 @@
+--- /dev/null
++++ libgcc/config/rs6000/freebsd-tc-alias.c
+@@ -0,0 +1,29 @@
++/* clang emits __multc3/__divtc3 (TCmode) for complex IEEE-128 long double,
++ where gcc uses the KCmode names __mulkc3/__divkc3. Provide TCmode forwarders
++ so clang-built shared libraries that link gcc's libgcc_s (e.g. USES=fortran
++ ports mixing a clang C compile with gfortran) resolve them. These are real
++ symbols, so mkmap-symver keeps them in the exported version map -- unlike a
++ link-time --defsym alias. The __asm__ names are not rewritten: the rs6000
++ IEEE-128 name mangling is disabled on FreeBSD, and only libgcc2.c's own
++ mode-based naming turns its __multc3/__divtc3 into __mulkc3/__divkc3. */
++
++extern _Complex long double __mulkc3 (_Complex long double, _Complex long double);
++extern _Complex long double __divkc3 (_Complex long double, _Complex long double);
++
++__attribute__ ((visibility ("default")))
++_Complex long double __freebsd_multc3 (_Complex long double, _Complex long double) __asm__ ("__multc3");
++
++_Complex long double
++__freebsd_multc3 (_Complex long double a, _Complex long double b)
++{
++ return __mulkc3 (a, b);
++}
++
++__attribute__ ((visibility ("default")))
++_Complex long double __freebsd_divtc3 (_Complex long double, _Complex long double) __asm__ ("__divtc3");
++
++_Complex long double
++__freebsd_divtc3 (_Complex long double a, _Complex long double b)
++{
++ return __divkc3 (a, b);
++}
diff --git a/lang/gcc14/files/patch-libgcc_config_rs6000_freebsd-unwind.h b/lang/gcc16/files/patch-libgcc_config_rs6000_freebsd-unwind.h
copy from lang/gcc14/files/patch-libgcc_config_rs6000_freebsd-unwind.h
copy to lang/gcc16/files/patch-libgcc_config_rs6000_freebsd-unwind.h
--- a/lang/gcc14/files/patch-libgcc_config_rs6000_freebsd-unwind.h
+++ b/lang/gcc16/files/patch-libgcc_config_rs6000_freebsd-unwind.h
@@ -1,30 +1,37 @@
---- libgcc/config/rs6000/freebsd-unwind.h.orig
+--- libgcc/config/rs6000/freebsd-unwind.h.orig 2026-04-30 08:33:28 UTC
+++ libgcc/config/rs6000/freebsd-unwind.h
-@@ -33,6 +33,11 @@
- const unsigned int *pc = (const unsigned int *) context->ra;
+@@ -24,6 +24,14 @@
- #ifdef __powerpc64__
+ #define R_LR 65
+
++#ifdef __powerpc64__
+#if _CALL_ELF == 2
-+#define TOC_SAVE_SLOT 24
++#define TOC_SAVE_SLOT 24
+#else
-+#define TOC_SAVE_SLOT 40
++#define TOC_SAVE_SLOT 40
++#endif
+#endif
- if (fs->regs.how[2] == REG_UNSAVED)
- {
- /* If the current unwind info (FS) does not contain explicit info
-@@ -40,9 +45,9 @@
++
+ #define MD_FROB_UPDATE_CONTEXT frob_update_context
+
+ static void
+@@ -40,9 +48,13 @@ frob_update_context (struct _Unwind_Context *context,
figure out if it was saved. The big problem here is that the
code that does the save/restore is generated by the linker, so
we have no good way to determine at compile time what to do. */
- if (pc[0] == 0xF8410028
+ if (pc[0] == 0xF8410000 + TOC_SAVE_SLOT
++#if _CALL_ELF != 2
++ /* The ELFv2 linker never generates the old PLT stub form. */
|| ((pc[0] & 0xFFFF0000) == 0x3D820000
- && pc[1] == 0xF8410028))
-+ && pc[1] == 0xF8410000 + TOC_SAVE_SLOT))
++ && pc[1] == 0xF8410000 + TOC_SAVE_SLOT)
++#endif
++ )
{
/* We are in a plt call stub or r2 adjusting long branch stub,
before r2 has been saved. Keep REG_UNSAVED. */
-@@ -51,17 +56,17 @@
+@@ -51,18 +63,21 @@ frob_update_context (struct _Unwind_Context *context,
{
unsigned int *insn
= (unsigned int *) _Unwind_GetGR (context, R_LR);
@@ -32,6 +39,8 @@
- _Unwind_SetGRPtr (context, 2, context->cfa + 40);
+ if (insn && *insn == 0xE8410000 + TOC_SAVE_SLOT)
+ _Unwind_SetGRPtr (context, 2, context->cfa + TOC_SAVE_SLOT);
++#if _CALL_ELF != 2
++ /* ELFv2 does not use this function pointer call sequence. */
else if (pc[0] == 0x4E800421
- && pc[1] == 0xE8410028)
+ && pc[1] == 0xE8410000 + TOC_SAVE_SLOT)
@@ -44,5 +53,7 @@
- _Unwind_SetGRPtr (context, 2, (void *)(sp + 40));
+ _Unwind_SetGRPtr (context, 2, (void *)(sp + TOC_SAVE_SLOT));
}
++#endif
}
}
+ #endif
diff --git a/lang/gcc16/files/patch-libgcc_config_rs6000_libgcc-freebsd-float128.ver b/lang/gcc16/files/patch-libgcc_config_rs6000_libgcc-freebsd-float128.ver
new file mode 100644
--- /dev/null
+++ b/lang/gcc16/files/patch-libgcc_config_rs6000_libgcc-freebsd-float128.ver
@@ -0,0 +1,40 @@
+--- /dev/null
++++ libgcc/config/rs6000/libgcc-freebsd-float128.ver
+@@ -0,0 +1,37 @@
++# 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
++ __multc3
++ __divtc3
++ __powikf2
++}
diff --git a/lang/gcc16/files/patch-libgcc_config_rs6000_t-float128-freebsd b/lang/gcc16/files/patch-libgcc_config_rs6000_t-float128-freebsd
new file mode 100644
--- /dev/null
+++ b/lang/gcc16/files/patch-libgcc_config_rs6000_t-float128-freebsd
@@ -0,0 +1,25 @@
+--- /dev/null
++++ libgcc/config/rs6000/t-float128-freebsd
+@@ -0,0 +1,22 @@
++# 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
++
++# clang emits the complex IEEE-128 helpers as __multc3/__divtc3 (TCmode) where
++# gcc names them __mulkc3/__divkc3 (KCmode). Provide real TCmode forwarders
++# (freebsd-tc-alias.c) so clang-built DSOs that link gcc's libgcc_s -- e.g.
++# USES=fortran ports mixing clang C with gfortran -- resolve them. Real symbols
++# survive mkmap-symver's map generation where a --defsym link alias would not.
++LIB2ADD += $(srcdir)/config/rs6000/freebsd-tc-alias.c
diff --git a/lang/gcc16/files/patch-libgcc_configure b/lang/gcc16/files/patch-libgcc_configure
new file mode 100644
--- /dev/null
+++ b/lang/gcc16/files/patch-libgcc_configure
@@ -0,0 +1,19 @@
+--- libgcc/configure.orig
++++ libgcc/configure
+@@ -5240,7 +5240,7 @@
+ # check if we have VSX (ISA 2.06) support to build the software libraries, and
+ # whether the assembler can handle xsaddqp for hardware support. Also check if
+ # a new glibc is being used so that __builtin_cpu_supports can be used.
+-powerpc*-*-linux*)
++powerpc*-*-linux* | powerpc*-*-freebsd*)
+ saved_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -mabi=altivec -mvsx -mfloat128"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PowerPC ISA 2.06 to build __float128 libraries" >&5
+@@ -5251,6 +5251,7 @@
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ vector double dadd (vector double a, vector double b) { return a + b; }
++__ibm128 conftest_ibm128;
+ _ACEOF
+ if ac_fn_c_try_compile "$LINENO"; then :
+ libgcc_cv_powerpc_float128=yes

File Metadata

Mime Type
text/plain
Expires
Sat, Jul 25, 7:45 AM (1 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35467436
Default Alt Text
D58116.id.diff (50 KB)

Event Timeline