pkgsrc-WIP-changes archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
gcc14: this one builds on Darwin/aarch64
Module Name: pkgsrc-wip
Committed By: Adam Ciarciński <aciarcinski%teonite.com@localhost>
Pushed By: adam
Date: Sat Jan 4 12:37:28 2025 +0100
Changeset: ec0f8e34d4603abcea617ad734b5d83adcea0e4d
Modified Files:
Makefile
Added Files:
gcc14/DESCR
gcc14/Makefile
gcc14/Makefile.common
gcc14/buildlink3.mk
gcc14/distinfo
gcc14/options.mk
gcc14/patches/patch-configure
gcc14/patches/patch-configure.ac
gcc14/patches/patch-fixincludes_fixincl.x
gcc14/patches/patch-fixincludes_inclhack.def
gcc14/patches/patch-gcc_Makefile.in
gcc14/patches/patch-gcc_ada_init.c
gcc14/patches/patch-gcc_builtins.cc
gcc14/patches/patch-gcc_c-family_c-attribs.cc
gcc14/patches/patch-gcc_c-family_c-common.cc
gcc14/patches/patch-gcc_c-family_c-common.h
gcc14/patches/patch-gcc_c-family_c-lex.cc
gcc14/patches/patch-gcc_c-family_c-opts.cc
gcc14/patches/patch-gcc_c-family_c-pragma.h
gcc14/patches/patch-gcc_c-family_c.opt
gcc14/patches/patch-gcc_c_c-parser.cc
gcc14/patches/patch-gcc_calls.cc
gcc14/patches/patch-gcc_calls.h
gcc14/patches/patch-gcc_collect2.cc
gcc14/patches/patch-gcc_common.opt
gcc14/patches/patch-gcc_common_config_aarch64_aarch64-common.cc
gcc14/patches/patch-gcc_config.gcc
gcc14/patches/patch-gcc_config.host
gcc14/patches/patch-gcc_config_aarch64_aarch64-builtins.cc
gcc14/patches/patch-gcc_config_aarch64_aarch64-c.cc
gcc14/patches/patch-gcc_config_aarch64_aarch64-cores.def
gcc14/patches/patch-gcc_config_aarch64_aarch64-netbsd.h
gcc14/patches/patch-gcc_config_aarch64_aarch64-protos.h
gcc14/patches/patch-gcc_config_aarch64_aarch64-tune.md
gcc14/patches/patch-gcc_config_aarch64_aarch64.cc
gcc14/patches/patch-gcc_config_aarch64_aarch64.h
gcc14/patches/patch-gcc_config_aarch64_aarch64.md
gcc14/patches/patch-gcc_config_aarch64_aarch64.opt
gcc14/patches/patch-gcc_config_aarch64_constraints.md
gcc14/patches/patch-gcc_config_aarch64_darwin.h
gcc14/patches/patch-gcc_config_aarch64_driver-aarch64.cc
gcc14/patches/patch-gcc_config_aarch64_predicates.md
gcc14/patches/patch-gcc_config_aarch64_t-aarch64-darwin
gcc14/patches/patch-gcc_config_arm_arm.h
gcc14/patches/patch-gcc_config_arm_bpabi.h
gcc14/patches/patch-gcc_config_arm_elf.h
gcc14/patches/patch-gcc_config_arm_netbsd-eabi.h
gcc14/patches/patch-gcc_config_arm_netbsd-elf.h
gcc14/patches/patch-gcc_config_darwin-driver.cc
gcc14/patches/patch-gcc_config_darwin-protos.h
gcc14/patches/patch-gcc_config_darwin.cc
gcc14/patches/patch-gcc_config_darwin.h
gcc14/patches/patch-gcc_config_darwin.opt
gcc14/patches/patch-gcc_configure
gcc14/patches/patch-gcc_configure.ac
gcc14/patches/patch-gcc_cp_decl2.cc
gcc14/patches/patch-gcc_cp_parser.cc
gcc14/patches/patch-gcc_cumulative-args.h
gcc14/patches/patch-gcc_doc_invoke.texi
gcc14/patches/patch-gcc_doc_tm.texi
gcc14/patches/patch-gcc_doc_tm.texi.in
gcc14/patches/patch-gcc_exec-tool.in
gcc14/patches/patch-gcc_explow.cc
gcc14/patches/patch-gcc_explow.h
gcc14/patches/patch-gcc_function.cc
gcc14/patches/patch-gcc_function.h
gcc14/patches/patch-gcc_ginclude_stddef.h
gcc14/patches/patch-gcc_jit_libgccjit.h
gcc14/patches/patch-gcc_opts.cc
gcc14/patches/patch-gcc_target.def
gcc14/patches/patch-gcc_target.h
gcc14/patches/patch-gcc_targhooks.cc
gcc14/patches/patch-gcc_targhooks.h
gcc14/patches/patch-gcc_testsuite_g++.dg_cpp0x_pr106435-b.cc
gcc14/patches/patch-gcc_testsuite_g++.dg_cpp0x_pr106435.C
gcc14/patches/patch-gcc_testsuite_g++.dg_cpp0x_pr106435.h
gcc14/patches/patch-gcc_testsuite_g++.target_aarch64_float128-darwin-1.C
gcc14/patches/patch-gcc_testsuite_gcc.target_aarch64_darwin_float128-01.c
gcc14/patches/patch-gcc_testsuite_gcc.target_aarch64_darwin_float128-02.c
gcc14/patches/patch-gcc_testsuite_gcc.target_aarch64_sme_aarch64-sme.exp
gcc14/patches/patch-isl_configure
gcc14/patches/patch-libffi_configure
gcc14/patches/patch-libffi_testsuite_libffi.call_float2.c
gcc14/patches/patch-libgcc_config.host
gcc14/patches/patch-libgcc_config_aarch64___arm_sme_state.S
gcc14/patches/patch-libgcc_config_aarch64___arm_tpidr2_restore.S
gcc14/patches/patch-libgcc_config_aarch64___arm_tpidr2_save.S
gcc14/patches/patch-libgcc_config_aarch64___arm_za_disable.S
gcc14/patches/patch-libgcc_config_aarch64_aarch64-asm.h
gcc14/patches/patch-libgcc_config_aarch64_lse.S
gcc14/patches/patch-libgcc_config_aarch64_sfp-machine.h
gcc14/patches/patch-libgcc_config_aarch64_t-darwin
gcc14/patches/patch-libgcc_config_i386_t-darwin
gcc14/patches/patch-libgcc_config_rs6000_t-darwin
gcc14/patches/patch-libgcc_config_t-darwin-libgccs1
gcc14/patches/patch-libgcc_config_t-darwin-min-11
gcc14/patches/patch-libgcc_crtstuff.c
gcc14/patches/patch-libgfortran_io_io.h
gcc14/patches/patch-libitm_config_aarch64_sjlj.S
gcc14/patches/patch-libitm_configure.tgt
gcc14/patches/patch-libphobos_libdruntime_core_internal_gc_impl_conservative_gc.d
gcc14/patches/patch-libquadmath_printf_quadmath-printf.c
gcc14/patches/patch-libquadmath_strtod_strtod__l.c
gcc14/patches/patch-libstdc++-v3_libsupc++_new__opa.cc
gcc14/version.mk
Log Message:
gcc14: this one builds on Darwin/aarch64
To see a diff of this commit:
https://wip.pkgsrc.org/cgi-bin/gitweb.cgi?p=pkgsrc-wip.git;a=commitdiff;h=ec0f8e34d4603abcea617ad734b5d83adcea0e4d
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
diffstat:
Makefile | 1 +
gcc14/DESCR | 2 +
gcc14/Makefile | 83 ++
gcc14/Makefile.common | 162 +++
gcc14/buildlink3.mk | 24 +
gcc14/distinfo | 106 ++
gcc14/options.mk | 163 +++
gcc14/patches/patch-configure | 15 +
gcc14/patches/patch-configure.ac | 15 +
gcc14/patches/patch-fixincludes_fixincl.x | 199 +++
gcc14/patches/patch-fixincludes_inclhack.def | 81 ++
gcc14/patches/patch-gcc_Makefile.in | 15 +
gcc14/patches/patch-gcc_ada_init.c | 17 +
gcc14/patches/patch-gcc_builtins.cc | 20 +
gcc14/patches/patch-gcc_c-family_c-attribs.cc | 25 +
gcc14/patches/patch-gcc_c-family_c-common.cc | 19 +
gcc14/patches/patch-gcc_c-family_c-common.h | 14 +
gcc14/patches/patch-gcc_c-family_c-lex.cc | 27 +
gcc14/patches/patch-gcc_c-family_c-opts.cc | 15 +
gcc14/patches/patch-gcc_c-family_c-pragma.h | 16 +
gcc14/patches/patch-gcc_c-family_c.opt | 17 +
gcc14/patches/patch-gcc_c_c-parser.cc | 176 +++
gcc14/patches/patch-gcc_calls.cc | 85 ++
gcc14/patches/patch-gcc_calls.h | 64 +
gcc14/patches/patch-gcc_collect2.cc | 118 ++
gcc14/patches/patch-gcc_common.opt | 27 +
...tch-gcc_common_config_aarch64_aarch64-common.cc | 44 +
gcc14/patches/patch-gcc_config.gcc | 45 +
gcc14/patches/patch-gcc_config.host | 15 +
.../patch-gcc_config_aarch64_aarch64-builtins.cc | 81 ++
.../patches/patch-gcc_config_aarch64_aarch64-c.cc | 32 +
.../patch-gcc_config_aarch64_aarch64-cores.def | 24 +
.../patch-gcc_config_aarch64_aarch64-netbsd.h | 18 +
.../patch-gcc_config_aarch64_aarch64-protos.h | 49 +
.../patch-gcc_config_aarch64_aarch64-tune.md | 13 +
gcc14/patches/patch-gcc_config_aarch64_aarch64.cc | 1402 ++++++++++++++++++++
gcc14/patches/patch-gcc_config_aarch64_aarch64.h | 81 ++
gcc14/patches/patch-gcc_config_aarch64_aarch64.md | 81 ++
gcc14/patches/patch-gcc_config_aarch64_aarch64.opt | 20 +
.../patch-gcc_config_aarch64_constraints.md | 29 +
gcc14/patches/patch-gcc_config_aarch64_darwin.h | 298 +++++
.../patch-gcc_config_aarch64_driver-aarch64.cc | 86 ++
.../patches/patch-gcc_config_aarch64_predicates.md | 31 +
.../patch-gcc_config_aarch64_t-aarch64-darwin | 32 +
gcc14/patches/patch-gcc_config_arm_arm.h | 45 +
gcc14/patches/patch-gcc_config_arm_bpabi.h | 22 +
gcc14/patches/patch-gcc_config_arm_elf.h | 14 +
gcc14/patches/patch-gcc_config_arm_netbsd-eabi.h | 57 +
gcc14/patches/patch-gcc_config_arm_netbsd-elf.h | 80 ++
gcc14/patches/patch-gcc_config_darwin-driver.cc | 99 ++
gcc14/patches/patch-gcc_config_darwin-protos.h | 30 +
gcc14/patches/patch-gcc_config_darwin.cc | 473 +++++++
gcc14/patches/patch-gcc_config_darwin.h | 77 ++
gcc14/patches/patch-gcc_config_darwin.opt | 28 +
gcc14/patches/patch-gcc_configure | 99 ++
gcc14/patches/patch-gcc_configure.ac | 71 +
gcc14/patches/patch-gcc_cp_decl2.cc | 123 ++
gcc14/patches/patch-gcc_cp_parser.cc | 274 ++++
gcc14/patches/patch-gcc_cumulative-args.h | 27 +
gcc14/patches/patch-gcc_doc_invoke.texi | 54 +
gcc14/patches/patch-gcc_doc_tm.texi | 63 +
gcc14/patches/patch-gcc_doc_tm.texi.in | 37 +
gcc14/patches/patch-gcc_exec-tool.in | 75 ++
gcc14/patches/patch-gcc_explow.cc | 31 +
gcc14/patches/patch-gcc_explow.h | 31 +
gcc14/patches/patch-gcc_function.cc | 108 ++
gcc14/patches/patch-gcc_function.h | 22 +
gcc14/patches/patch-gcc_ginclude_stddef.h | 18 +
gcc14/patches/patch-gcc_jit_libgccjit.h | 16 +
gcc14/patches/patch-gcc_opts.cc | 14 +
gcc14/patches/patch-gcc_target.def | 74 ++
gcc14/patches/patch-gcc_target.h | 31 +
gcc14/patches/patch-gcc_targhooks.cc | 52 +
gcc14/patches/patch-gcc_targhooks.h | 29 +
.../patch-gcc_testsuite_g++.dg_cpp0x_pr106435-b.cc | 24 +
.../patch-gcc_testsuite_g++.dg_cpp0x_pr106435.C | 27 +
.../patch-gcc_testsuite_g++.dg_cpp0x_pr106435.h | 21 +
...estsuite_g++.target_aarch64_float128-darwin-1.C | 48 +
...stsuite_gcc.target_aarch64_darwin_float128-01.c | 55 +
...stsuite_gcc.target_aarch64_darwin_float128-02.c | 108 ++
...estsuite_gcc.target_aarch64_sme_aarch64-sme.exp | 17 +
gcc14/patches/patch-isl_configure | 24 +
gcc14/patches/patch-libffi_configure | 16 +
.../patch-libffi_testsuite_libffi.call_float2.c | 15 +
gcc14/patches/patch-libgcc_config.host | 154 +++
.../patch-libgcc_config_aarch64___arm_sme_state.S | 37 +
...ch-libgcc_config_aarch64___arm_tpidr2_restore.S | 26 +
...patch-libgcc_config_aarch64___arm_tpidr2_save.S | 50 +
.../patch-libgcc_config_aarch64___arm_za_disable.S | 66 +
.../patch-libgcc_config_aarch64_aarch64-asm.h | 80 ++
gcc14/patches/patch-libgcc_config_aarch64_lse.S | 107 ++
.../patch-libgcc_config_aarch64_sfp-machine.h | 34 +
gcc14/patches/patch-libgcc_config_aarch64_t-darwin | 14 +
gcc14/patches/patch-libgcc_config_i386_t-darwin | 27 +
gcc14/patches/patch-libgcc_config_rs6000_t-darwin | 27 +
.../patches/patch-libgcc_config_t-darwin-libgccs1 | 23 +
gcc14/patches/patch-libgcc_config_t-darwin-min-11 | 17 +
gcc14/patches/patch-libgcc_crtstuff.c | 15 +
gcc14/patches/patch-libgfortran_io_io.h | 18 +
gcc14/patches/patch-libitm_config_aarch64_sjlj.S | 75 ++
gcc14/patches/patch-libitm_configure.tgt | 15 +
...runtime_core_internal_gc_impl_conservative_gc.d | 22 +
.../patch-libquadmath_printf_quadmath-printf.c | 26 +
gcc14/patches/patch-libquadmath_strtod_strtod__l.c | 23 +
.../patch-libstdc++-v3_libsupc++_new__opa.cc | 17 +
gcc14/version.mk | 3 +
106 files changed, 7292 insertions(+)
diffs:
diff --git a/Makefile b/Makefile
index 19deeccb76..8ceaef5d2c 100644
--- a/Makefile
+++ b/Makefile
@@ -1168,6 +1168,7 @@ SUBDIR+= gcc10-aux
SUBDIR+= gcc10snapshot
SUBDIR+= gcc13-gnat
SUBDIR+= gcc13-gnat-libs
+SUBDIR+= gcc14
SUBDIR+= gcc14-gnat
SUBDIR+= gcc14-gnat-libs
SUBDIR+= gcc42
diff --git a/gcc14/DESCR b/gcc14/DESCR
new file mode 100644
index 0000000000..902190a230
--- /dev/null
+++ b/gcc14/DESCR
@@ -0,0 +1,2 @@
+The GNU Compiler Collection (GCC) includes front ends for C, C++, Objective-C,
+Fortran, and Go.
diff --git a/gcc14/Makefile b/gcc14/Makefile
new file mode 100644
index 0000000000..8ad9c5a038
--- /dev/null
+++ b/gcc14/Makefile
@@ -0,0 +1,83 @@
+# $NetBSD: Makefile,v 1.1 2024/06/28 18:35:16 wiz Exp $
+
+PKGNAME= ${GCC_PKGNAME}-${GCC14_DIST_VERSION}
+## When bumping the PKGREVISION of this package the PKGREVISION of
+## lang/gcc14-libs needs to be bumped to be at least 1 more than the
+## PKGREVISION of this package!
+COMMENT= The GNU Compiler Collection (GCC) - 14.0 Release Series
+
+LANGS= c
+
+.include "Makefile.common"
+
+# In some cases LINKER_RPATH_FLAG needs a trailing space.
+LINKER_RPATH_FLAG:= ${LINKER_RPATH_FLAG:S/-rpath/& /}
+
+## The Library rpath to use in end programs.
+LDFLAGS_FOR_TARGET= ${LDFLAGS:M${COMPILER_RPATH_FLAG}*:N*/usr/lib*} ${LDFLAGS:M-Wl,-z*}
+
+# The "-static-libstdc++ -static-libgcc" flags are normally added to the
+# boot-ldflags by configure but because we are supply the boot-ldflags
+# we mash supply them.
+BOOT_LDFLAGS= -static-libstdc++ -static-libgcc ${LDFLAGS_FOR_TARGET}
+# Needed on Darwin when LDFLAGS point to a SDK
+BOOT_LDFLAGS+= ${LDFLAGS:M-Wl,-syslibroot*}
+# GCC does not understand this option; remove it, or stage build will fail
+BUILDLINK_TRANSFORM+= rm:-stdlib=libc++
+
+# Disable fixincludes on SmartOS, header changes result in broken includes
+# being generated, see https://github.com/joyent/pkgsrc-legacy/issues/270
+.if ${OS_VARIANT} == "SmartOS"
+SUBST_CLASSES+= fixinc
+SUBST_STAGE.fixinc= pre-configure
+SUBST_FILES.fixinc= gcc/Makefile.in
+SUBST_SED.fixinc= -e "s,\./fixinc.sh,-c true,"
+.endif
+
+.if !empty(MACHINE_PLATFORM:MNetBSD-*-*)
+# on NetBSD, use the native SSP code in libc
+CONFIGURE_ARGS+= --disable-libssp
+# Match base libstdc++ major
+SUBST_CLASSES+= libstdc
+SUBST_STAGE.libstdc= pre-configure
+SUBST_FILES.libstdc= libstdc++-v3/configure
+SUBST_MESSAGE.libstdc= Bumping libstdc++ major to 7
+SUBST_SED.libstdc= -e 's,libtool_VERSION=6:,libtool_VERSION=7:,g'
+.else
+CONFIGURE_ARGS+= --enable-libssp
+.endif
+
+## For target librarys and libjava programs.
+CONFIGURE_ENV+= LDFLAGS_FOR_TARGET=${LDFLAGS_FOR_TARGET:Q}
+
+.if ${USE_CROSS_COMPILE:U:tl} == "yes"
+CONFIGURE_ENV+= CC_FOR_BUILD=${NATIVE_CC:Q}
+CONFIGURE_ENV+= CXX_FOR_BUILD=${NATIVE_CXX:Q}
+.endif
+
+CONFIGURE_ARGS+= --enable-languages=${LANGS:Q}
+CONFIGURE_ARGS+= --enable-shared
+
+CTF_FILES_SKIP+= */gengtype # CPU limit exceeded
+
+TEST_TARGET= -j ${MAKE_JOBS} -k check || ${TRUE}
+TEST_DEPENDS+= dejagnu-[0-9]*:../../devel/dejagnu
+
+post-test:
+ ${RUN} cd ${WRKSRC} && cd ${OBJDIR} && \
+ ${SHELL} ${WRKSRC}/contrib/test_summary >${WRKDIR}/test_summary.log
+ ${INFO_MSG} "Test summary are available in ${WRKDIR}/test_summary.log"
+
+post-install:
+ ${TEST} -f ${DESTDIR}${GCC_PREFIX}/bin/cc || \
+ ( cd ${DESTDIR}${GCC_PREFIX}/bin ; ${LN} -f gcc cc )
+.if !empty(MACHINE_PLATFORM:MSunOS-*-*86*) && ${OS_VERSION} != "5.11"
+ ${SH} files/values.c ${DESTDIR}${GCC_PREFIX}/bin/gcc -m32 || ${TRUE}
+ ${SH} files/values.c ${DESTDIR}${GCC_PREFIX}/bin/gcc -m64 || ${TRUE}
+.endif
+
+GENERATE_PLIST+= \
+ cd ${DESTDIR}${PREFIX} && \
+ ${FIND} ${GCC_SUBPREFIX} \( -type f -o -type l \) -print | ${SORT};
+
+.include "../../mk/bsd.pkg.mk"
diff --git a/gcc14/Makefile.common b/gcc14/Makefile.common
new file mode 100644
index 0000000000..9a6f3ee831
--- /dev/null
+++ b/gcc14/Makefile.common
@@ -0,0 +1,162 @@
+# $NetBSD: Makefile.common,v 1.4 2024/09/29 16:51:55 adam Exp $
+# used by lang/gcc14-libjit/Makefile
+
+GCC_PKGNAME= gcc14
+.include "version.mk"
+
+DISTNAME= gcc-${GCC14_DIST_VERSION}
+CATEGORIES= lang
+MASTER_SITES= ${MASTER_SITE_GNU:=gcc/gcc-${GCC14_DIST_VERSION}/}
+EXTRACT_SUFX= .tar.xz
+
+MAINTAINER= pkgsrc-users%NetBSD.org@localhost
+HOMEPAGE= https://gcc.gnu.org/
+LICENSE= gnu-gpl-v2 AND gnu-gpl-v3 AND gnu-lgpl-v2 AND gnu-lgpl-v3
+
+DISTFILES= ${DEFAULT_DISTFILES}
+EXTRACT_ONLY= ${DEFAULT_DISTFILES}
+
+PATCHDIR= ${.CURDIR}/../../lang/gcc14/patches
+DISTINFO_FILE= ${.CURDIR}/../../lang/gcc14/distinfo
+
+# Relocations result in a linker error on AArch64, but not x86.
+MKPIE_SUPPORTED= no
+CHECK_RELRO_SKIP+= ${GCC_PKGNAME}/lib/*
+
+NOT_FOR_PLATFORM+= Interix-*-*
+
+USE_LANGUAGES= c c++
+USE_TOOLS+= gmake makeinfo sed tar:build
+USE_TOOLS.NetBSD+= gsed
+
+GNU_CONFIGURE= yes
+GNU_CONFIGURE_STRICT= no
+## Build outside ${WRKSRC}
+OBJDIR= ../build
+CONFIGURE_DIRS= ${OBJDIR}
+CONFIGURE_SCRIPT= ../${DISTNAME}/configure
+GCC_SUBPREFIX= ${GCC_PKGNAME}
+GCC_PREFIX= ${PREFIX}/${GCC_SUBPREFIX}
+GNU_CONFIGURE_PREFIX= ${GCC_PREFIX}
+INFO_FILES= yes
+CONFIGURE_ARGS+= --disable-libstdcxx-pch
+
+# error: 'for' loop initial declarations are only allowed in C99 mode
+USE_CC_FEATURES+= c99
+FORCE_C_STD= gnu99
+USE_CXX_FEATURES+= c++11
+FORCE_CXX_STD= c++11
+
+UNLIMIT_RESOURCES+= datasize
+UNLIMIT_RESOURCES+= stacksize
+
+CHECK_PORTABILITY_SKIP+= contrib/*
+CHECK_PORTABILITY_SKIP+= gcc/configure.orig_dist
+
+.include "../../mk/bsd.prefs.mk"
+
+.include "options.mk"
+
+.if ${OPSYS} == "Darwin"
+BUILDLINK_TRANSFORM+= rm:-nodefaultrpaths
+CONFIGURE_ARGS+= --disable-darwin-at-rpath
+.endif
+
+## For graphite support.
+.if !empty(PKG_OPTIONS:Mgcc-graphite)
+
+EXTRACT_ONLY+= ${ISL24}.tar.xz
+
+post-extract:
+ ${MV} ${WRKDIR}/${ISL24} ${WRKSRC}/isl
+.endif
+
+CONFIGURE_ARGS+= --enable-long-long
+CONFIGURE_ARGS+= --with-local-prefix=${GCC_PREFIX:Q}
+CONFIGURE_ARGS+= --enable-threads=posix
+CONFIGURE_ARGS+= --with-boot-ldflags=${BOOT_LDFLAGS:Q}
+CONFIGURE_ARGS+= --without-zstd
+# causes build errors even when using lang/gcc14 to self-host.
+CONFIGURE_ARGS.SunOS+= --disable-libsanitizer
+# multilib on Darwin requires fat-binaries
+CONFIGURE_ARGS.Darwin+= --disable-multilib
+.if !empty(OSX_SDK_PATH)
+CONFIGURE_ARGS.Darwin+= --with-sysroot=${OSX_SDK_PATH}
+.endif
+CONFIGURE_ARGS.NetBSD+= --with-gnu-ld --with-ld=/usr/bin/ld
+CONFIGURE_ARGS.NetBSD+= --with-gnu-as --with-as=/usr/bin/as
+MAKE_ENV.NetBSD+= ac_cv_func_clock_gettime=yes
+MAKE_ENV.NetBSD+= ac_cv_func_gethostbyname_r=no
+MAKE_ENV.NetBSD+= ac_cv_func_freelocale=no
+MAKE_ENV.NetBSD+= ac_cv_func_newlocale=no
+MAKE_ENV.NetBSD+= ac_cv_func_uselocale=no
+MAKE_ENV.SunOS+= ac_cv_func_mkostemp=no
+
+.if !empty(PKGSRC_COMPILER:Mclang) || ${OPSYS} == "DragonFly"
+CONFIGURE_ARGS+= --disable-bootstrap
+.endif
+
+.if ${MACHINE_PLATFORM:MNetBSD-*-i386} || ${MACHINE_PLATFORM:MLinux-*-i386}
+CONFIGURE_ARGS+= --with-arch=i486 --with-tune=i486
+.endif
+
+.if ${MACHINE_PLATFORM:MNetBSD-*-x86_64} || ${MACHINE_PLATFORM:MLinux-*-x86_64}
+CONFIGURE_ARGS+= --with-arch=nocona --with-tune=nocona --with-fpmath=sse
+.endif
+
+.if ${MACHINE_PLATFORM:MDarwin-[0-8].*-*}
+CONFIGURE_ARGS+= --with-dwarf2
+.endif
+
+# ${WRKSRC}/fixincludes/ looks for sed and compiles the path to sed into
+# a binary so we need to make sure we give it the installed sed and not
+# the tool wrapped one.
+MAKE_ENV+= ac_cv_path_SED=${TOOLS_SED}
+MAKE_ENV+= lt_cv_path_SED=${TOOLS_SED}
+
+# Determine whether to use binutils
+.if ${OPSYS} == "SunOS"
+. if exists(/usr/sfw/bin/gobjdump)
+CONFIGURE_ENV+= OBJDUMP=/usr/sfw/bin/gobjdump
+. endif
+. if exists(/usr/bin/ld)
+CONFIGURE_ARGS+= --without-gnu-ld --with-ld=/usr/bin/ld
+. else
+CONFIGURE_ARGS+= --without-gnu-ld --with-ld=/usr/ccs/bin/ld
+. endif
+. if exists(/usr/sfw/bin/gas)
+CONFIGURE_ARGS+= --with-gnu-as --with-as=/usr/sfw/bin/gas
+. elif exists(/usr/ccs/bin/as)
+CONFIGURE_ARGS+= --without-gnu-as --with-as=/usr/ccs/bin/as
+. else
+BUILDLINK_DEPMETHOD.binutils= full
+. include "../../devel/binutils/buildlink3.mk"
+CONFIGURE_ARGS+= --with-gnu-as --with-as=${PREFIX}/bin/gas
+. endif
+.endif
+
+.if ${OPSYS} == "Linux"
+# glibc limitations, needs at least -O1
+FORTIFY_SUPPORTED= no
+.endif
+
+.if ${OS_VARIANT} == "SmartOS"
+SUBST_CLASSES+= ccs
+SUBST_STAGE.ccs= pre-configure
+SUBST_FILES.ccs= contrib/make_sunver.pl
+SUBST_SED.ccs= -e 's,/usr/ccs/bin,/usr/bin,g'
+.endif
+
+pre-configure:
+ ${RUN} cd ${WRKSRC} && ${MKDIR} ${OBJDIR}
+
+CHECK_BUILTIN.zlib:= yes
+.include "../../devel/zlib/builtin.mk"
+CHECK_BUILTIN.zlib:= no
+.if ${USE_BUILTIN.zlib:tl} == yes
+CONFIGURE_ARGS+= --with-system-zlib
+.else
+CONFIGURE_ARGS+= --without-system-zlib
+.endif
+.include "../../mk/dlopen.buildlink3.mk"
+.include "../../mk/pthread.buildlink3.mk"
diff --git a/gcc14/buildlink3.mk b/gcc14/buildlink3.mk
new file mode 100644
index 0000000000..d324bb179b
--- /dev/null
+++ b/gcc14/buildlink3.mk
@@ -0,0 +1,24 @@
+# $NetBSD: buildlink3.mk,v 1.1 2024/06/28 18:35:16 wiz Exp $
+
+BUILDLINK_TREE+= gcc14
+
+.if !defined(GCC14_BUILDLINK3_MK)
+GCC14_BUILDLINK3_MK:=
+
+BUILDLINK_API_DEPENDS.gcc14+= gcc14>=${_GCC_REQD}
+BUILDLINK_ABI_DEPENDS.gcc14+= gcc14>=14.1
+BUILDLINK_PKGSRCDIR.gcc14= ../../lang/gcc14
+BUILDLINK_DEPMETHOD.gcc14?= build
+
+BUILDLINK_PASSTHRU_DIRS+= ${BUILDLINK_PREFIX.gcc14}/gcc14
+
+BUILDLINK_FILES.gcc14= # empty
+BUILDLINK_AUTO_VARS.gcc14= no
+
+pkgbase := gcc14
+.include "../../mk/pkg-build-options.mk"
+.include "../../mk/dlopen.buildlink3.mk"
+.include "../../mk/pthread.buildlink3.mk"
+.endif
+
+BUILDLINK_TREE+= -gcc14
diff --git a/gcc14/distinfo b/gcc14/distinfo
new file mode 100644
index 0000000000..48334294d7
--- /dev/null
+++ b/gcc14/distinfo
@@ -0,0 +1,106 @@
+$NetBSD: distinfo,v 1.5 2024/12/15 03:12:17 brook Exp $
+
+BLAKE2s (gcc-14.2.0.tar.xz) = 4cbc121d8d3982be05e1d0621363c6ec4cd34c78007a1af0599559370a93376e
+SHA512 (gcc-14.2.0.tar.xz) = 932bdef0cda94bacedf452ab17f103c0cb511ff2cec55e9112fc0328cbf1d803b42595728ea7b200e0a057c03e85626f937012e49a7515bc5dd256b2bf4bc396
+Size (gcc-14.2.0.tar.xz) = 92306460 bytes
+BLAKE2s (isl-0.24.tar.xz) = a3013b0d39b7fe68a1b3e15dc7e925b347d555348ee946a80f5319a76973cd61
+SHA512 (isl-0.24.tar.xz) = ff6bdcff839e1cd473f2a0c1e4dd4a3612ec6fee4544ccbc62b530a7248db2cf93b4b99bf493a86ddf2aba00e768927265d5d411f92061ea85fd7929073428e8
+Size (isl-0.24.tar.xz) = 1930956 bytes
+SHA1 (patch-configure) = 7d9225f1d9f0297a8cdb19aca2e584fc67742226
+SHA1 (patch-configure.ac) = d4229d5acd148959e8bfc2fd88745d7700828f72
+SHA1 (patch-fixincludes_fixincl.x) = 8705769847cfecbaea393960e2894517a5a05e28
+SHA1 (patch-fixincludes_inclhack.def) = 9a60dc8cbf702b374bf1e2a6c4e35009277301d9
+SHA1 (patch-gcc_Makefile.in) = c0f97c75ba1d37eae894141edd58bb36b734f651
+SHA1 (patch-gcc_ada_init.c) = 2851bff6d8de6671de6f75d769522f09e1d4efa0
+SHA1 (patch-gcc_builtins.cc) = 25b826dcd3553e5e5846a75bda7425eb9ef1f247
+SHA1 (patch-gcc_c-family_c-attribs.cc) = a0d99cc37d3c048aa86e6d2114d0b4ab719070b7
+SHA1 (patch-gcc_c-family_c-common.cc) = 0df51dabeb1210f54595767a8f4ae82475fe3556
+SHA1 (patch-gcc_c-family_c-common.h) = 8c25883409068172483dc8062c2f0d081c745b5e
+SHA1 (patch-gcc_c-family_c-lex.cc) = d01fcdf9eb3c48bc75d262abf5f097626629fb4d
+SHA1 (patch-gcc_c-family_c-opts.cc) = cd8e02798f74c937e3a2d86a79fdbcb9a312b1f7
+SHA1 (patch-gcc_c-family_c-pragma.h) = dc842411cc9a66f28052ebcf8e7dc9acdfedeb13
+SHA1 (patch-gcc_c-family_c.opt) = f3d93a56234cd9e88aa49d31812dc657196dd17d
+SHA1 (patch-gcc_c_c-parser.cc) = 7896860134e9e0c8169c24f31496091f239ccf6f
+SHA1 (patch-gcc_calls.cc) = eb65fbe28024a5e0ac76913ce67d862e3c24c984
+SHA1 (patch-gcc_calls.h) = ab2bc8d67d489fa78cbc7736e4d7487d8028caf4
+SHA1 (patch-gcc_collect2.cc) = 5950e9fbaa0061f5c7cbf53882fff8972feb552b
+SHA1 (patch-gcc_common.opt) = a2ae6fffc3da9c1a1fa958921405007828e268de
+SHA1 (patch-gcc_common_config_aarch64_aarch64-common.cc) = 7c5554783b27e33f8de958dc9ff1cd694b080e5a
+SHA1 (patch-gcc_config.gcc) = 4be431e0c92a5f181771d92f38035d36c5e78f3c
+SHA1 (patch-gcc_config.host) = bf95dd21bfdf79d173e745fbd35c9bb99fdf4087
+SHA1 (patch-gcc_config_aarch64_aarch64-builtins.cc) = 73fd302eedcc9b023f7acb448622cd5574778c58
+SHA1 (patch-gcc_config_aarch64_aarch64-c.cc) = 3d028fb5605a2d7218a05ccbba866265b60dfbc8
+SHA1 (patch-gcc_config_aarch64_aarch64-cores.def) = b087e883a7897c0e6fa3f5d296d7ca714f9224b0
+SHA1 (patch-gcc_config_aarch64_aarch64-netbsd.h) = abf19e2445bce1773162bddef16cd7f41eb36827
+SHA1 (patch-gcc_config_aarch64_aarch64-protos.h) = 5477a2f86e6eab0df6772410963c124aad5711d5
+SHA1 (patch-gcc_config_aarch64_aarch64-tune.md) = e9f7d16c78c26e41e4f7a768e209e1a620a142e0
+SHA1 (patch-gcc_config_aarch64_aarch64.cc) = 69884150b196b9065d153da421005213ece94b15
+SHA1 (patch-gcc_config_aarch64_aarch64.h) = 135bbc6864d1b9ee540ccc9bc1e4fa4503476401
+SHA1 (patch-gcc_config_aarch64_aarch64.md) = 5e43addc9418c4e79f5ee7e350ec6a404b2656ad
+SHA1 (patch-gcc_config_aarch64_aarch64.opt) = 0002e6f8c1f770b4734544e0d80c4bad4a7b7d02
+SHA1 (patch-gcc_config_aarch64_constraints.md) = 948a9608a57323e2a731936b472c9898c0e17da0
+SHA1 (patch-gcc_config_aarch64_darwin.h) = 674e39599154f63fb9d8fda7ace14ce9a3f0e046
+SHA1 (patch-gcc_config_aarch64_driver-aarch64.cc) = 82fb08124094038f5e12d2efe171a01ff3982a39
+SHA1 (patch-gcc_config_aarch64_predicates.md) = 25b2f1dbd79e77234acc2bb2ad5cca550d328d50
+SHA1 (patch-gcc_config_aarch64_t-aarch64-darwin) = 5407d281dd34adb6da784b838484626d315afb9b
+SHA1 (patch-gcc_config_arm_arm.h) = 9d554349869d67d6393552c33a7824f0dd53cb11
+SHA1 (patch-gcc_config_arm_bpabi.h) = 0b0de5ad95442e34397cb46739ef6e36048d6f45
+SHA1 (patch-gcc_config_arm_elf.h) = 57748157084319cb92d892f2ea5b2f3355567551
+SHA1 (patch-gcc_config_arm_netbsd-eabi.h) = 85eb89de6f2e64fac50251f06d7e4eab35903dae
+SHA1 (patch-gcc_config_arm_netbsd-elf.h) = 568f537d624199ef9f9f56088fe4fff7e946b2e2
+SHA1 (patch-gcc_config_darwin-driver.cc) = ac24a7ff6562bd69427a86942d40653a0301d3fd
+SHA1 (patch-gcc_config_darwin-protos.h) = cdaa9848139da663d99c0ebe3b1607f81ad972d8
+SHA1 (patch-gcc_config_darwin.cc) = 8502f81a59ab598ca2c95bce48402eb0faa7142d
+SHA1 (patch-gcc_config_darwin.h) = 572f28da4ed7894a82bd0c26f38a1c3c2ce1b5f6
+SHA1 (patch-gcc_config_darwin.opt) = 1fe22bedc6ae111157506a400ba6835040d6c2fe
+SHA1 (patch-gcc_configure) = df9cad73e43edc959cf114d047635eaf74cf8488
+SHA1 (patch-gcc_configure.ac) = abef894c5b5b00a9a6f5a480d01b36e021f87bef
+SHA1 (patch-gcc_cp_decl2.cc) = a49d15680d627b7bae2833ca6eafabf109c2fa5f
+SHA1 (patch-gcc_cp_parser.cc) = 31a5e3ac6ae9fda1559358876b18770f064293cc
+SHA1 (patch-gcc_cumulative-args.h) = aade3ac31d09ca3c0938dac82220ec4ed6663ab4
+SHA1 (patch-gcc_doc_invoke.texi) = bfc27f9c71e6ed09f9538eeba7277f39477c75a1
+SHA1 (patch-gcc_doc_tm.texi) = 1130d3ec9927dc7626cf4f32f8b39d4a634acdab
+SHA1 (patch-gcc_doc_tm.texi.in) = cbb2690415fb9efde88f2cfd8e8469fb2d41f897
+SHA1 (patch-gcc_exec-tool.in) = fffa1a0061e713f6f79bdc7ee3be1f92b84ba52e
+SHA1 (patch-gcc_explow.cc) = e3073e9cdbdffbec9e613aa48445aa23f2194c2c
+SHA1 (patch-gcc_explow.h) = 66e0b54bdf5d39fb4a18a1b46fa781d80129141a
+SHA1 (patch-gcc_function.cc) = ff6848b1d03f922f5e489b1b9b564645c7da8af0
+SHA1 (patch-gcc_function.h) = 0687d82c0af783cf5071aaafcf53a8bec5013f64
+SHA1 (patch-gcc_ginclude_stddef.h) = a1f29f148e6cb9496415d22c079beacaaf9a5730
+SHA1 (patch-gcc_jit_libgccjit.h) = ac21412bbe6624941fa31a95d24437f06992973d
+SHA1 (patch-gcc_opts.cc) = b6f8ac594d6bab92f3a151b5e271bc8ceca20266
+SHA1 (patch-gcc_target.def) = 81a916e275d63ce7cc09c4e2c0efa1aeee9e7c6c
+SHA1 (patch-gcc_target.h) = 633e6b3fab78ba7b6da721b986bd1ff5d7699f18
+SHA1 (patch-gcc_targhooks.cc) = ab9a4ff6142853aa863bb7bed3d585950ce27744
+SHA1 (patch-gcc_targhooks.h) = e3854e57faf284c8fec535fe970eb68b35ab59c2
+SHA1 (patch-gcc_testsuite_g++.dg_cpp0x_pr106435-b.cc) = a4d22c5924393b549caea0395e9490dcea356f83
+SHA1 (patch-gcc_testsuite_g++.dg_cpp0x_pr106435.C) = 3a60c331c0039c28b28ca17e97f752e6d1e59095
+SHA1 (patch-gcc_testsuite_g++.dg_cpp0x_pr106435.h) = 3a29fcb162127a477ec2977bdac1d02e10b51f04
+SHA1 (patch-gcc_testsuite_g++.target_aarch64_float128-darwin-1.C) = 9e7d6af938b6c5d32af98f0756f7b5c96a3a083e
+SHA1 (patch-gcc_testsuite_gcc.target_aarch64_darwin_float128-01.c) = fc6b2f9fa466c997c542416440106325fb145f8d
+SHA1 (patch-gcc_testsuite_gcc.target_aarch64_darwin_float128-02.c) = 3f37d4692c9d1dcb213260d115e96aea87486924
+SHA1 (patch-gcc_testsuite_gcc.target_aarch64_sme_aarch64-sme.exp) = d886766f77dc94c2801088aaf007007b6ae5a1bd
+SHA1 (patch-isl_configure) = a6295c509bdc82e8b54d7dec5252994532463091
+SHA1 (patch-libffi_configure) = 919bbe094e3ce547a0186eeaddb20a662595f79a
+SHA1 (patch-libffi_testsuite_libffi.call_float2.c) = 89e2dd6aaf2c1f75726f02362d8a8bf7178694ea
+SHA1 (patch-libgcc_config.host) = b37a525ca7b884743cdc85010b31b21e56a6b4e3
+SHA1 (patch-libgcc_config_aarch64___arm_sme_state.S) = 2ebd8dabeb8e350010cdafe87dec63e2d728b607
+SHA1 (patch-libgcc_config_aarch64___arm_tpidr2_restore.S) = 6799c0babc8a8599c3dbdec80b38d429ae6ebf71
+SHA1 (patch-libgcc_config_aarch64___arm_tpidr2_save.S) = 6aeb1565a75f21dceadfed9397ace93953090383
+SHA1 (patch-libgcc_config_aarch64___arm_za_disable.S) = 09fedb2d1c27b955e24b3dbfe92117559aed2d53
+SHA1 (patch-libgcc_config_aarch64_aarch64-asm.h) = 3b2fd361794886e63a6933b3628af41007345830
+SHA1 (patch-libgcc_config_aarch64_lse.S) = 8f239f7ca27ceca19445b94a2c62dae8c000f3be
+SHA1 (patch-libgcc_config_aarch64_sfp-machine.h) = d49154b264153eec5c2f47eb0d0c69779a31bb18
+SHA1 (patch-libgcc_config_aarch64_t-darwin) = 4ddd3fec628baedf4cda70aa0c97d540c38cb9c1
+SHA1 (patch-libgcc_config_i386_t-darwin) = 5c719be042134bf33f7d4d2bde63573f37df9a84
+SHA1 (patch-libgcc_config_rs6000_t-darwin) = a88cca89c7f28997e28b81d830b96613f23978ec
+SHA1 (patch-libgcc_config_t-darwin-libgccs1) = 75e5c3467bfd5716519a65f4d1a6da169486999e
+SHA1 (patch-libgcc_config_t-darwin-min-11) = 8bf932c0c2769c5e2e191626976af31f1c57df7e
+SHA1 (patch-libgcc_crtstuff.c) = a16d465039de00c195cf0694560140a9c38f3a25
+SHA1 (patch-libgfortran_io_io.h) = d44676239a7f45e42054d24bd5224f43c20055c0
+SHA1 (patch-libitm_config_aarch64_sjlj.S) = 519aaaebda4250d91b78081bb4e12e6133cb5840
+SHA1 (patch-libitm_configure.tgt) = e48229d449374b62ee348ef5eb117dd3060ee615
+SHA1 (patch-libphobos_libdruntime_core_internal_gc_impl_conservative_gc.d) = 089dc022732ebe65aa383225743f19b00827e1a2
+SHA1 (patch-libquadmath_printf_quadmath-printf.c) = 78e09f1e6d61ee57cee83275093cf46b2335d204
+SHA1 (patch-libquadmath_strtod_strtod__l.c) = 6142c10d34174174cce7f06c37eab04dc431b2dc
+SHA1 (patch-libstdc++-v3_libsupc++_new__opa.cc) = 891ec8488516592ea2065509b7310c55d7a367ad
diff --git a/gcc14/options.mk b/gcc14/options.mk
new file mode 100644
index 0000000000..7e8a3e9470
--- /dev/null
+++ b/gcc14/options.mk
@@ -0,0 +1,163 @@
+# $NetBSD: options.mk,v 1.1 2024/06/28 18:35:16 wiz Exp $
+
+PKG_OPTIONS_VAR= PKG_OPTIONS.${GCC_PKGNAME}
+PKG_SUPPORTED_OPTIONS= nls gcc-inplace-math gcc-c++ gcc-fortran \
+ gcc-go gcc-objc gcc-objc++ gcc-graphite \
+ always-libgcc
+PKG_SUGGESTED_OPTIONS= gcc-c++ gcc-fortran gcc-objc gcc-objc++ \
+ gcc-graphite gcc-inplace-math
+
+.include "../../mk/bsd.fast.prefs.mk"
+
+.if ${OPSYS} == "NetBSD"
+PKG_SUGGESTED_OPTIONS+= nls
+.elif ${OPSYS} == "Linux"
+PKG_SUGGESTED_OPTIONS+= nls
+.elif ${OPSYS} == "DragonFly"
+PKG_SUGGESTED_OPTIONS+= nls
+.elif ${OPSYS} == "SunOS"
+PKG_SUGGESTED_OPTIONS+= gcc-inplace-math always-libgcc
+.else
+.endif
+
+.include "../../mk/compiler.mk"
+.if empty(PKGSRC_COMPILER:Mgcc)
+PKG_SUGGESTED_OPTIONS+= always-libgcc
+.endif
+
+###
+### Determine if multilib is avalible.
+###
+MULTILIB_SUPPORTED?= unknown
+.if ${MACHINE_PLATFORM:MLinux-*-x86_64}
+. if exists(/usr/include/x86_64-linux-gnu/gnu)
+_GNU_INCLUDE_DIR= /usr/include/x86_64-linux-gnu/gnu
+. else
+_GNU_INCLUDE_DIR= /usr/include/gnu
+. endif
+. if exists(${_GNU_INCLUDE_DIR}/stubs-64.h) && \
+ !exists(${_GNU_INCLUDE_DIR}/stubs-32.h)
+MULTILIB_SUPPORTED= No
+. else
+MULTILIB_SUPPORTED= Yes
+. endif
+.endif
+.if !empty(MULTILIB_SUPPORTED:M[Yy][Ee][Ss])
+PKG_SUPPORTED_OPTIONS+= gcc-multilib
+PKG_SUGGESTED_OPTIONS+= gcc-multilib
+.endif
+
+.include "../../mk/bsd.options.mk"
+
+###
+### Don't install libgcc if it's older than the system one
+###
+.if empty(PKG_OPTIONS:Malways-libgcc)
+
+. for _libdir_ in ${_OPSYS_LIB_DIRS}
+. if exists(${_libdir_})
+BASE_LIBGCC!= find ${_libdir_} -name libgcc_s.so 2> /dev/null
+BASE_LIBGCC_MATCH_STRING!= ${ECHO} ${BASE_LIBGCC} ${GCC13_DIST_VERSION} | \
+ ${AWK} -f ../../mk/scripts/larger_symbol_version.awk
+. if ${BASE_LIBGCC_MATCH_STRING:Mnewer}
+DELETE_INSTALLED_LIBGCC= yes
+. endif
+. endif
+. endfor
+
+. if ${DELETE_INSTALLED_LIBGCC:Uno} == "yes"
+post-install: delete-installed-libgcc
+
+.PHONY: delete-installed-libgcc
+delete-installed-libgcc:
+ ${FIND} ${DESTDIR} -name 'libgcc_s.so*' -delete
+
+. endif
+
+.endif
+
+###
+### Native Language Support
+###
+.if !empty(PKG_OPTIONS:Mnls)
+USE_TOOLS+= msgfmt
+CONFIGURE_ARGS+= --enable-nls
+CONFIGURE_ARGS+= --with-libiconv-prefix=${BUILDLINK_PREFIX.iconv}
+MAKE_ENV+= ICONVPREFIX=${BUILDLINK_PREFIX.iconv}
+.include "../../converters/libiconv/buildlink3.mk"
+.include "../../devel/gettext-lib/buildlink3.mk"
+.else
+CONFIGURE_ARGS+= --disable-nls
+.endif
+
+###
+### Multilib Support
+###
+.if (!empty(MULTILIB_SUPPORTED:M[Yy][Ee][Ss]) && \
+ empty(PKG_OPTIONS:Mgcc-multilib) ) || \
+ !empty(MULTILIB_SUPPORTED:M[Nn][Oo])
+CONFIGURE_ARGS+= --disable-multilib
+.endif
+
+###
+### Build math libraries in place
+###
+.if !empty(PKG_OPTIONS:Mgcc-inplace-math)
+. include "../../devel/gmp/inplace.mk"
+. include "../../math/mpcomplex/inplace.mk"
+. include "../../math/mpfr/inplace.mk"
+.else
+CONFIGURE_ARGS+= --with-gmp=${BUILDLINK_PREFIX.gmp}
+CONFIGURE_ARGS+= --with-mpc=${BUILDLINK_PREFIX.mpcomplex}
+CONFIGURE_ARGS+= --with-mpfr=${BUILDLINK_PREFIX.mpfr}
+LIBS.SunOS+= -lgmp
+. include "../../devel/gmp/buildlink3.mk"
+. include "../../math/mpcomplex/buildlink3.mk"
+. include "../../math/mpfr/buildlink3.mk"
+.endif
+
+###
+### Graphite Support
+###
+.if !empty(PKG_OPTIONS:Mgcc-graphite)
+ISL24= isl-0.24
+SITES.${ISL24}.tar.bz2= ${MASTER_SITE_GNU:=gcc/infrastructure/}
+DISTFILES+= ${ISL24}.tar.xz
+.endif
+
+###
+### Optional languages
+### Ada could be added although there is a bootstrapping issue.
+###
+
+.if !empty(PKG_OPTIONS:Mgcc-objc++)
+. if empty(PKG_OPTIONS:Mgcc-c++)
+PKG_OPTIONS+= gcc-c++
+. endif
+. if empty(PKG_OPTIONS:Mgcc-objc)
+PKG_OPTIONS+= gcc-objc
+. endif
+LANGS+= obj-c++
+.endif
+
+.if !empty(PKG_OPTIONS:Mgcc-objc)
+LANGS+= objc
+.endif
+
+.if !empty(PKG_OPTIONS:Mgcc-go)
+LANGS+= go
+.endif
+
+.if !empty(PKG_OPTIONS:Mgcc-fortran)
+LANGS+= fortran
+.endif
+
+.if !empty(PKG_OPTIONS:Mgcc-c++)
+LANGS+= c++
+USE_TOOLS+= perl
+CONFIGURE_ARGS+= --enable-__cxa_atexit
+CONFIGURE_ARGS+= --with-gxx-include-dir=${GCC_PREFIX}/include/c++/
+.else
+CONFIGURE_ARGS+= --disable-build-with-cxx
+CONFIGURE_ARGS+= --disable-build-poststage1-with-cxx
+.endif
diff --git a/gcc14/patches/patch-configure b/gcc14/patches/patch-configure
new file mode 100644
index 0000000000..d3eb8ae777
--- /dev/null
+++ b/gcc14/patches/patch-configure
@@ -0,0 +1,15 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- configure
++++ configure
+@@ -3518,6 +3518,8 @@ esac
+
+ # Disable libffi for some systems.
+ case "${target}" in
++ aarch64*-*-darwin2*)
++ ;;
+ powerpc-*-darwin*)
+ ;;
+ i[3456789]86-*-darwin*)
diff --git a/gcc14/patches/patch-configure.ac b/gcc14/patches/patch-configure.ac
new file mode 100644
index 0000000000..1287698c80
--- /dev/null
+++ b/gcc14/patches/patch-configure.ac
@@ -0,0 +1,15 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- configure.ac
++++ configure.ac
+@@ -747,6 +747,8 @@ esac
+
+ # Disable libffi for some systems.
+ case "${target}" in
++ aarch64*-*-darwin2*)
++ ;;
+ powerpc-*-darwin*)
+ ;;
+ i[[3456789]]86-*-darwin*)
diff --git a/gcc14/patches/patch-fixincludes_fixincl.x b/gcc14/patches/patch-fixincludes_fixincl.x
new file mode 100644
index 0000000000..724a1c7258
--- /dev/null
+++ b/gcc14/patches/patch-fixincludes_fixincl.x
@@ -0,0 +1,199 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- fixincludes/fixincl.x
++++ fixincludes/fixincl.x
+@@ -2,11 +2,11 @@
+ *
+ * DO NOT EDIT THIS FILE (fixincl.x)
+ *
+- * It has been AutoGen-ed August 17, 2023 at 10:16:38 AM by AutoGen 5.18.12
++ * It has been AutoGen-ed October 6, 2024 at 07:10:01 PM by AutoGen 5.18.7
+ * From the definitions inclhack.def
+ * and the template file fixincl
+ */
+-/* DO NOT SVN-MERGE THIS FILE, EITHER Thu Aug 17 10:16:38 CEST 2023
++/* DO NOT SVN-MERGE THIS FILE, EITHER Sun Oct 6 19:10:01 BST 2024
+ *
+ * You must regenerate it. Use the ./genfixes script.
+ *
+@@ -15,7 +15,7 @@
+ * certain ANSI-incompatible system header files which are fixed to work
+ * correctly with ANSI C and placed in a directory that GNU C will search.
+ *
+- * This file contains 274 fixup descriptions.
++ * This file contains 272 fixup descriptions.
+ *
+ * See README for more information.
+ *
+@@ -267,56 +267,6 @@ static const char* apzAab_Darwin7_9_Long_Double_FuncsPatch[] = {
+ #endif /* __MATH__ */",
+ (char*)NULL };
+
+-/* * * * * * * * * * * * * * * * * * * * * * * * * *
+- *
+- * Description of Darwin_Api_Availability fix
+- */
+-tSCC zDarwin_Api_AvailabilityName[] =
+- "darwin_api_availability";
+-
+-/*
+- * File name selection pattern
+- */
+-tSCC zDarwin_Api_AvailabilityList[] =
+- "os/availability.h\0";
+-/*
+- * Machine/OS name selection pattern
+- */
+-tSCC* apzDarwin_Api_AvailabilityMachs[] = {
+- "*-*-darwin*",
+- (const char*)NULL };
+-
+-/*
+- * content selection pattern - do fix if pattern found
+- */
+-tSCC zDarwin_Api_AvailabilitySelect0[] =
+- " *#define __API_AVAILABLE.*\n\
+- *#define __API_DEPRECATED.*\n\
+- *#define __API_DEPRECATED_WITH_REPLACEMENT.*\n\
+- *#define __API_UNAVAILABLE.*\n";
+-
+-/*
+- * content bypass pattern - skip fix if pattern found
+- */
+-tSCC zDarwin_Api_AvailabilityBypass0[] =
+- "__IPHONE_OS_VERSION_MIN_REQUIRED";
+-
+-#define DARWIN_API_AVAILABILITY_TEST_CT 2
+-static tTestDesc aDarwin_Api_AvailabilityTests[] = {
+- { TT_NEGREP, zDarwin_Api_AvailabilityBypass0, (regex_t*)NULL },
+- { TT_EGREP, zDarwin_Api_AvailabilitySelect0, (regex_t*)NULL }, };
+-
+-/*
+- * Fix Command Arguments for Darwin_Api_Availability
+- */
+-static const char* apzDarwin_Api_AvailabilityPatch[] = {
+- "format",
+- " #define API_AVAILABLE(...)\n\
+- #define API_DEPRECATED(...)\n\
+- #define API_DEPRECATED_WITH_REPLACEMENT(...)\n\
+- #define API_UNAVAILABLE(...)\n",
+- (char*)NULL };
+-
+ /* * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * Description of Aab_Fd_Zero_Asm_Posix_Types_H fix
+@@ -2619,7 +2569,7 @@ tSCC zApple_Local_Stdio_Fn_DeprecationName[] =
+ * File name selection pattern
+ */
+ tSCC zApple_Local_Stdio_Fn_DeprecationList[] =
+- "stdio.h\0";
++ "stdio.h\0_stdio.h\0";
+ /*
+ * Machine/OS name selection pattern
+ */
+@@ -2763,51 +2713,6 @@ extern \"C\" {\n\
+ #endif\n",
+ (char*)NULL };
+
+-/* * * * * * * * * * * * * * * * * * * * * * * * * *
+- *
+- * Description of Darwin_Availabilityinternal fix
+- */
+-tSCC zDarwin_AvailabilityinternalName[] =
+- "darwin_availabilityinternal";
+-
+-/*
+- * File name selection pattern
+- */
+-tSCC zDarwin_AvailabilityinternalList[] =
+- "AvailabilityInternal.h\0";
+-/*
+- * Machine/OS name selection pattern
+- */
+-tSCC* apzDarwin_AvailabilityinternalMachs[] = {
+- "*-*-darwin*",
+- (const char*)NULL };
+-
+-/*
+- * content selection pattern - do fix if pattern found
+- */
+-tSCC zDarwin_AvailabilityinternalSelect0[] =
+- "#define[ \t]+(__API_[ADU]\\([^)]*\\)).*";
+-
+-#define DARWIN_AVAILABILITYINTERNAL_TEST_CT 1
+-static tTestDesc aDarwin_AvailabilityinternalTests[] = {
+- { TT_EGREP, zDarwin_AvailabilityinternalSelect0, (regex_t*)NULL }, };
+-
+-/*
+- * Fix Command Arguments for Darwin_Availabilityinternal
+- */
+-static const char* apzDarwin_AvailabilityinternalPatch[] = {
+- "format",
+- "#if defined(__has_attribute)\n\
+- #if __has_attribute(availability)\n\
+-%0\n\
+- #else\n\
+- #define %1\n\
+- #endif\n\
+-#else\n\
+- #define %1\n\
+-#endif",
+- (char*)NULL };
+-
+ /* * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * Description of Darwin_9_Long_Double_Funcs_2 fix
+@@ -11169,9 +11074,9 @@ static const char* apzX11_SprintfPatch[] = {
+ *
+ * List of all fixes
+ */
+-#define REGEX_COUNT 313
++#define REGEX_COUNT 310
+ #define MACH_LIST_SIZE_LIMIT 187
+-#define FIX_COUNT 274
++#define FIX_COUNT 272
+
+ /*
+ * Enumerate the fixes
+@@ -11180,7 +11085,6 @@ typedef enum {
+ AAB_AIX_STDIO_FIXIDX,
+ AAB_AIX_FCNTL_FIXIDX,
+ AAB_DARWIN7_9_LONG_DOUBLE_FUNCS_FIXIDX,
+- DARWIN_API_AVAILABILITY_FIXIDX,
+ AAB_FD_ZERO_ASM_POSIX_TYPES_H_FIXIDX,
+ AAB_FD_ZERO_GNU_TYPES_H_FIXIDX,
+ AAB_FD_ZERO_SELECTBITS_H_FIXIDX,
+@@ -11242,7 +11146,6 @@ typedef enum {
+ CTRL_QUOTES_DEF_FIXIDX,
+ CTRL_QUOTES_USE_FIXIDX,
+ CXX_UNREADY_FIXIDX,
+- DARWIN_AVAILABILITYINTERNAL_FIXIDX,
+ DARWIN_9_LONG_DOUBLE_FUNCS_2_FIXIDX,
+ DARWIN_EXTERNC_FIXIDX,
+ DARWIN_GCC4_BREAKAGE_FIXIDX,
+@@ -11469,11 +11372,6 @@ tFixDesc fixDescList[ FIX_COUNT ] = {
+ AAB_DARWIN7_9_LONG_DOUBLE_FUNCS_TEST_CT, FD_MACH_ONLY | FD_REPLACEMENT,
+ aAab_Darwin7_9_Long_Double_FuncsTests, apzAab_Darwin7_9_Long_Double_FuncsPatch, 0 },
+
+- { zDarwin_Api_AvailabilityName, zDarwin_Api_AvailabilityList,
+- apzDarwin_Api_AvailabilityMachs,
+- DARWIN_API_AVAILABILITY_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
+- aDarwin_Api_AvailabilityTests, apzDarwin_Api_AvailabilityPatch, 0 },
+-
+ { zAab_Fd_Zero_Asm_Posix_Types_HName, zAab_Fd_Zero_Asm_Posix_Types_HList,
+ apzAab_Fd_Zero_Asm_Posix_Types_HMachs,
+ AAB_FD_ZERO_ASM_POSIX_TYPES_H_TEST_CT, FD_MACH_ONLY | FD_REPLACEMENT,
+@@ -11779,11 +11677,6 @@ tFixDesc fixDescList[ FIX_COUNT ] = {
+ CXX_UNREADY_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
+ aCxx_UnreadyTests, apzCxx_UnreadyPatch, 0 },
+
+- { zDarwin_AvailabilityinternalName, zDarwin_AvailabilityinternalList,
+- apzDarwin_AvailabilityinternalMachs,
+- DARWIN_AVAILABILITYINTERNAL_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
+- aDarwin_AvailabilityinternalTests, apzDarwin_AvailabilityinternalPatch, 0 },
+-
+ { zDarwin_9_Long_Double_Funcs_2Name, zDarwin_9_Long_Double_Funcs_2List,
+ apzDarwin_9_Long_Double_Funcs_2Machs,
+ DARWIN_9_LONG_DOUBLE_FUNCS_2_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
diff --git a/gcc14/patches/patch-fixincludes_inclhack.def b/gcc14/patches/patch-fixincludes_inclhack.def
new file mode 100644
index 0000000000..db89851d46
--- /dev/null
+++ b/gcc14/patches/patch-fixincludes_inclhack.def
@@ -0,0 +1,81 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- fixincludes/inclhack.def
++++ fixincludes/inclhack.def
+@@ -194,33 +194,6 @@ fix = {
+ _EndOfHeader_;
+ };
+
+-/*
+- * SDKs for 10.13 and 10.14 omit the definitions for API_AVAILABLE where
+- * __attribute__((availability)) is not supported.
+- */
+-fix = {
+- hackname = darwin_api_availability;
+- mach = "*-*-darwin*";
+- files = os/availability.h;
+- bypass = "__IPHONE_OS_VERSION_MIN_REQUIRED";
+- select =
+- " *#define __API_AVAILABLE.*\n"
+- " *#define __API_DEPRECATED.*\n"
+- " *#define __API_DEPRECATED_WITH_REPLACEMENT.*\n"
+- " *#define __API_UNAVAILABLE.*\n";
+- c_fix = format;
+- c_fix_arg =
+- " #define API_AVAILABLE(...)\n"
+- " #define API_DEPRECATED(...)\n"
+- " #define API_DEPRECATED_WITH_REPLACEMENT(...)\n"
+- " #define API_UNAVAILABLE(...)\n";
+- test_text =
+- "#define __API_AVAILABLE(...)\n"
+- "#define __API_DEPRECATED(...)\n"
+- "#define __API_DEPRECATED_WITH_REPLACEMENT(...)\n"
+- "#define __API_UNAVAILABLE(...)\n";
+-};
+-
+ /*
+ * This fixes __FD_ZERO bug for linux 2.x.y (x <= 2 && y <= some n)
+ */
+@@ -1273,6 +1246,7 @@ fix = {
+ hackname = apple_local_stdio_fn_deprecation;
+ mach = "*-*-*darwin2*";
+ files = stdio.h;
++ files = _stdio.h;
+ select = "__deprecated_msg([^\n]*)$";
+ c_fix = format;
+ c_fix_arg = "#if defined(__APPLE_LOCAL_DEPRECATIONS)\n"
+@@ -1350,32 +1324,6 @@ fix = {
+ test_text = "extern void* malloc( size_t );";
+ };
+
+-/*
+- * macOS 10.12 <AvailabilityInternal.h> uses __attribute__((availability))
+- * unconditionally.
+- */
+-fix = {
+- hackname = darwin_availabilityinternal;
+- mach = "*-*-darwin*";
+- files = AvailabilityInternal.h;
+- select = "#define[ \t]+(__API_[ADU]\\([^)]*\\)).*";
+- c_fix = format;
+- c_fix_arg = <<- _EOFix_
+- #if defined(__has_attribute)
+- #if __has_attribute(availability)
+- %0
+- #else
+- #define %1
+- #endif
+- #else
+- #define %1
+- #endif
+- _EOFix_;
+-
+- test_text = "#define __API_A(x) __attribute__((availability(__API_AVAILABLE_PLATFORM_##x)))\n"
+- "#define __API_D(msg,x) __attribute__((availability(__API_DEPRECATED_PLATFORM_##x,message=msg)))";
+-};
+-
+ /*
+ * For the AAB_darwin7_9_long_double_funcs fix (and later fixes for long long)
+ * to be useful, the main math.h must use <> and not "" includes.
diff --git a/gcc14/patches/patch-gcc_Makefile.in b/gcc14/patches/patch-gcc_Makefile.in
new file mode 100644
index 0000000000..61ad8d9fbb
--- /dev/null
+++ b/gcc14/patches/patch-gcc_Makefile.in
@@ -0,0 +1,15 @@
+$NetBSD: patch-gcc_Makefile.in,v 1.1 2024/06/28 18:35:16 wiz Exp $
+
+Add gcc libdir to a programs rpath so that _this gcc's_ support libraries
+are found.
+
+--- gcc/Makefile.in.orig 2017-04-18 18:10:27.000000000 +0000
++++ gcc/Makefile.in
+@@ -2112,6 +2112,7 @@ prefix.o: $(BASEVER)
+ # Language-independent files.
+
+ DRIVER_DEFINES = \
++ -DLINK_LIBGCC_SPEC="\"%D $(LINKER_RPATH_FLAG) $(prefix)//lib/%M $(LINKER_RPATH_FLAG) $(libdir)/%M \"" \
+ -DSTANDARD_STARTFILE_PREFIX=\"$(unlibsubdir)/\" \
+ -DSTANDARD_EXEC_PREFIX=\"$(libdir)/gcc/\" \
+ -DSTANDARD_LIBEXEC_PREFIX=\"$(libexecdir)/gcc/\" \
diff --git a/gcc14/patches/patch-gcc_ada_init.c b/gcc14/patches/patch-gcc_ada_init.c
new file mode 100644
index 0000000000..b236505e5f
--- /dev/null
+++ b/gcc14/patches/patch-gcc_ada_init.c
@@ -0,0 +1,17 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/ada/init.c
++++ gcc/ada/init.c
+@@ -2479,7 +2479,10 @@ __gnat_map_signal (int sig, siginfo_t *si, void *mcontext ATTRIBUTE_UNUSED)
+ /* Reset the use of alt stack, so that the alt stack will be used
+ for the next signal delivery.
+ The stack can't be used in case of stack checking. */
++#pragma GCC diagnostic push
++#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+ syscall (SYS_sigreturn, NULL, UC_RESET_ALT_STACK);
++#pragma GCC diagnostic pop
+ break;
+
+ case SIGFPE:
diff --git a/gcc14/patches/patch-gcc_builtins.cc b/gcc14/patches/patch-gcc_builtins.cc
new file mode 100644
index 0000000000..cdc80d867f
--- /dev/null
+++ b/gcc14/patches/patch-gcc_builtins.cc
@@ -0,0 +1,20 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/builtins.cc
++++ gcc/builtins.cc
+@@ -5929,6 +5929,13 @@ expand_builtin_trap (void)
+ static void
+ expand_builtin_unreachable (void)
+ {
++ /* If the target wants a trap in place of the fall-through, use that. */
++ if (targetm.unreachable_should_trap ())
++ {
++ expand_builtin_trap ();
++ return;
++ }
++
+ /* Use gimple_build_builtin_unreachable or builtin_decl_unreachable
+ to avoid this. */
+ gcc_checking_assert (!sanitize_flags_p (SANITIZE_UNREACHABLE));
diff --git a/gcc14/patches/patch-gcc_c-family_c-attribs.cc b/gcc14/patches/patch-gcc_c-family_c-attribs.cc
new file mode 100644
index 0000000000..dfe786e22f
--- /dev/null
+++ b/gcc14/patches/patch-gcc_c-family_c-attribs.cc
@@ -0,0 +1,25 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/c-family/c-attribs.cc
++++ gcc/c-family/c-attribs.cc
+@@ -665,6 +665,18 @@ attribute_takes_identifier_p (const_tree attr_id)
+ return targetm.attribute_takes_identifier_p (attr_id);
+ }
+
++/* Returns TRUE iff the attribute indicated by ATTR_ID needs its
++ arguments converted to string constants. */
++
++bool
++attribute_clang_form_p (const_tree attr_id)
++{
++ const struct attribute_spec *spec = lookup_attribute_spec (attr_id);
++ if (spec && !strcmp ("availability", spec->name))
++ return true;
++ return false;
++}
++
+ /* Verify that argument value POS at position ARGNO to attribute NAME
+ applied to function FN (which is either a function declaration or function
+ type) refers to a function parameter at position POS and the expected type
diff --git a/gcc14/patches/patch-gcc_c-family_c-common.cc b/gcc14/patches/patch-gcc_c-family_c-common.cc
new file mode 100644
index 0000000000..7b175ec817
--- /dev/null
+++ b/gcc14/patches/patch-gcc_c-family_c-common.cc
@@ -0,0 +1,19 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/c-family/c-common.cc
++++ gcc/c-family/c-common.cc
+@@ -346,7 +346,11 @@ static constexpr hf_feature_info has_feature_table[] =
+ { "enumerator_attributes", HF_FLAG_NONE, 0 },
+ { "tls", HF_FLAG_NONE, 0 },
+ { "gnu_asm_goto_with_outputs", HF_FLAG_EXT, 0 },
+- { "gnu_asm_goto_with_outputs_full", HF_FLAG_EXT, 0 }
++ { "gnu_asm_goto_with_outputs_full", HF_FLAG_EXT, 0 },
++ { "attribute_availability", HF_FLAG_NONE, 0 },
++ { "attribute_availability_with_message", HF_FLAG_NONE, 0 },
++ { "attribute_availability_with_replacement", HF_FLAG_NONE, 0 },
++ { "attribute_availability_with_version_underscores", HF_FLAG_NONE, 0 }
+ };
+
+ /* Global visibility options. */
diff --git a/gcc14/patches/patch-gcc_c-family_c-common.h b/gcc14/patches/patch-gcc_c-family_c-common.h
new file mode 100644
index 0000000000..cd80dbacd6
--- /dev/null
+++ b/gcc14/patches/patch-gcc_c-family_c-common.h
@@ -0,0 +1,14 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/c-family/c-common.h
++++ gcc/c-family/c-common.h
+@@ -1628,6 +1628,7 @@ extern void check_for_xor_used_as_pow (location_t lhs_loc, tree lhs_val,
+ /* In c-attribs.cc. */
+ extern bool attribute_takes_identifier_p (const_tree);
+ extern tree handle_deprecated_attribute (tree *, tree, tree, int, bool *);
++extern bool attribute_clang_form_p (const_tree);
+ extern tree handle_unused_attribute (tree *, tree, tree, int, bool *);
+ extern tree handle_fallthrough_attribute (tree *, tree, tree, int, bool *);
+ extern int parse_tm_stmt_attr (tree, int);
diff --git a/gcc14/patches/patch-gcc_c-family_c-lex.cc b/gcc14/patches/patch-gcc_c-family_c-lex.cc
new file mode 100644
index 0000000000..c37f3944a3
--- /dev/null
+++ b/gcc14/patches/patch-gcc_c-family_c-lex.cc
@@ -0,0 +1,27 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/c-family/c-lex.cc
++++ gcc/c-family/c-lex.cc
+@@ -584,6 +584,21 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
+
+ case CPP_NUMBER:
+ {
++ /* If the user wants number-like entities to be returned as a raw
++ string, then don't try to classify them, which emits unwanted
++ diagnostics. */
++ if (lex_flags & C_LEX_NUMBER_AS_STRING)
++ {
++ /* build_string adds a trailing NUL at [len]. */
++ tree num_string = build_string (tok->val.str.len + 1,
++ (const char *) tok->val.str.text);
++ TREE_TYPE (num_string) = char_array_type_node;
++ *value = num_string;
++ /* We will effectively note this as CPP_N_INVALID, because we
++ made no checks here. */
++ break;
++ }
++
+ const char *suffix = NULL;
+ unsigned int flags = cpp_classify_number (parse_in, tok, &suffix, *loc);
diff --git a/gcc14/patches/patch-gcc_c-family_c-opts.cc b/gcc14/patches/patch-gcc_c-family_c-opts.cc
new file mode 100644
index 0000000000..5b7a716224
--- /dev/null
+++ b/gcc14/patches/patch-gcc_c-family_c-opts.cc
@@ -0,0 +1,15 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/c-family/c-opts.cc
++++ gcc/c-family/c-opts.cc
+@@ -1119,7 +1119,7 @@ c_common_post_options (const char **pfilename)
+
+ if (flag_extern_tls_init)
+ {
+- if (!TARGET_SUPPORTS_ALIASES || !SUPPORTS_WEAK)
++ if (!SUPPORTS_WEAK)
+ {
+ /* Lazy TLS initialization for a variable in another TU requires
+ alias and weak reference support. */
diff --git a/gcc14/patches/patch-gcc_c-family_c-pragma.h b/gcc14/patches/patch-gcc_c-family_c-pragma.h
new file mode 100644
index 0000000000..7233c8487c
--- /dev/null
+++ b/gcc14/patches/patch-gcc_c-family_c-pragma.h
@@ -0,0 +1,16 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/c-family/c-pragma.h
++++ gcc/c-family/c-pragma.h
+@@ -276,6 +276,9 @@ extern void pragma_lex_discard_to_eol ();
+ #define C_LEX_STRING_NO_JOIN 2 /* Do not concatenate strings
+ nor translate them into execution
+ character set. */
++#define C_LEX_NUMBER_AS_STRING 4 /* Do not classify a number, but
++ instead return it as a raw
++ string. */
+
+ /* This is not actually available to pragma parsers. It's merely a
+ convenient location to declare this function for c-lex, after
diff --git a/gcc14/patches/patch-gcc_c-family_c.opt b/gcc14/patches/patch-gcc_c-family_c.opt
new file mode 100644
index 0000000000..e8d3db4c7c
--- /dev/null
+++ b/gcc14/patches/patch-gcc_c-family_c.opt
@@ -0,0 +1,17 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/c-family/c.opt
++++ gcc/c-family/c.opt
+@@ -1708,6 +1708,10 @@ static-libmpxwrappers
+ Driver WarnRemoved
+ Removed in GCC 9. This switch has no effect.
+
++fallow-extended-attribute-placement
++C ObjC C++ ObjC++ LTO Var(flag_allow_ext_attr_placement) Init(0)
++Allow placement of attributes on function definitions.
++
+ fcilkplus
+ C ObjC C++ ObjC++ LTO Undocumented Ignore
+ Removed in GCC 8. This switch has no effect.
diff --git a/gcc14/patches/patch-gcc_c_c-parser.cc b/gcc14/patches/patch-gcc_c_c-parser.cc
new file mode 100644
index 0000000000..5e8d66d3af
--- /dev/null
+++ b/gcc14/patches/patch-gcc_c_c-parser.cc
@@ -0,0 +1,176 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/c/c-parser.cc
++++ gcc/c/c-parser.cc
+@@ -217,6 +217,9 @@ struct GTY(()) c_parser {
+ should translate them to the execution character set (false
+ inside attributes). */
+ BOOL_BITFIELD translate_strings_p : 1;
++ /* True if we want to lex arbitrary number-like sequences as their
++ string representation. */
++ BOOL_BITFIELD lex_number_as_string : 1;
+
+ /* Objective-C specific parser/lexer information. */
+
+@@ -308,10 +311,10 @@ c_lex_one_token (c_parser *parser, c_token *token, bool raw = false)
+
+ if (raw || vec_safe_length (parser->raw_tokens) == 0)
+ {
++ int lex_flags = parser->lex_joined_string ? 0 : C_LEX_STRING_NO_JOIN;
++ lex_flags |= parser->lex_number_as_string ? C_LEX_NUMBER_AS_STRING : 0;
+ token->type = c_lex_with_flags (&token->value, &token->location,
+- &token->flags,
+- (parser->lex_joined_string
+- ? 0 : C_LEX_STRING_NO_JOIN));
++ &token->flags, lex_flags);
+ token->id_kind = C_ID_NONE;
+ token->keyword = RID_MAX;
+ token->pragma_kind = PRAGMA_NONE;
+@@ -2579,15 +2582,28 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
+ d = d->declarator;
+ underspec_name = d->u.id.id;
+ }
++ tree postfix_attrs = NULL_TREE;
++ if (flag_allow_ext_attr_placement
++ && c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
++ {
++ postfix_attrs = c_parser_gnu_attributes (parser);
++ /* IF we have a function definition, and we're allowing it then
++ treat these attributes as if they had been prepended. */
++ if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
++ {
++ all_prefix_attrs = chainon (all_prefix_attrs, postfix_attrs);
++ postfix_attrs = NULL_TREE;
++ }
++ }
+ if (c_parser_next_token_is (parser, CPP_EQ)
+ || c_parser_next_token_is (parser, CPP_COMMA)
+ || c_parser_next_token_is (parser, CPP_SEMICOLON)
+ || c_parser_next_token_is_keyword (parser, RID_ASM)
+ || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)
++ || postfix_attrs
+ || c_parser_next_token_is_keyword (parser, RID_IN))
+ {
+ tree asm_name = NULL_TREE;
+- tree postfix_attrs = NULL_TREE;
+ if (!diagnosed_no_specs && !specs->declspecs_seen_p)
+ {
+ diagnosed_no_specs = true;
+@@ -2599,8 +2615,9 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
+ if (c_parser_next_token_is_keyword (parser, RID_ASM))
+ asm_name = c_parser_simple_asm_expr (parser);
+ if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
++ postfix_attrs = c_parser_gnu_attributes (parser);
++ if (postfix_attrs)
+ {
+- postfix_attrs = c_parser_gnu_attributes (parser);
+ if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
+ {
+ /* This means there is an attribute specifier after
+@@ -5213,6 +5230,88 @@ c_parser_gnu_attribute_any_word (c_parser *parser)
+ return attr_name;
+ }
+
++/* Handle parsing clang-form attribute arguments, where we need to adjust
++ the parsing rules to relate to a specific attribute. */
++
++static tree
++c_parser_clang_attribute_arguments (c_parser *parser, tree /*attr_id*/)
++{
++ /* We can, if required, alter the parsing on the basis of the attribute.
++ At present, we handle the availability attr, where ach entry can be :
++ identifier
++ identifier=N.MM.Z
++ identifier="string"
++ followed by ',' or ) for the last entry*/
++
++ tree attr_args = NULL_TREE;
++ do
++ {
++ tree name = NULL_TREE;
++ tree value = NULL_TREE;
++
++ if (c_parser_next_token_is (parser, CPP_NAME)
++ && c_parser_peek_token (parser)->id_kind == C_ID_ID)
++ {
++ name = c_parser_peek_token (parser)->value;
++ c_parser_consume_token (parser);
++ }
++ else if (c_parser_next_token_is (parser, CPP_COMMA))
++ name = error_mark_node; /* Comma handled below. */
++ else
++ {
++ bool saved_join_state = parser->lex_joined_string;
++ parser->lex_number_as_string = 1;
++ parser->lex_joined_string = 1;
++ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
++ "expected an attribute keyword");
++ parser->lex_number_as_string = 0;
++ parser->lex_joined_string = saved_join_state;
++ return error_mark_node;
++ }
++ if (c_parser_next_token_is (parser, CPP_EQ))
++ {
++ c_parser_consume_token (parser); /* eat the '=' */
++ /* We need to bludgeon the lexer into not trying to interpret the
++ xx.yy.zz form, since that just looks like a malformed float.
++ Also, as a result of macro processing, we can have strig literals
++ that are in multiple pieces so, for this specific part of the
++ parse, we need to join strings. */
++ bool saved_join_state = parser->lex_joined_string;
++ parser->lex_number_as_string = 1;
++ parser->lex_joined_string = 1;
++ /* So look at the next token, expecting a string, or something that
++ looks initially like a number, but might be a version number. */
++ c_parser_peek_token (parser);
++ /* Done with the funky number parsing. */
++ parser->lex_number_as_string = 0;
++ parser->lex_joined_string = saved_join_state;
++ if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN)
++ && c_parser_next_token_is_not (parser, CPP_COMMA))
++ {
++ value = c_parser_peek_token (parser)->value;
++ /* ???: check for error mark and early-return? */
++ c_parser_consume_token (parser);
++ }
++ /* else value is absent. */
++ }
++ else if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN)
++ && c_parser_next_token_is_not (parser, CPP_COMMA))
++ {
++ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
++ "expected %<,%> or %<=%>");
++ return error_mark_node;
++ }
++ if (c_parser_next_token_is (parser, CPP_COMMA))
++ c_parser_consume_token (parser); /* Just skip the comma. */
++ tree t = tree_cons (value, name, NULL);
++ if (!attr_args)
++ attr_args = t;
++ else
++ chainon (attr_args, t);
++ } while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN));
++ return attr_args;
++}
++
+ /* Parse attribute arguments. This is a common form of syntax
+ covering all currently valid GNU and standard attributes.
+
+@@ -5378,9 +5477,13 @@ c_parser_gnu_attribute (c_parser *parser, tree attrs,
+ attrs = chainon (attrs, attr);
+ return attrs;
+ }
+- c_parser_consume_token (parser);
++ c_parser_consume_token (parser); /* The '('. */
+
+- tree attr_args
++ tree attr_args;
++ if (attribute_clang_form_p (attr_name))
++ attr_args = c_parser_clang_attribute_arguments (parser, attr_name);
++ else
++ attr_args
+ = c_parser_attribute_arguments (parser,
+ attribute_takes_identifier_p (attr_name),
+ false,
diff --git a/gcc14/patches/patch-gcc_calls.cc b/gcc14/patches/patch-gcc_calls.cc
new file mode 100644
index 0000000000..8cc45494f3
--- /dev/null
+++ b/gcc14/patches/patch-gcc_calls.cc
@@ -0,0 +1,85 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/calls.cc
++++ gcc/calls.cc
+@@ -1376,7 +1376,8 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
+ with those made by function.cc. */
+
+ /* See if this argument should be passed by invisible reference. */
+- function_arg_info arg (type, argpos < n_named_args);
++ function_arg_info arg (type, argpos < n_named_args,
++ argpos == n_named_args - 1);
+ if (pass_by_reference (args_so_far_pnt, arg))
+ {
+ const bool callee_copies
+@@ -1496,10 +1497,13 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
+
+ unsignedp = TYPE_UNSIGNED (type);
+ arg.type = type;
+- arg.mode
+- = promote_function_mode (type, TYPE_MODE (type), &unsignedp,
+- fndecl ? TREE_TYPE (fndecl) : fntype, 0);
+-
++ arg.mode = TYPE_MODE (type);
++// arg.mode
++// = promote_function_mode (type, TYPE_MODE (type), &unsignedp,
++// fndecl ? TREE_TYPE (fndecl) : fntype, 0);
++ arg.mode = promote_function_mode (args_so_far, arg,
++ fndecl ? TREE_TYPE (fndecl) : fntype,
++ &unsignedp, 0);
+ args[i].unsignedp = unsignedp;
+ args[i].mode = arg.mode;
+
+@@ -1549,6 +1553,7 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
+ #endif
+ reg_parm_stack_space,
+ args[i].pass_on_stack ? 0 : args[i].partial,
++ args_so_far,
+ fndecl, args_size, &args[i].locate);
+ #ifdef BLOCK_REG_PADDING
+ else
+@@ -4096,6 +4101,7 @@ split_complex_types (tree types)
+ return types;
+ }
+
++extern void debug_tree (tree);
+ /* Output a library call to function ORGFUN (a SYMBOL_REF rtx)
+ for a value of mode OUTMODE,
+ with NARGS different arguments, passed as ARGS.
+@@ -4281,6 +4287,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
+ argvec[count].reg != 0,
+ #endif
+ reg_parm_stack_space, 0,
++ args_so_far,
+ NULL_TREE, &args_size, &argvec[count].locate);
+
+ if (argvec[count].reg == 0 || argvec[count].partial != 0
+@@ -4351,8 +4358,16 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
+ val = force_operand (XEXP (slot, 0), NULL_RTX);
+ }
+
+- arg.mode = promote_function_mode (NULL_TREE, arg.mode, &unsigned_p,
+- NULL_TREE, 0);
++// arg.mode = promote_function_mode (NULL_TREE, arg.mode, &unsigned_p,
++// NULL_TREE, 0);
++ tree t = arg.type;
++if (t)
++ debug_tree (t);
++gcc_assert (!t);
++ arg.type = NULL_TREE;
++ arg.mode = promote_function_mode (args_so_far, arg, NULL_TREE,
++ &unsigned_p, 0);
++ arg.type = t;
+ argvec[count].mode = arg.mode;
+ argvec[count].value = convert_modes (arg.mode, GET_MODE (val), val,
+ unsigned_p);
+@@ -4372,6 +4387,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
+ argvec[count].reg != 0,
+ #endif
+ reg_parm_stack_space, argvec[count].partial,
++ args_so_far,
+ NULL_TREE, &args_size, &argvec[count].locate);
+ args_size.constant += argvec[count].locate.size.constant;
+ gcc_assert (!argvec[count].locate.size.var);
diff --git a/gcc14/patches/patch-gcc_calls.h b/gcc14/patches/patch-gcc_calls.h
new file mode 100644
index 0000000000..172a3bcbac
--- /dev/null
+++ b/gcc14/patches/patch-gcc_calls.h
@@ -0,0 +1,64 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/calls.h
++++ gcc/calls.h
+@@ -35,24 +35,43 @@ class function_arg_info
+ {
+ public:
+ function_arg_info ()
+- : type (NULL_TREE), mode (VOIDmode), named (false),
++ : type (NULL_TREE), mode (VOIDmode), named (false), last_named (false),
+ pass_by_reference (false)
+ {}
+
+ /* Initialize an argument of mode MODE, either before or after promotion. */
+ function_arg_info (machine_mode mode, bool named)
+- : type (NULL_TREE), mode (mode), named (named), pass_by_reference (false)
++ : type (NULL_TREE), mode (mode), named (named), last_named (false),
++ pass_by_reference (false)
++ {}
++
++ function_arg_info (machine_mode mode, bool named, bool last_named)
++ : type (NULL_TREE), mode (mode), named (named), last_named (last_named),
++ pass_by_reference (false)
+ {}
+
+ /* Initialize an unpromoted argument of type TYPE. */
+ function_arg_info (tree type, bool named)
+- : type (type), mode (TYPE_MODE (type)), named (named),
++ : type (type), mode (TYPE_MODE (type)), named (named), last_named (false),
+ pass_by_reference (false)
+ {}
+
++ /* Initialize an unpromoted argument of type TYPE. */
++ function_arg_info (tree type, bool named, bool last_named)
++ : type (type), mode (TYPE_MODE (type)), named (named),
++ last_named (last_named), pass_by_reference (false)
++ {}
++
+ /* Initialize an argument with explicit properties. */
+ function_arg_info (tree type, machine_mode mode, bool named)
+- : type (type), mode (mode), named (named), pass_by_reference (false)
++ : type (type), mode (mode), named (named), last_named (false),
++ pass_by_reference (false)
++ {}
++
++ /* Initialize an argument with explicit properties. */
++ function_arg_info (tree type, machine_mode mode, bool named, bool last_named)
++ : type (type), mode (mode), named (named), last_named (last_named),
++ pass_by_reference (false)
+ {}
+
+ /* Return true if the gimple-level type is an aggregate. */
+@@ -105,6 +124,9 @@ public:
+ "..."). See also TARGET_STRICT_ARGUMENT_NAMING. */
+ unsigned int named : 1;
+
++ /* True if this is the last named argument. */
++ unsigned int last_named : 1;
++
+ /* True if we have decided to pass the argument by reference, in which case
+ the function_arg_info describes a pointer to the original argument. */
+ unsigned int pass_by_reference : 1;
diff --git a/gcc14/patches/patch-gcc_collect2.cc b/gcc14/patches/patch-gcc_collect2.cc
new file mode 100644
index 0000000000..6a73fdda49
--- /dev/null
+++ b/gcc14/patches/patch-gcc_collect2.cc
@@ -0,0 +1,118 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/collect2.cc
++++ gcc/collect2.cc
+@@ -73,7 +73,7 @@ along with GCC; see the file COPYING3. If not see
+ In a cross-compiler, this means you need a cross nm,
+ but that is not quite as unpleasant as special headers. */
+
+-#if !defined (OBJECT_FORMAT_COFF)
++#if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_MACHO)
+ #define OBJECT_FORMAT_NONE
+ #endif
+
+@@ -107,7 +107,7 @@ along with GCC; see the file COPYING3. If not see
+
+ #endif /* OBJECT_FORMAT_COFF */
+
+-#ifdef OBJECT_FORMAT_NONE
++#if defined (OBJECT_FORMAT_NONE) || defined (OBJECT_FORMAT_MACHO)
+
+ /* Default flags to pass to nm. */
+ #ifndef NM_FLAGS
+@@ -525,7 +525,7 @@ static const char *const target_machine = TARGET_MACHINE;
+
+ Return 0 if not found, otherwise return its name, allocated with malloc. */
+
+-#ifdef OBJECT_FORMAT_NONE
++#if defined (OBJECT_FORMAT_NONE) || defined (OBJECT_FORMAT_MACHO)
+
+ /* Add an entry for the object file NAME to object file list LIST.
+ New entries are added at the end of the list. The original pointer
+@@ -764,6 +764,12 @@ do_link (char **ld_argv, const char *atsuffix)
+ }
+ }
+
++#if defined (OBJECT_FORMAT_MACHO)
++# define LLD_NAME "ld64.lld"
++#else
++# define LLD_NAME "ld.lld"
++#endif
++
+ /* Main program. */
+
+ int
+@@ -777,16 +783,19 @@ main (int argc, char **argv)
+ USE_BFD_LD,
+ USE_LLD_LD,
+ USE_MOLD_LD,
++ USE_CLASSIC_LD,
+ USE_LD_MAX
+ } selected_linker = USE_DEFAULT_LD;
++
+ static const char *const ld_suffixes[USE_LD_MAX] =
+ {
+ "ld",
+ PLUGIN_LD_SUFFIX,
+ "ld.gold",
+ "ld.bfd",
+- "ld.lld",
+- "ld.mold"
++ LLD_NAME,
++ "ld.mold",
++ "ld-classic"
+ };
+ static const char *const real_ld_suffix = "real-ld";
+ static const char *const collect_ld_suffix = "collect-ld";
+@@ -868,7 +877,7 @@ main (int argc, char **argv)
+ #ifdef CROSS_DIRECTORY_STRUCTURE
+ /* lld and mold are platform-agnostic and not prefixed with target
+ triple. */
+- if (!(i == USE_LLD_LD || i == USE_MOLD_LD))
++ if (!(i == USE_LLD_LD || i == USE_MOLD_LD || i == USE_CLASSIC_LD))
+ full_ld_suffixes[i] = concat (target_machine, "-", ld_suffixes[i],
+ NULL);
+ else
+@@ -956,14 +965,22 @@ main (int argc, char **argv)
+ if (selected_linker == USE_DEFAULT_LD)
+ selected_linker = USE_PLUGIN_LD;
+ }
++#if !defined (OBJECT_FORMAT_MACHO)
+ else if (strcmp (argv[i], "-fuse-ld=bfd") == 0)
+ selected_linker = USE_BFD_LD;
+ else if (strcmp (argv[i], "-fuse-ld=gold") == 0)
+ selected_linker = USE_GOLD_LD;
++#endif
+ else if (strcmp (argv[i], "-fuse-ld=lld") == 0)
+ selected_linker = USE_LLD_LD;
+ else if (strcmp (argv[i], "-fuse-ld=mold") == 0)
+ selected_linker = USE_MOLD_LD;
++#if defined (OBJECT_FORMAT_MACHO)
++ else if (strcmp (argv[i], "-fuse-ld=classic") == 0)
++ selected_linker = USE_CLASSIC_LD;
++#endif
++ else if (strcmp (argv[i], "-fuse-ld=") == 0)
++ selected_linker = USE_DEFAULT_LD;
+ else if (startswith (argv[i], "-o"))
+ {
+ /* Parse the output filename if it's given so that we can make
+@@ -1055,7 +1072,8 @@ main (int argc, char **argv)
+ ld_file_name = 0;
+ #ifdef DEFAULT_LINKER
+ if (selected_linker == USE_BFD_LD || selected_linker == USE_GOLD_LD ||
+- selected_linker == USE_LLD_LD || selected_linker == USE_MOLD_LD)
++ selected_linker == USE_LLD_LD || selected_linker == USE_MOLD_LD ||
++ selected_linker == USE_CLASSIC_LD)
+ {
+ char *linker_name;
+ # ifdef HOST_EXECUTABLE_SUFFIX
+@@ -2270,7 +2288,7 @@ write_aix_file (FILE *stream, struct id *list)
+ }
+ #endif
+
+-#ifdef OBJECT_FORMAT_NONE
++#if defined (OBJECT_FORMAT_NONE) || defined (OBJECT_FORMAT_MACHO)
+
+ /* Check to make sure the file is an LTO object file. */
diff --git a/gcc14/patches/patch-gcc_common.opt b/gcc14/patches/patch-gcc_common.opt
new file mode 100644
index 0000000000..e6a3455438
--- /dev/null
+++ b/gcc14/patches/patch-gcc_common.opt
@@ -0,0 +1,27 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/common.opt
++++ gcc/common.opt
+@@ -2919,6 +2919,10 @@ fstack-usage
+ Common RejectNegative Var(flag_stack_usage)
+ Output stack usage information on a per-function basis.
+
++fstack-use-cumulative-args
++Common RejectNegative Var(flag_stack_use_cumulative_args) Init(STACK_USE_CUMULATIVE_ARGS_INIT)
++Use cumulative args-based stack layout hooks.
++
+ fstrength-reduce
+ Common Ignore
+ Does nothing. Preserved for backward compatibility.
+@@ -3292,6 +3296,10 @@ fuse-ld=mold
+ Common Driver Negative(fuse-ld=mold)
+ Use the Modern linker (MOLD) linker instead of the default linker.
+
++fuse-ld=classic
++Common Driver Negative(fuse-ld=classic)
++Use the ld-classic linker instead of the default linker.
++
+ fuse-linker-plugin
+ Common Undocumented Var(flag_use_linker_plugin)
diff --git a/gcc14/patches/patch-gcc_common_config_aarch64_aarch64-common.cc b/gcc14/patches/patch-gcc_common_config_aarch64_aarch64-common.cc
new file mode 100644
index 0000000000..fe6418482e
--- /dev/null
+++ b/gcc14/patches/patch-gcc_common_config_aarch64_aarch64-common.cc
@@ -0,0 +1,44 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/common/config/aarch64/aarch64-common.cc
++++ gcc/common/config/aarch64/aarch64-common.cc
+@@ -298,8 +298,12 @@ aarch64_get_extension_string_for_isa_flags
+
+ However, assemblers with Armv8-R AArch64 support should not have this
+ issue, so we don't need this fix when targeting Armv8-R. */
+- auto explicit_flags = (!(current_flags & AARCH64_FL_V8R)
+- ? AARCH64_FL_CRC : 0);
++ aarch64_feature_flags explicit_flags =
++#ifndef DISABLE_AARCH64_AS_CRC_BUGFIX
++ (!(current_flags & AARCH64_ISA_V8R) ? AARCH64_FL_CRC : 0);
++#else
++ 0;
++#endif
+
+ /* Add the features in isa_flags & ~current_flags using the smallest
+ possible number of extensions. We can do this by iterating over the
+@@ -329,7 +333,10 @@ aarch64_get_extension_string_for_isa_flags
+ if (added & opt.flag_canonical)
+ {
+ outstr += "+";
+- outstr += opt.name;
++ if (startswith (opt.name, "rdm"))
++ outstr += "rdm";
++ else
++ outstr += opt.name;
+ }
+
+ /* Remove the features in current_flags & ~isa_flags. If the feature does
+@@ -358,7 +365,10 @@ aarch64_get_extension_string_for_isa_flags
+ {
+ current_flags &= ~opt.flags_off;
+ outstr += "+no";
+- outstr += opt.name;
++ if (startswith (opt.name, "rdm"))
++ outstr += "rdm";
++ else
++ outstr += opt.name;
+ }
+ }
diff --git a/gcc14/patches/patch-gcc_config.gcc b/gcc14/patches/patch-gcc_config.gcc
new file mode 100644
index 0000000000..21a9919d16
--- /dev/null
+++ b/gcc14/patches/patch-gcc_config.gcc
@@ -0,0 +1,45 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/config.gcc
++++ gcc/config.gcc
+@@ -1177,13 +1177,22 @@ case ${target} in
+ ;;
+ esac
+
+-# Figure out if we need to enable heap trampolines by default
++# Figure out if we need to enable heap trampolines
++# and variadic functions handling.
+ case ${target} in
++aarch64*-*-darwin2*)
++ # This applies to arm64 Darwin variadic funtions.
++ tm_defines="$tm_defines STACK_USE_CUMULATIVE_ARGS_INIT=1"
++ # Executable stack is forbidden.
++ tm_defines="$tm_defines HEAP_TRAMPOLINES_INIT=1"
++ ;;
+ *-*-darwin2*)
++ tm_defines="$tm_defines STACK_USE_CUMULATIVE_ARGS_INIT=0"
+ # Currently, we do this for macOS 11 and above.
+ tm_defines="$tm_defines HEAP_TRAMPOLINES_INIT=1"
+ ;;
+ *)
++ tm_defines="$tm_defines STACK_USE_CUMULATIVE_ARGS_INIT=0"
+ tm_defines="$tm_defines HEAP_TRAMPOLINES_INIT=0"
+ ;;
+ esac
+@@ -1227,6 +1236,14 @@ aarch64*-*-elf | aarch64*-*-fuchsia* | aarch64*-*-rtems*)
+ done
+ TM_MULTILIB_CONFIG=`echo $TM_MULTILIB_CONFIG | sed 's/^,//'`
+ ;;
++aarch64-*-darwin* )
++ tm_file="${tm_file} aarch64/aarch64-errata.h"
++ tmake_file="${tmake_file} aarch64/t-aarch64 aarch64/t-aarch64-darwin"
++ tm_defines="${tm_defines} TARGET_DEFAULT_ASYNC_UNWIND_TABLES=1"
++ tm_defines="${tm_defines} DISABLE_AARCH64_AS_CRC_BUGFIX=1"
++ # Choose a default CPU version that will work for all current releases.
++ with_cpu=${with_cpu:-apple-m1}
++ ;;
+ aarch64*-*-freebsd*)
+ tm_file="${tm_file} elfos.h ${fbsd_tm_file}"
+ tm_file="${tm_file} aarch64/aarch64-elf.h aarch64/aarch64-errata.h aarch64/aarch64-freebsd.h"
diff --git a/gcc14/patches/patch-gcc_config.host b/gcc14/patches/patch-gcc_config.host
new file mode 100644
index 0000000000..9b868b631a
--- /dev/null
+++ b/gcc14/patches/patch-gcc_config.host
@@ -0,0 +1,15 @@
+$NetBSD: patch-gcc_config.host,v 1.1 2024/06/28 18:35:16 wiz Exp $
+
+Add aarch64*-*-netbsd*.
+
+--- gcc/config.host.orig 2022-05-06 07:30:56.000000000 +0000
++++ gcc/config.host
+@@ -99,7 +99,7 @@ case ${host} in
+ esac
+
+ case ${host} in
+- aarch64*-*-freebsd* | aarch64*-*-linux* | aarch64*-*-fuchsia* |\
++ aarch64*-*-freebsd* | aarch64*-*-netbsd* | aarch64*-*-linux* | aarch64*-*-fuchsia* |\
+ aarch64*-*-darwin*)
+ case ${target} in
+ aarch64*-*-*)
diff --git a/gcc14/patches/patch-gcc_config_aarch64_aarch64-builtins.cc b/gcc14/patches/patch-gcc_config_aarch64_aarch64-builtins.cc
new file mode 100644
index 0000000000..79f8a42c0e
--- /dev/null
+++ b/gcc14/patches/patch-gcc_config_aarch64_aarch64-builtins.cc
@@ -0,0 +1,81 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/config/aarch64/aarch64-builtins.cc
++++ gcc/config/aarch64/aarch64-builtins.cc
+@@ -788,6 +788,8 @@ enum aarch64_builtins
+ AARCH64_PLDX,
+ AARCH64_PLI,
+ AARCH64_PLIX,
++ /* OS-specific */
++ AARCH64_BUILTIN_CFSTRING,
+ AARCH64_BUILTIN_MAX
+ };
+
+@@ -887,6 +889,9 @@ tree aarch64_fp16_ptr_type_node = NULL_TREE;
+ /* Back-end node type for brain float (bfloat) types. */
+ tree aarch64_bf16_ptr_type_node = NULL_TREE;
+
++/* Pointer to __float128 on Mach-O, where the 128b float is not long double. */
++tree aarch64_float128_ptr_type_node = NULL_TREE;
++
+ /* Wrapper around add_builtin_function. NAME is the name of the built-in
+ function, TYPE is the function type, CODE is the function subcode
+ (relative to AARCH64_BUILTIN_GENERAL), and ATTRS is the function
+@@ -1662,6 +1667,29 @@ aarch64_init_bf16_types (void)
+ aarch64_bf16_ptr_type_node = build_pointer_type (bfloat16_type_node);
+ }
+
++/* Initialize the backend REAL_TYPE type supporting __float128 on Mach-O,
++ as well as the related built-ins. */
++static void
++aarch64_init_float128_types (void)
++{
++ /* The __float128 type. The node has already been created as
++ _Float128, so for C we only need to register the __float128 name for
++ it. For C++, we create a distinct type which will mangle differently
++ (g) vs. _Float128 (DF128_) and behave backwards compatibly. */
++ if (float128t_type_node == NULL_TREE)
++ {
++ float128t_type_node = make_node (REAL_TYPE);
++ TYPE_PRECISION (float128t_type_node)
++ = TYPE_PRECISION (float128_type_node);
++ SET_TYPE_MODE (float128t_type_node, TYPE_MODE (float128_type_node));
++ layout_type (float128t_type_node);
++ }
++ lang_hooks.types.register_builtin_type (float128t_type_node, "__float128");
++
++ aarch64_float128_ptr_type_node = build_pointer_type (float128t_type_node);
++}
++
++
+ /* Pointer authentication builtins that will become NOP on legacy platform.
+ Currently, these builtins are for internal use only (libgcc EH unwinder). */
+
+@@ -2047,8 +2075,9 @@ aarch64_general_init_builtins (void)
+ aarch64_init_fpsr_fpcr_builtins ();
+
+ aarch64_init_fp16_types ();
+-
+ aarch64_init_bf16_types ();
++ if (TARGET_MACHO)
++ aarch64_init_float128_types ();
+
+ {
+ aarch64_simd_switcher simd;
+@@ -2088,6 +2117,14 @@ aarch64_general_init_builtins (void)
+ handle_arm_acle_h ();
+ }
+
++void
++aarch64_init_subtarget_builtins (void)
++{
++#ifdef SUBTARGET_INIT_BUILTINS
++ SUBTARGET_INIT_BUILTINS;
++#endif
++}
++
+ /* Implement TARGET_BUILTIN_DECL for the AARCH64_BUILTIN_GENERAL group. */
+ tree
+ aarch64_general_builtin_decl (unsigned code, bool)
diff --git a/gcc14/patches/patch-gcc_config_aarch64_aarch64-c.cc b/gcc14/patches/patch-gcc_config_aarch64_aarch64-c.cc
new file mode 100644
index 0000000000..e7d5898673
--- /dev/null
+++ b/gcc14/patches/patch-gcc_config_aarch64_aarch64-c.cc
@@ -0,0 +1,32 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/config/aarch64/aarch64-c.cc
++++ gcc/config/aarch64/aarch64-c.cc
+@@ -285,6 +285,16 @@ aarch64_cpu_cpp_builtins (cpp_reader *pfile)
+ {
+ aarch64_define_unconditional_macros (pfile);
+ aarch64_update_cpp_builtins (pfile);
++
++ if (TARGET_MACHO)
++ {
++ builtin_define ("__builtin_copysignq=__builtin_copysignf128");
++ builtin_define ("__builtin_fabsq=__builtin_fabsf128");
++ builtin_define ("__builtin_huge_valq=__builtin_huge_valf128");
++ builtin_define ("__builtin_infq=__builtin_inff128");
++ builtin_define ("__builtin_nanq=__builtin_nanf128");
++ builtin_define ("__builtin_nansq=__builtin_nansf128");
++ }
+ }
+
+ /* Hook to validate the current #pragma GCC target and set the state, and
+@@ -424,4 +434,8 @@ aarch64_register_pragmas (void)
+ targetm.check_builtin_call = aarch64_check_builtin_call;
+
+ c_register_pragma ("GCC", "aarch64", aarch64_pragma_aarch64);
++
++#ifdef REGISTER_SUBTARGET_PRAGMAS
++ REGISTER_SUBTARGET_PRAGMAS ();
++#endif
+ }
diff --git a/gcc14/patches/patch-gcc_config_aarch64_aarch64-cores.def b/gcc14/patches/patch-gcc_config_aarch64_aarch64-cores.def
new file mode 100644
index 0000000000..c06aff1943
--- /dev/null
+++ b/gcc14/patches/patch-gcc_config_aarch64_aarch64-cores.def
@@ -0,0 +1,24 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/config/aarch64/aarch64-cores.def
++++ gcc/config/aarch64/aarch64-cores.def
+@@ -166,6 +166,17 @@ AARCH64_CORE("cortex-a76.cortex-a55", cortexa76cortexa55, cortexa53, V8_2A, (F
+ /* Armv8-R Architecture Processors. */
+ AARCH64_CORE("cortex-r82", cortexr82, cortexa53, V8R, (), cortexa53, 0x41, 0xd15, -1)
+
++/* Apple (A12 and M) cores.
++ Apple implementer ID from xnu,
++ guesses for part #, guesses for scheduler ident, generic_armv8_a for costs.
++ A12 seems mostly 8.3,
++ M1 seems to be 8.4 + extras (see comments in option-extensions about f16fml),
++ M2 mostly 8.5 but with missing mandatory features. */
++AARCH64_CORE("apple-a12", applea12, cortexa53, V8_3A, (), generic_armv8_a, 0x61, 0x12, -1)
++AARCH64_CORE("apple-m1", applem1, cortexa57, V8_4A, (F16, SB, SSBS), generic_armv8_a, 0x61, 0x23, -1)
++AARCH64_CORE("apple-m2", applem2, cortexa57, V8_4A, (I8MM, BF16, F16, SB, SSBS), generic_armv8_a, 0x61, 0x23, -1)
++AARCH64_CORE("apple-m3", applem3, cortexa57, V8_4A, (I8MM, BF16, F16, SB, SSBS), generic_armv8_a, 0x61, 0x23, -1)
++
+ /* Armv9.0-A Architecture Processors. */
+
+ /* Arm ('A') cores. */
diff --git a/gcc14/patches/patch-gcc_config_aarch64_aarch64-netbsd.h b/gcc14/patches/patch-gcc_config_aarch64_aarch64-netbsd.h
new file mode 100644
index 0000000000..09b32d3649
--- /dev/null
+++ b/gcc14/patches/patch-gcc_config_aarch64_aarch64-netbsd.h
@@ -0,0 +1,18 @@
+$NetBSD: patch-gcc_config_aarch64_aarch64-netbsd.h,v 1.1 2024/06/28 18:35:16 wiz Exp $
+
+Match what is in NetBSD src. Fixes at least aarch64eb, and
+probably several others.
+
+--- gcc/config/aarch64/aarch64-netbsd.h.orig 2021-04-08 04:56:28.033740243 -0700
++++ gcc/config/aarch64/aarch64-netbsd.h 2021-04-24 00:16:41.451665444 -0700
+@@ -20,6 +20,10 @@
+ #ifndef GCC_AARCH64_NETBSD_H
+ #define GCC_AARCH64_NETBSD_H
+
++/* NetBSD malloc(3) does 64, not 128 bytes. */
++#undef MALLOC_ABI_ALIGNMENT
++#define MALLOC_ABI_ALIGNMENT 64
++
+ #define TARGET_LINKER_BIG_EMULATION "aarch64nbsdb"
+ #define TARGET_LINKER_LITTLE_EMULATION "aarch64nbsd"
+
diff --git a/gcc14/patches/patch-gcc_config_aarch64_aarch64-protos.h b/gcc14/patches/patch-gcc_config_aarch64_aarch64-protos.h
new file mode 100644
index 0000000000..287dba43b4
--- /dev/null
+++ b/gcc14/patches/patch-gcc_config_aarch64_aarch64-protos.h
@@ -0,0 +1,49 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/config/aarch64/aarch64-protos.h
++++ gcc/config/aarch64/aarch64-protos.h
+@@ -109,6 +109,14 @@ enum aarch64_symbol_type
+ SYMBOL_TLSLE24,
+ SYMBOL_TLSLE32,
+ SYMBOL_TLSLE48,
++ SYMBOL_MO_SMALL_ABS,
++ SYMBOL_MO_SMALL_PCR,
++ SYMBOL_MO_SMALL_GOT,
++ SYMBOL_MO_SMALL_TLS,
++ SYMBOL_MO_LARGE_ABS,
++ SYMBOL_MO_LARGE_PCR,
++ SYMBOL_MO_LARGE_GOT,
++ SYMBOL_MO_LARGE_TLS,
+ SYMBOL_FORCE_TO_MEM
+ };
+
+@@ -748,6 +756,7 @@ void aarch64_post_cfi_startproc (void);
+ poly_int64 aarch64_initial_elimination_offset (unsigned, unsigned);
+ int aarch64_get_condition_code (rtx);
+ bool aarch64_address_valid_for_prefetch_p (rtx, bool);
++bool aarch64_address_valid_for_unscaled_prefetch_p (rtx, bool);
+ bool aarch64_bitmask_imm (unsigned HOST_WIDE_INT val, machine_mode);
+ unsigned HOST_WIDE_INT aarch64_and_split_imm1 (HOST_WIDE_INT val_in);
+ unsigned HOST_WIDE_INT aarch64_and_split_imm2 (HOST_WIDE_INT val_in);
+@@ -782,7 +791,11 @@ bool aarch64_is_extend_from_extract (scalar_int_mode, rtx, rtx);
+ bool aarch64_is_long_call_p (rtx);
+ bool aarch64_is_noplt_call_p (rtx);
+ bool aarch64_label_mentioned_p (rtx);
++#if TARGET_MACHO
++void aarch64_darwin_declare_function_name (FILE *, const char*, tree );
++#else
+ void aarch64_declare_function_name (FILE *, const char*, tree);
++#endif
+ void aarch64_asm_output_alias (FILE *, const tree, const tree);
+ void aarch64_asm_output_external (FILE *, tree, const char*);
+ bool aarch64_legitimate_pic_operand_p (rtx);
+@@ -999,6 +1012,7 @@ void aarch64_override_options_internal (struct gcc_options *);
+
+ const char *aarch64_general_mangle_builtin_type (const_tree);
+ void aarch64_general_init_builtins (void);
++void aarch64_init_subtarget_builtins (void);
+ tree aarch64_general_fold_builtin (unsigned int, tree, unsigned int, tree *);
+ gimple *aarch64_general_gimple_fold_builtin (unsigned int, gcall *,
+ gimple_stmt_iterator *);
diff --git a/gcc14/patches/patch-gcc_config_aarch64_aarch64-tune.md b/gcc14/patches/patch-gcc_config_aarch64_aarch64-tune.md
new file mode 100644
index 0000000000..a552866efa
--- /dev/null
+++ b/gcc14/patches/patch-gcc_config_aarch64_aarch64-tune.md
@@ -0,0 +1,13 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/config/aarch64/aarch64-tune.md
++++ gcc/config/aarch64/aarch64-tune.md
+@@ -1,5 +1,5 @@
+ ;; -*- buffer-read-only: t -*-
+ ;; Generated automatically by gentune.sh from aarch64-cores.def
+ (define_attr "tune"
+- "cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88p1,thunderxt88,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,ampere1a,ampere1b,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,cortexx1c,neoversen1,ares,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,tsv110,thunderx3t110,neoversev1,zeus,neoverse512tvb,saphira,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,cortexa510,cortexa520,cortexa710,cortexa715,cortexa720,cortexx2,cortexx3,cortexx4,neoversen2,cobalt100,neoversev2,grace,demeter,generic,generic_armv8_a,generic_armv9_a"
++ "cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88p1,thunderxt88,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,ampere1a,ampere1b,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,cortexx1c,neoversen1,ares,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,tsv110,thunderx3t110,neoversev1,zeus,neoverse512tvb,saphira,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,applea12,applem1,applem2,applem3,cortexa510,cortexa520,cortexa710,cortexa715,cortexa720,cortexx2,cortexx3,cortexx4,neoversen2,cobalt100,neoversev2,grace,demeter,generic,generic_armv8_a,generic_armv9_a"
+ (const (symbol_ref "((enum attr_tune) aarch64_tune)")))
diff --git a/gcc14/patches/patch-gcc_config_aarch64_aarch64.cc b/gcc14/patches/patch-gcc_config_aarch64_aarch64.cc
new file mode 100644
index 0000000000..cdf874bc56
--- /dev/null
+++ b/gcc14/patches/patch-gcc_config_aarch64_aarch64.cc
@@ -0,0 +1,1402 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/config/aarch64/aarch64.cc
++++ gcc/config/aarch64/aarch64.cc
+@@ -329,8 +329,10 @@ static bool aarch64_vfp_is_call_or_return_candidate (machine_mode,
+ const_tree,
+ machine_mode *, int *,
+ bool *, bool);
++#if !TARGET_MACHO
+ static void aarch64_elf_asm_constructor (rtx, int) ATTRIBUTE_UNUSED;
+ static void aarch64_elf_asm_destructor (rtx, int) ATTRIBUTE_UNUSED;
++#endif
+ static void aarch64_override_options_after_change (void);
+ static bool aarch64_vector_mode_supported_p (machine_mode);
+ static int aarch64_address_cost (rtx, machine_mode, addr_space_t, bool);
+@@ -848,6 +850,9 @@ static const attribute_spec aarch64_gnu_attributes[] =
+ {
+ /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
+ affects_type_identity, handler, exclude } */
++#ifdef SUBTARGET_ATTRIBUTE_TABLE
++ SUBTARGET_ATTRIBUTE_TABLE,
++#endif
+ { "aarch64_vector_pcs", 0, 0, false, true, true, true,
+ handle_aarch64_vector_pcs_attribute, NULL },
+ { "arm_sve_vector_bits", 1, 1, false, true, false, true,
+@@ -2067,7 +2072,7 @@ aarch64_hard_regno_mode_ok (unsigned regno, machine_mode mode)
+ if (known_le (GET_MODE_SIZE (mode), 8))
+ return true;
+ if (known_le (GET_MODE_SIZE (mode), 16))
+- return (regno & 1) == 0;
++ return (regno & 1) == 0 || TARGET_MACHO; /* darwinpcs D.4 */
+ }
+ else if (FP_REGNUM_P (regno))
+ {
+@@ -2113,8 +2118,10 @@ static bool
+ aarch64_takes_arguments_in_sve_regs_p (const_tree fntype)
+ {
+ CUMULATIVE_ARGS args_so_far_v;
++ /* This does not apply to variadic functions, so all the (currently
++ uncounted) arguments must be named. */
+ aarch64_init_cumulative_args (&args_so_far_v, NULL_TREE, NULL_RTX,
+- NULL_TREE, 0, true);
++ NULL_TREE, -1, true);
+ cumulative_args_t args_so_far = pack_cumulative_args (&args_so_far_v);
+
+ for (tree chain = TYPE_ARG_TYPES (fntype);
+@@ -2861,6 +2868,7 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm,
+ switch (type)
+ {
+ case SYMBOL_SMALL_ABSOLUTE:
++ case SYMBOL_MO_SMALL_PCR:
+ {
+ /* In ILP32, the mode of dest can be either SImode or DImode. */
+ rtx tmp_reg = dest;
+@@ -2871,6 +2879,21 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm,
+ if (can_create_pseudo_p ())
+ tmp_reg = gen_reg_rtx (mode);
+
++ if (TARGET_MACHO)
++ {
++ rtx sym, off;
++ split_const (imm, &sym, &off);
++ /* Negative offsets don't work, whether by intention is TBD. */
++ if (INTVAL (off) < 0 || INTVAL (off) > 8 * 1024 * 1024)
++ {
++ emit_move_insn (tmp_reg, gen_rtx_HIGH (mode, sym));
++ emit_insn (gen_add_losym (dest, tmp_reg, sym));
++ /* FIXME: add the SI option if/when we support ilp32. */
++ emit_insn (gen_adddi3 (dest, dest, off));
++ return;
++ }
++ /* else small enough positive offset is OK. */
++ }
+ emit_move_insn (tmp_reg, gen_rtx_HIGH (mode, copy_rtx (imm)));
+ emit_insn (gen_add_losym (dest, tmp_reg, imm));
+ return;
+@@ -2954,6 +2977,7 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm,
+ return;
+ }
+
++ case SYMBOL_MO_SMALL_GOT:
+ case SYMBOL_SMALL_GOT_4G:
+ emit_insn (gen_rtx_SET (dest, imm));
+ return;
+@@ -6026,6 +6050,7 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
+ case SYMBOL_SMALL_TLSIE:
+ case SYMBOL_SMALL_GOT_28K:
+ case SYMBOL_SMALL_GOT_4G:
++ case SYMBOL_MO_SMALL_GOT:
+ case SYMBOL_TINY_GOT:
+ case SYMBOL_TINY_TLSIE:
+ if (const_offset != 0)
+@@ -6039,6 +6064,7 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
+ /* FALLTHRU */
+
+ case SYMBOL_SMALL_ABSOLUTE:
++ case SYMBOL_MO_SMALL_PCR:
+ case SYMBOL_TINY_ABSOLUTE:
+ case SYMBOL_TLSLE12:
+ case SYMBOL_TLSLE24:
+@@ -6628,6 +6654,7 @@ aarch64_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED)
+ gcc_unreachable ();
+ }
+
++#if !TARGET_MACHO
+ static bool
+ aarch64_vfp_is_call_candidate (cumulative_args_t pcum_v, machine_mode mode,
+ const_tree type, int *nregs)
+@@ -6637,6 +6664,7 @@ aarch64_vfp_is_call_candidate (cumulative_args_t pcum_v, machine_mode mode,
+ &pcum->aapcs_vfp_rmode,
+ nregs, NULL, pcum->silent_p);
+ }
++#endif
+
+ /* Given MODE and TYPE of a function argument, return the alignment in
+ bits. The idea is to suppress any stronger alignment requested by
+@@ -6665,7 +6693,7 @@ aarch64_function_arg_alignment (machine_mode mode, const_tree type,
+ if (integer_zerop (TYPE_SIZE (type)))
+ return 0;
+
+- gcc_assert (TYPE_MODE (type) == mode);
++ gcc_assert (TARGET_MACHO || TYPE_MODE (type) == mode);
+
+ if (!AGGREGATE_TYPE_P (type))
+ {
+@@ -6863,6 +6891,14 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
+ Both behaviors were wrong, but in different cases. */
+
+ pcum->aapcs_arg_processed = true;
++ if (TARGET_MACHO)
++ {
++ /* Set suitable defaults for queries. */
++ pcum->darwinpcs_arg_boundary
++ = aarch64_function_arg_alignment (mode, type, &abi_break_gcc_9,
++ &abi_break_gcc_13, &abi_break_gcc_14);
++ pcum->darwinpcs_arg_padding = BITS_PER_UNIT;
++ }
+
+ pure_scalable_type_info pst_info;
+ if (type && pst_info.analyze_registers (type))
+@@ -6922,13 +6958,29 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
+ /* No frontends can create types with variable-sized modes, so we
+ shouldn't be asked to pass or return them. */
+ size = GET_MODE_SIZE (mode).to_constant ();
++
++ if (TARGET_MACHO)
++ /* Since we can pack things on the stack, we need the unrounded size. */
++ pcum->darwinpcs_stack_bytes = size;
++
+ size = ROUND_UP (size, UNITS_PER_WORD);
+
+ allocate_ncrn = (type) ? !(FLOAT_TYPE_P (type)) : !FLOAT_MODE_P (mode);
++ bool is_ha = false;
++#if !TARGET_MACHO
+ allocate_nvrn = aarch64_vfp_is_call_candidate (pcum_v,
+ mode,
+ type,
+ &nregs);
++#else
++ /* We care if the value is a homogenous aggregate when laying out the stack,
++ so use this call directly. */
++ allocate_nvrn
++ = aarch64_vfp_is_call_or_return_candidate (mode, type,
++ &pcum->aapcs_vfp_rmode,
++ &nregs, &is_ha,
++ pcum->silent_p);
++#endif
+ gcc_assert (!sve_p || !allocate_nvrn);
+
+ unsigned int alignment
+@@ -6957,7 +7009,13 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
+ if (!pcum->silent_p && !TARGET_FLOAT)
+ aarch64_err_no_fpadvsimd (mode);
+
+- if (nvrn + nregs <= NUM_FP_ARG_REGS)
++ if (TARGET_MACHO
++ && !arg.named)
++ {
++ pcum->aapcs_nextnvrn = NUM_FP_ARG_REGS;
++ goto on_stack;
++ }
++ else if (nvrn + nregs <= NUM_FP_ARG_REGS)
+ {
+ pcum->aapcs_nextnvrn = nvrn + nregs;
+ if (!aarch64_composite_type_p (type, mode))
+@@ -6987,6 +7045,7 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
+ }
+ pcum->aapcs_reg = par;
+ }
++ pcum->darwinpcs_stack_bytes = 0;
+ return;
+ }
+ else
+@@ -7003,14 +7062,24 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
+ /* C6 - C9. though the sign and zero extension semantics are
+ handled elsewhere. This is the case where the argument fits
+ entirely general registers. */
++
+ if (allocate_ncrn && (ncrn + nregs <= NUM_ARG_REGS))
+ {
+ gcc_assert (nregs == 0 || nregs == 1 || nregs == 2);
+
++ if (TARGET_MACHO
++ && !arg.named)
++ {
++ pcum->aapcs_nextncrn = NUM_ARG_REGS;
++ goto on_stack;
++ }
++
+ /* C.8 if the argument has an alignment of 16 then the NGRN is
+ rounded up to the next even number. */
+ if (nregs == 2
+- && ncrn % 2)
++ && ncrn % 2
++ /* Darwin PCS deletes rule C.8. */
++ && !TARGET_MACHO)
+ {
+ /* Emit a warning if the alignment changed when taking the
+ 'packed' attribute into account. */
+@@ -7080,8 +7149,8 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
+ }
+ pcum->aapcs_reg = par;
+ }
+-
+ pcum->aapcs_nextncrn = ncrn + nregs;
++ pcum->darwinpcs_stack_bytes = 0;
+ return;
+ }
+
+@@ -7091,7 +7160,81 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
+ /* The argument is passed on stack; record the needed number of words for
+ this argument and align the total size if necessary. */
+ on_stack:
+- pcum->aapcs_stack_words = size / UNITS_PER_WORD;
++
++ if (TARGET_MACHO)
++ {
++ /* Darwin does not round up the allocation for smaller entities to 8
++ bytes. It only requires the natural alignment for these.
++
++ but we don't do this for:
++ * unnamed parms in variadic functions
++ * complex types
++ * unions
++ * aggregates (except for homogeneous ones which are handles as the
++ enclosed type).
++ each entry starts a new slot.
++
++ 16 byte entities are naturally aligned on the stack.
++ There was no darwinpcs for GCC 9, so neither the implementation
++ change nor the warning should fire here (i.e. we do not need to check
++ if 16byte entities alter the stack size). */
++
++ gcc_checking_assert (arg.named == pcum->named_p);
++ pcum->darwinpcs_arg_padding = BITS_PER_UNIT;
++ if (!pcum->named_p
++ || TREE_CODE (type) == COMPLEX_TYPE
++ || (TREE_CODE (type) == RECORD_TYPE
++ && !is_ha && !SCALAR_FLOAT_MODE_P (pcum->aapcs_vfp_rmode))
++ || TREE_CODE (type) == UNION_TYPE)
++ {
++ pcum->aapcs_stack_words = size / UNITS_PER_WORD;
++ pcum->darwinpcs_sub_word_offset = 0;
++ pcum->darwinpcs_sub_word_pos = 0;
++ pcum->darwinpcs_arg_boundary = MAX (alignment, PARM_BOUNDARY);
++ if (!pcum->named_p)
++ pcum->darwinpcs_arg_padding = PARM_BOUNDARY;
++ return;
++ }
++
++ /* Updated sub-word offset aligned for the new object.
++ We are looking for the case that the new object will fit after some
++ existing object(s) in the same stack slot. In that case, we do not
++ need to add any more stack space for it. */
++ int new_off
++ = ROUND_UP (pcum->darwinpcs_sub_word_pos, alignment / BITS_PER_UNIT);
++
++ if (new_off >= UNITS_PER_WORD)
++ {
++ /* That exceeds a stack slot, start a new one. */
++ pcum->darwinpcs_sub_word_offset = 0;
++ pcum->darwinpcs_sub_word_pos = 0;
++ new_off = 0;
++ }
++ /* This is the end of the new object. */
++ int new_pos = new_off + pcum->darwinpcs_stack_bytes;
++
++ if (pcum->darwinpcs_sub_word_pos == 0)
++ /* New stack slot, just allocate one or more words, and note where
++ the next arg will start. */
++ pcum->aapcs_stack_words = size / UNITS_PER_WORD;
++ else if (new_pos <= UNITS_PER_WORD)
++ /* Old stack slot, object starts at new_off and goes to new_pos, we do
++ not add any stack space. */
++ pcum->darwinpcs_sub_word_offset = new_off;
++ pcum->darwinpcs_sub_word_pos = new_pos;
++ pcum->darwinpcs_arg_boundary = alignment ;
++ if (pcum->last_named_p && new_pos > 0)
++ {
++ /* Round the last named arg to the start of the next stack slot. */
++ if (new_pos <= 4)
++ pcum->darwinpcs_arg_padding = PARM_BOUNDARY;
++ else if (new_pos <= 6)
++ pcum->darwinpcs_arg_padding = 4 * BITS_PER_UNIT;
++ else if (pcum->darwinpcs_sub_word_pos <= 7)
++ pcum->darwinpcs_arg_padding = 2 * BITS_PER_UNIT;
++ }
++ return;
++ }
+
+ if (warn_pcs_change_le_gcc14
+ && abi_break_gcc_13
+@@ -7107,6 +7250,8 @@ on_stack:
+ inform (input_location, "parameter passing for argument of type "
+ "%qT changed in GCC 14.1", type);
+
++ /* size was already rounded up to PARM_BOUNDARY. */
++ pcum->aapcs_stack_words = size / UNITS_PER_WORD;
+ if (alignment == 16 * BITS_PER_UNIT)
+ {
+ int new_size = ROUND_UP (pcum->aapcs_stack_size, 16 / UNITS_PER_WORD);
+@@ -7211,12 +7356,33 @@ aarch64_init_cumulative_args (CUMULATIVE_ARGS *pcum,
+ pcum->aapcs_arg_processed = false;
+ pcum->aapcs_stack_words = 0;
+ pcum->aapcs_stack_size = 0;
++ pcum->darwinpcs_stack_bytes = 0;
++ pcum->darwinpcs_sub_word_offset = 0;
++ pcum->darwinpcs_sub_word_pos = 0;
++ pcum->darwinpcs_arg_boundary = BITS_PER_UNIT;
++ pcum->darwinpcs_arg_padding = BITS_PER_UNIT;
++ /* If we have been invoked for incoming args, then n_named will have been
++ set to -1, but we should have a function decl - so pick up the named
++ count from that. If that fails, and we end up with -1, this effectively
++ corresponds to assuming that there is an arbitrary number of named
++ args. */
++ pcum->darwinpcs_n_named = n_named;
++ if (n_named == (unsigned)-1 && fndecl)
++ {
++ tree fnt = TREE_TYPE (fndecl);
++ if (fnt && TYPE_ARG_TYPES (fnt))
++ pcum->darwinpcs_n_named = list_length (TYPE_ARG_TYPES (fnt));
++ }
++ pcum->darwinpcs_n_args_processed = 0;
++ pcum->named_p = pcum->darwinpcs_n_named != 0;
++ pcum->last_named_p = pcum->darwinpcs_n_named == 1;
+ pcum->silent_p = silent_p;
+ pcum->shared_za_flags
+ = (fntype ? aarch64_fntype_shared_flags (fntype, "za") : 0U);
+ pcum->shared_zt0_flags
+ = (fntype ? aarch64_fntype_shared_flags (fntype, "zt0") : 0U);
+ pcum->num_sme_mode_switch_args = 0;
++ pcum->aapcs_vfp_rmode = VOIDmode;
+
+ if (!silent_p
+ && !TARGET_FLOAT
+@@ -7255,9 +7421,11 @@ aarch64_function_arg_advance (cumulative_args_t pcum_v,
+ || pcum->pcs_variant == ARM_PCS_SVE)
+ {
+ aarch64_layout_arg (pcum_v, arg);
+- gcc_assert ((pcum->aapcs_reg != NULL_RTX)
+- != (pcum->aapcs_stack_words != 0));
+- if (pcum->aapcs_reg
++ pcum->darwinpcs_n_args_processed++;
++ gcc_assert (TARGET_MACHO
++ || (pcum->aapcs_reg != NULL_RTX)
++ != (pcum->aapcs_stack_words != 0));
++ if (pcum->aapcs_reg
+ && aarch64_call_switches_pstate_sm (pcum->isa_mode))
+ aarch64_record_sme_mode_switch_args (pcum);
+
+@@ -7268,6 +7436,12 @@ aarch64_function_arg_advance (cumulative_args_t pcum_v,
+ pcum->aapcs_stack_size += pcum->aapcs_stack_words;
+ pcum->aapcs_stack_words = 0;
+ pcum->aapcs_reg = NULL_RTX;
++ pcum->darwinpcs_arg_boundary = BITS_PER_UNIT;
++ pcum->darwinpcs_arg_padding = BITS_PER_UNIT;
++ pcum->named_p
++ = pcum->darwinpcs_n_args_processed < pcum->darwinpcs_n_named;
++ pcum->last_named_p
++ = pcum->darwinpcs_n_args_processed + 1 == pcum->darwinpcs_n_named;
+ }
+ }
+
+@@ -7279,12 +7453,15 @@ aarch64_function_arg_regno_p (unsigned regno)
+ || (PR_REGNUM_P (regno) && regno < P0_REGNUM + NUM_PR_ARG_REGS));
+ }
+
+-/* Implement FUNCTION_ARG_BOUNDARY. Every parameter gets at least
+- PARM_BOUNDARY bits of alignment, but will be given anything up
+- to STACK_BOUNDARY bits if the type requires it. This makes sure
+- that both before and after the layout of each argument, the Next
+- Stacked Argument Address (NSAA) will have a minimum alignment of
+- 8 bytes. */
++/* Implement FUNCTION_ARG_BOUNDARY.
++ For AAPCS64, Every parameter gets at least PARM_BOUNDARY bits of
++ alignment, but will be given anything up to STACK_BOUNDARY bits
++ if the type requires it. This makes sure that both before and after
++ the layout of each argument, the Next Stacked Argument Address (NSAA)
++ will have a minimum alignment of 8 bytes.
++
++ For darwinpcs, this is only called to lower va_arg entries which are
++ always aligned as for AAPCS64. */
+
+ static unsigned int
+ aarch64_function_arg_boundary (machine_mode mode, const_tree type)
+@@ -7298,8 +7475,108 @@ aarch64_function_arg_boundary (machine_mode mode, const_tree type)
+ &abi_break_gcc_14);
+ /* We rely on aarch64_layout_arg and aarch64_gimplify_va_arg_expr
+ to emit warnings about ABI incompatibility. */
++#if TARGET_MACHO
++ /* This can only work for unnamed args. */
++ machine_mode comp_mode = VOIDmode;
++ int nregs;
++ bool is_ha;
++ aarch64_vfp_is_call_or_return_candidate (mode, type, &comp_mode, &nregs,
++ &is_ha, /*silent*/true);
++ if (TREE_CODE (type) == COMPLEX_TYPE
++ || (TREE_CODE (type) == RECORD_TYPE
++ && !is_ha && !SCALAR_FLOAT_MODE_P (comp_mode))
++ || TREE_CODE (type) == UNION_TYPE)
++ return MIN (MAX (alignment, PARM_BOUNDARY), STACK_BOUNDARY);
++ return MIN (alignment, STACK_BOUNDARY);
++#else
++ alignment = MIN (MAX (alignment, PARM_BOUNDARY), STACK_BOUNDARY);
++ return alignment;
++#endif
++}
++
++/* For Darwin, we want to use the arg boundary computed when laying out the
++ function arg, to cope with items packed on the stack and the different
++ rules applied to unnamed parms. */
++
++static unsigned int
++aarch64_function_arg_boundary_ca (machine_mode mode ATTRIBUTE_UNUSED,
++ const_tree type ATTRIBUTE_UNUSED,
++ cumulative_args_t ca ATTRIBUTE_UNUSED)
++{
++ unsigned int abi_break_gcc_9;
++ unsigned int abi_break_gcc_13;
++ unsigned int abi_break_gcc_14;
++ unsigned int alignment
++ = aarch64_function_arg_alignment (mode, type, &abi_break_gcc_9,
++ &abi_break_gcc_13, &abi_break_gcc_14);
++ /* We rely on aarch64_layout_arg and aarch64_gimplify_va_arg_expr
++ to emit warnings about ABI incompatibility. */
++#if TARGET_MACHO
++ CUMULATIVE_ARGS *pcum = get_cumulative_args (ca);
++gcc_checking_assert (pcum->aapcs_arg_processed);
++
++ bool named_p = pcum->darwinpcs_n_args_processed < pcum->darwinpcs_n_named;
++gcc_checking_assert (named_p == pcum->named_p);
++ machine_mode comp_mode = VOIDmode;
++ int nregs;
++ bool is_ha;
++ aarch64_vfp_is_call_or_return_candidate (mode, type, &comp_mode, &nregs,
++ &is_ha, /*silent*/true);
++ bool no_pack = (TREE_CODE (type) == COMPLEX_TYPE
++ || (TREE_CODE (type) == RECORD_TYPE
++ && !is_ha && !SCALAR_FLOAT_MODE_P (comp_mode))
++ || TREE_CODE (type) == UNION_TYPE);
++
++ bool in_regs = (pcum->aapcs_reg != NULL_RTX);
++
++ if ((named_p && !no_pack) || in_regs)
++ ; /* Leave the alignment as natural. */
++ else
++ alignment = MAX (alignment, PARM_BOUNDARY);
++gcc_checking_assert (alignment == pcum->darwinpcs_arg_boundary);
++ return MIN (alignment, STACK_BOUNDARY);
++
++#else
+ alignment = MIN (MAX (alignment, PARM_BOUNDARY), STACK_BOUNDARY);
+ return alignment;
++#endif
++}
++
++/* Implement TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA for darwinpcs which allows
++ non-standard passing of byte-aligned items [D.2]. This is done by pulling
++ the values out of the cumulative args struct. */
++
++static unsigned int
++aarch64_function_arg_round_boundary_ca (machine_mode mode ATTRIBUTE_UNUSED,
++ const_tree type ATTRIBUTE_UNUSED,
++ cumulative_args_t ca)
++{
++ CUMULATIVE_ARGS *pcum = get_cumulative_args (ca);
++gcc_checking_assert (pcum->aapcs_arg_processed);
++ bool named_p = pcum->darwinpcs_n_args_processed < pcum->darwinpcs_n_named;
++gcc_checking_assert (named_p == pcum->named_p);
++ bool last_named_p = pcum->darwinpcs_n_args_processed + 1 == pcum->darwinpcs_n_named;
++gcc_checking_assert (last_named_p == pcum->last_named_p);
++
++ unsigned boundary = BITS_PER_UNIT;
++ if (last_named_p && pcum->darwinpcs_sub_word_pos > 0)
++ {
++ /* Round the last named arg to the start of the next stack slot. */
++ if (pcum->darwinpcs_sub_word_pos <= 4)
++ boundary = PARM_BOUNDARY;
++ else if (pcum->darwinpcs_sub_word_pos <= 6)
++ boundary = 4 * BITS_PER_UNIT;
++ else if (pcum->darwinpcs_sub_word_pos <= 7)
++ boundary = 2 * BITS_PER_UNIT;
++ }
++ else if (named_p)
++ /* Named args are naturally aligned, but with no rounding. */
++ ;
++ else
++ /* un-named args are rounded to fill slots. */
++ boundary = PARM_BOUNDARY;
++gcc_checking_assert (boundary == pcum->darwinpcs_arg_padding);
++ return boundary;
+ }
+
+ /* Implement TARGET_GET_RAW_RESULT_MODE and TARGET_GET_RAW_ARG_MODE. */
+@@ -10698,6 +10975,7 @@ aarch64_classify_address (struct aarch64_address_info *info,
+ /* load literal: pc-relative constant pool entry. Only supported
+ for SI mode or larger. */
+ info->type = ADDRESS_SYMBOLIC;
++ info->offset = NULL_RTX;
+
+ if (!load_store_pair_p
+ && GET_MODE_SIZE (mode).is_constant (&const_size)
+@@ -10705,6 +10983,7 @@ aarch64_classify_address (struct aarch64_address_info *info,
+ {
+ poly_int64 offset;
+ rtx sym = strip_offset_and_salt (x, &offset);
++
+ return ((LABEL_REF_P (sym)
+ || (SYMBOL_REF_P (sym)
+ && CONSTANT_POOL_ADDRESS_P (sym)
+@@ -10722,10 +11001,13 @@ aarch64_classify_address (struct aarch64_address_info *info,
+ poly_int64 offset;
+ HOST_WIDE_INT const_offset;
+ rtx sym = strip_offset_and_salt (info->offset, &offset);
++
+ if (SYMBOL_REF_P (sym)
+ && offset.is_constant (&const_offset)
+ && (aarch64_classify_symbol (sym, const_offset)
+- == SYMBOL_SMALL_ABSOLUTE))
++ == SYMBOL_SMALL_ABSOLUTE
++ || aarch64_classify_symbol (sym, const_offset)
++ == SYMBOL_MO_SMALL_PCR))
+ {
+ /* The symbol and offset must be aligned to the access size. */
+ unsigned int align;
+@@ -10775,6 +11057,55 @@ aarch64_address_valid_for_prefetch_p (rtx x, bool strict_p)
+ if (!res)
+ return false;
+
++ /* For ELF targets using GAS, we emit prfm unconditionally; GAS will alter
++ the instruction to pick the prfum form where possible (i.e. when the
++ offset is in the range -256..255) and fall back to prfm otherwise.
++ We can reject cases where the offset exceeds the range usable by both
++ insns [-256..32760], or for offsets > 255 when the value is not divisible
++ by 8.
++ For Mach-O (Darwin) where the assembler uses the LLVM back end, that does
++ not yet do the substitution, so we must reject all prfum cases. */
++ if (addr.offset)
++ {
++ HOST_WIDE_INT offs = INTVAL (addr.offset);
++ if (offs < -256) /* Out of range for both prfum and prfm. */
++ return false;
++ if (offs > 32760) /* Out of range for prfm. */
++ return false;
++ if (offs & 0x07) /* We cannot use prfm. */
++ {
++ if (offs > 255) /* Out of range for prfum. */
++ return false;
++ if (TARGET_MACHO)
++ return false;
++ }
++ if (TARGET_MACHO && offs < 0)
++ return false;
++ }
++
++ /* ... except writeback forms. */
++ return addr.type != ADDRESS_REG_WB;
++}
++
++/* Return true if the address X is valid for a PRFUM instruction.
++ STRICT_P is true if we should do strict checking with
++ aarch64_classify_address. */
++
++bool
++aarch64_address_valid_for_unscaled_prefetch_p (rtx x, bool strict_p)
++{
++ struct aarch64_address_info addr;
++
++ /* PRFUM accepts the same addresses as DImode, but constrained to a range
++ -256..255. */
++ bool res = aarch64_classify_address (&addr, x, DImode, strict_p);
++ if (!res)
++ return false;
++
++ if (addr.offset && ((INTVAL (addr.offset) > 255)
++ || (INTVAL (addr.offset) < -256)))
++ return false;
++
+ /* ... except writeback forms. */
+ return addr.type != ADDRESS_REG_WB;
+ }
+@@ -11908,6 +12239,144 @@ sizetochar (int size)
+ }
+ }
+
++static void
++output_macho_postfix_expr (FILE *file, rtx x, const char *postfix)
++{
++ char buf[256];
++
++ restart:
++ switch (GET_CODE (x))
++ {
++ case PC:
++ putc ('.', file);
++ break;
++
++ case SYMBOL_REF:
++ if (SYMBOL_REF_DECL (x))
++ assemble_external (SYMBOL_REF_DECL (x));
++ assemble_name (file, XSTR (x, 0));
++ fprintf (file, "@%s", postfix);
++ break;
++
++ case LABEL_REF:
++ x = label_ref_label (x);
++ /* Fall through. */
++ case CODE_LABEL:
++ ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
++ assemble_name (file, buf);
++ fprintf (file, "@%s", postfix);
++ break;
++
++ case CONST_INT:
++ fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
++ break;
++
++ case CONST:
++ /* This used to output parentheses around the expression,
++ but that does not work on the 386 (either ATT or BSD assembler). */
++ output_macho_postfix_expr (file, XEXP (x, 0), postfix);
++ break;
++
++ case CONST_WIDE_INT:
++ /* We do not know the mode here so we have to use a round about
++ way to build a wide-int to get it printed properly. */
++ {
++ wide_int w = wide_int::from_array (&CONST_WIDE_INT_ELT (x, 0),
++ CONST_WIDE_INT_NUNITS (x),
++ CONST_WIDE_INT_NUNITS (x)
++ * HOST_BITS_PER_WIDE_INT,
++ false);
++ print_decs (w, file);
++ }
++ break;
++
++ case CONST_DOUBLE:
++ if (CONST_DOUBLE_AS_INT_P (x))
++ {
++ /* We can use %d if the number is one word and positive. */
++ if (CONST_DOUBLE_HIGH (x))
++ fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
++ (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (x),
++ (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x));
++ else if (CONST_DOUBLE_LOW (x) < 0)
++ fprintf (file, HOST_WIDE_INT_PRINT_HEX,
++ (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x));
++ else
++ fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x));
++ }
++ else
++ /* We can't handle floating point constants;
++ PRINT_OPERAND must handle them. */
++ output_operand_lossage ("floating constant misused");
++ break;
++
++ case CONST_FIXED:
++ fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_FIXED_VALUE_LOW (x));
++ break;
++
++ case PLUS:
++ /* Some assemblers need integer constants to appear last (eg masm). */
++ if (CONST_INT_P (XEXP (x, 0)))
++ {
++ output_macho_postfix_expr (file, XEXP (x, 1), postfix);
++ if (INTVAL (XEXP (x, 0)) >= 0)
++ fprintf (file, "+");
++ output_addr_const (file, XEXP (x, 0));
++ }
++ else
++ {
++ output_macho_postfix_expr (file, XEXP (x, 0), postfix);
++ if (!CONST_INT_P (XEXP (x, 1))
++ || INTVAL (XEXP (x, 1)) >= 0)
++ fprintf (file, "+");
++ output_addr_const (file, XEXP (x, 1));
++ }
++ break;
++
++ case MINUS:
++ /* Avoid outputting things like x-x or x+5-x,
++ since some assemblers can't handle that. */
++ x = simplify_subtraction (x);
++ if (GET_CODE (x) != MINUS)
++ goto restart;
++
++ output_macho_postfix_expr (file, XEXP (x, 0), postfix);
++ fprintf (file, "-");
++ if ((CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) >= 0)
++ || GET_CODE (XEXP (x, 1)) == PC
++ || GET_CODE (XEXP (x, 1)) == SYMBOL_REF)
++ output_addr_const (file, XEXP (x, 1));
++ else
++ {
++ fputs (targetm.asm_out.open_paren, file);
++ output_addr_const (file, XEXP (x, 1));
++ fputs (targetm.asm_out.close_paren, file);
++ }
++ break;
++
++ case ZERO_EXTEND:
++ case SIGN_EXTEND:
++ case SUBREG:
++ case TRUNCATE:
++ output_addr_const (file, XEXP (x, 0));
++ break;
++
++ case UNSPEC:
++ if (XINT (x, 1) == UNSPEC_SALT_ADDR)
++ {
++ output_macho_postfix_expr (file, XVECEXP (x, 0, 0), postfix);
++ break;
++ }
++ /* FALLTHROUGH */
++ default:
++ if (targetm.asm_out.output_addr_const_extra (file, x))
++ break;
++
++ output_operand_lossage ("invalid expression as operand");
++ }
++
++}
++
+ /* Print operand X to file F in a target specific manner according to CODE.
+ The acceptable formatting commands given by CODE are:
+ 'c': An integer or symbol address without a preceding #
+@@ -11981,6 +12450,12 @@ aarch64_print_operand (FILE *f, rtx x, int code)
+ }
+ break;
+
++ case 'J':
++ output_macho_postfix_expr (f, x, "PAGEOFF");
++ break;
++ case 'O':
++ output_macho_postfix_expr (f, x, "GOTPAGEOFF");
++ break;
+ case 'e':
+ {
+ x = unwrap_const_vec_duplicate (x);
+@@ -12313,7 +12788,7 @@ aarch64_print_operand (FILE *f, rtx x, int code)
+ case 'A':
+ if (GET_CODE (x) == HIGH)
+ x = XEXP (x, 0);
+-
++#if !TARGET_MACHO
+ switch (aarch64_classify_symbolic_expression (x))
+ {
+ case SYMBOL_SMALL_GOT_4G:
+@@ -12344,9 +12819,26 @@ aarch64_print_operand (FILE *f, rtx x, int code)
+ break;
+ }
+ output_addr_const (asm_out_file, x);
++#endif
++#if TARGET_MACHO
++ switch (aarch64_classify_symbolic_expression (x))
++ {
++ case SYMBOL_MO_SMALL_PCR:
++ output_macho_postfix_expr (asm_out_file, x, "PAGE");
++ break;
++ case SYMBOL_MO_SMALL_GOT:
++ output_macho_postfix_expr (asm_out_file, x, "GOTPAGE");
++ break;
++ default:
++ /* large code model unimplemented. */
++ gcc_unreachable ();
++ break;
++ }
++#endif
+ break;
+
+ case 'L':
++#if !TARGET_MACHO
+ switch (aarch64_classify_symbolic_expression (x))
+ {
+ case SYMBOL_SMALL_GOT_4G:
+@@ -12384,10 +12876,12 @@ aarch64_print_operand (FILE *f, rtx x, int code)
+ default:
+ break;
+ }
++#endif
+ output_addr_const (asm_out_file, x);
+ break;
+
+ case 'G':
++#if !TARGET_MACHO
+ switch (aarch64_classify_symbolic_expression (x))
+ {
+ case SYMBOL_TLSLE24:
+@@ -12396,6 +12890,7 @@ aarch64_print_operand (FILE *f, rtx x, int code)
+ default:
+ break;
+ }
++#endif
+ output_addr_const (asm_out_file, x);
+ break;
+
+@@ -12561,8 +13056,13 @@ aarch64_print_address_internal (FILE *f, machine_mode mode, rtx x,
+ break;
+
+ case ADDRESS_LO_SUM:
++#if TARGET_MACHO
++ asm_fprintf (f, "[%s, #", reg_names [REGNO (addr.base)]);
++ output_macho_postfix_expr (f, addr.offset, "PAGEOFF");
++#else
+ asm_fprintf (f, "[%s, #:lo12:", reg_names [REGNO (addr.base)]);
+ output_addr_const (f, addr.offset);
++#endif
+ asm_fprintf (f, "]");
+ return true;
+
+@@ -12870,7 +13370,23 @@ aarch64_frame_pointer_required ()
+ {
+ /* If the function needs to record the incoming value of PSTATE.SM,
+ make sure that the slot is accessible from the frame pointer. */
+- return aarch64_need_old_pstate_sm ();
++ if (!TARGET_MACHO)
++ return aarch64_need_old_pstate_sm ();
++
++ /* We could do with some more general test.
++ gcc_checking_assert (!aarch64_need_old_pstate_sm ());*/
++
++ if (crtl->calls_eh_return || aarch64_need_old_pstate_sm ())
++ return true;
++
++ /* Not used in leaf functions (unless forced). */
++ if (flag_omit_leaf_frame_pointer && leaf_function_p ())
++ return false;
++
++ /* NOTE: We are allowing the user to force omission of the frame
++ pointer, (despite that it is not ABI-compliant). */
++
++ return flag_omit_frame_pointer != 1;
+ }
+
+ static bool
+@@ -13098,6 +13614,8 @@ aarch64_asm_output_labelref (FILE* f, const char *name)
+ asm_fprintf (f, "%U%s", name);
+ }
+
++#if !TARGET_MACHO
++
+ static void
+ aarch64_elf_asm_constructor (rtx symbol, int priority)
+ {
+@@ -13137,6 +13655,7 @@ aarch64_elf_asm_destructor (rtx symbol, int priority)
+ assemble_aligned_integer (POINTER_BYTES, symbol);
+ }
+ }
++#endif
+
+ const char*
+ aarch64_output_casesi (rtx *operands)
+@@ -13289,7 +13808,11 @@ aarch64_select_rtx_section (machine_mode mode,
+ if (aarch64_can_use_per_function_literal_pools_p ())
+ return function_section (current_function_decl);
+
++#if TARGET_MACHO
++ return machopic_select_rtx_section (mode, x, align);
++#else
+ return default_elf_select_rtx_section (mode, x, align);
++#endif
+ }
+
+ /* Implement ASM_OUTPUT_POOL_EPILOGUE. */
+@@ -15559,15 +16082,17 @@ aarch64_init_builtins ()
+ {
+ aarch64_general_init_builtins ();
+ aarch64_sve::init_builtins ();
+-#ifdef SUBTARGET_INIT_BUILTINS
+- SUBTARGET_INIT_BUILTINS;
+-#endif
++ aarch64_init_subtarget_builtins ();
+ }
+
+ /* Implement TARGET_FOLD_BUILTIN. */
+ static tree
+ aarch64_fold_builtin (tree fndecl, int nargs, tree *args, bool)
+ {
++#ifdef SUBTARGET_FOLD_BUILTIN
++ if (tree res = SUBTARGET_FOLD_BUILTIN (fndecl, nargs, args, false))
++ return res;
++#endif
+ unsigned int code = DECL_MD_FUNCTION_CODE (fndecl);
+ unsigned int subcode = code >> AARCH64_BUILTIN_SHIFT;
+ tree type = TREE_TYPE (TREE_TYPE (fndecl));
+@@ -18979,10 +19504,14 @@ initialize_aarch64_code_model (struct gcc_options *opts)
+ }
+ break;
+ case AARCH64_CMODEL_LARGE:
+- if (opts->x_flag_pic)
++ if (TARGET_MACHO)
++ /* We need to implement fPIC here (arm64_32 also accepts the large
++ model). */
++ sorry ("code model %qs not supported yet", "large");
++ else if (opts->x_flag_pic)
+ sorry ("code model %qs with %<-f%s%>", "large",
+ opts->x_flag_pic > 1 ? "PIC" : "pic");
+- if (opts->x_aarch64_abi == AARCH64_ABI_ILP32)
++ else if (opts->x_aarch64_abi == AARCH64_ABI_ILP32)
+ sorry ("code model %qs not supported in ilp32 mode", "large");
+ break;
+ case AARCH64_CMODEL_TINY_PIC:
+@@ -20899,7 +21428,9 @@ aarch64_classify_symbol (rtx x, HOST_WIDE_INT offset)
+ case AARCH64_CMODEL_SMALL_SPIC:
+ case AARCH64_CMODEL_SMALL_PIC:
+ case AARCH64_CMODEL_SMALL:
+- return SYMBOL_SMALL_ABSOLUTE;
++ return TARGET_MACHO
++ ? SYMBOL_MO_SMALL_PCR
++ : SYMBOL_SMALL_ABSOLUTE;
+
+ default:
+ gcc_unreachable ();
+@@ -20935,10 +21466,22 @@ aarch64_classify_symbol (rtx x, HOST_WIDE_INT offset)
+
+ return SYMBOL_TINY_ABSOLUTE;
+
+-
+ case AARCH64_CMODEL_SMALL_SPIC:
+ case AARCH64_CMODEL_SMALL_PIC:
+ case AARCH64_CMODEL_SMALL:
++#if TARGET_MACHO
++ if (TARGET_MACHO)
++ {
++ /* Constant pool addresses are always TU-local and PC-
++ relative. We indirect common, external and weak
++ symbols (but weak only if not hidden). */
++ if (!CONSTANT_POOL_ADDRESS_P (x)
++ && (MACHO_SYMBOL_MUST_INDIRECT_P (x)
++ || !aarch64_symbol_binds_local_p (x)))
++ return SYMBOL_MO_SMALL_GOT;
++ }
++ else
++#endif
+ if ((flag_pic || SYMBOL_REF_WEAK (x))
+ && !aarch64_symbol_binds_local_p (x))
+ return aarch64_cmodel == AARCH64_CMODEL_SMALL_SPIC
+@@ -20950,7 +21493,8 @@ aarch64_classify_symbol (rtx x, HOST_WIDE_INT offset)
+ || offset_within_block_p (x, offset)))
+ return SYMBOL_FORCE_TO_MEM;
+
+- return SYMBOL_SMALL_ABSOLUTE;
++ return TARGET_MACHO ? SYMBOL_MO_SMALL_PCR
++ : SYMBOL_SMALL_ABSOLUTE;
+
+ case AARCH64_CMODEL_LARGE:
+ /* This is alright even in PIC code as the constant
+@@ -21080,7 +21624,10 @@ static GTY(()) tree va_list_type;
+ void *__vr_top;
+ int __gr_offs;
+ int __vr_offs;
+- }; */
++ };
++
++ darwinpcs uses 'char *' for the va_list (in common with other platform
++ ports). */
+
+ static tree
+ aarch64_build_builtin_va_list (void)
+@@ -21088,6 +21635,13 @@ aarch64_build_builtin_va_list (void)
+ tree va_list_name;
+ tree f_stack, f_grtop, f_vrtop, f_groff, f_vroff;
+
++ /* darwinpcs uses a simple char * for this. */
++ if (TARGET_MACHO)
++ {
++ va_list_type = build_pointer_type (char_type_node);
++ return va_list_type;
++ }
++
+ /* Create the type. */
+ va_list_type = lang_hooks.types.make_type (RECORD_TYPE);
+ /* Give it the required name. */
+@@ -21159,6 +21713,13 @@ aarch64_expand_builtin_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
+ int vr_save_area_size = cfun->va_list_fpr_size;
+ int vr_offset;
+
++ /* darwinpcs uses the default, char * va_list impl. */
++ if (TARGET_MACHO)
++ {
++ std_expand_builtin_va_start (valist, nextarg);
++ return;
++ }
++
+ cum = &crtl->args.info;
+ if (cfun->va_list_gpr_size)
+ gr_save_area_size = MIN ((NUM_ARG_REGS - cum->aapcs_ncrn) * UNITS_PER_WORD,
+@@ -21249,6 +21810,9 @@ aarch64_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
+ HOST_WIDE_INT size, rsize, adjust, align;
+ tree t, u, cond1, cond2;
+
++ if (TARGET_MACHO)
++ return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
++
+ indirect_p = pass_va_arg_by_reference (type);
+ if (indirect_p)
+ type = build_pointer_type (type);
+@@ -21453,8 +22017,18 @@ aarch64_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
+ field_ptr_t = double_ptr_type_node;
+ break;
+ case E_TFmode:
+- field_t = long_double_type_node;
+- field_ptr_t = long_double_ptr_type_node;
++ if (TARGET_MACHO)
++ {
++ /* Darwin has __float128, and long double is the same as
++ double. */
++ field_t = float128_type_node;
++ field_ptr_t = aarch64_float128_ptr_type_node;
++ }
++ else
++ {
++ field_t = long_double_type_node;
++ field_ptr_t = long_double_ptr_type_node;
++ }
+ break;
+ case E_SDmode:
+ field_t = dfloat32_type_node;
+@@ -21537,6 +22111,9 @@ aarch64_setup_incoming_varargs (cumulative_args_t cum_v,
+ int gr_saved = cfun->va_list_gpr_size;
+ int vr_saved = cfun->va_list_fpr_size;
+
++ if (TARGET_MACHO)
++ return default_setup_incoming_varargs (cum_v, arg, pretend_size, no_rtl);
++
+ /* The caller has advanced CUM up to, but not beyond, the last named
+ argument. Advance a local copy of CUM past the last "real" named
+ argument, to find out how many registers are left over. */
+@@ -22380,6 +22957,12 @@ aarch64_autovectorize_vector_modes (vector_modes *modes, bool)
+ static const char *
+ aarch64_mangle_type (const_tree type)
+ {
++ /* The darwinpcs ABI documents say that "__va_list" has to be
++ mangled as char *. */
++ if (TARGET_MACHO
++ && lang_hooks.types_compatible_p (CONST_CAST_TREE (type), va_list_type))
++ return "Pc";
++
+ /* The AArch64 ABI documents say that "__va_list" has to be
+ mangled as if it is in the "std" namespace. */
+ if (lang_hooks.types_compatible_p (CONST_CAST_TREE (type), va_list_type))
+@@ -22396,6 +22979,12 @@ aarch64_mangle_type (const_tree type)
+ return "Dh";
+ }
+
++ /* __float128 is mangled as "g" on darwin. _Float128 is not mangled here,
++ but handled in common code (as "DF128_"). */
++ if (TARGET_MACHO && TYPE_MODE (type) == TFmode
++ && TYPE_MAIN_VARIANT (type) == float128t_type_node)
++ return "g";
++
+ /* Mangle AArch64-specific internal types. TYPE_NAME is non-NULL_TREE for
+ builtin types. */
+ if (TYPE_NAME (type) != NULL)
+@@ -23093,7 +23682,8 @@ aarch64_mov_operand_p (rtx x, machine_mode mode)
+
+ /* GOT accesses are valid moves. */
+ if (SYMBOL_REF_P (x)
+- && aarch64_classify_symbolic_expression (x) == SYMBOL_SMALL_GOT_4G)
++ && (aarch64_classify_symbolic_expression (x) == SYMBOL_SMALL_GOT_4G
++ || aarch64_classify_symbolic_expression (x) == SYMBOL_MO_SMALL_GOT))
+ return true;
+
+ if (SYMBOL_REF_P (x) && mode == DImode && CONSTANT_ADDRESS_P (x))
+@@ -24430,12 +25020,8 @@ aarch64_asm_output_variant_pcs (FILE *stream, const tree decl, const char* name)
+ static std::string aarch64_last_printed_arch_string;
+ static std::string aarch64_last_printed_tune_string;
+
+-/* Implement ASM_DECLARE_FUNCTION_NAME. Output the ISA features used
+- by the function fndecl. */
+-
+-void
+-aarch64_declare_function_name (FILE *stream, const char* name,
+- tree fndecl)
++static void
++aarch64_function_options_preamble (tree fndecl)
+ {
+ tree target_parts = DECL_FUNCTION_SPECIFIC_TARGET (fndecl);
+
+@@ -24474,15 +25060,60 @@ aarch64_declare_function_name (FILE *stream, const char* name,
+ this_tune->name);
+ aarch64_last_printed_tune_string = this_tune->name;
+ }
++}
++
++/* Implement ASM_DECLARE_FUNCTION_NAME. Output the ISA features used
++ by the function fndecl. */
++
++#if TARGET_MACHO
++void
++aarch64_darwin_declare_function_name (FILE *stream, const char* name,
++ tree fndecl)
++{
++ gcc_checking_assert (TREE_CODE (fndecl) == FUNCTION_DECL);
++ gcc_checking_assert (!DECL_COMMON (fndecl));
+
++ /* Update .arch and .tune as needed. */
++ aarch64_function_options_preamble (fndecl);
++
++ /* Darwin does not emit pcs variant info. */
++
++ rtx decl_rtx = XEXP (DECL_RTL (fndecl), 0);
++ if (GET_CODE (decl_rtx) != SYMBOL_REF)
++ name = IDENTIFIER_POINTER (DECL_NAME (fndecl));
++
++ if (! DECL_WEAK (fndecl)
++ && ((TREE_STATIC (fndecl) && !TREE_PUBLIC (fndecl))
++ || DECL_INITIAL (fndecl)))
++ machopic_define_symbol (DECL_RTL (fndecl));
++ if ((TREE_STATIC (fndecl) && !TREE_PUBLIC (fndecl))
++ || DECL_INITIAL (fndecl))
++ (* targetm.encode_section_info) (fndecl, DECL_RTL (fndecl), false);
++ ASM_OUTPUT_FUNCTION_LABEL (stream, name, fndecl);
++
++ cfun->machine->label_is_assembled = true;
++}
++
++#else
++
++void
++aarch64_declare_function_name (FILE *stream, const char* name,
++ tree fndecl)
++{
++ /* Update .arch and .tune as needed. */
++ aarch64_function_options_preamble (fndecl);
++ /* Emit any necessary pcs information. */
+ aarch64_asm_output_variant_pcs (stream, fndecl, name);
+
+ /* Don't forget the type directive for ELF. */
++#ifdef ASM_OUTPUT_TYPE_DIRECTIVE
+ ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "function");
++#endif
+ ASM_OUTPUT_FUNCTION_LABEL (stream, name, fndecl);
+
+ cfun->machine->label_is_assembled = true;
+ }
++#endif
+
+ /* Implement PRINT_PATCHABLE_FUNCTION_ENTRY. */
+
+@@ -24539,12 +25170,17 @@ aarch64_output_patchable_area (unsigned int patch_area_size, bool record_p)
+ /* Implement ASM_OUTPUT_DEF_FROM_DECLS. Output .variant_pcs for aliases. */
+
+ void
+-aarch64_asm_output_alias (FILE *stream, const tree decl, const tree target)
++aarch64_asm_output_alias (FILE *stream, const tree decl,
++ const tree target ATTRIBUTE_UNUSED)
+ {
+ const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
++#ifdef ASM_OUTPUT_DEF
+ const char *value = IDENTIFIER_POINTER (target);
++#endif
+ aarch64_asm_output_variant_pcs (stream, decl, name);
++#ifdef ASM_OUTPUT_DEF
+ ASM_OUTPUT_DEF (stream, name, value);
++#endif
+ }
+
+ /* Implement ASM_OUTPUT_EXTERNAL. Output .variant_pcs for undefined
+@@ -24590,6 +25226,9 @@ aarch64_start_file (void)
+ aarch64_last_printed_arch_string.c_str ());
+
+ default_file_start ();
++#if TARGET_MACHO
++ darwin_file_start ();
++#endif
+ }
+
+ /* Emit load exclusive. */
+@@ -25169,6 +25808,16 @@ aarch64_output_simd_mov_immediate (rtx const_vector, unsigned width,
+ }
+
+ gcc_assert (CONST_INT_P (info.u.mov.value));
++ unsigned HOST_WIDE_INT value = UINTVAL (info.u.mov.value);
++
++ /* We have signed chars which can result in a sign-extended 8bit value
++ which is then emitted as an unsigned hex value, and the LLVM back end
++ assembler rejects that as being too big. */
++ if (TARGET_MACHO && (known_eq (GET_MODE_BITSIZE (info.elt_mode), 8)))
++ {
++ unsigned HOST_WIDE_INT mask = (1U << GET_MODE_BITSIZE (info.elt_mode))-1;
++ value &= mask;
++ }
+
+ if (which == AARCH64_CHECK_MOV)
+ {
+@@ -25177,16 +25826,16 @@ aarch64_output_simd_mov_immediate (rtx const_vector, unsigned width,
+ ? "msl" : "lsl");
+ if (lane_count == 1)
+ snprintf (templ, sizeof (templ), "%s\t%%d0, " HOST_WIDE_INT_PRINT_HEX,
+- mnemonic, UINTVAL (info.u.mov.value));
++ mnemonic, value);
+ else if (info.u.mov.shift)
+ snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, "
+ HOST_WIDE_INT_PRINT_HEX ", %s %d", mnemonic, lane_count,
+- element_char, UINTVAL (info.u.mov.value), shift_op,
++ element_char, value, shift_op,
+ info.u.mov.shift);
+ else
+ snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, "
+ HOST_WIDE_INT_PRINT_HEX, mnemonic, lane_count,
+- element_char, UINTVAL (info.u.mov.value));
++ element_char, value);
+ }
+ else
+ {
+@@ -25195,12 +25844,12 @@ aarch64_output_simd_mov_immediate (rtx const_vector, unsigned width,
+ if (info.u.mov.shift)
+ snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, #"
+ HOST_WIDE_INT_PRINT_DEC ", %s #%d", mnemonic, lane_count,
+- element_char, UINTVAL (info.u.mov.value), "lsl",
++ element_char, value, "lsl",
+ info.u.mov.shift);
+ else
+ snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, #"
+ HOST_WIDE_INT_PRINT_DEC, mnemonic, lane_count,
+- element_char, UINTVAL (info.u.mov.value));
++ element_char, value);
+ }
+ return templ;
+ }
+@@ -28437,7 +29086,8 @@ aarch64_libgcc_floating_mode_supported_p (scalar_float_mode mode)
+ }
+
+ /* Implement TARGET_SCALAR_MODE_SUPPORTED_P - return TRUE
+- if MODE is [BH]Fmode, and punt to the generic implementation otherwise. */
++ if MODE is [BH]Fmode, or TFmode on Mach-O, and punt to the generic
++ implementation otherwise. */
+
+ static bool
+ aarch64_scalar_mode_supported_p (scalar_mode mode)
+@@ -28445,7 +29095,7 @@ aarch64_scalar_mode_supported_p (scalar_mode mode)
+ if (DECIMAL_FLOAT_MODE_P (mode))
+ return default_decimal_float_supported_p ();
+
+- return ((mode == HFmode || mode == BFmode)
++ return ((mode == HFmode || mode == BFmode || (mode == TFmode && TARGET_MACHO))
+ ? true
+ : default_scalar_mode_supported_p (mode));
+ }
+@@ -29262,19 +29912,37 @@ aarch64_sls_emit_shared_blr_thunks (FILE *out_file)
+ continue;
+
+ const char *name = indirect_symbol_names[regnum];
+- switch_to_section (get_named_section (decl, NULL, 0));
++ /* If the target uses a unique section for this switch to it. */
++ if (DECL_SECTION_NAME (decl))
++ switch_to_section (get_named_section (decl, NULL, 0));
++ else
++ switch_to_section (text_section);
+ ASM_OUTPUT_ALIGN (out_file, 2);
+- targetm.asm_out.globalize_label (out_file, name);
++ if (!TARGET_MACHO)
++ targetm.asm_out.globalize_label (out_file, name);
++#ifdef ASM_OUTPUT_TYPE_DIRECTIVE
++ ASM_OUTPUT_TYPE_DIRECTIVE (out_file, name, "function");
++#endif
++ if (TARGET_MACHO)
++ {
++#ifdef ASM_WEAKEN_DECL
++ if (DECL_WEAK (decl))
++ ASM_WEAKEN_DECL (out_file, decl, name, 0);
++ else
++#endif
++ targetm.asm_out.globalize_decl_name (out_file, decl);
++ }
+ /* Only emits if the compiler is configured for an assembler that can
+ handle visibility directives. */
+ targetm.asm_out.assemble_visibility (decl, VISIBILITY_HIDDEN);
+- ASM_OUTPUT_TYPE_DIRECTIVE (out_file, name, "function");
+ ASM_OUTPUT_LABEL (out_file, name);
+ aarch64_sls_emit_function_stub (out_file, regnum);
+ /* Use the most conservative target to ensure it can always be used by any
+ function in the translation unit. */
+ asm_fprintf (out_file, "\tdsb\tsy\n\tisb\n");
++#ifdef ASM_DECLARE_FUNCTION_SIZE
+ ASM_DECLARE_FUNCTION_SIZE (out_file, name, decl);
++#endif
+ }
+ }
+
+@@ -30366,6 +31034,60 @@ aarch64_retrieve_sysreg (const char *regname, bool write_p, bool is128op)
+ return sysreg->encoding;
+ }
+
++#if TARGET_MACHO
++/* This handles the promotion of function return values.
++ It also handles function args under two specific curcumstances:
++ - called from combine with a register argument
++ - caller for a libcall with type == NULL.
++ The remaining cases for argument promotion are handled with access to
++ cumulative args data, below. */
++machine_mode
++aarch64_darwin_promote_fn_mode (const_tree type, machine_mode mode,
++ int *punsignedp,
++ const_tree funtype ATTRIBUTE_UNUSED,
++ int for_return ATTRIBUTE_UNUSED)
++{
++ /* With the amended use of promote using cargs, the only cases that arrive
++ here with for_return == 0 are from combine (where the value is definitely
++ in a register) and for libcalls, where type == NULL. We want to promote
++ function return values in the callee, so this becomes pretty much
++ unconditional now. */
++ if (type != NULL_TREE)
++ return promote_mode (type, mode, punsignedp);
++ return mode;
++}
++
++/* Ensure that we only promote the mode of named parms when they are passed in
++ a register. Named values passed on the stack retain their original mode and
++ alignment. */
++machine_mode
++aarch64_darwin_promote_function_mode_ca (cumulative_args_t ca,
++ function_arg_info arg,
++ const_tree funtype ATTRIBUTE_UNUSED,
++ int *punsignedp,
++ int for_return ATTRIBUTE_UNUSED)
++{
++ tree type = arg.type;
++ machine_mode mode = arg.mode;
++ machine_mode new_mode = promote_mode (type, mode, punsignedp);
++ if (new_mode == mode || arg.named == false
++ || GET_MODE_CLASS (new_mode) != MODE_INT
++ || known_gt (GET_MODE_SIZE (new_mode), 4))
++ return new_mode;
++
++ CUMULATIVE_ARGS *pcum = get_cumulative_args (ca);
++ /* Make sure that changes in assumption do not get missed. */
++ gcc_checking_assert (for_return == 0 && new_mode == SImode
++ && !pcum->aapcs_arg_processed);
++ /* We have a named integer value that fits in a reg; if there's one available
++ then promote the value. */
++ if (pcum->aapcs_ncrn < 8)
++ return new_mode;
++ return mode;
++}
++
++#endif
++
+ /* Target-specific selftests. */
+
+ #if CHECKING_P
+@@ -30571,6 +31293,15 @@ aarch64_run_selftests (void)
+ #undef TARGET_ASM_ALIGNED_SI_OP
+ #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
+
++#if TARGET_MACHO
++#undef TARGET_ASM_UNALIGNED_HI_OP
++#define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
++#undef TARGET_ASM_UNALIGNED_SI_OP
++#define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
++#undef TARGET_ASM_UNALIGNED_DI_OP
++#define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
++#endif
++
+ #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
+ #define TARGET_ASM_CAN_OUTPUT_MI_THUNK \
+ hook_bool_const_tree_hwi_hwi_const_tree_true
+@@ -30673,6 +31404,12 @@ aarch64_run_selftests (void)
+ #undef TARGET_FUNCTION_ARG_BOUNDARY
+ #define TARGET_FUNCTION_ARG_BOUNDARY aarch64_function_arg_boundary
+
++#undef TARGET_FUNCTION_ARG_BOUNDARY_CA
++#define TARGET_FUNCTION_ARG_BOUNDARY_CA aarch64_function_arg_boundary_ca
++
++#undef TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA
++#define TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA aarch64_function_arg_round_boundary_ca
++
+ #undef TARGET_FUNCTION_ARG_PADDING
+ #define TARGET_FUNCTION_ARG_PADDING aarch64_function_arg_padding
+
+@@ -31013,7 +31750,7 @@ aarch64_libgcc_floating_mode_supported_p
+
+ /* The architecture reserves bits 0 and 1 so use bit 2 for descriptors. */
+ #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
+-#define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 4
++#define TARGET_CUSTOM_FUNCTION_DESCRIPTORS AARCH64_CUSTOM_FUNCTION_TEST
+
+ #undef TARGET_HARD_REGNO_NREGS
+ #define TARGET_HARD_REGNO_NREGS aarch64_hard_regno_nregs
diff --git a/gcc14/patches/patch-gcc_config_aarch64_aarch64.h b/gcc14/patches/patch-gcc_config_aarch64_aarch64.h
new file mode 100644
index 0000000000..f310983e9d
--- /dev/null
+++ b/gcc14/patches/patch-gcc_config_aarch64_aarch64.h
@@ -0,0 +1,81 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/config/aarch64/aarch64.h
++++ gcc/config/aarch64/aarch64.h
+@@ -72,6 +72,10 @@
+ #define TARGET_SIMD (AARCH64_ISA_SIMD && AARCH64_ISA_SM_OFF)
+ #define TARGET_FLOAT (AARCH64_ISA_FP)
+
++/* If this is non-zero then generated code of the object format, ABI and
++ assembler syntax used by Darwin (Mach-O) platforms. */
++#define TARGET_MACHO 0
++
+ #define UNITS_PER_WORD 8
+
+ #define UNITS_PER_VREG 16
+@@ -149,6 +153,12 @@
+ /* Heap alignment (same as BIGGEST_ALIGNMENT and STACK_BOUNDARY). */
+ #define MALLOC_ABI_ALIGNMENT 128
+
++/* We will and with this value to test if a custom function descriptor needs
++ a static chain. The function boundary must the adjusted so that the bit
++ this represents is no longer part of the address. 0 Disables the custom
++ function descriptors. */
++#define AARCH64_CUSTOM_FUNCTION_TEST 4
++
+ /* Defined by the ABI */
+ #define WCHAR_TYPE "unsigned int"
+ #define WCHAR_TYPE_SIZE 32
+@@ -1146,6 +1156,24 @@ typedef struct
+ aapcs_reg == NULL_RTX. */
+ int aapcs_stack_size; /* The total size (in words, per 8 byte) of the
+ stack arg area so far. */
++
++ /* In the darwinpcs, items smaller than one word are packed onto the stack
++ naturally aligned. Unnamed parameters passed in a variadic call are,
++ however, aligned the same way as the AAPCS64. This means that we need to
++ pad the last named arg to the next parm boundary (and hence notice when
++ we are processing that arg). */
++ int darwinpcs_stack_bytes; /* If the argument is passed on the stack, this
++ the byte-size. */
++ int darwinpcs_sub_word_offset;/* This is the offset of this arg within a word
++ when placing smaller items for darwinpcs. */
++ int darwinpcs_sub_word_pos; /* The next byte available within the word for
++ darwinpcs. */
++ unsigned darwinpcs_arg_boundary; /* The computed argument boundary. */
++ unsigned darwinpcs_arg_padding; /* The computed argument padding. */
++ unsigned darwinpcs_n_named; /* Number of named arguments. */
++ unsigned darwinpcs_n_args_processed; /* Processed so far. */
++ bool named_p; /* Is this arg named? */
++ bool last_named_p; /* Is this the last named arg? */
+ bool silent_p; /* True if we should act silently, rather than
+ raise an error for invalid calls. */
+
+@@ -1457,8 +1485,13 @@ extern const char *aarch64_rewrite_mcpu (int argc, const char **argv);
+ #define ASM_CPU_SPEC \
+ MCPU_TO_MARCH_SPEC
+
++#ifndef SUBTARGET_EXTRA_SPECS
++#define SUBTARGET_EXTRA_SPECS
++#endif
++
+ #define EXTRA_SPECS \
+- { "asm_cpu_spec", ASM_CPU_SPEC }
++ { "asm_cpu_spec", ASM_CPU_SPEC }, \
++ SUBTARGET_EXTRA_SPECS
+
+ #define ASM_OUTPUT_POOL_EPILOGUE aarch64_asm_output_pool_epilogue
+
+@@ -1471,6 +1504,10 @@ extern GTY(()) tree aarch64_fp16_ptr_type_node;
+ bfloat16_type_node. Defined in aarch64-builtins.cc. */
+ extern GTY(()) tree aarch64_bf16_ptr_type_node;
+
++/* A pointer to the user-visible __float128 (on Mach-O). Defined in
++ aarch64-builtins.c. */
++extern GTY(()) tree aarch64_float128_ptr_type_node;
++
+ /* The generic unwind code in libgcc does not initialize the frame pointer.
+ So in order to unwind a function using a frame pointer, the very first
+ function that is unwound must save the frame pointer. That way the frame
diff --git a/gcc14/patches/patch-gcc_config_aarch64_aarch64.md b/gcc14/patches/patch-gcc_config_aarch64_aarch64.md
new file mode 100644
index 0000000000..5c4b7bd37f
--- /dev/null
+++ b/gcc14/patches/patch-gcc_config_aarch64_aarch64.md
@@ -0,0 +1,81 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/config/aarch64/aarch64.md
++++ gcc/config/aarch64/aarch64.md
+@@ -363,6 +363,7 @@
+ ;; Wraps a constant integer that should be multiplied by the number
+ ;; of quadwords in an SME vector.
+ UNSPEC_SME_VQ
++ UNSPEC_MACHOPIC_OFFSET ; Common to Mach-O ports.
+ ])
+
+ (define_c_enum "unspecv" [
+@@ -995,6 +996,37 @@
+ [(set_attr "type" "load_4")]
+ )
+
++(define_insn "prefetch_unscaled"
++ [(prefetch (match_operand:DI 0 "aarch64_unscaled_prefetch_operand" "Du")
++ (match_operand:QI 1 "const_int_operand" "")
++ (match_operand:QI 2 "const_int_operand" ""))]
++ ""
++ {
++ const char * pftype[2][4] =
++ {
++ {"prfum\\tPLDL1STRM, %0",
++ "prfum\\tPLDL3KEEP, %0",
++ "prfum\\tPLDL2KEEP, %0",
++ "prfum\\tPLDL1KEEP, %0"},
++ {"prfum\\tPSTL1STRM, %0",
++ "prfum\\tPSTL3KEEP, %0",
++ "prfum\\tPSTL2KEEP, %0",
++ "prfum\\tPSTL1KEEP, %0"},
++ };
++
++ int locality = INTVAL (operands[2]);
++
++ gcc_assert (IN_RANGE (locality, 0, 3));
++
++ /* PRFUM accepts the same addresses as a 64-bit LDR so wrap
++ the address into a DImode MEM so that aarch64_print_operand knows
++ how to print it. */
++ operands[0] = gen_rtx_MEM (DImode, operands[0]);
++ return pftype[INTVAL(operands[1])][locality];
++ }
++ [(set_attr "type" "load_4")]
++)
++
+ (define_insn "trap"
+ [(trap_if (const_int 1) (const_int 8))]
+ ""
+@@ -1447,7 +1479,7 @@
+ [w , m ; load_4 , fp , 4] ldr\t%s0, %1
+ [m , r Z; store_4 , * , 4] str\t%w1, %0
+ [m , w ; store_4 , fp , 4] str\t%s1, %0
+- [r , Usw; load_4 , * , 8] adrp\t%x0, %A1;ldr\t%w0, [%x0, %L1]
++ [r , Usw; load_4 , * , 8] << TARGET_MACHO ? \"adrp\\t%x0, %A1\;ldr\\t%w0, [%x0, %O1]\" : \"adrp\\t%x0, %A1\;ldr\\t%w0, [%x0, %L1]\";
+ [r , Usa; adr , * , 4] adr\t%x0, %c1
+ [r , Ush; adr , * , 4] adrp\t%x0, %A1
+ [w , r Z; f_mcr , fp , 4] fmov\t%s0, %w1
+@@ -1484,7 +1516,7 @@
+ [w, m ; load_8 , fp , 4] ldr\t%d0, %1
+ [m, r Z; store_8 , * , 4] str\t%x1, %0
+ [m, w ; store_8 , fp , 4] str\t%d1, %0
+- [r, Usw; load_8 , * , 8] << TARGET_ILP32 ? "adrp\t%0, %A1;ldr\t%w0, [%0, %L1]" : "adrp\t%0, %A1;ldr\t%0, [%0, %L1]";
++ [r, Usw; load_8 , * , 8] << TARGET_ILP32 ? (TARGET_MACHO ? \"adrp\\t%0, %A1\;ldr\\t%w0, [%0, %O1]\" : \"adrp\\t%0, %A1\;ldr\\t%w0, [%0, %L1]\") : (TARGET_MACHO ? \"adrp\\t%0, %A1\;ldr\\t%0, [%0, %O1]\" : \"adrp\\t%0, %A1\;ldr\\t%0, [%0, %L1]\");
+ [r, Usa; adr , * , 4] adr\t%x0, %c1
+ [r, Ush; adr , * , 4] adrp\t%x0, %A1
+ [w, r Z; f_mcr , fp , 4] fmov\t%d0, %x1
+@@ -7387,7 +7419,10 @@
+ (lo_sum:P (match_operand:P 1 "register_operand" "r")
+ (match_operand 2 "aarch64_valid_symref" "S")))]
+ ""
+- "add\\t%<w>0, %<w>1, :lo12:%c2"
++ { return TARGET_MACHO
++ ? "add\\t%<w>0, %<w>1, %J2;"
++ : "add\\t%<w>0, %<w>1, :lo12:%c2";
++ }
+ [(set_attr "type" "alu_imm")]
+ )
diff --git a/gcc14/patches/patch-gcc_config_aarch64_aarch64.opt b/gcc14/patches/patch-gcc_config_aarch64_aarch64.opt
new file mode 100644
index 0000000000..7ac169cc02
--- /dev/null
+++ b/gcc14/patches/patch-gcc_config_aarch64_aarch64.opt
@@ -0,0 +1,20 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/config/aarch64/aarch64.opt
++++ gcc/config/aarch64/aarch64.opt
+@@ -193,6 +193,13 @@ Enum(aarch64_abi) String(ilp32) Value(AARCH64_ABI_ILP32)
+ EnumValue
+ Enum(aarch64_abi) String(lp64) Value(AARCH64_ABI_LP64)
+
++EnumValue
++Enum(aarch64_abi) String(darwinpcs) Value(AARCH64_ABI_LP64)
++
++m64
++Target RejectNegative Alias(mabi=, darwinpcs)
++On Darwin for compatibility with other platform variants.
++
+ mpc-relative-literal-loads
+ Target Save Var(pcrelative_literal_loads) Init(2) Save
+ PC relative literal loads.
diff --git a/gcc14/patches/patch-gcc_config_aarch64_constraints.md b/gcc14/patches/patch-gcc_config_aarch64_constraints.md
new file mode 100644
index 0000000000..89d1bcc141
--- /dev/null
+++ b/gcc14/patches/patch-gcc_config_aarch64_constraints.md
@@ -0,0 +1,29 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/config/aarch64/constraints.md
++++ gcc/config/aarch64/constraints.md
+@@ -203,7 +203,9 @@
+ A constraint that matches a small GOT access."
+ (and (match_code "const,symbol_ref")
+ (match_test "aarch64_classify_symbolic_expression (op)
+- == SYMBOL_SMALL_GOT_4G")))
++ == SYMBOL_SMALL_GOT_4G
++ || aarch64_classify_symbolic_expression (op)
++ == SYMBOL_MO_SMALL_GOT")))
+
+ (define_constraint "Uss"
+ "@internal
+@@ -574,6 +576,11 @@
+ An address valid for a prefetch instruction."
+ (match_test "aarch64_address_valid_for_prefetch_p (op, true)"))
+
++(define_address_constraint "Du"
++ "@internal
++ An address valid for a prefetch instruction with an unscaled offset."
++ (match_test "aarch64_address_valid_for_unscaled_prefetch_p (op, true)"))
++
+ (define_constraint "vgb"
+ "@internal
+ A constraint that matches an immediate offset valid for SVE LD1B
diff --git a/gcc14/patches/patch-gcc_config_aarch64_darwin.h b/gcc14/patches/patch-gcc_config_aarch64_darwin.h
new file mode 100644
index 0000000000..48524bedc3
--- /dev/null
+++ b/gcc14/patches/patch-gcc_config_aarch64_darwin.h
@@ -0,0 +1,298 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- /dev/null
++++ gcc/config/aarch64/darwin.h
+@@ -0,0 +1,291 @@
++/* Target definitions for Arm64/Aarch64 running on macOS/iOS.
++
++Copyright The GNU Toolchain Authors.
++Contributed by Iain Sandoe.
++
++This file is part of GCC.
++
++GCC is free software; you can redistribute it and/or modify
++it under the terms of the GNU General Public License as published by
++the Free Software Foundation; either version 3, or (at your option)
++any later version.
++
++GCC is distributed in the hope that it will be useful,
++but WITHOUT ANY WARRANTY; without even the implied warranty of
++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++GNU General Public License for more details.
++
++You should have received a copy of the GNU General Public License
++along with GCC; see the file COPYING3. If not see
++<http://www.gnu.org/licenses/>. */
++
++/* Enable Mach-O bits in generic Aarch64 code. */
++#undef TARGET_MACHO
++#define TARGET_MACHO 1
++
++#undef DARWIN_ARM64
++#define DARWIN_ARM64 1
++
++/* This is used in generic code in darwin.cc (at present, we have no support
++ for the arm64_32 target). */
++#undef TARGET_64BIT
++#define TARGET_64BIT 1
++
++#undef PTRDIFF_TYPE
++#define PTRDIFF_TYPE "long int"
++
++#undef TARGET_PROMOTE_FUNCTION_MODE
++#define TARGET_PROMOTE_FUNCTION_MODE aarch64_darwin_promote_fn_mode
++
++#undef TARGET_PROMOTE_FUNCTION_MODE_CA
++#define TARGET_PROMOTE_FUNCTION_MODE_CA aarch64_darwin_promote_function_mode_ca
++
++/* NOTE that arm64_32 is a valid thing and corresponds to darwinpcs
++ and TARGET_ILP32, but we are not implementing that for now. */
++#define TARGET_OS_CPP_BUILTINS() \
++ do { \
++ builtin_define ("__LITTLE_ENDIAN__"); \
++ builtin_define ("__arm64"); \
++ builtin_define ("__arm64__"); \
++ darwin_cpp_builtins (pfile); \
++ } while (0)
++
++/* In Darwin's Arm64 ABI, chars are signed. */
++
++#undef DEFAULT_SIGNED_CHAR
++#define DEFAULT_SIGNED_CHAR 1
++
++#undef LONG_DOUBLE_TYPE_SIZE
++#define LONG_DOUBLE_TYPE_SIZE 64
++
++/* Disable custom function descriptors on Darwin (we use heap-based
++ trampolines). */
++#undef AARCH64_CUSTOM_FUNCTION_TEST
++#define AARCH64_CUSTOM_FUNCTION_TEST 0
++
++/* Non-PIE executables are forbidden by the Arm64-darwin security model;
++ remove the option from link-lines since they just produce a warning from
++ ld64 and are then ignored anyway. */
++#undef DARWIN_NOPIE_SPEC
++#define DARWIN_NOPIE_SPEC \
++" %<no-pie %<fno-pie %<fno-PIE "
++
++/* Force the default endianness and ABI flags onto the command line
++ in order to make the other specs easier to write. Match clang in
++ silently ignoring mdynamic-no-pic */
++#undef DRIVER_SELF_SPECS
++#define DRIVER_SELF_SPECS \
++"%{mbig-endian:%eDarwin platforms do not support big-endian arm64}" \
++"%{!mlittle-endian:-mlittle-endian} " \
++"%{mabi=ilp32:%eSorry, support for Darwin ilp32 arm64 is not implemented} " \
++"%{!mabi=*:-mabi=lp64} " \
++" %<mdynamic-no-pic* " \
++ MCPU_MTUNE_NATIVE_SPECS \
++ SUBTARGET_DRIVER_SELF_SPECS
++
++/* We want -fPIC by default, unless we're using -static to compile for
++ the kernel or some such. */
++
++#undef CC1_SPEC
++#define CC1_SPEC \
++"%{!mkernel:%{!static:-fPIC}} " DARWIN_CC1_SPEC
++
++#undef ASM_SPEC
++#define ASM_SPEC "-arch %(darwin_arch) %{march*} %{mtune*} "\
++ ASM_OPTIONS " %{static} " ASM_MMACOSX_VERSION_MIN_SPEC
++
++#undef ENDFILE_SPEC
++#define ENDFILE_SPEC \
++ " " TM_DESTRUCTOR
++
++/* The arch is known as 'arm64' by the system tools. */
++#define DARWIN_ARCH_SPEC "arm64"
++
++#undef SUBTARGET_EXTRA_SPECS
++#define SUBTARGET_EXTRA_SPECS \
++ DARWIN_EXTRA_SPECS \
++ { "darwin_arch", DARWIN_ARCH_SPEC }, \
++ { "darwin_crt2", "" }, \
++ { "darwin_subarch", DARWIN_ARCH_SPEC },
++
++#undef TARGET_ASM_FILE_END
++#define TARGET_ASM_FILE_END darwin_file_end
++
++/* For now, we do not give global entities any extra alignment
++ TODO: determine if we should for some optimisation level. */
++#undef DATA_ALIGNMENT
++#define DATA_ALIGNMENT(EXP, ALIGN) \
++ AARCH64_EXPAND_ALIGNMENT (false, EXP, ALIGN)
++
++/* Darwin binds locally for PIC code (the default) without which
++ we lose many in-lineing opportunities. */
++#undef TARGET_BINDS_LOCAL_P
++#define TARGET_BINDS_LOCAL_P darwin_binds_local_p
++
++/* Define the syntax of pseudo-ops, labels and comments. */
++
++#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
++/* Support for -falign-* switches. Use .p2align to ensure that code
++ sections are padded with NOP instructions, rather than zeros. */
++#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE, LOG, MAX_SKIP) \
++ do \
++ { \
++ if ((LOG) != 0) \
++ { \
++ if ((MAX_SKIP) == 0) \
++ fprintf ((FILE), "\t.p2align %d\n", (int) (LOG)); \
++ else \
++ fprintf ((FILE), "\t.p2align %d,,%d\n", \
++ (int) (LOG), (int) (MAX_SKIP)); \
++ } \
++ } while (0)
++
++#endif /* HAVE_GAS_MAX_SKIP_P2ALIGN */
++
++/* String containing the assembler's comment-starter. */
++
++#define ASM_COMMENT_START ";"
++
++/* Define the syntax of pseudo-ops, labels and comments. */
++
++#define LPREFIX "L"
++
++/* Assembler pseudos to introduce constants of various size. */
++
++#define ASM_BYTE "\t.byte\t"
++#define ASM_SHORT "\t.word\t"
++#define ASM_LONG "\t.long\t"
++#define ASM_QUAD "\t.quad\t"
++
++/* darwinpcs reserves X18. */
++
++#undef FIXED_REGISTERS
++#define FIXED_REGISTERS \
++ { \
++ 0, 0, 0, 0, 0, 0, 0, 0, /* R0 - R7 */ \
++ 0, 0, 0, 0, 0, 0, 0, 0, /* R8 - R15 */ \
++ 0, 0, 1, 0, 0, 0, 0, 0, /* R16 - R23 */ \
++ 0, 0, 0, 0, 0, 1, 0, 1, /* R24 - R30, SP */ \
++ 0, 0, 0, 0, 0, 0, 0, 0, /* V0 - V7 */ \
++ 0, 0, 0, 0, 0, 0, 0, 0, /* V8 - V15 */ \
++ 0, 0, 0, 0, 0, 0, 0, 0, /* V16 - V23 */ \
++ 0, 0, 0, 0, 0, 0, 0, 0, /* V24 - V31 */ \
++ 1, 1, 1, 1, /* SFP, AP, CC, VG */ \
++ 0, 0, 0, 0, 0, 0, 0, 0, /* P0 - P7 */ \
++ 0, 0, 0, 0, 0, 0, 0, 0, /* P8 - P15 */ \
++ 1, 1, /* FFR and FFRT */ \
++ 1, 1, 1, 1, 1, 1, 1, 1 /* Fake registers */ \
++ }
++
++/* Assign a static chain regnum. At the moment using R16 (IP0) is
++ available. */
++#undef STATIC_CHAIN_REGNUM
++#define STATIC_CHAIN_REGNUM R16_REGNUM
++
++/* Heap trampoline support in a CRT. */
++#undef DARWIN_HEAP_T_LIB
++#define DARWIN_HEAP_T_LIB " -lheapt_w "
++
++#define SUBTARGET_ENCODE_SECTION_INFO darwin_encode_section_info
++
++#undef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
++#define ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX(FILE, ENCODING, SIZE, ADDR, DONE) \
++ if (TARGET_64BIT) \
++ { \
++ if ((SIZE) == 4 && ((ENCODING) & 0x70) == DW_EH_PE_pcrel) \
++ { \
++ static unsigned got_pcr_count = 0; \
++ fprintf (FILE, "L_got_pcr%d:\n" ASM_LONG, got_pcr_count); \
++ assemble_name (FILE, XSTR (ADDR, 0)); \
++ fprintf (FILE, "@GOT-L_got_pcr%d", got_pcr_count++); \
++ goto DONE; \
++ } \
++ } \
++ else \
++ { \
++ if (ENCODING == ASM_PREFERRED_EH_DATA_FORMAT (2, 1)) \
++ { \
++ gcc_unreachable (); /* no 32b support yet.*/ \
++ goto DONE; \
++ } \
++ }
++
++#undef ASM_DECLARE_FUNCTION_NAME
++#define ASM_DECLARE_FUNCTION_NAME(STR, NAME, DECL) \
++ aarch64_darwin_declare_function_name (STR, NAME, DECL)
++
++/* Darwin assemblers support the .ident directive. */
++
++#undef TARGET_ASM_OUTPUT_IDENT
++#define TARGET_ASM_OUTPUT_IDENT default_asm_output_ident_directive
++
++/* Darwin has experimental support for section anchors on aarch64*; it is
++ not enabled by default (the -fsection-anchors is required), see below. */
++
++#undef TARGET_ASM_OUTPUT_ANCHOR
++#define TARGET_ASM_OUTPUT_ANCHOR darwin_asm_output_anchor
++
++#undef TARGET_USE_ANCHORS_FOR_SYMBOL_P
++#define TARGET_USE_ANCHORS_FOR_SYMBOL_P darwin_use_anchors_for_symbol_p
++
++#undef DARWIN_SECTION_ANCHORS
++#define DARWIN_SECTION_ANCHORS 1
++
++/* Executable stack is prohibited by the system security policy. */
++#undef HAVE_ENABLE_EXECUTE_STACK
++
++/* Pull in the stuff common to all Darwin-based platforms. */
++#define C_COMMON_OVERRIDE_OPTIONS \
++ do { \
++ SUBTARGET_C_COMMON_OVERRIDE_OPTIONS; \
++ } while (0)
++
++/* We do not have a definition for a tiny code model.
++ Section anchors are (probably) not useful with ld64 atom model so
++ default them off - this can be overridden by the user at present.
++ mdynamic-no-pic is silently ignored by clang (and not applicable
++ to this port). */
++#undef SUBTARGET_OVERRIDE_OPTIONS
++#define SUBTARGET_OVERRIDE_OPTIONS \
++ do { \
++ if (global_options.x_aarch64_cmodel_var == AARCH64_CMODEL_TINY) \
++ sorry ("code model %qs is not supported on Darwin platforms", \
++ "tiny"); \
++ if (!global_options_set.x_flag_section_anchors) \
++ flag_section_anchors = 0; \
++ target_flags &= ~MASK_MACHO_DYNAMIC_NO_PIC; \
++ } while (0); \
++ SUBSUBTARGET_OVERRIDE_OPTIONS
++
++#undef SUBTARGET_INIT_BUILTINS
++#define SUBTARGET_INIT_BUILTINS \
++ do { \
++ aarch64_builtin_decls[AARCH64_BUILTIN_CFSTRING] \
++ = darwin_init_cfstring_builtins ((AARCH64_BUILTIN_CFSTRING << AARCH64_BUILTIN_SHIFT) | AARCH64_BUILTIN_GENERAL); \
++ } while(0)
++
++/* Darwin on Arm64 uses dwarf-2. */
++#ifndef DARWIN_PREFER_DWARF
++# undef PREFERRED_DEBUGGING_TYPE
++# define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
++#endif
++
++#undef REGISTER_SUBTARGET_PRAGMAS
++#define REGISTER_SUBTARGET_PRAGMAS() DARWIN_REGISTER_TARGET_PRAGMAS()
++
++#undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
++#define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES darwin_set_default_type_attributes
++
++/* FIXME: CHECK Define the shadow offset for asan. */
++#undef SUBTARGET_SHADOW_OFFSET
++#define SUBTARGET_SHADOW_OFFSET (HOST_WIDE_INT_1 << 44)
++
++/* First available SYMBOL flag bit for use by subtargets. */
++#define SYMBOL_FLAG_SUBT_DEP (SYMBOL_FLAG_MACH_DEP)
++
++#undef ASM_OUTPUT_DEF_FROM_DECLS
++
++#undef CLEAR_INSN_CACHE
++#define CLEAR_INSN_CACHE(beg, end) \
++ extern void sys_icache_invalidate(void *start, size_t len); \
++ sys_icache_invalidate ((beg), (size_t)((end)-(beg)))
diff --git a/gcc14/patches/patch-gcc_config_aarch64_driver-aarch64.cc b/gcc14/patches/patch-gcc_config_aarch64_driver-aarch64.cc
new file mode 100644
index 0000000000..9ea7b74e63
--- /dev/null
+++ b/gcc14/patches/patch-gcc_config_aarch64_driver-aarch64.cc
@@ -0,0 +1,86 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/config/aarch64/driver-aarch64.cc
++++ gcc/config/aarch64/driver-aarch64.cc
+@@ -28,6 +28,74 @@
+ #include "aarch64-protos.h"
+ #include "aarch64-feature-deps.h"
+
++#if TARGET_MACHO
++# include <sys/types.h>
++# include <sys/sysctl.h>
++#endif
++
++
++#if TARGET_MACHO
++
++/* Default architecture to use if -mcpu=native did not detect a known CPU. */
++#define DEFAULT_ARCH "apple-m1"
++
++/* macOS does not have /proc/cpuinfo and needs a different approach,
++ based on sysctl. It is much simpler. */
++
++const char *
++host_detect_local_cpu (ATTRIBUTE_UNUSED int argc, ATTRIBUTE_UNUSED const char **argv)
++{
++ bool arch = false;
++ bool tune = false;
++ bool cpu = false;
++ const char *res = NULL;
++ uint32_t family;
++ size_t len = sizeof(family);
++
++ gcc_assert (argc);
++ if (!argv[0])
++ return NULL;
++
++ /* Are we processing -march, mtune or mcpu? */
++ arch = strcmp (argv[0], "arch") == 0;
++ if (!arch)
++ tune = strcmp (argv[0], "tune") == 0;
++ if (!arch && !tune)
++ cpu = strcmp (argv[0], "cpu") == 0;
++ if (!arch && !tune && !cpu)
++ return NULL;
++
++ sysctlbyname("hw.cpufamily", &family, &len, NULL, 0);
++
++ switch (family)
++ {
++ case 0x07d34b9f: // Vortex, Tempest
++ res = "apple-a12";
++ break;
++ case 0x573b5eec:
++ case 0x1b588bb3: // Firestorm, Icestorm
++ res = "apple-m1";
++ break;
++ case 0xda33d83d: // Blizzard, Avalanche
++ res = "apple-m2";
++ break;
++ case 0xfa33415e: // Ibiza (M3)
++ case 0x5f4dea93: // Lobos (M3 Pro)
++ case 0x72015832: // Palma (M3 Max)
++ res = "apple-m3";
++ break;
++ default:
++ res = DEFAULT_ARCH;
++ }
++
++ if (res)
++ return concat ("-m", argv[0], "=", res, NULL);
++ else
++ return NULL;
++}
++
++#else
++
+ struct aarch64_arch_extension
+ {
+ const char *ext;
+@@ -477,3 +545,4 @@ not_found:
+ }
+ }
+
++#endif
diff --git a/gcc14/patches/patch-gcc_config_aarch64_predicates.md b/gcc14/patches/patch-gcc_config_aarch64_predicates.md
new file mode 100644
index 0000000000..e2e7245d9f
--- /dev/null
+++ b/gcc14/patches/patch-gcc_config_aarch64_predicates.md
@@ -0,0 +1,31 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/config/aarch64/predicates.md
++++ gcc/config/aarch64/predicates.md
+@@ -352,9 +352,24 @@
+ (define_predicate "aarch64_prefetch_operand"
+ (match_test "aarch64_address_valid_for_prefetch_p (op, false)"))
+
++(define_predicate "aarch64_unscaled_prefetch_operand"
++ (match_test "aarch64_address_valid_for_unscaled_prefetch_p (op, false)"))
++
+ (define_predicate "aarch64_valid_symref"
+ (match_code "const, symbol_ref, label_ref")
+ {
++ if (TARGET_MACHO)
++ {
++ rtx x = op;
++ rtx offset;
++ split_const (x, &x, &offset);
++ if (GET_CODE (x) == CONST)
++ x = XEXP (x, 0);
++ if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_SALT_ADDR)
++ x = XVECEXP (x, 0, 0);
++ if (SYMBOL_REF_P (x) && INTVAL (offset) < 0)
++ return false;
++ }
+ return (aarch64_classify_symbolic_expression (op)
+ != SYMBOL_FORCE_TO_MEM);
+ })
diff --git a/gcc14/patches/patch-gcc_config_aarch64_t-aarch64-darwin b/gcc14/patches/patch-gcc_config_aarch64_t-aarch64-darwin
new file mode 100644
index 0000000000..4e37695920
--- /dev/null
+++ b/gcc14/patches/patch-gcc_config_aarch64_t-aarch64-darwin
@@ -0,0 +1,32 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- /dev/null
++++ gcc/config/aarch64/t-aarch64-darwin
+@@ -0,0 +1,25 @@
++# Machine description for AArch64 architecture.
++# Copyright (C) 2020 Free Software Foundation, Inc.
++#
++# This file is part of GCC.
++#
++# GCC is free software; you can redistribute it and/or modify it
++# under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 3, or (at your option)
++# any later version.
++#
++# GCC is distributed in the hope that it will be useful, but
++# WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++# General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with GCC; see the file COPYING3. If not see
++# <http://www.gnu.org/licenses/>.
++
++LIB1ASMSRC = aarch64/lib1funcs.asm
++LIB1ASMFUNCS = _aarch64_sync_cache_range
++
++# TODO - figure out what multilib provisions we should make for
++# a) arm64e
++# b) arm64_32
diff --git a/gcc14/patches/patch-gcc_config_arm_arm.h b/gcc14/patches/patch-gcc_config_arm_arm.h
new file mode 100644
index 0000000000..e37a9a7a87
--- /dev/null
+++ b/gcc14/patches/patch-gcc_config_arm_arm.h
@@ -0,0 +1,45 @@
+$NetBSD: patch-gcc_config_arm_arm.h,v 1.1 2024/06/28 18:35:16 wiz Exp $
+
+--- gcc/config/arm/arm.h.orig 2021-04-08 04:56:28.057740534 -0700
++++ gcc/config/arm/arm.h 2022-01-31 21:11:39.595024008 -0800
+@@ -937,6 +937,11 @@
+ #define ARM_UNWIND_INFO 0
+ #endif
+
++/* Overriden by config/arm/netbsd-eabi.h. */
++#ifndef ARM_DWARF_UNWIND_TABLES
++#define ARM_DWARF_UNWIND_TABLES 0
++#endif
++
+ /* Use r0 and r1 to pass exception handling information. */
+ #define EH_RETURN_DATA_REGNO(N) (((N) < 2) ? N : INVALID_REGNUM)
+
+@@ -948,11 +953,19 @@
+ #define ARM_TARGET2_DWARF_FORMAT DW_EH_PE_pcrel
+ #endif
+
++#if ARM_DWARF_UNWIND_TABLES
++/* DWARF unwinding uses the normal indirect/pcrel vs absptr format
++ for 32bit platforms. */
++#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
++ (flag_pic ? (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4) \
++ : DW_EH_PE_absptr)
++#else
+ /* ttype entries (the only interesting data references used)
+ use TARGET2 relocations. */
+ #define ASM_PREFERRED_EH_DATA_FORMAT(code, data) \
+ (((code) == 0 && (data) == 1 && ARM_UNWIND_INFO) ? ARM_TARGET2_DWARF_FORMAT \
+ : DW_EH_PE_absptr)
++#endif
+
+ /* The native (Norcroft) Pascal compiler for the ARM passes the static chain
+ as an invisible last argument (possible since varargs don't exist in
+@@ -2342,7 +2355,7 @@
+
+ /* -mcpu=native handling only makes sense with compiler running on
+ an ARM chip. */
+-#if defined(__arm__)
++#if defined(__arm__) && defined(__linux__)
+ extern const char *host_detect_local_cpu (int argc, const char **argv);
+ #define HAVE_LOCAL_CPU_DETECT
+ # define MCPU_MTUNE_NATIVE_FUNCTIONS \
diff --git a/gcc14/patches/patch-gcc_config_arm_bpabi.h b/gcc14/patches/patch-gcc_config_arm_bpabi.h
new file mode 100644
index 0000000000..7426da0545
--- /dev/null
+++ b/gcc14/patches/patch-gcc_config_arm_bpabi.h
@@ -0,0 +1,22 @@
+$NetBSD: patch-gcc_config_arm_bpabi.h,v 1.1 2024/06/28 18:35:16 wiz Exp $
+
+--- gcc/config/arm/bpabi.h.orig 2021-04-08 04:56:28.061740583 -0700
++++ gcc/config/arm/bpabi.h 2022-01-31 21:13:16.734263818 -0800
+@@ -24,6 +24,7 @@
+ <http://www.gnu.org/licenses/>. */
+
+ /* Use the AAPCS ABI by default. */
++#undef ARM_DEFAULT_ABI
+ #define ARM_DEFAULT_ABI ARM_ABI_AAPCS
+
+ /* Assume that AAPCS ABIs should adhere to the full BPABI. */
+@@ -107,7 +108,9 @@
+ /* The BPABI specifies the use of .{init,fini}_array. Therefore, we
+ do not want GCC to put anything into the .{init,fini} sections. */
+ #undef INIT_SECTION_ASM_OP
++#define INIT_SECTION_ASM_OP ""
+ #undef FINI_SECTION_ASM_OP
++#define FINI_SECTION_ASM_OP ""
+ #define INIT_ARRAY_SECTION_ASM_OP ARM_EABI_CTORS_SECTION_OP
+ #define FINI_ARRAY_SECTION_ASM_OP ARM_EABI_DTORS_SECTION_OP
+
diff --git a/gcc14/patches/patch-gcc_config_arm_elf.h b/gcc14/patches/patch-gcc_config_arm_elf.h
new file mode 100644
index 0000000000..87d8f55d08
--- /dev/null
+++ b/gcc14/patches/patch-gcc_config_arm_elf.h
@@ -0,0 +1,14 @@
+$NetBSD: patch-gcc_config_arm_elf.h,v 1.1 2024/06/28 18:35:16 wiz Exp $
+
+--- gcc/config/arm/elf.h.orig 2021-04-08 04:56:28.065740630 -0700
++++ gcc/config/arm/elf.h 2022-01-31 21:14:04.684223580 -0800
+@@ -147,6 +147,8 @@
+ #undef L_floatdidf
+ #undef L_floatdisf
+ #undef L_floatundidf
++/* XXXMRG: don't take this out, we need it! */
++# ifndef __NetBSD__
+ #undef L_floatundisf
++# endif
+ #endif
+-
diff --git a/gcc14/patches/patch-gcc_config_arm_netbsd-eabi.h b/gcc14/patches/patch-gcc_config_arm_netbsd-eabi.h
new file mode 100644
index 0000000000..621f4220de
--- /dev/null
+++ b/gcc14/patches/patch-gcc_config_arm_netbsd-eabi.h
@@ -0,0 +1,57 @@
+$NetBSD: patch-gcc_config_arm_netbsd-eabi.h,v 1.1 2024/06/28 18:35:16 wiz Exp $
+
+--- gcc/config/arm/netbsd-eabi.h.orig 2021-04-08 04:56:28.065740630 -0700
++++ gcc/config/arm/netbsd-eabi.h 2022-01-31 21:15:29.555403989 -0800
+@@ -49,8 +49,8 @@
+
+ #undef ARM_UNWIND_INFO
+ #define ARM_UNWIND_INFO 0
+-#undef DWARF2_UNWIND_INFO
+-#define DWARF2_UNWIND_INFO 1
++#undef ARM_DWARF_UNWIND_TABLES
++#define ARM_DWARF_UNWIND_TABLES 1
+
+ #undef TARGET_OS_CPP_BUILTINS
+ #define TARGET_OS_CPP_BUILTINS() \
+@@ -59,7 +59,7 @@
+ if (TARGET_AAPCS_BASED) \
+ TARGET_BPABI_CPP_BUILTINS(); \
+ NETBSD_OS_CPP_BUILTINS_ELF(); \
+- if (DWARF2_UNWIND_INFO) \
++ if (ARM_DWARF_UNWIND_TABLES) \
+ builtin_define ("__ARM_DWARF_EH__"); \
+ } \
+ while (0)
+@@ -81,17 +81,25 @@
+
+ #undef SUBTARGET_EXTRA_ASM_SPEC
+ #define SUBTARGET_EXTRA_ASM_SPEC \
+- "%{mabi=apcs-gnu|mabi=atpcs:-meabi=gnu} " \
++ "-matpcs %{mabi=apcs-gnu|mabi=atpcs:-meabi=gnu} " \
+ "%{fpic|fpie:-k} " \
+ "%{fPIC|fPIE:-k}"
+
++/* Default to full VFP if -mhard-float is specified. */
++#undef SUBTARGET_ASM_FLOAT_SPEC
++#define SUBTARGET_ASM_FLOAT_SPEC \
++ "%{mhard-float:%{!mfpu=*:-mfpu=vfp}} \
++ %{mfloat-abi=hard:%{!mfpu=*:-mfpu=vfp}}"
++
+ #undef SUBTARGET_EXTRA_SPECS
+ #define SUBTARGET_EXTRA_SPECS \
+ { "subtarget_extra_asm_spec", SUBTARGET_EXTRA_ASM_SPEC }, \
++ { "subtarget_asm_float_spec", SUBTARGET_ASM_FLOAT_SPEC }, \
+ { "linker_eabi_suffix", TARGET_LINKER_EABI_SUFFIX }, \
+ { "linker_emulation", TARGET_LINKER_EMULATION }, \
+ { "linker_big_emulation", TARGET_LINKER_BIG_EMULATION }, \
+ { "linker_little_emulation", TARGET_LINKER_LITTLE_EMULATION }, \
++ { "be8_link_spec", BE8_LINK_SPEC }, \
+ { "target_fix_v4bx_spec", TARGET_FIX_V4BX_SPEC }, \
+ NETBSD_SUBTARGET_EXTRA_SPECS
+
+@@ -102,4 +110,5 @@
+ "-X %{mbig-endian:-EB -m %(linker_big_emulation)} " \
+ "%{mlittle-endian:-EL -m %(linker_liitle_emulation)} " \
+ "%{!mbig-endian:%{!mlittle-endian:-m %(linker_emulation)}} " \
++ "%(be8_link_spec) " \
+ "%(target_fix_v4bx_spec) %(netbsd_link_spec)"
diff --git a/gcc14/patches/patch-gcc_config_arm_netbsd-elf.h b/gcc14/patches/patch-gcc_config_arm_netbsd-elf.h
new file mode 100644
index 0000000000..4aef964c62
--- /dev/null
+++ b/gcc14/patches/patch-gcc_config_arm_netbsd-elf.h
@@ -0,0 +1,80 @@
+$NetBSD: patch-gcc_config_arm_netbsd-elf.h,v 1.1 2024/06/28 18:35:16 wiz Exp $
+
+--- gcc/config/arm/netbsd-elf.h.orig 2023-04-26 07:09:39.000000000 +0000
++++ gcc/config/arm/netbsd-elf.h
+@@ -27,9 +27,20 @@
+
+ /* arm.h defaults to ARM6 CPU. */
+
+-/* This defaults us to little-endian. */
+-#ifndef TARGET_ENDIAN_DEFAULT
+-#define TARGET_ENDIAN_DEFAULT 0
++/* Default EABI to armv5t so that thumb shared libraries work.
++ The ARM926EH-S core is the default for armv5te, so set
++ SUBTARGET_CPU_DEFAULT to achieve this. */
++
++#define SUBTARGET_CPU_DEFAULT \
++ (ARM_DEFAULT_ABI != ARM_ABI_APCS && ARM_DEFAULT_ABI != ARM_ABI_ATPCS \
++ ? TARGET_CPU_arm926ejs : TARGET_CPU_arm6)
++
++/* TARGET_BIG_ENDIAN_DEFAULT is set in
++ config.gcc for big endian configurations. */
++#if TARGET_BIG_ENDIAN_DEFAULT
++#define TARGET_ENDIAN_DEFAULT MASK_BIG_END
++#else
++#define TARGET_ENDIAN_DEFAULT 0
+ #endif
+
+ #undef MULTILIB_DEFAULTS
+@@ -56,25 +67,28 @@
+
+ #undef SUBTARGET_EXTRA_ASM_SPEC
+ #define SUBTARGET_EXTRA_ASM_SPEC \
++ "-matpcs %{mabi=aapcs*:-meabi=5} " \
+ "%{" FPIE_OR_FPIC_SPEC ":-k}"
+
++#undef SUBTARGET_EXTRA_SPECS
++#define SUBTARGET_EXTRA_SPECS \
++ { "subtarget_extra_asm_spec", SUBTARGET_EXTRA_ASM_SPEC }, \
++ { "subtarget_asm_float_spec", SUBTARGET_ASM_FLOAT_SPEC }, \
++ NETBSD_SUBTARGET_EXTRA_SPECS
++
+ /* Default to full VFP if -mfloat-abi=hard is specified. */
+ #undef SUBTARGET_ASM_FLOAT_SPEC
+-#define SUBTARGET_ASM_FLOAT_SPEC \
+- "%{mfloat-abi=hard:{!mfpu=*:-mfpu=vfp}}"
+-
+-#undef SUBTARGET_EXTRA_SPECS
+-#define SUBTARGET_EXTRA_SPECS \
+- { "subtarget_extra_asm_spec", SUBTARGET_EXTRA_ASM_SPEC }, \
+- { "subtarget_asm_float_spec", SUBTARGET_ASM_FLOAT_SPEC }, \
+- { "netbsd_link_spec", NETBSD_LINK_SPEC_ELF }, \
+- { "netbsd_entry_point", NETBSD_ENTRY_POINT },
++#define SUBTARGET_ASM_FLOAT_SPEC \
++ "%{mhard-float:%{!mfpu=*:-mfpu=vfp}} \
++ %{mfloat-abi=hard:%{!mfpu=*:-mfpu=vfp}}"
+
+ #define NETBSD_ENTRY_POINT "__start"
+
+ #undef LINK_SPEC
+ #define LINK_SPEC \
+- "-X %{mbig-endian:-EB} %{mlittle-endian:-EL} \
++ "-X \
++ %{mbig-endian:-EB %{-mabi=aapcs*:-m armelfb_nbsd_eabi}} \
++ %{mlittle-endian:-EL %{-mabi=aapcs*:-m armelf_nbsd_eabi}} \
+ %(netbsd_link_spec)"
+
+ /* Make GCC agree with <machine/ansi.h>. */
+@@ -85,6 +99,12 @@
+ #undef PTRDIFF_TYPE
+ #define PTRDIFF_TYPE "long int"
+
++#undef INTPTR_TYPE
++#define INTPTR_TYPE PTRDIFF_TYPE
++
++#undef UINTPTR_TYPE
++#define UINTPTR_TYPE SIZE_TYPE
++
+ /* NetBSD does its profiling differently to the Acorn compiler. We
+ don't need a word following the mcount call; and to skip it
+ requires either an assembly stub or use of fomit-frame-pointer when
diff --git a/gcc14/patches/patch-gcc_config_darwin-driver.cc b/gcc14/patches/patch-gcc_config_darwin-driver.cc
new file mode 100644
index 0000000000..fb0244718f
--- /dev/null
+++ b/gcc14/patches/patch-gcc_config_darwin-driver.cc
@@ -0,0 +1,99 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/config/darwin-driver.cc.orig 2024-08-01 08:17:14.000000000 +0000
++++ gcc/config/darwin-driver.cc
+@@ -268,10 +268,13 @@ darwin_driver_init (unsigned int *decode
+ bool seenX86_64 = false;
+ bool seenPPC = false;
+ bool seenPPC64 = false;
++#if !DARWIN_ARM64
++ bool seenArm64 = false;
+ bool seenM32 = false;
+ bool seenM64 = false;
+ bool appendM32 = false;
+ bool appendM64 = false;
++#endif
+ const char *vers_string = NULL;
+ bool seen_version_min = false;
+ bool seen_sysroot_p = false;
+@@ -296,6 +299,12 @@ darwin_driver_init (unsigned int *decode
+ seenPPC = true;
+ else if (!strcmp ((*decoded_options)[i].arg, "ppc64"))
+ seenPPC64 = true;
++ else if (!strcmp ((*decoded_options)[i].arg, "arm64"))
++#if !DARWIN_ARM64
++ seenArm64 = true;
++#else
++ ; /* We accept the option, but don't need to act on it. */
++#endif
+ else
+ error ("this compiler does not support %qs",
+ (*decoded_options)[i].arg);
+@@ -309,7 +318,7 @@ darwin_driver_init (unsigned int *decode
+ --i;
+ --*decoded_options_count;
+ break;
+-
++#if !DARWIN_ARM64
+ case OPT_m32:
+ seenM32 = true;
+ break;
+@@ -317,6 +326,7 @@ darwin_driver_init (unsigned int *decode
+ case OPT_m64:
+ seenM64 = true;
+ break;
++#endif
+
+ case OPT_mmacosx_version_min_:
+ seen_version_min = true;
+@@ -366,6 +376,9 @@ darwin_driver_init (unsigned int *decode
+ if (seenPPC || seenPPC64)
+ warning (0, "this compiler does not support PowerPC"
+ " (%<-arch%> option ignored)");
++ else if (seenArm64)
++ warning (0, "this compiler does not support Arm64"
++ " (%<-arch%> option ignored)");
+ if (seenX86)
+ {
+ if (seenX86_64 || seenM64)
+@@ -389,6 +402,9 @@ darwin_driver_init (unsigned int *decode
+ if (seenX86 || seenX86_64)
+ warning (0, "this compiler does not support x86"
+ " (%<-arch%> option ignored)");
++ else if (seenArm64)
++ warning (0, "this compiler does not support Arm64"
++ " (%<-arch%> option ignored)");
+ if (seenPPC)
+ {
+ if (seenPPC64 || seenM64)
+@@ -408,12 +424,20 @@ darwin_driver_init (unsigned int *decode
+ if (! seenM64) /* Add -m64 if the User didn't. */
+ appendM64 = true;
+ }
++#elif DARWIN_ARM64
++ if (seenPPC || seenPPC64)
++ warning (0, "this compiler does not support PowerPC"
++ " (%<-arch%> option ignored)");
++ if (seenX86 || seenX86_64)
++ warning (0, "this compiler does not support x86"
++ " (%<-arch%> option ignored)");
+ #endif
+
+ /* If there is nothing else on the command line, do not add sysroot etc. */
+ if (*decoded_options_count <= 1)
+ return;
+
++#if !DARWIN_ARM64
+ if (appendM32 || appendM64)
+ {
+ ++*decoded_options_count;
+@@ -423,6 +447,7 @@ darwin_driver_init (unsigned int *decode
+ generate_option (appendM32 ? OPT_m32 : OPT_m64, NULL, 1, CL_DRIVER,
+ &(*decoded_options)[*decoded_options_count - 1]);
+ }
++#endif
+
+ if (!seen_sysroot_p)
+ {
diff --git a/gcc14/patches/patch-gcc_config_darwin-protos.h b/gcc14/patches/patch-gcc_config_darwin-protos.h
new file mode 100644
index 0000000000..dfc64fc448
--- /dev/null
+++ b/gcc14/patches/patch-gcc_config_darwin-protos.h
@@ -0,0 +1,30 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/config/darwin-protos.h
++++ gcc/config/darwin-protos.h
+@@ -86,9 +86,12 @@ extern void darwin_asm_lto_end (void);
+ extern void darwin_mark_decl_preserved (const char *);
+
+ extern tree darwin_handle_kext_attribute (tree *, tree, tree, int, bool *);
+-extern tree darwin_handle_weak_import_attribute (tree *node, tree name,
+- tree args, int flags,
+- bool * no_add_attrs);
++extern tree darwin_handle_weak_import_attribute (tree *, tree, tree, int,
++ bool *);
++extern tree darwin_handle_availability_attribute (tree *, tree, tree,
++ int, bool *);
++extern bool darwin_attribute_takes_identifier_p (const_tree);
++
+ extern void machopic_output_stub (FILE *, const char *, const char *);
+ extern void darwin_globalize_label (FILE *, const char *);
+ extern void darwin_assemble_visibility (tree, int);
+@@ -124,6 +127,7 @@ extern void darwin_enter_string_into_cfstring_table (tree);
+ extern void darwin_asm_output_anchor (rtx symbol);
+ extern bool darwin_use_anchors_for_symbol_p (const_rtx symbol);
+ extern bool darwin_kextabi_p (void);
++extern bool darwin_unreachable_traps_p (void);
+ extern void darwin_override_options (void);
+ extern void darwin_patch_builtins (void);
+ extern void darwin_rename_builtins (void);
diff --git a/gcc14/patches/patch-gcc_config_darwin.cc b/gcc14/patches/patch-gcc_config_darwin.cc
new file mode 100644
index 0000000000..22b7878783
--- /dev/null
+++ b/gcc14/patches/patch-gcc_config_darwin.cc
@@ -0,0 +1,473 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/config/darwin.cc
++++ gcc/config/darwin.cc
+@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
+ #include "cfghooks.h"
+ #include "df.h"
+ #include "memmodel.h"
++#include "c-family/c-common.h" /* enum rid. */
+ #include "tm_p.h"
+ #include "stringpool.h"
+ #include "attribs.h"
+@@ -49,6 +50,7 @@ along with GCC; see the file COPYING3. If not see
+ #include "optabs.h"
+ #include "flags.h"
+ #include "opts.h"
++#include "c-family/c-objc.h" /* for objc_method_decl(). */
+
+ /* Fix and Continue.
+
+@@ -102,6 +104,7 @@ int darwin_running_cxx;
+
+ /* Some code-gen now depends on OS major version numbers (at least). */
+ int generating_for_darwin_version ;
++unsigned long current_os_version = 0;
+
+ /* For older linkers we need to emit special sections (marked 'coalesced') for
+ for weak or single-definition items. */
+@@ -131,7 +134,7 @@ struct {
+ section * darwin_sections[NUM_DARWIN_SECTIONS];
+
+ /* While we transition to using in-tests instead of ifdef'd code. */
+-#if !HAVE_lo_sum
++#if !HAVE_lo_sum || DARWIN_ARM64
+ #define gen_macho_high(m,a,b) (a)
+ #define gen_macho_low(m,a,b,c) (a)
+ #endif
+@@ -1104,6 +1107,7 @@ machopic_legitimize_pic_address (rtx orig, machine_mode mode, rtx reg)
+ return pic_ref;
+ }
+
++#if !DARWIN_ARM64
+ /* Callbacks to output the stub or non-lazy pointers.
+ Each works on the item in *SLOT,if it has been used.
+ DATA is the FILE* for assembly output.
+@@ -1259,6 +1263,7 @@ machopic_finish (FILE *out_file)
+ machopic_indirections->traverse_noresize
+ <FILE *, machopic_output_indirection> (out_file);
+ }
++#endif
+
+ int
+ machopic_operand_p (rtx op)
+@@ -2194,6 +2199,122 @@ darwin_handle_kext_attribute (tree *node, tree name,
+ return NULL_TREE;
+ }
+
++enum version_components { MAJOR, MINOR, TINY };
++
++/* Parse a version number in x.y.z form and validate it as a macOS
++ version. Ideally, we'd put this in a common place usable by the
++ Darwin backend. */
++
++static bool
++parse_version (unsigned version_array[3], const char *version_str)
++{
++ size_t version_len;
++ char *end, last = '\0', delimiter = '.', alt_delim = '_';
++
++ if (!version_str)
++ return false;
++
++ /* Handle the odd situation in which we get STRING_CST which contain the
++ starting and ending quotes. */
++ if (version_str[0] == '"')
++ {
++ version_str++;
++ version_len = strrchr (&version_str[1], '"') - version_str;
++ last = '"';
++ }
++ else
++ version_len = strlen (version_str);
++
++ if (version_len < 1)
++ return false;
++
++ /* Version string must consist of digits and periods only. */
++ if (strspn (version_str, "0123456789._") != version_len)
++ return false;
++
++ if (!ISDIGIT (version_str[0]) || !ISDIGIT (version_str[version_len - 1]))
++ return false;
++
++ version_array[MAJOR] = strtoul (version_str, &end, 10);
++ if (*end == '_')
++ {
++ delimiter = '_';
++ alt_delim = '.';
++ }
++ version_str = end + ((*end == delimiter) ? 1 : 0);
++ if (version_array[MAJOR] == 100000)
++ return true;
++ if (version_array[MAJOR] > 99)
++ return false;
++
++ /* Version string must not contain adjacent delimiters. */
++ if (*version_str == delimiter || *version_str == alt_delim)
++ return false;
++
++ version_array[MINOR] = strtoul (version_str, &end, 10);
++ if (*end == alt_delim)
++ return false;
++ version_str = end + ((*end == delimiter) ? 1 : 0);
++ if (version_array[MINOR] > 99)
++ return false;
++
++ version_array[TINY] = strtoul (version_str, &end, 10);
++ if (version_array[TINY] > 99)
++ return false;
++
++ /* Version string must contain no more than three tokens. */
++ if (*end != last)
++ return false;
++
++ return true;
++}
++
++/* Turn a version expressed as maj.min.tiny into an unsigned long
++ integer representing the value used in macOS availability macros. */
++
++static unsigned long
++version_from_version_array (unsigned vers[3])
++{
++ unsigned long res = 0;
++ /* There seems to be a special "unknown" value. */
++ if (vers[0] == 100000)
++ return 999999;
++
++ /* Here, we follow the 'modern' / 'legacy' numbering scheme for versions. */
++ if (vers[0] > 10 || vers[1] >= 10)
++ res = vers[0] * 10000 + vers[1] * 100 + vers[2];
++ else
++ {
++ res = vers[0] * 100;
++ if (vers[1] > 9)
++ res += 90;
++ else
++ res += vers[1] * 10;
++ if (vers[2] > 9)
++ res += 9;
++ else
++ res += vers[1];
++ }
++ return res;
++}
++
++/* Extract a macOS version from an availability attribute argument. */
++
++static unsigned long
++os_version_from_avail_value (tree value)
++{
++ unsigned long res = 0;
++ unsigned vers[3] = {0,0,0};
++ if (TREE_CODE (value) == STRING_CST)
++ {
++ if (parse_version (&vers[0], TREE_STRING_POINTER (value)))
++ res = version_from_version_array (&vers[0]);
++ }
++ else
++ gcc_unreachable ();
++ return res;
++}
++
+ /* Handle a "weak_import" attribute; arguments as in
+ struct attribute_spec.handler. */
+
+@@ -2215,6 +2336,231 @@ darwin_handle_weak_import_attribute (tree *node, tree name,
+ return NULL_TREE;
+ }
+
++#define NUM_AV_OSES 13
++const char *availability_os[NUM_AV_OSES]
++ = { "macos", "macosx", "ios", "tvos", "watchos", "driverkit", "swift",
++ "maccatalyst", "macCatalyst", "xros", "visionos", "android", "zos" };
++
++#define NUM_AV_CLAUSES 6
++const char *availability_clause[NUM_AV_CLAUSES]
++ = { "unavailable", "introduced", "deprecated", "obsoleted", "message",
++ "replacement" };
++
++/* Validate and act upon the arguments to an 'availability' attribute. */
++
++tree
++darwin_handle_availability_attribute (tree *node, tree name, tree args,
++ int flags, bool * no_add_attrs)
++{
++ tree decl = *node;
++ *no_add_attrs = true;
++
++ if (!decl || (!TYPE_P (decl) && !DECL_P (decl)))
++ {
++ warning (OPT_Wattributes, "%qE attribute ignored", name);
++ return NULL_TREE;
++ }
++ else if (decl == error_mark_node)
++ return NULL_TREE;
++
++ location_t loc = DECL_SOURCE_LOCATION (decl);
++ if (args == NULL_TREE)
++ {
++ error_at (loc, "%qE attribute requires at least one argument",
++ name);
++ return NULL_TREE;
++ }
++ else if (args == error_mark_node)
++ return NULL_TREE;
++
++ /* The first argument must name a supported OS - although we could choose
++ to ignore any OS we don't recognise. */
++ gcc_checking_assert (TREE_CODE (args) == TREE_LIST);
++ tree platform = TREE_VALUE (args);
++ if (platform == error_mark_node)
++ return NULL_TREE;
++
++ gcc_checking_assert (TREE_CODE (platform) == IDENTIFIER_NODE);
++ bool platform_ok = false;
++ unsigned plat_num = 0;
++ for (; plat_num < (unsigned) NUM_AV_OSES; plat_num++)
++ if (strcmp (availability_os[plat_num], IDENTIFIER_POINTER (platform)) == 0)
++ {
++ platform_ok = true;
++ break;
++ }
++ if (!platform_ok)
++ {
++ error_at (input_location,
++ "platform %qE is not recognised for the %<availability%> "
++ "attribute", platform);
++ return NULL_TREE;
++ }
++ else if (plat_num > 1) /* We only compile for macos so far. */
++ return NULL_TREE;
++
++ /* We might be dealing with an object or type. */
++ tree target_decl = NULL_TREE;
++ tree type = NULL_TREE;
++ bool warn = false;
++ if (DECL_P (*node))
++ {
++ type = TREE_TYPE (decl);
++
++ if (TREE_CODE (decl) == TYPE_DECL
++ || TREE_CODE (decl) == PARM_DECL
++ || VAR_OR_FUNCTION_DECL_P (decl)
++ || TREE_CODE (decl) == FIELD_DECL
++ || TREE_CODE (decl) == CONST_DECL
++ /*|| objc_method_decl (TREE_CODE (decl))*/)
++ target_decl = decl;
++ else
++ warn = true;
++ }
++ else if (TYPE_P (*node))
++ type = target_decl = *node;
++ else
++ warn = true;
++
++ tree what = NULL_TREE;
++ if (warn)
++ {
++ if (type && TYPE_NAME (type))
++ {
++ if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
++ what = TYPE_NAME (*node);
++ else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
++ && DECL_NAME (TYPE_NAME (type)))
++ what = DECL_NAME (TYPE_NAME (type));
++ }
++ if (what)
++ warning (OPT_Wattributes, "%qE attribute ignored for %qE", name, what);
++ else
++ warning (OPT_Wattributes, "%qE attribute ignored", name);
++ return NULL_TREE;
++ }
++
++ /* Now we have to parse the availability clauses. */
++ tree msg = NULL_TREE;
++ tree replacement = NULL_TREE;
++ bool unavailable = false;
++ unsigned introduced = 1000;
++ unsigned deprecated = current_os_version + 1;
++ unsigned obsoleted = current_os_version + 1;
++ for (tree arg = TREE_CHAIN (args); arg; arg = TREE_CHAIN (arg))
++ {
++ tree clause_name = TREE_VALUE (arg);
++ tree clause_value = TREE_PURPOSE (arg);
++ if (clause_name == error_mark_node
++ || clause_value == error_mark_node)
++ continue;
++ unsigned clause_num = 0;
++ for (; clause_num < (unsigned) NUM_AV_CLAUSES; clause_num++)
++ if (strcmp (availability_clause[clause_num],
++ IDENTIFIER_POINTER (clause_name)) == 0)
++ break;
++ switch (clause_num)
++ {
++ default:
++ error_at (input_location,
++ "clause %qE is not recognised for the %<availability%> "
++ "attribute", clause_name);
++ break;
++ case 0:
++ unavailable = true;
++ break;
++ case 1:
++ case 2:
++ case 3:
++ if (!clause_value)
++ error_at (input_location, "%<%E=%> requires a value", clause_name);
++ else
++ {
++ unsigned version = os_version_from_avail_value (clause_value);
++ if (version == 0)
++ error_at (input_location, "the value %qE provided to %qE is "
++ "not a valid OS version", clause_value, clause_name);
++ else if (clause_num == 1)
++ introduced = version;
++ else if (clause_num == 2)
++ deprecated = version;
++ else if (clause_num == 3)
++ obsoleted = version;
++ }
++ break;
++ case 4:
++ case 5:
++ if (!clause_value || TREE_CODE (clause_value) != STRING_CST)
++ error_at (input_location, "%<%E=%> requires a string", clause_name);
++ else if (clause_num == 4)
++ msg = clause_value;
++ else
++ replacement = clause_value;
++ break;
++ }
++ }
++ /* Now figure out what to do. */
++ tree maybe_text = NULL_TREE;
++ if (replacement)
++ maybe_text = tree_cons (NULL_TREE, replacement, NULL_TREE);
++ else if (msg)
++ maybe_text = tree_cons (NULL_TREE, msg, NULL_TREE);
++
++ if (unavailable || current_os_version >= obsoleted)
++ {
++ TREE_UNAVAILABLE (*node) = true;
++ /* We do not handle the availability attribute at diagnostics-time, so
++ if we want the informational messages, then attach them to additional
++ attributes for the deprecation or unavailability. TODO; maybe we can
++ fabricate the composite here. */
++ if (maybe_text)
++ {
++ *no_add_attrs = false;
++ tree new_attr = tree_cons (get_identifier ("unavailable"),
++ maybe_text, NULL_TREE);
++ /* This is the actual consequence of the evaluation. */
++ if (TYPE_P (target_decl) && !(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
++ {
++ *node = build_variant_type_copy (*node);
++ TYPE_ATTRIBUTES (*node) = chainon (TYPE_ATTRIBUTES (*node),
++ new_attr);
++ }
++ else
++ DECL_ATTRIBUTES (*node) = chainon (DECL_ATTRIBUTES (*node),
++ new_attr);
++ }
++ }
++ else if (current_os_version > deprecated)
++ {
++ TREE_DEPRECATED (*node) = true;
++ if (maybe_text)
++ {
++ *no_add_attrs = false;
++ tree new_attr = tree_cons (get_identifier ("deprecated"),
++ maybe_text, NULL_TREE);
++ /* This is the actual consequence of the evaluation. */
++ if (TYPE_P (target_decl) && !(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
++ {
++ *node = build_variant_type_copy (*node);
++ TYPE_ATTRIBUTES (*node) = chainon (TYPE_ATTRIBUTES (*node),
++ new_attr);
++ }
++ else
++ DECL_ATTRIBUTES (*node) = chainon (DECL_ATTRIBUTES (*node),
++ new_attr);
++ }
++ }
++ else if (current_os_version < introduced)
++ *no_add_attrs = false;
++ return NULL_TREE;
++}
++
++bool
++darwin_attribute_takes_identifier_p (const_tree attr_id)
++{
++ return is_attribute_p ("availability", attr_id);
++}
++
+ /* Emit a label for an FDE, making it global and/or weak if appropriate.
+ The third parameter is nonzero if this is for exception handling.
+ The fourth parameter is nonzero if this is just a placeholder for an
+@@ -2306,6 +2652,8 @@ darwin_emit_except_table_label (FILE *file)
+ rtx
+ darwin_make_eh_symbol_indirect (rtx orig, bool ARG_UNUSED (pubvis))
+ {
++ if (DARWIN_ARM64)
++ return orig;
+ if (DARWIN_PPC == 0 && TARGET_64BIT)
+ return orig;
+
+@@ -3154,7 +3502,12 @@ darwin_file_end (void)
+ fprintf (asm_out_file, "\t.long\t0\n\t.long\t%u\n", flags);
+ }
+
++#if !DARWIN_ARM64
+ machopic_finish (asm_out_file);
++#else
++ gcc_checking_assert (!machopic_indirections);
++#endif
++
+ if (flag_apple_kext)
+ {
+ /* These sections are only used for kernel code. */
+@@ -3330,6 +3683,13 @@ darwin_kextabi_p (void) {
+ return flag_apple_kext;
+ }
+
++/* True, iff we want to map __builtin_unreachable to a trap. */
++
++bool
++darwin_unreachable_traps_p (void) {
++ return darwin_unreachable_traps;
++}
++
+ void
+ darwin_override_options (void)
+ {
+@@ -3350,7 +3710,14 @@ darwin_override_options (void)
+ generating_for_darwin_version = 8;
+
+ /* Earlier versions are not specifically accounted, until required. */
++ unsigned vers[3] = {0,0,0};
++ if (!parse_version (vers, darwin_macosx_version_min))
++ error_at (UNKNOWN_LOCATION, "how did we get a bad OS version? (%s)",
++ darwin_macosx_version_min);
++ current_os_version = version_from_version_array (vers);
+ }
++ else
++ current_os_version = 1058;
+
+ /* Some codegen needs to account for the capabilities of the target
+ linker. */
+@@ -3592,6 +3959,11 @@ darwin_override_options (void)
+
+ /* The c_dialect...() macros are not available to us here. */
+ darwin_running_cxx = (strstr (lang_hooks.name, "C++") != 0);
++
++ /* We need to consume attributes on function definitions from the the SDK
++ headers. */
++ if (!OPTION_SET_P (flag_allow_ext_attr_placement))
++ flag_allow_ext_attr_placement = true;
+ }
+
+ #if DARWIN_PPC
diff --git a/gcc14/patches/patch-gcc_config_darwin.h b/gcc14/patches/patch-gcc_config_darwin.h
new file mode 100644
index 0000000000..90a76fedb9
--- /dev/null
+++ b/gcc14/patches/patch-gcc_config_darwin.h
@@ -0,0 +1,77 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/config/darwin.h
++++ gcc/config/darwin.h
+@@ -42,6 +42,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+
+ #define DARWIN_X86 0
+ #define DARWIN_PPC 0
++#define DARWIN_ARM64 0
+
+ #define OBJECT_FORMAT_MACHO 1
+
+@@ -264,6 +265,8 @@ extern GTY(()) int darwin_ms_struct;
+ "%{weak_reference_mismatches*:\
+ -Xlinker -weak_reference_mismatches -Xlinker %*} \
+ %<weak_reference_mismatches*", \
++ "%{weak_framework*: -Xlinker -weak_framework -Xlinker %*} \
++ %<weak_framework*", \
+ "%{whyload:-Xlinker -whyload} %<whyload", \
+ "%{whatsloaded:-Xlinker -whatsloaded} %<whatsloaded", \
+ "%{w:-Xlinker -w}", \
+@@ -371,7 +374,8 @@ extern GTY(()) int darwin_ms_struct;
+ */
+
+ #define DARWIN_NOCOMPACT_UNWIND \
+-" %:version-compare(>= 10.6 mmacosx-version-min= -no_compact_unwind) "
++"%{!fuse-ld=lld: \
++ %:version-compare(>= 10.6 mmacosx-version-min= -no_compact_unwind)}"
+
+ /* In Darwin linker specs we can put -lcrt0.o and ld will search the library
+ path for crt0.o or -lcrtx.a and it will search for libcrtx.a. As for
+@@ -395,7 +399,8 @@ extern GTY(()) int darwin_ms_struct;
+ LINK_PLUGIN_SPEC \
+ "%{flto*:%<fcompare-debug*} \
+ %{flto} %{fno-lto} %{flto=*} \
+- %l " \
++ %l \
++ %{fuse-ld=*:-fuse-ld=%*} " \
+ DARWIN_PLATFORM_ID \
+ LINK_COMPRESS_DEBUG_SPEC \
+ "%X %{s} %{t} %{Z} %{u*} \
+@@ -646,6 +651,8 @@ extern GTY(()) int darwin_ms_struct;
+ #define ASM_OPTIONS "%{v} %{w:-W} %{I*}"
+ #endif
+
++#define AS_NEEDS_DASH_FOR_PIPED_INPUT
++
+ /* Default Darwin ASM_SPEC, very simple. */
+ #define ASM_SPEC \
+ "%{static} -arch %(darwin_arch) " \
+@@ -975,7 +982,12 @@ extern GTY(()) section * darwin_sections[NUM_DARWIN_SECTIONS];
+ { "apple_kext_compatibility", 0, 0, false, true, false, false, \
+ darwin_handle_kext_attribute, NULL }, \
+ { "weak_import", 0, 0, true, false, false, false, \
+- darwin_handle_weak_import_attribute, NULL }
++ darwin_handle_weak_import_attribute, NULL }, \
++ { "availability", 0, -1, true, false, false, false, \
++ darwin_handle_availability_attribute, NULL }
++
++#undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
++#define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P darwin_attribute_takes_identifier_p
+
+ /* Make local constant labels linker-visible, so that if one follows a
+ weak_global constant, ld64 will be able to separate the atoms. */
+@@ -1223,6 +1235,10 @@ void add_framework_path (char *);
+ #define TARGET_N_FORMAT_TYPES 1
+ #define TARGET_FORMAT_TYPES darwin_additional_format_types
+
++/* We want __builtin_unreachable to be expanded as a trap instruction. */
++#undef TARGET_UNREACHABLE_SHOULD_TRAP
++#define TARGET_UNREACHABLE_SHOULD_TRAP darwin_unreachable_traps_p
++
+ #ifndef USED_FOR_TARGET
+ extern void darwin_driver_init (unsigned int *,struct cl_decoded_option **);
+ #define GCC_DRIVER_HOST_INITIALIZATION \
diff --git a/gcc14/patches/patch-gcc_config_darwin.opt b/gcc14/patches/patch-gcc_config_darwin.opt
new file mode 100644
index 0000000000..034fa0e852
--- /dev/null
+++ b/gcc14/patches/patch-gcc_config_darwin.opt
@@ -0,0 +1,28 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/config/darwin.opt
++++ gcc/config/darwin.opt
+@@ -91,6 +91,10 @@ mtarget-linker
+ Target RejectNegative Joined Separate Var(darwin_target_linker) Init(LD64_VERSION)
+ -mtarget-linker <version> Specify that ld64 <version> is the toolchain linker for the current invocation.
+
++munreachable-traps
++Target Var(darwin_unreachable_traps) Init(1)
++When set (the default) this makes __builtin_unreachable render as a trap.
++
+ ; Driver options.
+
+ all_load
+@@ -381,6 +385,10 @@ unexported_symbols_list
+ Driver RejectNegative Separate
+ -unexported_symbols_list <filename> Do not export the global symbols listed in <filename>.
+
++weak_framework
++Driver RejectNegative Separate
++-weak_framework <framework> Make a weak link to the specified framework.
++
+ weak_reference_mismatches
+ Driver RejectNegative Separate
+ -weak_reference_mismatches <treatment> Specifies what to do if a symbol import conflicts between file (weak in one and not in another) the default is to treat the symbol as non-weak.
diff --git a/gcc14/patches/patch-gcc_configure b/gcc14/patches/patch-gcc_configure
new file mode 100644
index 0000000000..e0497d79ec
--- /dev/null
+++ b/gcc14/patches/patch-gcc_configure
@@ -0,0 +1,99 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/configure
++++ gcc/configure
+@@ -740,6 +740,8 @@ ORIGINAL_NM_FOR_TARGET
+ gcc_cv_nm
+ ORIGINAL_LD_GOLD_FOR_TARGET
+ ORIGINAL_LD_BFD_FOR_TARGET
++ORIGINAL_CLASSIC_LD_FOR_TARGET
++ORIGINAL_LLD_FOR_TARGET
+ ORIGINAL_LD_FOR_TARGET
+ ORIGINAL_PLUGIN_LD_FOR_TARGET
+ gcc_cv_ld
+@@ -3803,20 +3805,19 @@ gcc_gxx_libcxx_include_dir=
+
+ # Check whether --with-gxx-libcxx-include-dir was given.
+ if test "${with_gxx_libcxx_include_dir+set}" = set; then :
+- withval=$with_gxx_libcxx_include_dir; case "${withval}" in
+-yes) as_fn_error $? "bad value ${withval} given for libc++ include directory" "$LINENO" 5 ;;
+-*) gcc_gxx_libcxx_include_dir=$with_gxx_libcxx_include_dir ;;
+-esac
++ withval=$with_gxx_libcxx_include_dir; gcc_gxx_libcxx_include_dir=$with_gxx_libcxx_include_dir
+ fi
+
+
+ # --with-gxx-libcxx-include-dir controls the enabling of the -stdlib option.
+ # if --with-gxx-libcxx-include-dir is 'no' we disable the stdlib option.
++# if --with-gxx-libcxx-include-dir is 'yes' we enable the stdlib option and use
++# the default path within the installation.
+ # if --with-gxx-libcxx-include-dir is unset we enable the stdlib option
+-# based on the platform (to be available on platform versions where it is the
++# based on the platform (to be available on platform versions where it is the
+ # default for the system tools). We also use a default path within the compiler
+-# install tree.
+-# Otherwise, we use the path provided and enable the stdlib option.
++# install tree.
++# Otherwise, we use the path provided and enable the stdlib option.
+ # If both --with-sysroot and --with-gxx-libcxx-include-dir are passed, we
+ # check to see if the latter starts with the former and, upon success, compute
+ # gcc_gxx_libcxx_include_dir as relative to the sysroot.
+@@ -3824,16 +3825,20 @@ gcc_gxx_libcxx_include_dir_add_sysroot=0
+ gcc_enable_stdlib_opt=0
+ if test x${gcc_gxx_libcxx_include_dir} != x; then
+ if test x${gcc_gxx_libcxx_include_dir} = xno; then
+- # set defaults for the dir, but the option is disabled anyway.
++ # set defaults for the dir, but the option is disabled anyway.
++ gcc_gxx_libcxx_include_dir=
++ elif test x${gcc_gxx_libcxx_include_dir} = xyes; then
++ # set defaults for the dir, and enable.
+ gcc_gxx_libcxx_include_dir=
++ gcc_enable_stdlib_opt=1
+ else
+ gcc_enable_stdlib_opt=1
+ fi
+ else
+ case $target in
+ *-darwin1[1-9]* | *-darwin2*)
+- # Default this on for Darwin versions which default to libcxx,
+- # and embed the path in the compiler install so that we get a
++ # Default this on for Darwin versions which default to libcxx,
++ # and embed the path in the compiler install so that we get a
+ # self-contained toolchain.
+ gcc_enable_stdlib_opt=1
+ ;;
+@@ -21575,7 +21580,7 @@ else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+-#line 21578 "configure"
++#line 21583 "configure"
+ #include "confdefs.h"
+
+ #if HAVE_DLFCN_H
+@@ -21681,7 +21686,7 @@ else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+-#line 21684 "configure"
++#line 21689 "configure"
+ #include "confdefs.h"
+
+ #if HAVE_DLFCN_H
+@@ -25306,6 +25311,14 @@ fi
+ $as_echo "$gold_non_default" >&6; }
+
+ ORIGINAL_LD_FOR_TARGET=$gcc_cv_ld
++if test x"$ld64_flag" = x"yes"; then
++ORIGINAL_LLD_FOR_TARGET=${gcc_cv_ld}64.lld
++else
++ORIGINAL_LLD_FOR_TARGET=$gcc_cv_lld
++fi
++ORIGINAL_CLASSIC_LD_FOR_TARGET=$gcc_cv_ld-classic
++
++
+
+ case "$ORIGINAL_LD_FOR_TARGET" in
+ ./collect-ld | ./collect-ld$build_exeext) ;;
diff --git a/gcc14/patches/patch-gcc_configure.ac b/gcc14/patches/patch-gcc_configure.ac
new file mode 100644
index 0000000000..9b874f1482
--- /dev/null
+++ b/gcc14/patches/patch-gcc_configure.ac
@@ -0,0 +1,71 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/configure.ac
++++ gcc/configure.ac
+@@ -235,18 +235,17 @@ gcc_gxx_libcxx_include_dir=
+ AC_ARG_WITH(gxx-libcxx-include-dir,
+ [AS_HELP_STRING([--with-gxx-libcxx-include-dir=DIR],
+ [specifies directory to find libc++ header files])],
+-[case "${withval}" in
+-yes) AC_MSG_ERROR(bad value ${withval} given for libc++ include directory) ;;
+-*) gcc_gxx_libcxx_include_dir=$with_gxx_libcxx_include_dir ;;
+-esac])
++[gcc_gxx_libcxx_include_dir=$with_gxx_libcxx_include_dir])
+
+ # --with-gxx-libcxx-include-dir controls the enabling of the -stdlib option.
+ # if --with-gxx-libcxx-include-dir is 'no' we disable the stdlib option.
++# if --with-gxx-libcxx-include-dir is 'yes' we enable the stdlib option and use
++# the default path within the installation.
+ # if --with-gxx-libcxx-include-dir is unset we enable the stdlib option
+-# based on the platform (to be available on platform versions where it is the
++# based on the platform (to be available on platform versions where it is the
+ # default for the system tools). We also use a default path within the compiler
+-# install tree.
+-# Otherwise, we use the path provided and enable the stdlib option.
++# install tree.
++# Otherwise, we use the path provided and enable the stdlib option.
+ # If both --with-sysroot and --with-gxx-libcxx-include-dir are passed, we
+ # check to see if the latter starts with the former and, upon success, compute
+ # gcc_gxx_libcxx_include_dir as relative to the sysroot.
+@@ -254,16 +253,20 @@ gcc_gxx_libcxx_include_dir_add_sysroot=0
+ gcc_enable_stdlib_opt=0
+ if test x${gcc_gxx_libcxx_include_dir} != x; then
+ if test x${gcc_gxx_libcxx_include_dir} = xno; then
+- # set defaults for the dir, but the option is disabled anyway.
++ # set defaults for the dir, but the option is disabled anyway.
+ gcc_gxx_libcxx_include_dir=
++ elif test x${gcc_gxx_libcxx_include_dir} = xyes; then
++ # set defaults for the dir, and enable.
++ gcc_gxx_libcxx_include_dir=
++ gcc_enable_stdlib_opt=1
+ else
+ gcc_enable_stdlib_opt=1
+ fi
+ else
+ case $target in
+ *-darwin1[[1-9]]* | *-darwin2*)
+- # Default this on for Darwin versions which default to libcxx,
+- # and embed the path in the compiler install so that we get a
++ # Default this on for Darwin versions which default to libcxx,
++ # and embed the path in the compiler install so that we get a
+ # self-contained toolchain.
+ gcc_enable_stdlib_opt=1
+ ;;
+@@ -2817,7 +2820,15 @@ fi
+ AC_MSG_RESULT($gold_non_default)
+
+ ORIGINAL_LD_FOR_TARGET=$gcc_cv_ld
++if test x"$ld64_flag" = x"yes"; then
++ORIGINAL_LLD_FOR_TARGET=${gcc_cv_ld}64.lld
++else
++ORIGINAL_LLD_FOR_TARGET=$gcc_cv_lld
++fi
++ORIGINAL_CLASSIC_LD_FOR_TARGET=$gcc_cv_ld-classic
+ AC_SUBST(ORIGINAL_LD_FOR_TARGET)
++AC_SUBST(ORIGINAL_LLD_FOR_TARGET)
++AC_SUBST(ORIGINAL_CLASSIC_LD_FOR_TARGET)
+ case "$ORIGINAL_LD_FOR_TARGET" in
+ ./collect-ld | ./collect-ld$build_exeext) ;;
+ *) AC_CONFIG_FILES(collect-ld:exec-tool.in, [chmod +x collect-ld]) ;;
diff --git a/gcc14/patches/patch-gcc_cp_decl2.cc b/gcc14/patches/patch-gcc_cp_decl2.cc
new file mode 100644
index 0000000000..710fb78e85
--- /dev/null
+++ b/gcc14/patches/patch-gcc_cp_decl2.cc
@@ -0,0 +1,123 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/cp/decl2.cc
++++ gcc/cp/decl2.cc
+@@ -3839,9 +3839,8 @@ get_tls_init_fn (tree var)
+ if (!flag_extern_tls_init && DECL_EXTERNAL (var))
+ return NULL_TREE;
+
+- /* If the variable is internal, or if we can't generate aliases,
+- call the local init function directly. */
+- if (!TREE_PUBLIC (var) || !TARGET_SUPPORTS_ALIASES)
++ /* If the variable is internal call the local init function directly. */
++ if (!TREE_PUBLIC (var))
+ return get_local_tls_init_fn (DECL_SOURCE_LOCATION (var));
+
+ tree sname = mangle_tls_init_fn (var);
+@@ -4005,6 +4004,25 @@ generate_tls_wrapper (tree fn)
+ expand_or_defer_fn (finish_function (/*inline_p=*/false));
+ }
+
++/* A dummy init function to act as a weak placeholder for a (possibly non-
++ existent) dynamic init. */
++static void
++generate_tls_dummy_init (tree fn)
++{
++ tree var = DECL_BEFRIENDING_CLASSES (fn);
++ tree init_fn = get_tls_init_fn (var);
++ /* If have no init fn, or it is non-weak, then we do not need to make a
++ dummy. */
++ if (!init_fn || !lookup_attribute ("weak", DECL_ATTRIBUTES (init_fn)))
++ return;
++ start_preparsed_function (init_fn, NULL_TREE, SF_DEFAULT | SF_PRE_PARSED);
++ tree body = begin_function_body ();
++ declare_weak (init_fn);
++ finish_return_stmt (NULL_TREE);
++ finish_function_body (body);
++ expand_or_defer_fn (finish_function (/*inline_p=*/false));
++}
++
+ /* Start a global constructor or destructor function. */
+
+ static tree
+@@ -4823,22 +4841,24 @@ handle_tls_init (void)
+ finish_expr_stmt (cp_build_modify_expr (loc, guard, NOP_EXPR,
+ boolean_true_node,
+ tf_warning_or_error));
++ auto_vec<tree> direct_calls;
+ for (; vars; vars = TREE_CHAIN (vars))
+ {
+ tree var = TREE_VALUE (vars);
+ tree init = TREE_PURPOSE (vars);
+ one_static_initialization_or_destruction (/*initp=*/true, var, init);
+
+- /* Output init aliases even with -fno-extern-tls-init. */
+- if (TARGET_SUPPORTS_ALIASES && TREE_PUBLIC (var))
++ /* Output inits even with -fno-extern-tls-init.
++ We save the list here and output either an alias or a stub function
++ below. */
++ if (TREE_PUBLIC (var))
+ {
+- tree single_init_fn = get_tls_init_fn (var);
++ tree single_init_fn = get_tls_init_fn (var);
+ if (single_init_fn == NULL_TREE)
+ continue;
+- cgraph_node *alias
+- = cgraph_node::get_create (fn)->create_same_body_alias
+- (single_init_fn, fn);
+- gcc_assert (alias != NULL);
++ if (single_init_fn == fn)
++ continue;
++ direct_calls.safe_push (single_init_fn);
+ }
+ }
+
+@@ -4846,6 +4866,30 @@ handle_tls_init (void)
+ finish_if_stmt (if_stmt);
+ finish_function_body (body);
+ expand_or_defer_fn (finish_function (/*inline_p=*/false));
++
++ /* For each TLS var that we have an init function, we either emit an alias
++ between that and the tls_init, or a stub function that just calls the
++ tls_init. */
++ while (!direct_calls.is_empty())
++ {
++ tree single_init_fn = direct_calls.pop ();
++ if (TARGET_SUPPORTS_ALIASES)
++ {
++ cgraph_node *alias
++ = cgraph_node::get_create (fn)->create_same_body_alias
++ (single_init_fn, fn);
++ gcc_assert (alias != NULL);
++ }
++ else
++ {
++ start_preparsed_function (single_init_fn, NULL_TREE, SF_PRE_PARSED);
++ tree body = begin_function_body ();
++ tree r = build_call_expr (fn, 0);
++ finish_expr_stmt (r);
++ finish_function_body (body);
++ expand_or_defer_fn (finish_function (/*inline_p=*/false));
++ }
++ }
+ }
+
+ /* We're at the end of compilation, so generate any mangling aliases that
+@@ -5265,7 +5309,14 @@ c_parse_final_cleanups (void)
+ }
+
+ if (!DECL_INITIAL (decl) && decl_tls_wrapper_p (decl))
+- generate_tls_wrapper (decl);
++ {
++ generate_tls_wrapper (decl);
++ /* The wrapper might have a weak reference to an init, we provide
++ a dummy function to satisfy that here. The linker/dynamic
++ loader will override this with the actual init, if one is
++ required. */
++ generate_tls_dummy_init (decl);
++ }
+
+ if (!DECL_SAVED_TREE (decl))
+ continue;
diff --git a/gcc14/patches/patch-gcc_cp_parser.cc b/gcc14/patches/patch-gcc_cp_parser.cc
new file mode 100644
index 0000000000..e9aa1c3963
--- /dev/null
+++ b/gcc14/patches/patch-gcc_cp_parser.cc
@@ -0,0 +1,274 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/cp/parser.cc
++++ gcc/cp/parser.cc
+@@ -705,6 +705,91 @@ cp_lexer_handle_early_pragma (cp_lexer *lexer)
+ static cp_parser *cp_parser_new (cp_lexer *);
+ static GTY (()) cp_parser *the_parser;
+
++/* Context-sensitive parse-checking for clang-style attributes. */
++
++enum clang_attr_state {
++ CA_NONE = 0,
++ CA_ATTR,
++ CA_BR1, CA_BR2,
++ CA_LIST,
++ CA_LIST_ARGS,
++ CA_IS_CA,
++ CA_CA_ARGS,
++ CA_LIST_CONT
++};
++
++/* State machine tracking context of attribute lexing. */
++
++static enum clang_attr_state
++cp_lexer_attribute_state (cp_token& token, enum clang_attr_state attr_state)
++{
++ /* Implement a context-sensitive parser for clang attributes.
++ We detect __attribute__((clang_style_attribute (ARGS))) and lex the
++ args ARGS with the following differences from GNU attributes:
++ (a) number-like values are lexed as strings [this allows lexing XX.YY.ZZ
++ version numbers].
++ (b) we concatenate strings, since clang attributes allow this too. */
++ switch (attr_state)
++ {
++ case CA_NONE:
++ if (token.type == CPP_KEYWORD
++ && token.keyword == RID_ATTRIBUTE)
++ attr_state = CA_ATTR;
++ break;
++ case CA_ATTR:
++ if (token.type == CPP_OPEN_PAREN)
++ attr_state = CA_BR1;
++ else
++ attr_state = CA_NONE;
++ break;
++ case CA_BR1:
++ if (token.type == CPP_OPEN_PAREN)
++ attr_state = CA_BR2;
++ else
++ attr_state = CA_NONE;
++ break;
++ case CA_BR2:
++ if (token.type == CPP_NAME)
++ {
++ tree identifier = (token.type == CPP_KEYWORD)
++ /* For keywords, use the canonical spelling, not the
++ parsed identifier. */
++ ? ridpointers[(int) token.keyword]
++ : token.u.value;
++ identifier = canonicalize_attr_name (identifier);
++ if (attribute_clang_form_p (identifier))
++ attr_state = CA_IS_CA;
++ else
++ attr_state = CA_LIST;
++ }
++ else
++ attr_state = CA_NONE;
++ break;
++ case CA_IS_CA:
++ case CA_LIST:
++ if (token.type == CPP_COMMA)
++ attr_state = CA_BR2; /* Back to the list outer. */
++ else if (token.type == CPP_OPEN_PAREN)
++ attr_state = attr_state == CA_IS_CA ? CA_CA_ARGS
++ : CA_LIST_ARGS;
++ else
++ attr_state = CA_NONE;
++ break;
++ case CA_CA_ARGS: /* We will special-case args in this state. */
++ case CA_LIST_ARGS:
++ if (token.type == CPP_CLOSE_PAREN)
++ attr_state = CA_LIST_CONT;
++ break;
++ case CA_LIST_CONT:
++ if (token.type == CPP_COMMA)
++ attr_state = CA_BR2; /* Back to the list outer. */
++ else
++ attr_state = CA_NONE;
++ break;
++ }
++ return attr_state;
++}
++
+ /* Create a new main C++ lexer, the lexer that gets tokens from the
+ preprocessor, and also create the main parser. */
+
+@@ -721,6 +806,8 @@ cp_lexer_new_main (void)
+ c_common_no_more_pch ();
+
+ cp_lexer *lexer = cp_lexer_alloc ();
++ enum clang_attr_state attr_state = CA_NONE;
++
+ /* Put the first token in the buffer. */
+ cp_token *tok = lexer->buffer->quick_push (token);
+
+@@ -744,8 +831,14 @@ cp_lexer_new_main (void)
+ if (tok->type == CPP_PRAGMA_EOL)
+ cp_lexer_handle_early_pragma (lexer);
+
++ attr_state = cp_lexer_attribute_state (*tok, attr_state);
+ tok = vec_safe_push (lexer->buffer, cp_token ());
+- cp_lexer_get_preprocessor_token (C_LEX_STRING_NO_JOIN, tok);
++ unsigned int flags = C_LEX_STRING_NO_JOIN;
++ /* If we are processing clang-style attribute args, lex numbers as
++ potential version strings; NN .. NN.MM .. NN.MM.OO */
++ if (attr_state == CA_CA_ARGS)
++ flags |= C_LEX_NUMBER_AS_STRING;
++ cp_lexer_get_preprocessor_token (flags, tok);
+ }
+
+ lexer->next_token = lexer->buffer->address ();
+@@ -962,7 +1055,7 @@ cp_lexer_get_preprocessor_token (unsigned flags, cp_token *token)
+ {
+ static int is_extern_c = 0;
+
+- /* Get a new token from the preprocessor. */
++ /* Get a new token from the preprocessor. */
+ token->type
+ = c_lex_with_flags (&token->u.value, &token->location, &token->flags,
+ flags);
+@@ -23348,9 +23441,16 @@ cp_parser_init_declarator (cp_parser* parser,
+ "an %<asm%> specification is not allowed "
+ "on a function-definition");
+ if (attributes)
+- error_at (attributes_start_token->location,
+- "attributes are not allowed "
+- "on a function-definition");
++ {
++ /* When we are allowing attributes in this position, then add
++ them to the prefix ones. */
++ if (flag_allow_ext_attr_placement)
++ prefix_attributes = chainon (prefix_attributes, attributes);
++ else
++ error_at (attributes_start_token->location,
++ "attributes are not allowed "
++ "on a function-definition");
++ }
+ /* This is a function-definition. */
+ *function_definition_p = true;
+
+@@ -29707,6 +29807,91 @@ cp_parser_gnu_attributes_opt (cp_parser* parser)
+ return attributes;
+ }
+
++/* Parse the arguments list for a clang attribute. */
++static tree
++cp_parser_clang_attribute (cp_parser *parser, tree/*attr_id*/)
++{
++ /* Each entry can be :
++ identifier
++ identifier=N.MM.Z
++ identifier="string"
++ followed by ',' or ) for the last entry*/
++
++ matching_parens parens;
++ if (!parens.require_open (parser))
++ return NULL;
++
++ bool save_translate_strings_p = parser->translate_strings_p;
++ parser->translate_strings_p = false;
++ tree attr_args = NULL_TREE;
++ cp_token *token;
++ do
++ {
++ tree name = NULL_TREE;
++ tree value = NULL_TREE;
++
++ token = cp_lexer_peek_token (parser->lexer);
++ if (token->type == CPP_NAME)
++ name = token->u.value;
++ else if (token->type == CPP_KEYWORD)
++ name = ridpointers[(int) token->keyword];
++ else if (token->flags & NAMED_OP)
++ name = get_identifier (cpp_type2name (token->type, token->flags));
++ else
++ {
++ /* FIXME: context-sensitive for that attrib. */
++ error_at (token->location, "expected an attribute keyword");
++ cp_parser_skip_to_closing_parenthesis (parser,
++ /*recovering=*/true,
++ /*or_comma=*/false,
++ /*consume_paren=*/false);
++ attr_args = error_mark_node;
++ break;
++ }
++ cp_lexer_consume_token (parser->lexer);
++
++ if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
++ {
++ cp_lexer_consume_token (parser->lexer); /* eat the '=' */
++ if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)
++ && cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
++ {
++ token = cp_lexer_peek_token (parser->lexer);
++ if (token->type == CPP_STRING)
++ value = cp_parser_string_literal (parser, /*translate=*/false,
++ /*wide_ok=*/false);
++ else
++ {
++ value = token->u.value;
++ cp_lexer_consume_token (parser->lexer);
++ }
++ }
++ /* else value is missing. */
++ }
++ else if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)
++ && cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
++ {
++ error_at (token->location, "expected %<,%>, %<=%> or %<)%>");
++ cp_parser_skip_to_closing_parenthesis (parser,
++ /*recovering=*/true,
++ /*or_comma=*/false,
++ /*consume_paren=*/false);
++ attr_args = error_mark_node;
++ break;
++ }
++ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
++ cp_lexer_consume_token (parser->lexer);
++ tree t = tree_cons (value, name, NULL_TREE);
++ attr_args = chainon (attr_args, t);
++ } while (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN));
++
++ parser->translate_strings_p = save_translate_strings_p;
++ if (!parens.require_close (parser))
++ return error_mark_node;
++
++ return attr_args;
++}
++
+ /* Parse a GNU attribute-list.
+
+ attribute-list:
+@@ -29766,9 +29951,12 @@ cp_parser_gnu_attribute_list (cp_parser* parser, bool exactly_one /* = false */)
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+- /* If it's an `(', then parse the attribute arguments. */
+- if (token->type == CPP_OPEN_PAREN)
++ if (token->type == CPP_OPEN_PAREN
++ && attribute_clang_form_p (identifier))
++ arguments = cp_parser_clang_attribute (parser, identifier);
++ else if (token->type == CPP_OPEN_PAREN)
+ {
++ /* If it's an `(', then parse the attribute arguments. */
+ vec<tree, va_gc> *vec;
+ int attr_flag = (attribute_takes_identifier_p (identifier)
+ ? id_attr : normal_attr);
+@@ -29785,12 +29973,12 @@ cp_parser_gnu_attribute_list (cp_parser* parser, bool exactly_one /* = false */)
+ arguments = build_tree_list_vec (vec);
+ release_tree_vector (vec);
+ }
+- /* Save the arguments away. */
+- TREE_VALUE (attribute) = arguments;
+ }
+
+ if (arguments != error_mark_node)
+ {
++ /* Save the arguments away. */
++ TREE_VALUE (attribute) = arguments;
+ /* Add this attribute to the list. */
+ TREE_CHAIN (attribute) = attribute_list;
+ attribute_list = attribute;
diff --git a/gcc14/patches/patch-gcc_cumulative-args.h b/gcc14/patches/patch-gcc_cumulative-args.h
new file mode 100644
index 0000000000..5634085119
--- /dev/null
+++ b/gcc14/patches/patch-gcc_cumulative-args.h
@@ -0,0 +1,27 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- /dev/null
++++ gcc/cumulative-args.h
+@@ -0,0 +1,20 @@
++#ifndef GCC_CUMULATIVE_ARGS_H
++#define GCC_CUMULATIVE_ARGS_H
++
++#if CHECKING_P
++
++struct cumulative_args_t { void *magic; void *p; };
++
++#else /* !CHECKING_P */
++
++/* When using a GCC build compiler, we could use
++ __attribute__((transparent_union)) to get cumulative_args_t function
++ arguments passed like scalars where the ABI would mandate a less
++ efficient way of argument passing otherwise. However, that would come
++ at the cost of less type-safe !CHECKING_P compilation. */
++
++union cumulative_args_t { void *p; };
++
++#endif /* !CHECKING_P */
++
++#endif /* GCC_CUMULATIVE_ARGS_H */
diff --git a/gcc14/patches/patch-gcc_doc_invoke.texi b/gcc14/patches/patch-gcc_doc_invoke.texi
new file mode 100644
index 0000000000..daa685b57d
--- /dev/null
+++ b/gcc14/patches/patch-gcc_doc_invoke.texi
@@ -0,0 +1,54 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/doc/invoke.texi
++++ gcc/doc/invoke.texi
+@@ -732,7 +732,7 @@ Objective-C and Objective-C++ Dialects}.
+ -freg-struct-return -fshort-enums -fshort-wchar
+ -fverbose-asm -fpack-struct[=@var{n}]
+ -fleading-underscore -ftls-model=@var{model}
+--fstack-reuse=@var{reuse_level}
++-fstack-reuse=@var{reuse_level} -fstack-use-cumulative-args
+ -ftrampolines -ftrampoline-impl=@r{[}stack@r{|}heap@r{]}
+ -ftrapv -fwrapv
+ -fvisibility=@r{[}default@r{|}internal@r{|}hidden@r{|}protected@r{]}
+@@ -954,7 +954,7 @@ Objective-C and Objective-C++ Dialects}.
+ -twolevel_namespace -umbrella -undefined
+ -unexported_symbols_list -weak_reference_mismatches
+ -whatsloaded -F -gused -gfull -mmacosx-version-min=@var{version}
+--mkernel -mone-byte-bool}
++-mkernel -mone-byte-bool -munreachable-traps}
+
+ @emph{DEC Alpha Options}
+ @gccoptlist{-mno-fp-regs -msoft-float
+@@ -19132,6 +19132,17 @@ the behavior of older compilers in which temporaries' stack space is
+ not reused, the aggressive stack reuse can lead to runtime errors. This
+ option is used to control the temporary stack reuse optimization.
+
++@opindex fstack_use_cumulative_args
++@item -fstack-use-cumulative-args
++This option instructs the compiler to use the
++@code{cumulative_args_t}-based stack layout target hooks,
++@code{TARGET_FUNCTION_ARG_BOUNDARY_CA} and
++@code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA}. If a given target does
++not define these hooks, the default behaviour is to fallback to using
++the standard non-@code{_CA} variants instead. Certain targets (such as
++AArch64 Darwin) require using the more advanced @code{_CA}-based
++hooks: For these targets this option should be enabled by default.
++
+ @opindex ftrapv
+ @item -ftrapv
+ This option generates traps for signed overflow on addition, subtraction,
+@@ -25148,6 +25159,11 @@ without that switch. Using this switch may require recompiling all
+ other modules in a program, including system libraries. Use this
+ switch to conform to a non-default data model.
+
++@opindex munreachable-traps
++@item -munreachable-traps
++Causes @code{__builtin_unreachable} to be rendered as a trap. This is the
++default for all Darwin architectures.
++
+ @opindex mfix-and-continue
+ @opindex ffix-and-continue
+ @opindex findirect-data
diff --git a/gcc14/patches/patch-gcc_doc_tm.texi b/gcc14/patches/patch-gcc_doc_tm.texi
new file mode 100644
index 0000000000..9ca01ce454
--- /dev/null
+++ b/gcc14/patches/patch-gcc_doc_tm.texi
@@ -0,0 +1,63 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/doc/tm.texi
++++ gcc/doc/tm.texi
+@@ -1066,6 +1066,10 @@ also define the hook to @code{default_promote_function_mode_always_promote}
+ if you would like to apply the same rules given by @code{PROMOTE_MODE}.
+ @end deftypefn
+
++@deftypefn {Target Hook} machine_mode TARGET_PROMOTE_FUNCTION_MODE_CA (cumulative_args_t, @var{function_arg_info}, @var{const_tree}, int *@var{}, @var{int})
++Like @code{promote_function_mode}, but takes a cumulative_args pointer and a current arg to supply the input.
++@end deftypefn
++
+ @defmac PARM_BOUNDARY
+ Normal alignment required for function parameters on the stack, in
+ bits. All stack parameters receive at least this much alignment
+@@ -4471,6 +4475,16 @@ with the specified mode and type. The default hook returns
+ @code{PARM_BOUNDARY} for all arguments.
+ @end deftypefn
+
++@deftypefn {Target Hook} {unsigned int} TARGET_FUNCTION_ARG_BOUNDARY_CA (machine_mode @var{mode}, const_tree @var{type}, cumulative_args_t @var{ca})
++This is the @code{cumulative_args_t}-based version of
++@code{TARGET_FUNCTION_ARG_BOUNDARY}. Define this hook if you need more
++fine-grained control over argument alignment, e.g. depending on whether
++it is a named argument or not, or any other criteria that you choose to
++place in the @var{ca} structure.
++
++The default hook will call @code{TARGET_FUNCTION_ARG_BOUNDARY}.
++@end deftypefn
++
+ @deftypefn {Target Hook} {unsigned int} TARGET_FUNCTION_ARG_ROUND_BOUNDARY (machine_mode @var{mode}, const_tree @var{type})
+ Normally, the size of an argument is rounded up to @code{PARM_BOUNDARY},
+ which is the default value for this hook. You can define this hook to
+@@ -4478,6 +4492,16 @@ return a different value if an argument size must be rounded to a larger
+ value.
+ @end deftypefn
+
++@deftypefn {Target Hook} {unsigned int} TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA (machine_mode @var{mode}, const_tree @var{type}, cumulative_args_t @var{ca})
++This is the @code{cumulative_args_t}-based version of
++@code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY}. Define this hook if you need more
++fine-grained control over argument size rounding, e.g. depending on whether
++it is a named argument or not, or any other criteria that you choose to
++place in the @var{ca} structure.
++
++The default hook will call @code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY}.
++@end deftypefn
++
+ @defmac FUNCTION_ARG_REGNO_P (@var{regno})
+ A C expression that is nonzero if @var{regno} is the number of a hard
+ register in which function arguments are sometimes passed. This does
+@@ -12709,6 +12733,11 @@ This target hook can be used to generate a target-specific code
+ If selftests are enabled, run any selftests for this target.
+ @end deftypefn
+
++@deftypefn {Target Hook} bool TARGET_UNREACHABLE_SHOULD_TRAP (void)
++This hook should return @code{true} if the target wants @code{__builtin_unreachable} to expand to a trap or @code{abort ()}.
++ The default value is false.
++@end deftypefn
++
+ @deftypefn {Target Hook} bool TARGET_MEMTAG_CAN_TAG_ADDRESSES ()
+ True if the backend architecture naturally supports ignoring some region
+ of pointers. This feature means that @option{-fsanitize=hwaddress} can
diff --git a/gcc14/patches/patch-gcc_doc_tm.texi.in b/gcc14/patches/patch-gcc_doc_tm.texi.in
new file mode 100644
index 0000000000..3bd6a52826
--- /dev/null
+++ b/gcc14/patches/patch-gcc_doc_tm.texi.in
@@ -0,0 +1,37 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/doc/tm.texi.in
++++ gcc/doc/tm.texi.in
+@@ -949,6 +949,8 @@ applied.
+
+ @hook TARGET_PROMOTE_FUNCTION_MODE
+
++@hook TARGET_PROMOTE_FUNCTION_MODE_CA
++
+ @defmac PARM_BOUNDARY
+ Normal alignment required for function parameters on the stack, in
+ bits. All stack parameters receive at least this much alignment
+@@ -3441,8 +3443,12 @@ required.
+
+ @hook TARGET_FUNCTION_ARG_BOUNDARY
+
++@hook TARGET_FUNCTION_ARG_BOUNDARY_CA
++
+ @hook TARGET_FUNCTION_ARG_ROUND_BOUNDARY
+
++@hook TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA
++
+ @defmac FUNCTION_ARG_REGNO_P (@var{regno})
+ A C expression that is nonzero if @var{regno} is the number of a hard
+ register in which function arguments are sometimes passed. This does
+@@ -8099,6 +8105,8 @@ maintainer is familiar with.
+
+ @hook TARGET_RUN_TARGET_SELFTESTS
+
++@hook TARGET_UNREACHABLE_SHOULD_TRAP
++
+ @hook TARGET_MEMTAG_CAN_TAG_ADDRESSES
+
+ @hook TARGET_MEMTAG_TAG_SIZE
diff --git a/gcc14/patches/patch-gcc_exec-tool.in b/gcc14/patches/patch-gcc_exec-tool.in
new file mode 100644
index 0000000000..1b35c4eb0d
--- /dev/null
+++ b/gcc14/patches/patch-gcc_exec-tool.in
@@ -0,0 +1,75 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/exec-tool.in
++++ gcc/exec-tool.in
+@@ -23,6 +23,8 @@ ORIGINAL_AS_FOR_TARGET="@ORIGINAL_AS_FOR_TARGET@"
+ ORIGINAL_LD_FOR_TARGET="@ORIGINAL_LD_FOR_TARGET@"
+ ORIGINAL_LD_BFD_FOR_TARGET="@ORIGINAL_LD_BFD_FOR_TARGET@"
+ ORIGINAL_LD_GOLD_FOR_TARGET="@ORIGINAL_LD_GOLD_FOR_TARGET@"
++ORIGINAL_LLD_FOR_TARGET="@ORIGINAL_LLD_FOR_TARGET@"
++ORIGINAL_CLASSIC_LD_FOR_TARGET="@ORIGINAL_CLASSIC_LD_FOR_TARGET@"
+ ORIGINAL_PLUGIN_LD_FOR_TARGET="@ORIGINAL_PLUGIN_LD_FOR_TARGET@"
+ ORIGINAL_NM_FOR_TARGET="@ORIGINAL_NM_FOR_TARGET@"
+ ORIGINAL_DSYMUTIL_FOR_TARGET="@ORIGINAL_DSYMUTIL_FOR_TARGET@"
+@@ -39,24 +41,41 @@ case "$invoked" in
+ dir=gas
+ ;;
+ collect-ld)
+- # Check -fuse-ld=bfd and -fuse-ld=gold
+- case " $* " in
+- *\ -fuse-ld=bfd\ *)
+- original=$ORIGINAL_LD_BFD_FOR_TARGET
+- ;;
+- *\ -fuse-ld=gold\ *)
+- original=$ORIGINAL_LD_GOLD_FOR_TARGET
+- ;;
+- *)
+- # when using a linker plugin, gcc will always pass '-plugin' as the
+- # first or second option to the linker.
+- if test x"$1" = "x-plugin" || test x"$2" = "x-plugin"; then
+- original=$ORIGINAL_PLUGIN_LD_FOR_TARGET
+- else
+- original=$ORIGINAL_LD_FOR_TARGET
+- fi
+- ;;
+- esac
++ # when using a linker plugin, gcc will always pass '-plugin' as the
++ # first or second option to the linker.
++ if test x"$1" = "x-plugin" || test x"$2" = "x-plugin"; then
++ original=$ORIGINAL_PLUGIN_LD_FOR_TARGET
++ else
++ original=$ORIGINAL_LD_FOR_TARGET
++ fi
++ # Check -fuse-ld=bfd, -fuse-ld=gold and -fuse-ld=classic
++ # Remove -fuse-ld=classic from the command line
++ for arg do
++ # temporarily, remove the arg.
++ shift
++ case $arg in
++ -fuse-ld=bfd)
++ original=$ORIGINAL_LD_BFD_FOR_TARGET
++ ;;
++ -fuse-ld=gold)
++ original=$ORIGINAL_LD_GOLD_FOR_TARGET
++ ;;
++ -fuse-ld=lld)
++ original=$ORIGINAL_LLD_FOR_TARGET
++ # We want to remove this from the command line; by the slightly
++ # obtuse mechanism of not putting it back.
++ continue
++ ;;
++ -fuse-ld=classic)
++ original=$ORIGINAL_CLASSIC_LD_FOR_TARGET
++ # As for lld.
++ continue
++ ;;
++ *) ;;
++ esac
++ # if we want to keep the arg, put it back.
++ set -- "$@" "$arg"
++ done
+ prog=ld-new$exeext
+ if test "$original" = ../gold/ld-new$exeext; then
+ dir=gold
diff --git a/gcc14/patches/patch-gcc_explow.cc b/gcc14/patches/patch-gcc_explow.cc
new file mode 100644
index 0000000000..91171d04d0
--- /dev/null
+++ b/gcc14/patches/patch-gcc_explow.cc
@@ -0,0 +1,31 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/explow.cc
++++ gcc/explow.cc
+@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see
+ #include "langhooks.h"
+ #include "except.h"
+ #include "dojump.h"
++#include "calls.h"
+ #include "explow.h"
+ #include "expr.h"
+ #include "stringpool.h"
+@@ -817,6 +818,16 @@ promote_function_mode (const_tree type, machine_mode mode, int *punsignedp,
+ return mode;
+ }
+ }
++
++machine_mode
++promote_function_mode (cumulative_args_t args_so_far, function_arg_info arg,
++ const_tree funtype, int *punsignedp , int for_return)
++{
++ return targetm.calls.promote_function_mode_ca (args_so_far, arg, funtype,
++ punsignedp, for_return);
++// return promote_function_mode (arg.type, arg.mode, punsignedp, funtype, for_return);
++}
++
+ /* Return the mode to use to store a scalar of TYPE and MODE.
+ PUNSIGNEDP points to the signedness of the type and may be adjusted
+ to show what signedness to use on extension operations. */
diff --git a/gcc14/patches/patch-gcc_explow.h b/gcc14/patches/patch-gcc_explow.h
new file mode 100644
index 0000000000..18f57b30dc
--- /dev/null
+++ b/gcc14/patches/patch-gcc_explow.h
@@ -0,0 +1,31 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/explow.h
++++ gcc/explow.h
+@@ -20,6 +20,8 @@ along with GCC; see the file COPYING3. If not see
+ #ifndef GCC_EXPLOW_H
+ #define GCC_EXPLOW_H
+
++#include "calls.h" /* for cummulative args stuff. */
++
+ /* Return a memory reference like MEMREF, but which is known to have a
+ valid address. */
+ extern rtx validize_mem (rtx);
+@@ -47,8 +49,13 @@ extern rtx force_not_mem (rtx);
+
+ /* Return mode and signedness to use when an argument or result in the
+ given mode is promoted. */
+-extern machine_mode promote_function_mode (const_tree, machine_mode, int *,
+- const_tree, int);
++machine_mode promote_function_mode (const_tree, machine_mode, int *,
++ const_tree, int);
++
++/* Return mode and signedness to use when an argument or result in the
++ given mode is promoted. */
++machine_mode promote_function_mode (cumulative_args_t, function_arg_info,
++ const_tree, int *, int);
+
+ /* Return mode and signedness to use when an object in the given mode
+ is promoted. */
diff --git a/gcc14/patches/patch-gcc_function.cc b/gcc14/patches/patch-gcc_function.cc
new file mode 100644
index 0000000000..229339c413
--- /dev/null
+++ b/gcc14/patches/patch-gcc_function.cc
@@ -0,0 +1,108 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/function.cc
++++ gcc/function.cc
+@@ -58,8 +58,8 @@ along with GCC; see the file COPYING3. If not see
+ #include "varasm.h"
+ #include "except.h"
+ #include "dojump.h"
+-#include "explow.h"
+ #include "calls.h"
++#include "explow.h"
+ #include "expr.h"
+ #include "optabs-tree.h"
+ #include "output.h"
+@@ -2449,7 +2449,10 @@ assign_parm_find_data_types (struct assign_parm_data_all *all, tree parm,
+ else if (DECL_CHAIN (parm))
+ data->arg.named = 1; /* Not the last non-variadic parm. */
+ else if (targetm.calls.strict_argument_naming (all->args_so_far))
+- data->arg.named = 1; /* Only variadic ones are unnamed. */
++ {
++ data->arg.named = 1; /* Only variadic ones are unnamed. */
++ data->arg.last_named = 1;
++ }
+ else
+ data->arg.named = 0; /* Treat as variadic. */
+
+@@ -2491,9 +2494,12 @@ assign_parm_find_data_types (struct assign_parm_data_all *all, tree parm,
+
+ /* Find mode as it is passed by the ABI. */
+ unsignedp = TYPE_UNSIGNED (data->arg.type);
+- data->arg.mode
+- = promote_function_mode (data->arg.type, data->arg.mode, &unsignedp,
+- TREE_TYPE (current_function_decl), 0);
++// data->arg.mode
++// = promote_function_mode (data->arg.type, data->arg.mode, &unsignedp,
++// TREE_TYPE (current_function_decl), 0);
++ data->arg.mode = promote_function_mode (all->args_so_far, data->arg,
++ TREE_TYPE (current_function_decl),
++ &unsignedp, 0);
+ }
+
+ /* A subroutine of assign_parms. Invoke setup_incoming_varargs. */
+@@ -2506,6 +2512,7 @@ assign_parms_setup_varargs (struct assign_parm_data_all *all,
+
+ function_arg_info last_named_arg = data->arg;
+ last_named_arg.named = true;
++ last_named_arg.last_named = true;
+ targetm.calls.setup_incoming_varargs (all->args_so_far, last_named_arg,
+ &varargs_pretend_bytes, no_rtl);
+
+@@ -2614,7 +2621,9 @@ assign_parm_find_entry_rtl (struct assign_parm_data_all *all,
+
+ locate_and_pad_parm (data->arg.mode, data->arg.type, in_regs,
+ all->reg_parm_stack_space,
+- entry_parm ? data->partial : 0, current_function_decl,
++ entry_parm ? data->partial : 0,
++ all->args_so_far,
++ current_function_decl,
+ &all->stack_args_size, &data->locate);
+
+ /* Update parm_stack_boundary if this parameter is passed in the
+@@ -3921,7 +3930,8 @@ gimplify_parameters (gimple_seq *cleanup)
+ if (data.arg.pass_by_reference)
+ {
+ tree type = TREE_TYPE (data.arg.type);
+- function_arg_info orig_arg (type, data.arg.named);
++ function_arg_info orig_arg (type, data.arg.named,
++ data.arg.last_named);
+ if (reference_callee_copied (&all.args_so_far_v, orig_arg))
+ {
+ tree local, t;
+@@ -4024,6 +4034,7 @@ gimplify_parameters (gimple_seq *cleanup)
+ void
+ locate_and_pad_parm (machine_mode passed_mode, tree type, int in_regs,
+ int reg_parm_stack_space, int partial,
++ cumulative_args_t ca,
+ tree fndecl ATTRIBUTE_UNUSED,
+ struct args_size *initial_offset_ptr,
+ struct locate_and_pad_arg_data *locate)
+@@ -4061,9 +4072,23 @@ locate_and_pad_parm (machine_mode passed_mode, tree type, int in_regs,
+ ? arg_size_in_bytes (type)
+ : size_int (GET_MODE_SIZE (passed_mode)));
+ where_pad = targetm.calls.function_arg_padding (passed_mode, type);
+- boundary = targetm.calls.function_arg_boundary (passed_mode, type);
+- round_boundary = targetm.calls.function_arg_round_boundary (passed_mode,
+- type);
++
++ if (flag_stack_use_cumulative_args)
++ {
++ boundary = targetm.calls.function_arg_boundary_ca (passed_mode,
++ type,
++ ca);
++ round_boundary = targetm.calls.function_arg_round_boundary_ca
++ (passed_mode, type, ca);
++ }
++ else
++ {
++ boundary = targetm.calls.function_arg_boundary (passed_mode,
++ type);
++ round_boundary = targetm.calls.function_arg_round_boundary
++ (passed_mode, type);
++ }
++
+ locate->where_pad = where_pad;
+
+ /* Alignment can't exceed MAX_SUPPORTED_STACK_ALIGNMENT. */
diff --git a/gcc14/patches/patch-gcc_function.h b/gcc14/patches/patch-gcc_function.h
new file mode 100644
index 0000000000..20a254e6f6
--- /dev/null
+++ b/gcc14/patches/patch-gcc_function.h
@@ -0,0 +1,22 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/function.h
++++ gcc/function.h
+@@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see
+ #ifndef GCC_FUNCTION_H
+ #define GCC_FUNCTION_H
+
++#include "cumulative-args.h"
+
+ /* Stack of pending (incomplete) sequences saved by `start_sequence'.
+ Each element describes one pending sequence.
+@@ -680,6 +681,7 @@ extern bool aggregate_value_p (const_tree, const_tree);
+ extern bool use_register_for_decl (const_tree);
+ extern gimple_seq gimplify_parameters (gimple_seq *);
+ extern void locate_and_pad_parm (machine_mode, tree, int, int, int,
++ cumulative_args_t,
+ tree, struct args_size *,
+ struct locate_and_pad_arg_data *);
+ extern void generate_setjmp_warnings (void);
diff --git a/gcc14/patches/patch-gcc_ginclude_stddef.h b/gcc14/patches/patch-gcc_ginclude_stddef.h
new file mode 100644
index 0000000000..cea4667909
--- /dev/null
+++ b/gcc14/patches/patch-gcc_ginclude_stddef.h
@@ -0,0 +1,18 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/ginclude/stddef.h
++++ gcc/ginclude/stddef.h
+@@ -428,9 +428,8 @@ typedef struct {
+ /* _Float128 is defined as a basic type, so max_align_t must be
+ sufficiently aligned for it. This code must work in C++, so we
+ use __float128 here; that is only available on some
+- architectures, but only on i386 is extra alignment needed for
+- __float128. */
+-#ifdef __i386__
++ architectures. */
++#if defined(__i386__) || (__APPLE__ && __aarch64__)
+ __float128 __max_align_f128 __attribute__((__aligned__(__alignof(__float128))));
+ #endif
+ } max_align_t;
diff --git a/gcc14/patches/patch-gcc_jit_libgccjit.h b/gcc14/patches/patch-gcc_jit_libgccjit.h
new file mode 100644
index 0000000000..8c7903d782
--- /dev/null
+++ b/gcc14/patches/patch-gcc_jit_libgccjit.h
@@ -0,0 +1,16 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/jit/libgccjit.h
++++ gcc/jit/libgccjit.h
+@@ -21,6 +21,9 @@ along with GCC; see the file COPYING3. If not see
+ #define LIBGCCJIT_H
+
+ #include <stdio.h>
++#ifdef __APPLE__
++# include <sys/types.h> /* For ssize_t. */
++#endif
+
+ #ifdef __cplusplus
+ extern "C" {
diff --git a/gcc14/patches/patch-gcc_opts.cc b/gcc14/patches/patch-gcc_opts.cc
new file mode 100644
index 0000000000..335fb97e86
--- /dev/null
+++ b/gcc14/patches/patch-gcc_opts.cc
@@ -0,0 +1,14 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/opts.cc
++++ gcc/opts.cc
+@@ -3289,6 +3289,7 @@ common_handle_option (struct gcc_options *opts,
+ break;
+
+ case OPT_fuse_ld_bfd:
++ case OPT_fuse_ld_classic:
+ case OPT_fuse_ld_gold:
+ case OPT_fuse_ld_lld:
+ case OPT_fuse_ld_mold:
diff --git a/gcc14/patches/patch-gcc_target.def b/gcc14/patches/patch-gcc_target.def
new file mode 100644
index 0000000000..bfdc7e3a71
--- /dev/null
+++ b/gcc14/patches/patch-gcc_target.def
@@ -0,0 +1,74 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/target.def
++++ gcc/target.def
+@@ -4680,6 +4680,13 @@ if you would like to apply the same rules given by @code{PROMOTE_MODE}.",
+ const_tree funtype, int for_return),
+ default_promote_function_mode)
+
++DEFHOOK
++(promote_function_mode_ca,
++ "Like @code{promote_function_mode}, but takes a cumulative_args pointer \
++ and a current arg to supply the input.",
++ machine_mode, (cumulative_args_t, function_arg_info, const_tree, int *, int),
++ default_promote_function_mode_ca)
++
+ DEFHOOK
+ (promote_prototypes,
+ "This target hook returns @code{true} if an argument declared in a\n\
+@@ -5133,6 +5140,18 @@ with the specified mode and type. The default hook returns\n\
+ unsigned int, (machine_mode mode, const_tree type),
+ default_function_arg_boundary)
+
++DEFHOOK
++(function_arg_boundary_ca,
++ "This is the @code{cumulative_args_t}-based version of\n\
++@code{TARGET_FUNCTION_ARG_BOUNDARY}. Define this hook if you need more\n\
++fine-grained control over argument alignment, e.g. depending on whether\n\
++it is a named argument or not, or any other criteria that you choose to\n\
++place in the @var{ca} structure.\n\
++\n\
++The default hook will call @code{TARGET_FUNCTION_ARG_BOUNDARY}.",
++ unsigned int, (machine_mode mode, const_tree type, cumulative_args_t ca),
++ default_function_arg_boundary_ca)
++
+ DEFHOOK
+ (function_arg_round_boundary,
+ "Normally, the size of an argument is rounded up to @code{PARM_BOUNDARY},\n\
+@@ -5142,6 +5161,18 @@ value.",
+ unsigned int, (machine_mode mode, const_tree type),
+ default_function_arg_round_boundary)
+
++DEFHOOK
++(function_arg_round_boundary_ca,
++ "This is the @code{cumulative_args_t}-based version of\n\
++@code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY}. Define this hook if you need more\n\
++fine-grained control over argument size rounding, e.g. depending on whether\n\
++it is a named argument or not, or any other criteria that you choose to\n\
++place in the @var{ca} structure.\n\
++\n\
++The default hook will call @code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY}.",
++ unsigned int, (machine_mode mode, const_tree type, cumulative_args_t ca),
++ default_function_arg_round_boundary_ca)
++
+ /* Return the diagnostic message string if function without a prototype
+ is not allowed for this 'val' argument; NULL otherwise. */
+ DEFHOOK
+@@ -7389,6 +7420,16 @@ DEFHOOKPOD
+ libatomic. The default value is false.",
+ bool, false)
+
++/* This value represents whether __builtin_unreachable should be expanded
++ as a trap instruction (or an abort() if the trap is not available). */
++DEFHOOK
++(unreachable_should_trap,
++ "This hook should return @code{true} if the target wants \
++ @code{__builtin_unreachable} to expand to a trap or @code{abort ()}.\n\
++ The default value is false.",
++ bool, (void),
++ hook_bool_void_false)
++
+ /* Close the 'struct gcc_target' definition. */
+ HOOK_VECTOR_END (C90_EMPTY_HACK)
diff --git a/gcc14/patches/patch-gcc_target.h b/gcc14/patches/patch-gcc_target.h
new file mode 100644
index 0000000000..baf364267a
--- /dev/null
+++ b/gcc14/patches/patch-gcc_target.h
@@ -0,0 +1,31 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/target.h
++++ gcc/target.h
+@@ -51,22 +51,8 @@
+ #include "insn-codes.h"
+ #include "tm.h"
+ #include "hard-reg-set.h"
+-
+-#if CHECKING_P
+-
+-struct cumulative_args_t { void *magic; void *p; };
+-
+-#else /* !CHECKING_P */
+-
+-/* When using a GCC build compiler, we could use
+- __attribute__((transparent_union)) to get cumulative_args_t function
+- arguments passed like scalars where the ABI would mandate a less
+- efficient way of argument passing otherwise. However, that would come
+- at the cost of less type-safe !CHECKING_P compilation. */
+-
+-union cumulative_args_t { void *p; };
+-
+-#endif /* !CHECKING_P */
++#include "tree-core.h"
++#include "cumulative-args.h"
+
+ /* Target properties of _BitInt(N) type. _BitInt(N) is to be represented
+ as series of abi_limb_mode CEIL (N, GET_MODE_PRECISION (abi_limb_mode))
diff --git a/gcc14/patches/patch-gcc_targhooks.cc b/gcc14/patches/patch-gcc_targhooks.cc
new file mode 100644
index 0000000000..22f1c9aac9
--- /dev/null
+++ b/gcc14/patches/patch-gcc_targhooks.cc
@@ -0,0 +1,52 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/targhooks.cc
++++ gcc/targhooks.cc
+@@ -161,6 +161,15 @@ default_promote_function_mode_always_promote (const_tree type,
+ return promote_mode (type, mode, punsignedp);
+ }
+
++machine_mode
++default_promote_function_mode_ca (cumulative_args_t, function_arg_info arg,
++ const_tree funtype, int *punsignedp,
++ int for_return)
++{
++ return promote_function_mode (arg.type, arg.mode, punsignedp,
++ funtype, for_return);
++}
++
+ machine_mode
+ default_cc_modes_compatible (machine_mode m1, machine_mode m2)
+ {
+@@ -876,6 +885,14 @@ default_function_arg_boundary (machine_mode mode ATTRIBUTE_UNUSED,
+ return PARM_BOUNDARY;
+ }
+
++unsigned int
++default_function_arg_boundary_ca (machine_mode mode ATTRIBUTE_UNUSED,
++ const_tree type ATTRIBUTE_UNUSED,
++ cumulative_args_t ca ATTRIBUTE_UNUSED)
++{
++ return default_function_arg_boundary (mode, type);
++}
++
+ unsigned int
+ default_function_arg_round_boundary (machine_mode mode ATTRIBUTE_UNUSED,
+ const_tree type ATTRIBUTE_UNUSED)
+@@ -883,6 +900,14 @@ default_function_arg_round_boundary (machine_mode mode ATTRIBUTE_UNUSED,
+ return PARM_BOUNDARY;
+ }
+
++unsigned int
++default_function_arg_round_boundary_ca (machine_mode mode ATTRIBUTE_UNUSED,
++ const_tree type ATTRIBUTE_UNUSED,
++ cumulative_args_t ca ATTRIBUTE_UNUSED)
++{
++ return default_function_arg_round_boundary (mode, type);
++}
++
+ void
+ hook_void_bitmap (bitmap regs ATTRIBUTE_UNUSED)
+ {
diff --git a/gcc14/patches/patch-gcc_targhooks.h b/gcc14/patches/patch-gcc_targhooks.h
new file mode 100644
index 0000000000..3a86881599
--- /dev/null
+++ b/gcc14/patches/patch-gcc_targhooks.h
@@ -0,0 +1,29 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/targhooks.h
++++ gcc/targhooks.h
+@@ -34,6 +34,9 @@ extern machine_mode default_promote_function_mode (const_tree, machine_mode,
+ extern machine_mode default_promote_function_mode_always_promote
+ (const_tree, machine_mode, int *, const_tree, int);
+
++extern machine_mode default_promote_function_mode_ca
++ (cumulative_args_t, function_arg_info, const_tree, int *, int);
++
+ extern machine_mode default_cc_modes_compatible (machine_mode,
+ machine_mode);
+
+@@ -160,6 +163,12 @@ extern unsigned int default_function_arg_boundary (machine_mode,
+ const_tree);
+ extern unsigned int default_function_arg_round_boundary (machine_mode,
+ const_tree);
++extern unsigned int default_function_arg_boundary_ca (machine_mode,
++ const_tree,
++ cumulative_args_t ca);
++extern unsigned int default_function_arg_round_boundary_ca (machine_mode,
++ const_tree,
++ cumulative_args_t ca);
+ extern bool hook_bool_const_rtx_commutative_p (const_rtx, int);
+ extern rtx default_function_value (const_tree, const_tree, bool);
+ extern HARD_REG_SET default_zero_call_used_regs (HARD_REG_SET);
diff --git a/gcc14/patches/patch-gcc_testsuite_g++.dg_cpp0x_pr106435-b.cc b/gcc14/patches/patch-gcc_testsuite_g++.dg_cpp0x_pr106435-b.cc
new file mode 100644
index 0000000000..9cc84fd8ec
--- /dev/null
+++ b/gcc14/patches/patch-gcc_testsuite_g++.dg_cpp0x_pr106435-b.cc
@@ -0,0 +1,24 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- /dev/null
++++ gcc/testsuite/g++.dg/cpp0x/pr106435-b.cc
+@@ -0,0 +1,17 @@
++// PR c++/106435
++#include "pr106435.h"
++
++//#include <iostream>
++
++Foo::Foo() {
++ ++num_calls;
++// std::cout << "Foo::Foo(this=" << this << ")\n";
++}
++
++int Foo::func() {
++// std::cout << "Foo::func(this=" << this << ")\n";
++ return num_calls;
++}
++
++thread_local Foo Bar::foo;
++thread_local Foo Bar::baz;
diff --git a/gcc14/patches/patch-gcc_testsuite_g++.dg_cpp0x_pr106435.C b/gcc14/patches/patch-gcc_testsuite_g++.dg_cpp0x_pr106435.C
new file mode 100644
index 0000000000..0c50099e41
--- /dev/null
+++ b/gcc14/patches/patch-gcc_testsuite_g++.dg_cpp0x_pr106435.C
@@ -0,0 +1,27 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- /dev/null
++++ gcc/testsuite/g++.dg/cpp0x/pr106435.C
+@@ -0,0 +1,20 @@
++// PR c++/106435
++// { dg-do run { target c++11 } }
++// { dg-additional-sources "pr106435-b.cc" }
++
++#include "pr106435.h"
++
++int num_calls = 0;
++
++extern "C" __attribute__((__noreturn__)) void abort();
++
++thread_local Foo Bar::bat;
++
++int main() {
++ int v = Bar::foo.func();
++ if (v != 2)
++ abort();
++ v = Bar::bat.func();
++ if (v != 3)
++ abort();
++}
diff --git a/gcc14/patches/patch-gcc_testsuite_g++.dg_cpp0x_pr106435.h b/gcc14/patches/patch-gcc_testsuite_g++.dg_cpp0x_pr106435.h
new file mode 100644
index 0000000000..c9caf4c80b
--- /dev/null
+++ b/gcc14/patches/patch-gcc_testsuite_g++.dg_cpp0x_pr106435.h
@@ -0,0 +1,21 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- /dev/null
++++ gcc/testsuite/g++.dg/cpp0x/pr106435.h
+@@ -0,0 +1,14 @@
++// PR c++/106435
++#pragma once
++
++extern int num_calls;
++struct Foo {
++ Foo();
++ int func();
++};
++
++struct Bar {
++ thread_local static Foo foo;
++ thread_local static Foo baz;
++ thread_local static Foo bat;
++};
diff --git a/gcc14/patches/patch-gcc_testsuite_g++.target_aarch64_float128-darwin-1.C b/gcc14/patches/patch-gcc_testsuite_g++.target_aarch64_float128-darwin-1.C
new file mode 100644
index 0000000000..53414a2d97
--- /dev/null
+++ b/gcc14/patches/patch-gcc_testsuite_g++.target_aarch64_float128-darwin-1.C
@@ -0,0 +1,48 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- /dev/null
++++ gcc/testsuite/g++.target/aarch64/float128-darwin-1.C
+@@ -0,0 +1,41 @@
++/* { dg-do run { target { aarch64*-*-darwin* } } } */
++/* { dg-options "-std=c++11 -std=gnu++98" } */
++
++#include <limits>
++#include <string>
++#include <typeinfo>
++
++void foo ()
++{
++ float x1 = 1.0q;
++ double x2 = 1.0q;
++ long double x3 = 1.0q;
++
++ _Float128 w1 = 0;
++ __float128 w2 = 0;
++
++ float y1 = w1; // { dg-warning "with greater conversion rank" }
++ double y2 = w1; // { dg-warning "with greater conversion rank" }
++ long double y3 = w1; // { dg-warning "with greater conversion rank" }
++
++ float z1 = w2;
++ double z2 = w2;
++ long double z3 = w2;
++}
++
++int main ()
++{
++ // Check the correct mangling of floating-point types
++ if (typeid(float).name() != std::string("f"))
++ __builtin_abort();
++ if (typeid(double).name() != std::string("d"))
++ __builtin_abort();
++ if (typeid(long double).name() != std::string("e"))
++ __builtin_abort();
++ if (typeid(__float128).name() != std::string("g"))
++ __builtin_abort();
++ if (typeid(_Float128).name() != std::string("DF128_"))
++ __builtin_abort();
++ if (typeid(1.0q).name() != std::string("g"))
++ __builtin_abort();
++}
diff --git a/gcc14/patches/patch-gcc_testsuite_gcc.target_aarch64_darwin_float128-01.c b/gcc14/patches/patch-gcc_testsuite_gcc.target_aarch64_darwin_float128-01.c
new file mode 100644
index 0000000000..178622510f
--- /dev/null
+++ b/gcc14/patches/patch-gcc_testsuite_gcc.target_aarch64_darwin_float128-01.c
@@ -0,0 +1,55 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- /dev/null
++++ gcc/testsuite/gcc.target/aarch64/darwin/float128-01.c
+@@ -0,0 +1,48 @@
++/* { dg-do run } */
++/* we need this for _Float128. */
++/* { dg-options "-std=gnu99 " } */
++/* { dg-additional-options "-Wfloat-conversion" } */
++
++float f1 (__float128 z1, _Float128 z2)
++{
++ float x, y;
++ x = z1; /* { dg-warning "conversion from '_Float128' to 'float'" } */
++ y = z2; /* { dg-warning "conversion from '_Float128' to 'float'" } */
++ return x + y;
++}
++
++__float128 f2 () {
++ float f = 0.q;
++ return f;
++}
++
++_Float128 f3 () {
++ float f = 0.q;
++ return f;
++}
++
++int main ()
++{
++ __float128 x1 = __builtin_huge_valq ();
++ __float128 x2 = __builtin_infq ();
++
++ _Float128 y1 = __builtin_huge_valq ();
++ _Float128 y2 = __builtin_infq ();
++
++ if (!__builtin_isinf (x1))
++ __builtin_abort();
++ if (!__builtin_isinf (x2))
++ __builtin_abort();
++
++ if (!__builtin_isinf (y1))
++ __builtin_abort();
++ if (!__builtin_isinf (y2))
++ __builtin_abort();
++
++ if (x1 != x2)
++ __builtin_abort();
++ if (y1 != y2)
++ __builtin_abort();
++
++ return 0;
++}
diff --git a/gcc14/patches/patch-gcc_testsuite_gcc.target_aarch64_darwin_float128-02.c b/gcc14/patches/patch-gcc_testsuite_gcc.target_aarch64_darwin_float128-02.c
new file mode 100644
index 0000000000..c86795efc6
--- /dev/null
+++ b/gcc14/patches/patch-gcc_testsuite_gcc.target_aarch64_darwin_float128-02.c
@@ -0,0 +1,108 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- /dev/null
++++ gcc/testsuite/gcc.target/aarch64/darwin/float128-02.c
+@@ -0,0 +1,101 @@
++/* { dg-do run } */
++/* we need this for _Float128. */
++/* { dg-options "-std=gnu99 " } */
++
++void test (__float128 z1, __float128 z2, __float128 z3, __float128 z4)
++{
++ __float128 w;
++
++ if (!__builtin_isinf (z1))
++ __builtin_abort();
++ if (__builtin_isnan (z1))
++ __builtin_abort();
++ if (__builtin_isfinite (z1))
++ __builtin_abort();
++ if (__builtin_isnormal (z1))
++ __builtin_abort();
++ if (__builtin_signbit (z1))
++ __builtin_abort();
++
++ if (__builtin_isinf (z2))
++ __builtin_abort();
++ if (!__builtin_isnan (z2))
++ __builtin_abort();
++ if (__builtin_isfinite (z2))
++ __builtin_abort();
++ if (__builtin_isnormal (z2))
++ __builtin_abort();
++ if (__builtin_signbit (z2))
++ __builtin_abort();
++
++ if (__builtin_isinf (z3))
++ __builtin_abort();
++ if (!__builtin_isnan (z3))
++ __builtin_abort();
++ if (__builtin_isfinite (z3))
++ __builtin_abort();
++ if (__builtin_isnormal (z3))
++ __builtin_abort();
++ if (__builtin_signbit (z3))
++ __builtin_abort();
++
++ if (__builtin_isinf (z4))
++ __builtin_abort();
++ if (__builtin_isnan (z4))
++ __builtin_abort();
++ if (!__builtin_isfinite (z4))
++ __builtin_abort();
++ if (!__builtin_isnormal (z4))
++ __builtin_abort();
++ if (__builtin_signbit (z4))
++ __builtin_abort();
++
++ w = __builtin_copysignq (z1, -z4);
++ if (!__builtin_signbit (w))
++ __builtin_abort();
++
++ w = __builtin_copysignq (z2, -z4);
++ if (!__builtin_signbit (w))
++ __builtin_abort();
++
++ w = __builtin_copysignq (z3, -z4);
++ if (!__builtin_signbit (w))
++ __builtin_abort();
++
++ w = __builtin_copysignq (z4, -z4);
++ if (!__builtin_signbit (w))
++ __builtin_abort();
++
++ w = __builtin_copysignq (z1, -z4);
++ w = __builtin_fabsq (w);
++ if (__builtin_signbit (w))
++ __builtin_abort();
++
++ w = __builtin_copysignq (z2, -z4);
++ w = __builtin_fabsq (w);
++ if (__builtin_signbit (w))
++ __builtin_abort();
++
++ w = __builtin_copysignq (z3, -z4);
++ w = __builtin_fabsq (w);
++ if (__builtin_signbit (w))
++ __builtin_abort();
++
++ w = __builtin_copysignq (z4, -z4);
++ w = __builtin_fabsq (w);
++ if (__builtin_signbit (w))
++ __builtin_abort();
++
++}
++
++int main ()
++{
++ __float128 x1 = __builtin_infq ();
++ __float128 x2 = __builtin_nanq ("");
++ __float128 x3 = __builtin_nansq ("");
++ __float128 x4 = 41.1094721q;
++
++ test (x1, x2, x3, x4);
++
++ return 0;
++}
diff --git a/gcc14/patches/patch-gcc_testsuite_gcc.target_aarch64_sme_aarch64-sme.exp b/gcc14/patches/patch-gcc_testsuite_gcc.target_aarch64_sme_aarch64-sme.exp
new file mode 100644
index 0000000000..4971384a84
--- /dev/null
+++ b/gcc14/patches/patch-gcc_testsuite_gcc.target_aarch64_sme_aarch64-sme.exp
@@ -0,0 +1,17 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- gcc/testsuite/gcc.target/aarch64/sme/aarch64-sme.exp
++++ gcc/testsuite/gcc.target/aarch64/sme/aarch64-sme.exp
+@@ -24,6 +24,11 @@ if {![istarget aarch64*-*-*] } {
+ return
+ }
+
++# Exit immediately if this is Darwin (for now).
++if {[istarget *-*-darwin*] } {
++ return
++}
++
+ # Load support procs.
+ load_lib gcc-dg.exp
diff --git a/gcc14/patches/patch-isl_configure b/gcc14/patches/patch-isl_configure
new file mode 100644
index 0000000000..89d5d08ba2
--- /dev/null
+++ b/gcc14/patches/patch-isl_configure
@@ -0,0 +1,24 @@
+$NetBSD: patch-isl_configure,v 1.1 2024/06/28 18:35:16 wiz Exp $
+
+Fix unportable test(1) operator.
+
+--- isl/configure.orig 2021-04-26 09:13:19.000000000 +0000
++++ isl/configure
+@@ -20657,7 +20657,7 @@ else
+ HAVE_CXX11_FALSE=
+ fi
+
+- if test "x$with_int" == "ximath-32"; then
++ if test "x$with_int" = "ximath-32"; then
+ SMALL_INT_OPT_TRUE=
+ SMALL_INT_OPT_FALSE='#'
+ else
+@@ -20665,7 +20665,7 @@ else
+ SMALL_INT_OPT_FALSE=
+ fi
+
+-if test "x$with_int" == "ximath-32"; then :
++if test "x$with_int" = "ximath-32"; then :
+
+
+ $as_echo "#define USE_SMALL_INT_OPT /**/" >>confdefs.h
diff --git a/gcc14/patches/patch-libffi_configure b/gcc14/patches/patch-libffi_configure
new file mode 100644
index 0000000000..866d7eea2c
--- /dev/null
+++ b/gcc14/patches/patch-libffi_configure
@@ -0,0 +1,16 @@
+$NetBSD: patch-libffi_configure,v 1.1 2024/06/28 18:35:16 wiz Exp $
+
+https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90146
+https://github.com/libffi/libffi/issues/485
+
+--- libffi/configure.orig 2022-05-06 07:31:19.000000000 +0000
++++ libffi/configure
+@@ -16155,7 +16155,7 @@ case "$target" in
+ $as_echo "#define FFI_EXEC_TRAMPOLINE_TABLE 1" >>confdefs.h
+
+ ;;
+- *-apple-* | *-*-freebsd* | *-*-kfreebsd* | *-*-openbsd* | *-pc-solaris* | *-linux-android*)
++ *-apple-* | *-*-freebsd* | *-*-kfreebsd* | *-*-netbsd* | *-*-openbsd* | *-pc-solaris* | *-linux-android*)
+
+ $as_echo "#define FFI_MMAP_EXEC_WRIT 1" >>confdefs.h
+
diff --git a/gcc14/patches/patch-libffi_testsuite_libffi.call_float2.c b/gcc14/patches/patch-libffi_testsuite_libffi.call_float2.c
new file mode 100644
index 0000000000..0747128551
--- /dev/null
+++ b/gcc14/patches/patch-libffi_testsuite_libffi.call_float2.c
@@ -0,0 +1,15 @@
+$NetBSD: patch-libffi_testsuite_libffi.call_float2.c,v 1.1 2024/06/28 18:35:16 wiz Exp $
+
+https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90146
+
+--- libffi/testsuite/libffi.call/float2.c.orig 2022-05-06 07:30:59.000000000 +0000
++++ libffi/testsuite/libffi.call/float2.c
+@@ -47,7 +47,7 @@ int main (void)
+ /* long double support under SunOS/gcc is pretty much non-existent.
+ You'll get the odd bus error in library routines like printf() */
+ #else
+- printf ("%Lf, %Lf, %Lf, %Lf\n", ld, ldblit(f), ld - ldblit(f), LDBL_EPSILON);
++ printf ("%Lf, %Lf, %Lf, %Lf\n", (long double)ld, (long double)ldblit(f), (long double)(ld - ldblit(f)), (long double)LDBL_EPSILON);
+ #endif
+
+ /* These are not always the same!! Check for a reasonable delta */
diff --git a/gcc14/patches/patch-libgcc_config.host b/gcc14/patches/patch-libgcc_config.host
new file mode 100644
index 0000000000..b4b482bb80
--- /dev/null
+++ b/gcc14/patches/patch-libgcc_config.host
@@ -0,0 +1,154 @@
+$NetBSD: patch-libgcc_config.host,v 1.2 2024/12/15 03:12:17 brook Exp $
+
+Part 1: drop legacy library build for macOS >= 14 [PR116809].
+
+This is a mixture of two upstream patches. See
+
+ https://github.com/gcc-mirror/gcc/blob/master/libgcc/config.host
+
+libgcc, Darwin: Drop the legacy library build for macOS >= 15 [PR116809].
+
+We have been building a legacy libgcc_s.1 DSO to support code that
+was built with older compilers.
+
+From macOS 15, the unwinder no longer exports some of the symbols used
+in that library which (a) cuases bootstrap fail and (b) means that the
+legacy library is no longer useful.
+
+No open branch of GCC emits references to this library - and any already
+-built code that depends on the symbols would need rework anyway.
+
+ PR target/116809
+
+libgcc, Darwin: Don't build legacy libgcc_s.1 on macOS 14 [PR116809]
+
+d9cafa0 stopped building libgcc_s.1 on macOS >= 15, in part because
+that is required to bootstrap the compiler using the macOS 15 SDK. The
+macOS 15 SDK ships in Xcode 16, which also runs on macOS 14. libgcc_s.1
+can no longer be built on macOS 14 using Xcode 16 by the same logic that
+the previous change disabled it for macOS 15.
+
+ PR target/116809
+
+Parts 2-3: This is needed for arm64 to get Out-of-line LSE atomics linked into libgcc.
+libsupc++ fails to link without this, and for arm to build.
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- libgcc/config.host.orig 2024-08-01 08:17:17.000000000 +0000
++++ libgcc/config.host
+@@ -82,7 +82,7 @@ m32c*-*-*)
+ cpu_type=m32c
+ tmake_file=t-fdpbit
+ ;;
+-aarch64*-*-*)
++aarch64*-*-* | arm64*-*-*)
+ cpu_type=aarch64
+ ;;
+ alpha*-*-*)
+@@ -236,19 +236,25 @@ case ${host} in
+ esac
+ tmake_file="$tmake_file t-slibgcc-darwin"
+ case ${host} in
+- *-*-darwin1[89]* | *-*-darwin2* )
+- tmake_file="t-darwin-min-8 $tmake_file"
++ x86_64-*-darwin2[0-2]*)
++ tmake_file="t-darwin-min-11 t-darwin-libgccs1 $tmake_file"
++ ;;
++ *-*-darwin2*)
++ tmake_file="t-darwin-min-11 $tmake_file"
++ ;;
++ *-*-darwin1[89]*)
++ tmake_file="t-darwin-min-8 t-darwin-libgccs1 $tmake_file"
+ ;;
+ *-*-darwin9* | *-*-darwin1[0-7]*)
+- tmake_file="t-darwin-min-5 $tmake_file"
++ tmake_file="t-darwin-min-5 t-darwin-libgccs1 $tmake_file"
+ ;;
+ *-*-darwin[4-8]*)
+- tmake_file="t-darwin-min-1 $tmake_file"
++ tmake_file="t-darwin-min-1 t-darwin-libgccs1 $tmake_file"
+ ;;
+ *)
+ # Fall back to configuring for the oldest system known to work with
+ # all archs and the current sources.
+- tmake_file="t-darwin-min-5 $tmake_file"
++ tmake_file="t-darwin-min-5 t-darwin-libgccs1 $tmake_file"
+ echo "Warning: libgcc configured to support macOS 10.5" 1>&2
+ ;;
+ esac
+@@ -274,7 +280,7 @@ case ${host} in
+ if test "x$enable_darwin_at_rpath" = "xyes"; then
+ tmake_file="$tmake_file t-darwin-rpath "
+ fi
+- extra_parts="crt3.o libd10-uwfef.a crttms.o crttme.o libemutls_w.a"
++ extra_parts="crt3.o crttms.o crttme.o libemutls_w.a "
+ ;;
+ *-*-dragonfly*)
+ tmake_file="$tmake_file t-crtstuff-pic t-libgcc-pic t-eh-dw2-dip"
+@@ -418,6 +424,15 @@ aarch64*-*-elf | aarch64*-*-rtems*)
+ tmake_file="${tmake_file} t-dfprules"
+ md_unwind_header=aarch64/aarch64-unwind.h
+ ;;
++aarch64*-*-darwin*)
++ extra_parts="$extra_parts crtfastmath.o libheapt_w.a"
++ tmake_file="${tmake_file} ${cpu_type}/t-aarch64"
++ tmake_file="${tmake_file} ${cpu_type}/t-lse"
++ tmake_file="${tmake_file} t-crtfm t-dfprules"
++ tmake_file="${tmake_file} ${cpu_type}/t-softfp t-softfp"
++ tmake_file="${tmake_file} ${cpu_type}/t-heap-trampoline"
++ md_unwind_header=aarch64/aarch64-unwind.h
++ ;;
+ aarch64*-*-freebsd*)
+ extra_parts="$extra_parts crtfastmath.o"
+ tmake_file="${tmake_file} ${cpu_type}/t-aarch64"
+@@ -429,6 +444,7 @@ aarch64*-*-freebsd*)
+ aarch64*-*-netbsd*)
+ extra_parts="$extra_parts crtfastmath.o"
+ tmake_file="${tmake_file} ${cpu_type}/t-aarch64"
++ tmake_file="${tmake_file} ${cpu_type}/t-lse"
+ tmake_file="${tmake_file} ${cpu_type}/t-softfp t-softfp t-crtfm"
+ tmake_file="${tmake_file} t-dfprules"
+ md_unwind_header=aarch64/aarch64-unwind.h
+@@ -530,7 +546,8 @@ arm*-*-netbsdelf*)
+ case ${host} in
+ arm*-*-netbsdelf-*eabi*)
+ tmake_file="${tmake_file} arm/t-netbsd-eabi"
+- unwind_header=config/arm/unwind-arm.h
++ # GCC 7 vs NetBSD/eabi -> avoid arm unwinder
++ #unwind_header=config/arm/unwind-arm.h
+ ;;
+ *)
+ tmake_file="${tmake_file} arm/t-netbsd t-slibgcc-gld-nover"
+@@ -725,14 +742,14 @@ i[34567]86-*-darwin*)
+ tmake_file="$tmake_file i386/t-crtpc t-crtfm i386/t-msabi"
+ tm_file="$tm_file i386/darwin-lib.h"
+ extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o"
+- extra_parts="$extra_parts crtfastmath.o libheapt_w.a"
++ extra_parts="$extra_parts crtfastmath.o libd10-uwfef.a libheapt_w.a"
+ tmake_file="${tmake_file} i386/t-heap-trampoline"
+ ;;
+ x86_64-*-darwin*)
+ tmake_file="$tmake_file i386/t-crtpc t-crtfm i386/t-msabi"
+ tm_file="$tm_file i386/darwin-lib.h"
+ extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o"
+- extra_parts="$extra_parts crtfastmath.o libheapt_w.a"
++ extra_parts="$extra_parts crtfastmath.o libd10-uwfef.a libheapt_w.a"
+ tmake_file="${tmake_file} i386/t-heap-trampoline"
+ ;;
+ i[34567]86-*-elfiamcu)
+@@ -1215,12 +1232,14 @@ powerpc-*-darwin*)
+ # We build the darwin10 EH shim for Rosetta (running on x86 machines).
+ tm_file="$tm_file i386/darwin-lib.h"
+ tmake_file="$tmake_file rs6000/t-ppc64-fp rs6000/t-ibm-ldouble"
++ extra_parts="$extra_parts libd10-uwfef.a "
+ extra_parts="$extra_parts crt2.o crt3_2.o libef_ppc.a dw_ppc.o"
+ ;;
+ powerpc64-*-darwin*)
+ # We build the darwin10 EH shim for Rosetta (running on x86 machines).
+ tm_file="$tm_file i386/darwin-lib.h"
+ tmake_file="$tmake_file rs6000/t-darwin64 rs6000/t-ibm-ldouble"
++ extra_parts="$extra_parts libd10-uwfef.a "
+ extra_parts="$extra_parts crt2.o crt3_2.o libef_ppc.a dw_ppc.o"
+ ;;
+ powerpc*-*-freebsd*)
diff --git a/gcc14/patches/patch-libgcc_config_aarch64___arm_sme_state.S b/gcc14/patches/patch-libgcc_config_aarch64___arm_sme_state.S
new file mode 100644
index 0000000000..619115d084
--- /dev/null
+++ b/gcc14/patches/patch-libgcc_config_aarch64___arm_sme_state.S
@@ -0,0 +1,37 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- libgcc/config/aarch64/__arm_sme_state.S
++++ libgcc/config/aarch64/__arm_sme_state.S
+@@ -30,14 +30,19 @@
+ - Takes no argument.
+ - Returns SME state in x0 and TPIDR2_EL0 in x1. */
+
+-HIDDEN (__aarch64_have_sme)
++HIDDEN (ASMNAME (__aarch64_have_sme))
+
+-variant_pcs (__arm_sme_state)
++variant_pcs (ASMNAME (__arm_sme_state))
+
+-ENTRY (__arm_sme_state)
++ENTRY (ASMNAME (__arm_sme_state))
+ /* Check if SME is available. */
+- adrp x1, __aarch64_have_sme
+- ldrb w1, [x1, :lo12:__aarch64_have_sme]
++#ifdef __APPLE__
++ adrp x1, ASMNAME (__aarch64_have_sme)@PAGE
++ ldrb w1, [x1, ASMNAME (__aarch64_have_sme)@PAGEOFF]
++#else
++ adrp x1, ASMNAME (__aarch64_have_sme)
++ ldrb w1, [x1, :lo12:ASMNAME (__aarch64_have_sme)]
++#endif
+ cbz w1, L(nosme)
+
+ /* Expose the bottom 2 bits of svcr (SM, ZA) in x0 and set the
+@@ -52,4 +57,4 @@ L(nosme):
+ mov x0, 0
+ mov x1, 0
+ ret
+-END (__arm_sme_state)
++ENDm ASMNAME(__arm_sme_state)
diff --git a/gcc14/patches/patch-libgcc_config_aarch64___arm_tpidr2_restore.S b/gcc14/patches/patch-libgcc_config_aarch64___arm_tpidr2_restore.S
new file mode 100644
index 0000000000..121e8d1f40
--- /dev/null
+++ b/gcc14/patches/patch-libgcc_config_aarch64___arm_tpidr2_restore.S
@@ -0,0 +1,26 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- libgcc/config/aarch64/__arm_tpidr2_restore.S
++++ libgcc/config/aarch64/__arm_tpidr2_restore.S
+@@ -31,9 +31,9 @@
+ - Does not return a value.
+ - Can abort on failure (then registers are not preserved). */
+
+-variant_pcs (__arm_tpidr2_restore)
++variant_pcs (ASMNAME (__arm_tpidr2_restore))
+
+-ENTRY (__arm_tpidr2_restore)
++ENTRY (ASMNAME (__arm_tpidr2_restore))
+ .inst 0xd53bd0ae /* mrs x14, tpidr2_el0 */
+ cbnz x14, L(fail)
+
+@@ -85,5 +85,5 @@ L(fail):
+ str x16, [sp, 16]
+ .cfi_rel_offset 46, 16
+ .inst 0xd503467f /* smstop */
+- bl abort
+-END (__arm_tpidr2_restore)
++ bl ASMNAME (abort)
++ENDm ASMNAME (__arm_tpidr2_restore)
diff --git a/gcc14/patches/patch-libgcc_config_aarch64___arm_tpidr2_save.S b/gcc14/patches/patch-libgcc_config_aarch64___arm_tpidr2_save.S
new file mode 100644
index 0000000000..d6b5f2b3d2
--- /dev/null
+++ b/gcc14/patches/patch-libgcc_config_aarch64___arm_tpidr2_save.S
@@ -0,0 +1,50 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- libgcc/config/aarch64/__arm_tpidr2_save.S
++++ libgcc/config/aarch64/__arm_tpidr2_save.S
+@@ -35,10 +35,15 @@ HIDDEN (__aarch64_have_sme)
+
+ variant_pcs (__arm_tpidr2_save)
+
+-ENTRY (__arm_tpidr2_save)
++ENTRY (ASMNAME (__arm_tpidr2_save))
+ /* Check if SME is available. */
+- adrp x14, __aarch64_have_sme
+- ldrb w14, [x14, :lo12:__aarch64_have_sme]
++#if __APPLE__
++ adrp x14, ASMNAME (__aarch64_have_sme)@PAGE
++ ldrb w14, [x14, ASMNAME (__aarch64_have_sme)@PAGEOFF]
++#else
++ adrp x14, ASMNAME (__aarch64_have_sme)
++ ldrb w14, [x14, :lo12:ASMNAME (__aarch64_have_sme)]
++#endif
+ cbz w14, L(end)
+
+ .inst 0xd53bd0ae /* mrs x14, tpidr2_el0 */
+@@ -92,10 +97,18 @@ L(fail):
+ str x16, [sp, 16]
+ .cfi_rel_offset 46, 16
+ .inst 0xd503467f /* smstop */
+- bl abort
+-END (__arm_tpidr2_save)
+-
++ bl ASMNAME (abort)
++ENDm ASMNAME (__arm_tpidr2_save)
++
++ GLOBAL(ASMNAME (__libgcc_arm_tpidr2_save))
++ HIDDEN (ASMNAME (__libgcc_arm_tpidr2_save))
++#if __APPLE__
++ .text
++ .p2align 4
++ASMNAME (__libgcc_arm_tpidr2_save):
++ b ASMNAME (__arm_tpidr2_save)
++#else
+ /* Hidden alias used by __arm_za_disable. */
+-.global __libgcc_arm_tpidr2_save
+-HIDDEN (__libgcc_arm_tpidr2_save)
+-.set __libgcc_arm_tpidr2_save, __arm_tpidr2_save
++.set ASMNAME (__libgcc_arm_tpidr2_save), ASMNAME (__arm_tpidr2_save)
++#endif
++
diff --git a/gcc14/patches/patch-libgcc_config_aarch64___arm_za_disable.S b/gcc14/patches/patch-libgcc_config_aarch64___arm_za_disable.S
new file mode 100644
index 0000000000..074f50ca3a
--- /dev/null
+++ b/gcc14/patches/patch-libgcc_config_aarch64___arm_za_disable.S
@@ -0,0 +1,66 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- libgcc/config/aarch64/__arm_za_disable.S
++++ libgcc/config/aarch64/__arm_za_disable.S
+@@ -31,16 +31,33 @@
+ - Does not return a value.
+ - Can abort on failure (then registers are not preserved). */
+
+-HIDDEN (__aarch64_have_sme)
++HIDDEN (ASMNAME(__aarch64_have_sme))
+
+-HIDDEN (__libgcc_arm_tpidr2_save)
++HIDDEN (ASMNAME(__libgcc_arm_tpidr2_save))
+
+-variant_pcs (__arm_za_disable)
++variant_pcs (ASMNAME(__arm_za_disable))
+
+-ENTRY (__arm_za_disable)
++GLOBAL (ASMNAME (__libgcc_arm_za_disable))
++HIDDEN (ASMNAME (__libgcc_arm_za_disable))
++#if __APPLE__
++ .text
++ .p2align 4
++ASMNAME (__libgcc_arm_za_disable):
++ b ASMNAME (__arm_za_disable)
++#else
++/* Hidden alias used by the unwinder. */
++.set ASMNAME (__libgcc_arm_za_disable), ASMNAME (__arm_za_disable)
++#endif
++
++ENTRY (ASMNAME (__arm_za_disable))
+ /* Check if SME is available. */
+- adrp x14, __aarch64_have_sme
+- ldrb w14, [x14, :lo12:__aarch64_have_sme]
++#if __APPLE__
++ adrp x14, ASMNAME (__aarch64_have_sme)@PAGE
++ ldrb w14, [x14, ASMNAME (__aarch64_have_sme)@PAGEOFF]
++#else
++ adrp x14, ASMNAME (__aarch64_have_sme)
++ ldrb w14, [x14, :lo12:ASMNAME (__aarch64_have_sme)]
++#endif
+ cbz w14, L(end)
+
+ .inst 0xd53bd0ae /* mrs x14, tpidr2_el0 */
+@@ -52,7 +69,7 @@ ENTRY (__arm_za_disable)
+ .cfi_rel_offset x29, 0
+ .cfi_rel_offset x30, 8
+ mov x29, sp
+- bl __libgcc_arm_tpidr2_save
++ bl ASMNAME (__libgcc_arm_tpidr2_save)
+ .inst 0xd51bd0bf /* msr tpidr2_el0, xzr */
+ .inst 0xd503447f /* smstop za */
+ ldp x29, x30, [sp], 16
+@@ -62,9 +79,5 @@ ENTRY (__arm_za_disable)
+ AUTIASP
+ L(end):
+ ret
+-END (__arm_za_disable)
++ENDm ASMNAME(__arm_za_disable)
+
+-/* Hidden alias used by the unwinder. */
+-.global __libgcc_arm_za_disable
+-HIDDEN (__libgcc_arm_za_disable)
+-.set __libgcc_arm_za_disable, __arm_za_disable
diff --git a/gcc14/patches/patch-libgcc_config_aarch64_aarch64-asm.h b/gcc14/patches/patch-libgcc_config_aarch64_aarch64-asm.h
new file mode 100644
index 0000000000..070e0d32f9
--- /dev/null
+++ b/gcc14/patches/patch-libgcc_config_aarch64_aarch64-asm.h
@@ -0,0 +1,80 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- libgcc/config/aarch64/aarch64-asm.h
++++ libgcc/config/aarch64/aarch64-asm.h
+@@ -24,8 +24,6 @@
+
+ #include "auto-target.h"
+
+-#define L(label) .L ## label
+-
+ /* Marking variant PCS symbol references is important for PLT calls
+ otherwise it is for documenting the PCS in the symbol table. */
+ #ifdef HAVE_AS_VARIANT_PCS
+@@ -58,12 +56,31 @@
+ # define AUTIASP
+ #endif
+
++#define PASTE2(a, b) PASTE2a(a, b)
++#define PASTE2a(a, b) a ## b
++
++#ifdef __USER_LABEL_PREFIX__
++# define ASMNAME(name) PASTE2(__USER_LABEL_PREFIX__, name)
++#else
++# define ASMNAME(name) name
++#endif
++
+ #ifdef __ELF__
++#define L(label) .L ## label
+ #define HIDDEN(name) .hidden name
++#define GLOBAL(name) .global name
+ #define SYMBOL_SIZE(name) .size name, .-name
+ #define SYMBOL_TYPE(name, _type) .type name, _type
++#elif __APPLE__
++#define L(label) L ## label
++#define HIDDEN(name) .private_extern name
++#define GLOBAL(name) .globl name
++#define SYMBOL_SIZE(name)
++#define SYMBOL_TYPE(name, _type)
+ #else
++#define L(label) .L ## label
+ #define HIDDEN(name)
++#define GLOBAL(name) .global name
+ #define SYMBOL_SIZE(name)
+ #define SYMBOL_TYPE(name, _type)
+ #endif
+@@ -93,16 +110,19 @@ GNU_PROPERTY (FEATURE_1_AND, BTI_FLAG|PAC_FLAG)
+ # endif
+ #endif
+
+-#define ENTRY_ALIGN(name, align) \
+- .global name; \
+- SYMBOL_TYPE(name, %function); \
+- .balign align; \
+- name: \
+- .cfi_startproc; \
+- BTI_C
+-
+-#define ENTRY(name) ENTRY_ALIGN(name, 16)
+-
+-#define END(name) \
+- .cfi_endproc; \
+- SYMBOL_SIZE(name)
++.macro ENTRY_ALIGNP2m, name, align
++ .text
++ .p2align \align
++ GLOBAL (\name)
++ SYMBOL_TYPE(\name, %function)
++\name:
++ .cfi_startproc
++ BTI_C
++.endm
++
++#define ENTRY(name) ENTRY_ALIGNP2m name, 4
++
++.macro ENDm, name
++ .cfi_endproc
++ SYMBOL_SIZE (\name)
++.endm
diff --git a/gcc14/patches/patch-libgcc_config_aarch64_lse.S b/gcc14/patches/patch-libgcc_config_aarch64_lse.S
new file mode 100644
index 0000000000..7f14e2b236
--- /dev/null
+++ b/gcc14/patches/patch-libgcc_config_aarch64_lse.S
@@ -0,0 +1,107 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- libgcc/config/aarch64/lse.S
++++ libgcc/config/aarch64/lse.S
+@@ -62,7 +62,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ #endif
+
+ /* Declare the symbol gating the LSE implementations. */
+- HIDDEN(__aarch64_have_lse_atomics)
++ HIDDEN (ASMNAME (__aarch64_have_lse_atomics))
+
+ /* Turn size and memory model defines into mnemonic fragments. */
+ #if SIZE == 1
+@@ -85,6 +85,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ # error
+ #endif
+
++#undef L
+ #if MODEL == 1
+ # define SUFF _relax
+ # define A
+@@ -167,32 +168,21 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ #define tmp3 14
+ #define tmp4 13
+
+-/* Start and end a function. */
+-.macro STARTFN name
+- .text
+- .balign 16
+- .globl \name
+- HIDDEN(\name)
+- SYMBOL_TYPE(\name, %function)
+- .cfi_startproc
+-\name:
+-.endm
+-
+-.macro ENDFN name
+- .cfi_endproc
+- SYMBOL_SIZE(\name)
+-.endm
+-
+ /* Branch to LABEL if LSE is disabled. */
+ .macro JUMP_IF_NOT_LSE label
+- adrp x(tmp0), __aarch64_have_lse_atomics
+- ldrb w(tmp0), [x(tmp0), :lo12:__aarch64_have_lse_atomics]
++#if __APPLE__
++ adrp x(tmp0), ASMNAME (__aarch64_have_lse_atomics)@PAGE
++ ldrb w(tmp0), [x(tmp0), ASMNAME (__aarch64_have_lse_atomics)@PAGEOFF]
++#else
++ adrp x(tmp0), ASMNAME (__aarch64_have_lse_atomics)
++ ldrb w(tmp0), [x(tmp0), :lo12:ASMNAME (__aarch64_have_lse_atomics)]
++#endif
+ cbz w(tmp0), \label
+ .endm
+
+ #ifdef L_cas
+
+-STARTFN NAME(cas)
++ENTRY (ASMNAME (NAME(cas)))
+ JUMP_IF_NOT_LSE 8f
+
+ #if SIZE < 16
+@@ -245,7 +235,7 @@ STARTFN NAME(cas)
+
+ #endif
+
+-ENDFN NAME(cas)
++ENDm ASMNAME (NAME(cas))
+ #endif
+
+ #ifdef L_swp
+@@ -255,7 +245,7 @@ ENDFN NAME(cas)
+ # define SWP .inst 0x38208020 + B + N
+ #endif
+
+-STARTFN NAME(swp)
++ENTRY (ASMNAME (NAME (swp)))
+ JUMP_IF_NOT_LSE 8f
+
+ SWP /* s(0), s(0), [x1] */
+@@ -268,7 +258,7 @@ STARTFN NAME(swp)
+ BARRIER
+ ret
+
+-ENDFN NAME(swp)
++ENDm ASMNAME (NAME (swp))
+ #endif
+
+ #if defined(L_ldadd) || defined(L_ldclr) \
+@@ -299,7 +289,7 @@ ENDFN NAME(swp)
+ # define LDOP .inst 0x38200020 + OPN + B + N
+ #endif
+
+-STARTFN NAME(LDNM)
++ENTRY (ASMNAME (NAME (LDNM)))
+ JUMP_IF_NOT_LSE 8f
+
+ LDOP /* s(0), s(0), [x1] */
+@@ -313,5 +303,5 @@ STARTFN NAME(LDNM)
+ BARRIER
+ ret
+
+-ENDFN NAME(LDNM)
++ENDm ASMNAME (NAME (LDNM))
+ #endif
diff --git a/gcc14/patches/patch-libgcc_config_aarch64_sfp-machine.h b/gcc14/patches/patch-libgcc_config_aarch64_sfp-machine.h
new file mode 100644
index 0000000000..cbcab538cb
--- /dev/null
+++ b/gcc14/patches/patch-libgcc_config_aarch64_sfp-machine.h
@@ -0,0 +1,34 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- libgcc/config/aarch64/sfp-machine.h
++++ libgcc/config/aarch64/sfp-machine.h
+@@ -124,6 +124,27 @@ void __sfp_handle_exceptions (int);
+
+
+ /* Define ALIASNAME as a strong alias for NAME. */
++#if defined __APPLE__
++/* Mach-O doesn't support aliasing, so we build a secondary function for
++ the alias - we need to do a bit of a dance to find out what the type of
++ the arguments is and then apply that to the secondary function.
++ If these functions ever return anything but CMPtype we need to revisit
++ this... */
++typedef float alias_HFtype __attribute__ ((mode (HF)));
++typedef float alias_SFtype __attribute__ ((mode (SF)));
++typedef float alias_DFtype __attribute__ ((mode (DF)));
++typedef float alias_TFtype __attribute__ ((mode (TF)));
++#define ALIAS_SELECTOR \
++ CMPtype (*) (alias_HFtype, alias_HFtype): (alias_HFtype) 0, \
++ CMPtype (*) (alias_SFtype, alias_SFtype): (alias_SFtype) 0, \
++ CMPtype (*) (alias_DFtype, alias_DFtype): (alias_DFtype) 0, \
++ CMPtype (*) (alias_TFtype, alias_TFtype): (alias_TFtype) 0
++#define strong_alias(name, aliasname) \
++ CMPtype aliasname (__typeof (_Generic (name, ALIAS_SELECTOR)) a, \
++ __typeof (_Generic (name, ALIAS_SELECTOR)) b) \
++ { return name (a, b); }
++#else
+ # define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+ # define _strong_alias(name, aliasname) \
+ extern __typeof (name) aliasname __attribute__ ((alias (#name)));
++#endif
diff --git a/gcc14/patches/patch-libgcc_config_aarch64_t-darwin b/gcc14/patches/patch-libgcc_config_aarch64_t-darwin
new file mode 100644
index 0000000000..9fc14de226
--- /dev/null
+++ b/gcc14/patches/patch-libgcc_config_aarch64_t-darwin
@@ -0,0 +1,14 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- /dev/null
++++ libgcc/config/aarch64/t-darwin
+@@ -0,0 +1,7 @@
++# Ensure we have a suitable minimum OS version.
++
++HOST_LIBGCC2_CFLAGS += -mmacosx-version-min=11.0
++
++LIB2_SIDITI_CONV_FUNCS = yes
++
++BUILD_LIBGCCS1 =
diff --git a/gcc14/patches/patch-libgcc_config_i386_t-darwin b/gcc14/patches/patch-libgcc_config_i386_t-darwin
new file mode 100644
index 0000000000..b3fc9b074a
--- /dev/null
+++ b/gcc14/patches/patch-libgcc_config_i386_t-darwin
@@ -0,0 +1,27 @@
+$NetBSD: patch-libgcc_config_i386_t-darwin,v 1.1 2024/12/15 03:12:17 brook Exp $
+
+libgcc, Darwin: Drop the legacy library build for macOS >= 15 [PR116809].
+
+We have been building a legacy libgcc_s.1 DSO to support code that
+was built with older compilers.
+
+From macOS 15, the unwinder no longer exports some of the symbols used
+in that library which (a) cuases bootstrap fail and (b) means that the
+legacy library is no longer useful.
+
+No open branch of GCC emits references to this library - and any already
+-built code that depends on the symbols would need rework anyway.
+
+ PR target/116809
+
+See https://github.com/gcc-mirror/gcc/blob/master/libgcc/config/i386/t-darwin.
+
+--- libgcc/config/i386/t-darwin.orig 2024-05-21 07:47:41.000000000 +0000
++++ libgcc/config/i386/t-darwin
+@@ -4,6 +4,3 @@ LIB2FUNCS_EXCLUDE = _fixtfdi _fixunstfdi
+
+ # Extra symbols for this port.
+ SHLIB_MAPFILES += $(srcdir)/config/i386/libgcc-darwin.ver
+-
+-# Build a legacy libgcc_s.1
+-BUILD_LIBGCCS1 = YES
diff --git a/gcc14/patches/patch-libgcc_config_rs6000_t-darwin b/gcc14/patches/patch-libgcc_config_rs6000_t-darwin
new file mode 100644
index 0000000000..f2b257410c
--- /dev/null
+++ b/gcc14/patches/patch-libgcc_config_rs6000_t-darwin
@@ -0,0 +1,27 @@
+$NetBSD: patch-libgcc_config_rs6000_t-darwin,v 1.1 2024/12/15 03:12:17 brook Exp $
+
+libgcc, Darwin: Drop the legacy library build for macOS >= 15 [PR116809].
+
+We have been building a legacy libgcc_s.1 DSO to support code that
+was built with older compilers.
+
+From macOS 15, the unwinder no longer exports some of the symbols used
+in that library which (a) cuases bootstrap fail and (b) means that the
+legacy library is no longer useful.
+
+No open branch of GCC emits references to this library - and any already
+-built code that depends on the symbols would need rework anyway.
+
+ PR target/116809
+
+See https://github.com/gcc-mirror/gcc/blob/master/libgcc/config/rs6000/t-darwin.
+
+--- libgcc/config/rs6000/t-darwin.orig 2024-05-21 07:47:41.000000000 +0000
++++ libgcc/config/rs6000/t-darwin
+@@ -56,6 +56,3 @@ unwind-dw2_s.o: HOST_LIBGCC2_CFLAGS += -
+ unwind-dw2.o: HOST_LIBGCC2_CFLAGS += -maltivec
+
+ LIB2ADDEH += $(srcdir)/config/rs6000/darwin-fallback.c
+-
+-# Build a legacy libgcc_s.1
+-BUILD_LIBGCCS1 = YES
diff --git a/gcc14/patches/patch-libgcc_config_t-darwin-libgccs1 b/gcc14/patches/patch-libgcc_config_t-darwin-libgccs1
new file mode 100644
index 0000000000..405fde7609
--- /dev/null
+++ b/gcc14/patches/patch-libgcc_config_t-darwin-libgccs1
@@ -0,0 +1,23 @@
+$NetBSD: patch-libgcc_config_t-darwin-libgccs1,v 1.1 2024/12/15 03:12:17 brook Exp $
+
+libgcc, Darwin: Drop the legacy library build for macOS >= 15 [PR116809].
+
+We have been building a legacy libgcc_s.1 DSO to support code that
+was built with older compilers.
+
+From macOS 15, the unwinder no longer exports some of the symbols used
+in that library which (a) cuases bootstrap fail and (b) means that the
+legacy library is no longer useful.
+
+No open branch of GCC emits references to this library - and any already
+-built code that depends on the symbols would need rework anyway.
+
+ PR target/116809
+
+See https://github.com/gcc-mirror/gcc/blob/master/libgcc/config/t-darwin-libgccs1.
+
+--- libgcc/config/t-darwin-libgccs1.orig 2024-12-09 03:35:09.522148209 +0000
++++ libgcc/config/t-darwin-libgccs1
+@@ -0,0 +1,2 @@
++# Build a legacy libgcc_s.1
++BUILD_LIBGCCS1 = YES
diff --git a/gcc14/patches/patch-libgcc_config_t-darwin-min-11 b/gcc14/patches/patch-libgcc_config_t-darwin-min-11
new file mode 100644
index 0000000000..1a70b63f00
--- /dev/null
+++ b/gcc14/patches/patch-libgcc_config_t-darwin-min-11
@@ -0,0 +1,17 @@
+$NetBSD: patch-libgcc_config_t-darwin-min-11,v 1.1 2024/12/15 03:12:17 brook Exp $
+
+libgcc, Darwin: From macOS 11, make that the earliest supported.
+
+For libgcc, we have (so far) supported building a DSO that supports
+earlier versions of the OS than the target. From macOS 11, there are
+APIs that do not exist on earlier OS versions, so limit the libgcc
+range to macOS11..current.
+
+See https://github.com/gcc-mirror/gcc/blob/master/libgcc/config/t-darwin-min-11.
+
+--- libgcc/config/t-darwin-min-11.orig 2024-12-10 16:14:54.471536671 +0000
++++ libgcc/config/t-darwin-min-11
+@@ -0,0 +1,3 @@
++# Support building with -mmacosx-version-min back to macOS 11.
++DARWIN_MIN_LIB_VERSION = -mmacosx-version-min=11
++DARWIN_MIN_CRT_VERSION = -mmacosx-version-min=11
diff --git a/gcc14/patches/patch-libgcc_crtstuff.c b/gcc14/patches/patch-libgcc_crtstuff.c
new file mode 100644
index 0000000000..37daf97714
--- /dev/null
+++ b/gcc14/patches/patch-libgcc_crtstuff.c
@@ -0,0 +1,15 @@
+$NetBSD: patch-libgcc_crtstuff.c,v 1.1 2024/06/28 18:35:16 wiz Exp $
+
+https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90147
+
+--- libgcc/crtstuff.c.orig 2017-01-01 12:07:43.000000000 +0000
++++ libgcc/crtstuff.c
+@@ -81,7 +81,7 @@ call_ ## FUNC (void) \
+ #endif
+
+ #if defined(TARGET_DL_ITERATE_PHDR) && \
+- (defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__))
++ (defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__))
+ #define BSD_DL_ITERATE_PHDR_AVAILABLE
+ #endif
+
diff --git a/gcc14/patches/patch-libgfortran_io_io.h b/gcc14/patches/patch-libgfortran_io_io.h
new file mode 100644
index 0000000000..82e244a6ba
--- /dev/null
+++ b/gcc14/patches/patch-libgfortran_io_io.h
@@ -0,0 +1,18 @@
+$NetBSD: patch-libgfortran_io_io.h,v 1.1 2024/06/28 18:35:16 wiz Exp $
+
+Don't declare old_locale* an internal_proto to avoid linking problems
+
+--- libgfortran/io/io.h.orig 2018-01-07 10:17:52.000000000 +0000
++++ libgfortran/io/io.h
+@@ -57,11 +57,8 @@ extern locale_t c_locale;
+ internal_proto(c_locale);
+ #else
+ extern char* old_locale;
+-internal_proto(old_locale);
+ extern int old_locale_ctr;
+-internal_proto(old_locale_ctr);
+ extern __gthread_mutex_t old_locale_lock;
+-internal_proto(old_locale_lock);
+ #endif
+
+
diff --git a/gcc14/patches/patch-libitm_config_aarch64_sjlj.S b/gcc14/patches/patch-libitm_config_aarch64_sjlj.S
new file mode 100644
index 0000000000..d78b46c2c9
--- /dev/null
+++ b/gcc14/patches/patch-libitm_config_aarch64_sjlj.S
@@ -0,0 +1,75 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- libitm/config/aarch64/sjlj.S
++++ libitm/config/aarch64/sjlj.S
+@@ -57,10 +57,19 @@
+
+ .text
+ .align 2
++#if __ELF__
+ .global _ITM_beginTransaction
+ .type _ITM_beginTransaction, %function
+
+ _ITM_beginTransaction:
++
++#elif __MACH__
++ .global __ITM_beginTransaction
++
++__ITM_beginTransaction:
++
++#endif
++
+ cfi_startproc
+ CFI_PAC_KEY
+ PAC_AND_BTI
+@@ -84,8 +93,13 @@ _ITM_beginTransaction:
+
+ /* Invoke GTM_begin_transaction with the struct we just built. */
+ mov x1, sp
++#if __ELF__
+ bl GTM_begin_transaction
+-
++#elif __MACH__
++ bl _GTM_begin_transaction
++#else
++#error "unexpected object format"
++#endif
+ /* Return; we don't need to restore any of the call-saved regs. */
+ ldp x29, x30, [sp], 11*16
+ cfi_adjust_cfa_offset(-11*16)
+@@ -95,14 +109,23 @@ _ITM_beginTransaction:
+ CFI_PAC_TOGGLE
+ ret
+ cfi_endproc
++#if __ELF__
+ .size _ITM_beginTransaction, . - _ITM_beginTransaction
++#endif
+
+ .align 2
++#if __ELF__
+ .global GTM_longjmp
+ .hidden GTM_longjmp
+ .type GTM_longjmp, %function
+
+ GTM_longjmp:
++
++#elif __MACH__
++ .private_extern _GTM_longjmp
++
++_GTM_longjmp:
++#endif
+ /* The first parameter becomes the return value (x0).
+ The third parameter is ignored for now. */
+ cfi_startproc
+@@ -126,7 +149,9 @@ GTM_longjmp:
+ CFI_PAC_TOGGLE
+ br x30
+ cfi_endproc
++#if __ELF__
+ .size GTM_longjmp, . - GTM_longjmp
++#endif
+
+ /* GNU_PROPERTY_AARCH64_* macros from elf.h for use in asm code. */
+ #define FEATURE_1_AND 0xc0000000
diff --git a/gcc14/patches/patch-libitm_configure.tgt b/gcc14/patches/patch-libitm_configure.tgt
new file mode 100644
index 0000000000..7918ac7119
--- /dev/null
+++ b/gcc14/patches/patch-libitm_configure.tgt
@@ -0,0 +1,15 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- libitm/configure.tgt
++++ libitm/configure.tgt
+@@ -50,7 +50,7 @@ fi
+ # Map the target cpu to an ARCH sub-directory. At the same time,
+ # work out any special compilation flags as necessary.
+ case "${target_cpu}" in
+- aarch64*) ARCH=aarch64 ;;
++ aarch64* | arm64*) ARCH=aarch64 ;;
+ alpha*) ARCH=alpha ;;
+ rs6000 | powerpc*)
+ XCFLAGS="${XCFLAGS} -mhtm"
diff --git a/gcc14/patches/patch-libphobos_libdruntime_core_internal_gc_impl_conservative_gc.d b/gcc14/patches/patch-libphobos_libdruntime_core_internal_gc_impl_conservative_gc.d
new file mode 100644
index 0000000000..4745119de8
--- /dev/null
+++ b/gcc14/patches/patch-libphobos_libdruntime_core_internal_gc_impl_conservative_gc.d
@@ -0,0 +1,22 @@
+$NetBSD$
+
+Support Darwin/aarch64, from https://github.com/Homebrew/formula-patches.
+
+--- libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d
++++ libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d
+@@ -30,8 +30,13 @@ module core.internal.gc.impl.conservative.gc;
+
+ /***************************************************/
+ version = COLLECT_PARALLEL; // parallel scanning
+-version (Posix)
+- version = COLLECT_FORK;
++version (GNU)
++{
++ version (linux)
++ version = COLLECT_FORK; // uses clone(), battle tested and reliable
++}
++else version (Posix)
++ version = COLLECT_FORK;
+
+ import core.internal.gc.bits;
+ import core.internal.gc.os;
diff --git a/gcc14/patches/patch-libquadmath_printf_quadmath-printf.c b/gcc14/patches/patch-libquadmath_printf_quadmath-printf.c
new file mode 100644
index 0000000000..5332affdd0
--- /dev/null
+++ b/gcc14/patches/patch-libquadmath_printf_quadmath-printf.c
@@ -0,0 +1,26 @@
+$NetBSD: patch-libquadmath_printf_quadmath-printf.c,v 1.1 2024/06/28 18:35:16 wiz Exp $
+
+Fix -Werror=char-subscripts.
+
+https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95178
+
+--- libquadmath/printf/quadmath-printf.c.orig 2020-05-07 10:50:02.000000000 +0000
++++ libquadmath/printf/quadmath-printf.c
+@@ -189,7 +189,7 @@ quadmath_snprintf (char *str, size_t siz
+ ++format;
+ info.width = va_arg (ap, int);
+ }
+- else if (isdigit (*format))
++ else if (isdigit ((unsigned char) *format))
+ /* Constant width specification. */
+ info.width = read_int (&format);
+
+@@ -206,7 +206,7 @@ quadmath_snprintf (char *str, size_t siz
+
+ info.prec = va_arg (ap, int);
+ }
+- else if (isdigit (*format))
++ else if (isdigit ((unsigned char) *format))
+ info.prec = read_int (&format);
+ else
+ /* "%.?" is treated like "%.0?". */
diff --git a/gcc14/patches/patch-libquadmath_strtod_strtod__l.c b/gcc14/patches/patch-libquadmath_strtod_strtod__l.c
new file mode 100644
index 0000000000..a775de6a75
--- /dev/null
+++ b/gcc14/patches/patch-libquadmath_strtod_strtod__l.c
@@ -0,0 +1,23 @@
+$NetBSD: patch-libquadmath_strtod_strtod__l.c,v 1.1 2024/06/28 18:35:16 wiz Exp $
+
+Fix -Werror=char-subscripts.
+
+https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95178
+
+--- libquadmath/strtod/strtod_l.c.orig 2020-05-07 10:50:02.000000000 +0000
++++ libquadmath/strtod/strtod_l.c
+@@ -57,10 +57,10 @@
+ # define STRING_TYPE char
+ # define CHAR_TYPE char
+ # define L_(Ch) Ch
+-# define ISSPACE(Ch) isspace (Ch)
+-# define ISDIGIT(Ch) isdigit (Ch)
+-# define ISXDIGIT(Ch) isxdigit (Ch)
+-# define TOLOWER(Ch) tolower (Ch)
++# define ISSPACE(Ch) isspace ((unsigned char) Ch)
++# define ISDIGIT(Ch) isdigit ((unsigned char) Ch)
++# define ISXDIGIT(Ch) isxdigit ((unsigned char) Ch)
++# define TOLOWER(Ch) tolower ((unsigned char) Ch)
+ # define TOLOWER_C(Ch) \
+ ({__typeof(Ch) __tlc = (Ch); \
+ (__tlc >= 'A' && __tlc <= 'Z') ? __tlc - 'A' + 'a' : __tlc; })
diff --git a/gcc14/patches/patch-libstdc++-v3_libsupc++_new__opa.cc b/gcc14/patches/patch-libstdc++-v3_libsupc++_new__opa.cc
new file mode 100644
index 0000000000..bf819d7e3d
--- /dev/null
+++ b/gcc14/patches/patch-libstdc++-v3_libsupc++_new__opa.cc
@@ -0,0 +1,17 @@
+$NetBSD: patch-libstdc++-v3_libsupc++_new__opa.cc,v 1.1 2024/06/28 18:35:16 wiz Exp $
+
+Ensure we can find SunOS std::aligned_alloc if using it.
+
+--- libstdc++-v3/libsupc++/new_opa.cc.orig 2024-05-21 07:47:42.000000000 +0000
++++ libstdc++-v3/libsupc++/new_opa.cc
+@@ -62,6 +62,10 @@ extern "C"
+ }
+ #endif
+
++#if defined(__sun) && _GLIBCXX_HAVE_ALIGNED_ALLOC
++using std::aligned_alloc;
++#endif
++
+ namespace __gnu_cxx {
+ // Prefer posix_memalign if available, because it's older than aligned_alloc
+ // and so more likely to be provided by replacement malloc libraries that
diff --git a/gcc14/version.mk b/gcc14/version.mk
new file mode 100644
index 0000000000..005db973bb
--- /dev/null
+++ b/gcc14/version.mk
@@ -0,0 +1,3 @@
+# $NetBSD: version.mk,v 1.2 2024/08/02 07:44:51 wiz Exp $
+
+GCC14_DIST_VERSION:= 14.2.0
Home |
Main Index |
Thread Index |
Old Index