aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--12.4.0/gentoo/78_all_PR115917-ada-lto.patch52
-rw-r--r--12.4.0/gentoo/README.history4
-rw-r--r--13.3.0/gentoo/93_all_PR115917-ada-lto.patch52
-rw-r--r--13.3.0/gentoo/README.history4
-rw-r--r--14.2.0/gentoo/32_all_time64_ssemath.patch43
-rw-r--r--14.2.0/gentoo/77_all_m2_docs_sandbox.patch37
-rw-r--r--14.2.0/gentoo/78_all_PR115917-ada-lto.patch52
-rw-r--r--14.2.0/gentoo/README.history8
-rw-r--r--15.0.0/gentoo/04_all_nossp-on-nostdlib.patch2
-rw-r--r--15.0.0/gentoo/26_all_enable-cet.patch2
-rw-r--r--15.0.0/gentoo/28_all_drop_CFLAGS_sed.patch12
-rw-r--r--15.0.0/gentoo/34_all_time64_ssemath.patch43
-rw-r--r--15.0.0/gentoo/72_all_PR111600-genrecog-Split-into-separate-partitions.patch1369
-rw-r--r--15.0.0/gentoo/72_all_PR117628-libgcc-c23.patch71
-rw-r--r--15.0.0/gentoo/README.history15
15 files changed, 1493 insertions, 273 deletions
diff --git a/12.4.0/gentoo/78_all_PR115917-ada-lto.patch b/12.4.0/gentoo/78_all_PR115917-ada-lto.patch
deleted file mode 100644
index 2e25ddf..0000000
--- a/12.4.0/gentoo/78_all_PR115917-ada-lto.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From dd97dff998c9fc35e36397fc647f7360e1cadf70 Mon Sep 17 00:00:00 2001
-Message-ID: <dd97dff998c9fc35e36397fc647f7360e1cadf70.1727635310.git.sam@gentoo.org>
-From: =?UTF-8?q?Arsen=20Arsenovi=C4=87?= <arsen@aarsen.me>
-Date: Thu, 15 Aug 2024 19:17:41 +0200
-Subject: [PATCH] gnat: fix lto-type-mismatch between C_Version_String and
- gnat_version_string [PR115917]
-
-gcc/ada/ChangeLog:
-
- PR ada/115917
- * gnatvsn.ads: Add note about the duplication of this value in
- version.c.
- * version.c (VER_LEN_MAX): Define to the same value as
- Gnatvsn.Ver_Len_Max.
- (gnat_version_string): Use VER_LEN_MAX as bound.
-
-(cherry picked from commit 9cbcf8d1de159e6113fafb5dc2feb4a7e467a302)
----
- gcc/ada/gnatvsn.ads | 3 ++-
- gcc/ada/version.c | 5 ++++-
- 2 files changed, 6 insertions(+), 2 deletions(-)
-
-diff --git a/gcc/ada/gnatvsn.ads b/gcc/ada/gnatvsn.ads
-index 47a06b96c3cf..99d06c7e5aa4 100644
---- a/gcc/ada/gnatvsn.ads
-+++ b/gcc/ada/gnatvsn.ads
-@@ -83,7 +83,8 @@ package Gnatvsn is
- -- space to store any possible version string value for checks. This
- -- value should never be decreased in the future, but it would be
- -- OK to increase it if absolutely necessary. If it is increased,
-- -- be sure to increase GNAT.Compiler.Version.Ver_Len_Max as well.
-+ -- be sure to increase GNAT.Compiler.Version.Ver_Len_Max, and to update
-+ -- the VER_LEN_MAX define in version.c as well.
-
- Ver_Prefix : constant String := "GNAT Version: ";
- -- Prefix generated by binder. If it is changed, be sure to change
-diff --git a/gcc/ada/version.c b/gcc/ada/version.c
-index 5e64edd0b17d..2fa9b8c2c859 100644
---- a/gcc/ada/version.c
-+++ b/gcc/ada/version.c
-@@ -31,4 +31,7 @@
-
- #include "version.h"
-
--char gnat_version_string[] = version_string;
-+/* Logically a reference to Gnatvsn.Ver_Len_Max. Please keep in sync. */
-+#define VER_LEN_MAX 256
-+
-+char gnat_version_string[VER_LEN_MAX] = version_string;
---
-2.46.2
-
diff --git a/12.4.0/gentoo/README.history b/12.4.0/gentoo/README.history
index adc0133..52e5c88 100644
--- a/12.4.0/gentoo/README.history
+++ b/12.4.0/gentoo/README.history
@@ -1,3 +1,7 @@
+2 29 Nov 2024
+
+ - 78_all_PR115917-ada-lto.patch
+
1 29 Sept 2024
+ 01_all_default-fortify-source.patch
diff --git a/13.3.0/gentoo/93_all_PR115917-ada-lto.patch b/13.3.0/gentoo/93_all_PR115917-ada-lto.patch
deleted file mode 100644
index 023c0d1..0000000
--- a/13.3.0/gentoo/93_all_PR115917-ada-lto.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From f55ac7e8ceabaf54ba9fc3ca4393abeae2ee1c19 Mon Sep 17 00:00:00 2001
-Message-ID: <f55ac7e8ceabaf54ba9fc3ca4393abeae2ee1c19.1727635911.git.sam@gentoo.org>
-From: =?UTF-8?q?Arsen=20Arsenovi=C4=87?= <arsen@aarsen.me>
-Date: Thu, 15 Aug 2024 19:17:41 +0200
-Subject: [PATCH] gnat: fix lto-type-mismatch between C_Version_String and
- gnat_version_string [PR115917]
-
-gcc/ada/ChangeLog:
-
- PR ada/115917
- * gnatvsn.ads: Add note about the duplication of this value in
- version.c.
- * version.c (VER_LEN_MAX): Define to the same value as
- Gnatvsn.Ver_Len_Max.
- (gnat_version_string): Use VER_LEN_MAX as bound.
-
-(cherry picked from commit 9cbcf8d1de159e6113fafb5dc2feb4a7e467a302)
----
- gcc/ada/gnatvsn.ads | 3 ++-
- gcc/ada/version.c | 5 ++++-
- 2 files changed, 6 insertions(+), 2 deletions(-)
-
-diff --git a/gcc/ada/gnatvsn.ads b/gcc/ada/gnatvsn.ads
-index b6edc9dabed9..308986afc182 100644
---- a/gcc/ada/gnatvsn.ads
-+++ b/gcc/ada/gnatvsn.ads
-@@ -83,7 +83,8 @@ package Gnatvsn is
- -- space to store any possible version string value for checks. This
- -- value should never be decreased in the future, but it would be
- -- OK to increase it if absolutely necessary. If it is increased,
-- -- be sure to increase GNAT.Compiler.Version.Ver_Len_Max as well.
-+ -- be sure to increase GNAT.Compiler.Version.Ver_Len_Max, and to update
-+ -- the VER_LEN_MAX define in version.c as well.
-
- Ver_Prefix : constant String := "GNAT Version: ";
- -- Prefix generated by binder. If it is changed, be sure to change
-diff --git a/gcc/ada/version.c b/gcc/ada/version.c
-index 5e64edd0b17d..2fa9b8c2c859 100644
---- a/gcc/ada/version.c
-+++ b/gcc/ada/version.c
-@@ -31,4 +31,7 @@
-
- #include "version.h"
-
--char gnat_version_string[] = version_string;
-+/* Logically a reference to Gnatvsn.Ver_Len_Max. Please keep in sync. */
-+#define VER_LEN_MAX 256
-+
-+char gnat_version_string[VER_LEN_MAX] = version_string;
---
-2.46.2
-
diff --git a/13.3.0/gentoo/README.history b/13.3.0/gentoo/README.history
index a1120c2..d17cd25 100644
--- a/13.3.0/gentoo/README.history
+++ b/13.3.0/gentoo/README.history
@@ -1,3 +1,7 @@
+2 29 Nov 2024
+
+ - 93_all_PR115917-ada-lto.patch
+
1 29 Sept 2024
+ 01_all_default-fortify-source.patch
diff --git a/14.2.0/gentoo/32_all_time64_ssemath.patch b/14.2.0/gentoo/32_all_time64_ssemath.patch
new file mode 100644
index 0000000..3701b6b
--- /dev/null
+++ b/14.2.0/gentoo/32_all_time64_ssemath.patch
@@ -0,0 +1,43 @@
+From 33ba5944f2b887fe8bddd541790645b74f1f2655 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= <mgorny@gentoo.org>
+Date: Sun, 24 Nov 2024 14:45:37 +0100
+Subject: [PATCH] Default to -mfpmath=sse on x86 with time64
+
+Our time64 stages already default to `-mfpmath=sse`, so let's have
+the time64 flag implicitly enable it as the default to make things more
+consistent. Furthermore, this also improves compatibility with clang
+that always enables it whenever the target architectures supports SSE.
+
+Note that this works only if `-march=` with SSE support is specified.
+We could technically improve the consistency even further by raising
+the default `-march=`, but that seems a bit intrusive and probably
+unnecessary, given that the vast majority of Gentoo users and/or
+upstream projects will specify `-march=`.
+
+See also:
+https://public-inbox.gentoo.org/gentoo-dev/ce894afe6c2b324fef012da9bb9387cfde7aed03.camel@gentoo.org/
+https://public-inbox.gentoo.org/gentoo-dev/baa1ca92da4941b0999ea2feecf02334b5b20ade.camel@gentoo.org/
+---
+ gcc/config/i386/i386-options.cc | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc
+index 6c212a8ed..03801f382 100644
+--- a/gcc/config/i386/i386-options.cc
++++ b/gcc/config/i386/i386-options.cc
+@@ -2881,7 +2881,11 @@ ix86_option_override_internal (bool main_args_p,
+ Also -mfpmath=387 is overall a lot more compact (bout 4-5%) than SSE
+ codegen. We may switch to 387 with -ffast-math for size optimized
+ functions. */
+- else if (fast_math_flags_set_p (&global_options)
++#ifndef _GENTOO_TIME64_FORCE
++ #define _GENTOO_TIME64_FORCE 0
++#endif
++
++ else if ((fast_math_flags_set_p (&global_options) || _GENTOO_TIME64_FORCE)
+ && TARGET_SSE2_P (opts->x_ix86_isa_flags))
+ opts->x_ix86_fpmath = FPMATH_SSE;
+ else
+--
+2.47.0
+
diff --git a/14.2.0/gentoo/77_all_m2_docs_sandbox.patch b/14.2.0/gentoo/77_all_m2_docs_sandbox.patch
deleted file mode 100644
index c402937..0000000
--- a/14.2.0/gentoo/77_all_m2_docs_sandbox.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-https://bugs.gentoo.org/930014
-https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=232a86f9640cde6908d0875b8df52c36030c5b5e
-
-From 232a86f9640cde6908d0875b8df52c36030c5b5e Mon Sep 17 00:00:00 2001
-From: Sam James <sam@gentoo.org>
-Date: Tue, 21 May 2024 12:31:47 +0100
-Subject: [PATCH] modula2: Pass --destdir for dir index during install of
- m2.info.
-
-This patch adds DESTDIR to the infodir when installing m2.info.
-
-gcc/m2/ChangeLog
-
- * Make-lang.in (m2.install-info): Pass --destdir for dir index.
-
-Signed-off-by: Gaius Mulley <gaiusmod2@gmail.com>
----
- gcc/m2/Make-lang.in | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gcc/m2/Make-lang.in b/gcc/m2/Make-lang.in
-index 0abd8ce1455..da4226123df 100644
---- a/gcc/m2/Make-lang.in
-+++ b/gcc/m2/Make-lang.in
-@@ -425,7 +425,7 @@ m2.install-info: installdirs
- else true; fi
- -if [ -f gm2$(exeext) ] && [ -f $(DESTDIR)$(infodir)/m2.info ]; then \
- if $(SHELL) -c 'install-info --version' >/dev/null 2>&1; then \
-- install-info --dir-file=$(infodir)/dir $(DESTDIR)$(infodir)/m2.info; \
-+ install-info --dir-file=$(DESTDIR)$(infodir)/dir $(DESTDIR)$(infodir)/m2.info; \
- else true; fi; \
- else true; fi
-
---
-2.43.5
-
-
diff --git a/14.2.0/gentoo/78_all_PR115917-ada-lto.patch b/14.2.0/gentoo/78_all_PR115917-ada-lto.patch
deleted file mode 100644
index f4bac9c..0000000
--- a/14.2.0/gentoo/78_all_PR115917-ada-lto.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From b56e463bd20beca5609dee69837a6b3dfaa542e2 Mon Sep 17 00:00:00 2001
-Message-ID: <b56e463bd20beca5609dee69837a6b3dfaa542e2.1727636544.git.sam@gentoo.org>
-From: =?UTF-8?q?Arsen=20Arsenovi=C4=87?= <arsen@aarsen.me>
-Date: Thu, 15 Aug 2024 19:17:41 +0200
-Subject: [PATCH] gnat: fix lto-type-mismatch between C_Version_String and
- gnat_version_string [PR115917]
-
-gcc/ada/ChangeLog:
-
- PR ada/115917
- * gnatvsn.ads: Add note about the duplication of this value in
- version.c.
- * version.c (VER_LEN_MAX): Define to the same value as
- Gnatvsn.Ver_Len_Max.
- (gnat_version_string): Use VER_LEN_MAX as bound.
-
-(cherry picked from commit 9cbcf8d1de159e6113fafb5dc2feb4a7e467a302)
----
- gcc/ada/gnatvsn.ads | 3 ++-
- gcc/ada/version.c | 5 ++++-
- 2 files changed, 6 insertions(+), 2 deletions(-)
-
-diff --git a/gcc/ada/gnatvsn.ads b/gcc/ada/gnatvsn.ads
-index 29238362cc04..f2082ece0965 100644
---- a/gcc/ada/gnatvsn.ads
-+++ b/gcc/ada/gnatvsn.ads
-@@ -83,7 +83,8 @@ package Gnatvsn is
- -- space to store any possible version string value for checks. This
- -- value should never be decreased in the future, but it would be
- -- OK to increase it if absolutely necessary. If it is increased,
-- -- be sure to increase GNAT.Compiler.Version.Ver_Len_Max as well.
-+ -- be sure to increase GNAT.Compiler.Version.Ver_Len_Max, and to update
-+ -- the VER_LEN_MAX define in version.c as well.
-
- Ver_Prefix : constant String := "GNAT Version: ";
- -- Prefix generated by binder. If it is changed, be sure to change
-diff --git a/gcc/ada/version.c b/gcc/ada/version.c
-index 5e64edd0b17d..2fa9b8c2c859 100644
---- a/gcc/ada/version.c
-+++ b/gcc/ada/version.c
-@@ -31,4 +31,7 @@
-
- #include "version.h"
-
--char gnat_version_string[] = version_string;
-+/* Logically a reference to Gnatvsn.Ver_Len_Max. Please keep in sync. */
-+#define VER_LEN_MAX 256
-+
-+char gnat_version_string[VER_LEN_MAX] = version_string;
---
-2.46.2
-
diff --git a/14.2.0/gentoo/README.history b/14.2.0/gentoo/README.history
index adbcc3e..c80977a 100644
--- a/14.2.0/gentoo/README.history
+++ b/14.2.0/gentoo/README.history
@@ -1,3 +1,11 @@
+5 1 Dec 2024
+
+ - 77_all_m2_docs_sandbox.patch
+
+4 30 Nov 2024
+
+ - 78_all_PR115917-ada-lto.patch
+
3 2 Nov 2024
+ 79_all_sanitizer_time64.patch
diff --git a/15.0.0/gentoo/04_all_nossp-on-nostdlib.patch b/15.0.0/gentoo/04_all_nossp-on-nostdlib.patch
index e17b6a3..4462c0e 100644
--- a/15.0.0/gentoo/04_all_nossp-on-nostdlib.patch
+++ b/15.0.0/gentoo/04_all_nossp-on-nostdlib.patch
@@ -8,7 +8,7 @@ https://bugs.gentoo.org/484714
#endif
+#ifdef ENABLE_DEFAULT_SSP
-+#define NO_SSP_SPEC "%{nostdlib|nodefaultlibs|ffreestanding:-fno-stack-protector} "
++#define NO_SSP_SPEC "%{nostdlib|nodefaultlibs|ffreestanding:-fno-stack-protector} -foffload-options=-fno-stack-protector "
+#else
+#define NO_SSP_SPEC ""
+#endif
diff --git a/15.0.0/gentoo/26_all_enable-cet.patch b/15.0.0/gentoo/26_all_enable-cet.patch
index 85591e9..be772d0 100644
--- a/15.0.0/gentoo/26_all_enable-cet.patch
+++ b/15.0.0/gentoo/26_all_enable-cet.patch
@@ -68,7 +68,7 @@ Only supported on amd64.
+ We use a new option (EXTRA_OPTIONS_CF) here to avoid turning
+ this on accidentally for other arches. */
+#ifdef EXTRA_OPTIONS_CF
-+#define DEFAULT_FLAG_CF_SPEC " %{!m16:%{!m32:%{!fcf-protection*:%{!fno-cf-protection:-fcf-protection}}}}"
++#define DEFAULT_FLAG_CF_SPEC " %{!m16:%{!m32:%{!fcf-protection*:%{!fno-cf-protection:-fcf-protection}}}} -foffload-options=-fcf-protection=none"
+#endif
+#ifndef DEFAULT_FLAG_CF_SPEC
+#define DEFAULT_FLAG_CF_SPEC ""
diff --git a/15.0.0/gentoo/28_all_drop_CFLAGS_sed.patch b/15.0.0/gentoo/28_all_drop_CFLAGS_sed.patch
index 764f34c..fb514cb 100644
--- a/15.0.0/gentoo/28_all_drop_CFLAGS_sed.patch
+++ b/15.0.0/gentoo/28_all_drop_CFLAGS_sed.patch
@@ -3,7 +3,7 @@ https://github.com/InBetweenNames/gentooLTO/issues/846
https://github.com/vaeth/portage-bashrc-mv/issues/11
--- a/gcc/configure
+++ b/gcc/configure
-@@ -5388,13 +5388,6 @@ ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ex
+@@ -5473,13 +5473,6 @@ ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ex
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
@@ -11,15 +11,15 @@ https://github.com/vaeth/portage-bashrc-mv/issues/11
-# optimizations to be activated explicitly by the toplevel.
-case "$CC" in
- */prev-gcc/xgcc*) ;;
-- *) CFLAGS=`echo "$CFLAGS " | sed -e "s/-Ofast[ ]//" -e "s/-O[gs][ ]//" -e "s/-O[0-9]*[ ]//" `
-- CXXFLAGS=`echo "$CXXFLAGS " | sed -e "s/-Ofast[ ]//" -e "s/-O[gs][ ]//" -e "s/-O[0-9]*[ ]//" ` ;;
+- *) CFLAGS=`echo "$CFLAGS " | sed -e "s/-Ofast[ ]//" -e "s/-O[gs][ ]//" -e "s/[^,]-O[0-9]*[ ]//" `
+- CXXFLAGS=`echo "$CXXFLAGS " | sed -e "s/-Ofast[ ]//" -e "s/-O[gs][ ]//" -e "s/[^,]-O[0-9]*[ ]//" ` ;;
-esac
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
-@@ -440,13 +440,6 @@ ACX_PROG_GDC([-I"$srcdir"/d])
+@@ -463,13 +463,6 @@ ACX_PROG_GDC([-I"$srcdir"/d])
# Do configure tests with the C++ compiler, since that's what we build with.
AC_LANG(C++)
@@ -27,8 +27,8 @@ https://github.com/vaeth/portage-bashrc-mv/issues/11
-# optimizations to be activated explicitly by the toplevel.
-case "$CC" in
- */prev-gcc/xgcc*) ;;
-- *) CFLAGS=`echo "$CFLAGS " | sed -e "s/-Ofast[[ ]]//" -e "s/-O[[gs]][[ ]]//" -e "s/-O[[0-9]]*[[ ]]//" `
-- CXXFLAGS=`echo "$CXXFLAGS " | sed -e "s/-Ofast[[ ]]//" -e "s/-O[[gs]][[ ]]//" -e "s/-O[[0-9]]*[[ ]]//" ` ;;
+- *) CFLAGS=`echo "$CFLAGS " | sed -e "s/-Ofast[[ ]]//" -e "s/-O[[gs]][[ ]]//" -e "s/[[^,]]-O[[0-9]]*[[ ]]//" `
+- CXXFLAGS=`echo "$CXXFLAGS " | sed -e "s/-Ofast[[ ]]//" -e "s/-O[[gs]][[ ]]//" -e "s/[[^,]]-O[[0-9]]*[[ ]]//" ` ;;
-esac
AC_SUBST(CFLAGS)
AC_SUBST(CXXFLAGS)
diff --git a/15.0.0/gentoo/34_all_time64_ssemath.patch b/15.0.0/gentoo/34_all_time64_ssemath.patch
new file mode 100644
index 0000000..3701b6b
--- /dev/null
+++ b/15.0.0/gentoo/34_all_time64_ssemath.patch
@@ -0,0 +1,43 @@
+From 33ba5944f2b887fe8bddd541790645b74f1f2655 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= <mgorny@gentoo.org>
+Date: Sun, 24 Nov 2024 14:45:37 +0100
+Subject: [PATCH] Default to -mfpmath=sse on x86 with time64
+
+Our time64 stages already default to `-mfpmath=sse`, so let's have
+the time64 flag implicitly enable it as the default to make things more
+consistent. Furthermore, this also improves compatibility with clang
+that always enables it whenever the target architectures supports SSE.
+
+Note that this works only if `-march=` with SSE support is specified.
+We could technically improve the consistency even further by raising
+the default `-march=`, but that seems a bit intrusive and probably
+unnecessary, given that the vast majority of Gentoo users and/or
+upstream projects will specify `-march=`.
+
+See also:
+https://public-inbox.gentoo.org/gentoo-dev/ce894afe6c2b324fef012da9bb9387cfde7aed03.camel@gentoo.org/
+https://public-inbox.gentoo.org/gentoo-dev/baa1ca92da4941b0999ea2feecf02334b5b20ade.camel@gentoo.org/
+---
+ gcc/config/i386/i386-options.cc | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc
+index 6c212a8ed..03801f382 100644
+--- a/gcc/config/i386/i386-options.cc
++++ b/gcc/config/i386/i386-options.cc
+@@ -2881,7 +2881,11 @@ ix86_option_override_internal (bool main_args_p,
+ Also -mfpmath=387 is overall a lot more compact (bout 4-5%) than SSE
+ codegen. We may switch to 387 with -ffast-math for size optimized
+ functions. */
+- else if (fast_math_flags_set_p (&global_options)
++#ifndef _GENTOO_TIME64_FORCE
++ #define _GENTOO_TIME64_FORCE 0
++#endif
++
++ else if ((fast_math_flags_set_p (&global_options) || _GENTOO_TIME64_FORCE)
+ && TARGET_SSE2_P (opts->x_ix86_isa_flags))
+ opts->x_ix86_fpmath = FPMATH_SSE;
+ else
+--
+2.47.0
+
diff --git a/15.0.0/gentoo/72_all_PR111600-genrecog-Split-into-separate-partitions.patch b/15.0.0/gentoo/72_all_PR111600-genrecog-Split-into-separate-partitions.patch
new file mode 100644
index 0000000..07486e4
--- /dev/null
+++ b/15.0.0/gentoo/72_all_PR111600-genrecog-Split-into-separate-partitions.patch
@@ -0,0 +1,1369 @@
+From 1135970eb38c8f90db20c12cb4222e3a5214557e Mon Sep 17 00:00:00 2001
+Message-ID: <1135970eb38c8f90db20c12cb4222e3a5214557e.1732630692.git.sam@gentoo.org>
+From: Robin Dapp <rdapp.gcc@gmail.com>
+Date: Tue, 26 Nov 2024 14:44:17 +0100
+Subject: [PATCH] genrecog: Split into separate partitions [PR111600].
+
+Hi,
+
+this patch makes genrecog split its output into separate files (10 by
+default) in the same vein genemit does. The changes are mostly
+mechanical again, changing printfs and puts to fprintf.
+As insn-recog.cc relies on being able to call other recog functions a
+header insn-recog.h is introduced that pre declares all of those.
+
+For simplicity the number of files is determined by (re-using)
+--with-insnemit-partitions. Naming suggestions welcome :)
+
+Bootstrapped and regtested on x86 and power10, regtested on riscv.
+aarch64 bootstrap is currently blocked because of the
+"maybe uninitialized" issue discussed on IRC.
+
+Regards
+ Robin
+
+gcc/ChangeLog:
+
+* Makefile.in: Add insn-recog split.
+ * configure.ac: Document that the number of insnemit partitions is
+ used for insn-recog as well.
+ * genconditions.cc (write_one_condition): Use fprintf.
+ * genpreds.cc (write_predicate_expr): Ditto.
+ (write_init_reg_class_start_regs): Ditto.
+ * genrecog.cc (write_header): Add header file to includes.
+ (printf_indent): Use fprintf.
+ (change_state): Ditto.
+ (print_code): Ditto.
+ (print_host_wide_int): Ditto.
+ (print_parameter_value): Ditto.
+ (print_test_rtx): Ditto.
+ (print_nonbool_test): Ditto.
+ (print_label_value): Ditto.
+ (print_test): Ditto.
+ (print_decision): Ditto.
+ (print_state): Ditto.
+ (print_subroutine_call): Ditto.
+ (print_acceptance): Ditto.
+ (print_subroutine_start): Ditto.
+ (print_pattern): Ditto.
+ (print_subroutine): Ditto.
+ (print_subroutine_group): Ditto.
+ (handle_arg): Add -O and -H for output and header file handling.
+ (main): Use callback.
+ * gentarget-def.cc (def_target_insn): Use fprintf.
+ * read-md.cc (md_reader::print_c_condition): Ditto.
+ * read-md.h (class md_reader): Ditto.
+---
+ gcc/Makefile.in | 29 ++-
+ gcc/configure.ac | 4 +-
+ gcc/genconditions.cc | 4 +-
+ gcc/genpreds.cc | 4 +-
+ gcc/genrecog.cc | 552 +++++++++++++++++++++++++------------------
+ gcc/gentarget-def.cc | 2 +-
+ gcc/read-md.cc | 4 +-
+ gcc/read-md.h | 2 +-
+ 8 files changed, 358 insertions(+), 243 deletions(-)
+
+diff --git a/gcc/Makefile.in b/gcc/Makefile.in
+index ead8d2eb094c..d301bef47003 100644
+--- a/gcc/Makefile.in
++++ b/gcc/Makefile.in
+@@ -239,6 +239,12 @@ INSNEMIT_SEQ_SRC = $(patsubst %, insn-emit-%.cc, $(INSNEMIT_SPLITS_SEQ))
+ INSNEMIT_SEQ_TMP = $(patsubst %, tmp-emit-%.cc, $(INSNEMIT_SPLITS_SEQ))
+ INSNEMIT_SEQ_O = $(patsubst %, insn-emit-%.o, $(INSNEMIT_SPLITS_SEQ))
+
++# Re-use the split number for insn-recog as well.
++INSNRECOG_SPLITS_SEQ = $(wordlist 1,$(NUM_INSNEMIT_SPLITS),$(one_to_9999))
++INSNRECOG_SEQ_SRC = $(patsubst %, insn-recog-%.cc, $(INSNRECOG_SPLITS_SEQ))
++INSNRECOG_SEQ_TMP = $(patsubst %, tmp-recog-%.cc, $(INSNRECOG_SPLITS_SEQ))
++INSNRECOG_SEQ_O = $(patsubst %, insn-recog-%.o, $(INSNRECOG_SPLITS_SEQ))
++
+ # These files are to have specific diagnostics suppressed, or are not to
+ # be subject to -Werror:
+ # flex output may yield harmless "no previous prototype" warnings
+@@ -1385,7 +1391,7 @@ OBJS = \
+ insn-output.o \
+ insn-peep.o \
+ insn-preds.o \
+- insn-recog.o \
++ $(INSNRECOG_SEQ_O) \
+ insn-enums.o \
+ ggc-page.o \
+ adjust-alignment.o \
+@@ -1903,8 +1909,8 @@ TREECHECKING = @TREECHECKING@
+ FULL_DRIVER_NAME=$(target_noncanonical)-gcc-$(version)$(exeext)
+
+ MOSTLYCLEANFILES = insn-flags.h insn-config.h insn-codes.h \
+- insn-output.cc insn-recog.cc $(INSNEMIT_SEQ_SRC) \
+- insn-extract.cc insn-peep.cc \
++ insn-output.cc $(INSNRECOG_SEQ_SRC) insn-recog.h \
++ $(INSNEMIT_SEQ_SRC) insn-extract.cc insn-peep.cc \
+ insn-attr.h insn-attr-common.h insn-attrtab.cc insn-dfatab.cc \
+ insn-latencytab.cc insn-opinit.cc insn-opinit.h insn-preds.cc insn-constants.h \
+ tm-preds.h tm-constrs.h checksum-options $(GIMPLE_MATCH_PD_SEQ_SRC) \
+@@ -2671,7 +2677,8 @@ $(common_out_object_file): $(common_out_file)
+ # and compile them.
+
+ .PRECIOUS: insn-config.h insn-flags.h insn-codes.h insn-constants.h \
+- $(INSNEMIT_SEQ_SRC) insn-recog.cc insn-extract.cc insn-output.cc \
++ $(INSNEMIT_SEQ_SRC) insn-recog.h $(INSNRECOG_SEQ_SRC) \
++ insn-extract.cc insn-output.cc \
+ insn-peep.cc insn-attr.h insn-attr-common.h insn-attrtab.cc \
+ insn-dfatab.cc insn-latencytab.cc insn-preds.cc \
+ $(GIMPLE_MATCH_PD_SEQ_SRC) $(GENERIC_MATCH_PD_SEQ_SRC) \
+@@ -2700,7 +2707,7 @@ simple_rtl_generated_h = insn-attr.h insn-attr-common.h insn-codes.h \
+
+ simple_rtl_generated_c = insn-automata.cc \
+ insn-extract.cc insn-output.cc \
+- insn-peep.cc insn-recog.cc
++ insn-peep.cc
+
+ simple_generated_h = $(simple_rtl_generated_h) insn-constants.h
+
+@@ -2738,6 +2745,18 @@ s-tmp-emit: build/genemit$(build_exeext) $(MD_DEPS) insn-conditions.md
+ insn-emit-$(id).cc;)
+ $(STAMP) s-tmp-emit
+
++# Same for genrecog.
++$(INSNRECOG_SEQ_SRC): s-tmp-recog; @true
++insn-recog.h: s-tmp-recog; @true
++s-tmp-recog: build/genrecog$(build_exeext) $(MD_DEPS) insn-conditions.md
++ $(RUN_GEN) build/genrecog$(build_exeext) $(md_file) insn-conditions.md \
++ -Hinsn-recog.h \
++ $(addprefix -O,${INSNRECOG_SEQ_TMP})
++ $(foreach id, $(INSNRECOG_SPLITS_SEQ), \
++ $(SHELL) $(srcdir)/../move-if-change tmp-recog-$(id).cc \
++ insn-recog-$(id).cc;)
++ $(STAMP) s-tmp-recog
++
+ # gencheck doesn't read the machine description, and the file produced
+ # doesn't use the insn-* convention.
+
+diff --git a/gcc/configure.ac b/gcc/configure.ac
+index c546432b2775..a0d9038ea595 100644
+--- a/gcc/configure.ac
++++ b/gcc/configure.ac
+@@ -913,10 +913,10 @@ fi
+
+ AC_SUBST(DEFAULT_MATCHPD_PARTITIONS)
+
+-# Specify the number of splits of insn-emit.cc to generate.
++# Specify the number of splits of insn-emit.cc and insn-recog.cc to generate.
+ AC_ARG_WITH(insnemit-partitions,
+ [AS_HELP_STRING([--with-insnemit-partitions=num],
+-[Set the number of partitions of insn-emit.cc for genemit to create. [default=10]])],
++[Set the number of partitions of insn-emit.cc for genemit and genrecog to create. [default=10]])],
+ [DEFAULT_INSNEMIT_PARTITIONS="$with_insnemit_partitions"], [DEFAULT_INSNEMIT_PARTITIONS=10])
+ if (test $DEFAULT_INSNEMIT_PARTITIONS -lt 1); then
+ AC_MSG_ERROR(m4_normalize([
+diff --git a/gcc/genconditions.cc b/gcc/genconditions.cc
+index 13963dc3ff46..9da460893d52 100644
+--- a/gcc/genconditions.cc
++++ b/gcc/genconditions.cc
+@@ -141,9 +141,9 @@ write_one_condition (void **slot, void * ARG_UNUSED (dummy))
+ }
+
+ fputs ("\",\n __builtin_constant_p ", stdout);
+- rtx_reader_ptr->print_c_condition (test->expr);
++ rtx_reader_ptr->print_c_condition (stdout, test->expr);
+ fputs ("\n ? (int) ", stdout);
+- rtx_reader_ptr->print_c_condition (test->expr);
++ rtx_reader_ptr->print_c_condition (stdout, test->expr);
+ fputs ("\n : -1 },\n", stdout);
+ return 1;
+ }
+diff --git a/gcc/genpreds.cc b/gcc/genpreds.cc
+index 55d149e8a404..b8f3bf279d97 100644
+--- a/gcc/genpreds.cc
++++ b/gcc/genpreds.cc
+@@ -538,7 +538,7 @@ write_predicate_expr (rtx exp)
+ break;
+
+ case MATCH_TEST:
+- rtx_reader_ptr->print_c_condition (XSTR (exp, 0));
++ rtx_reader_ptr->print_c_condition (stdout, XSTR (exp, 0));
+ break;
+
+ default:
+@@ -1344,7 +1344,7 @@ write_init_reg_class_start_regs ()
+ for (unsigned int i = 0; i < register_filters.length (); ++i)
+ {
+ printf (" if (");
+- rtx_reader_ptr->print_c_condition (register_filters[i]);
++ rtx_reader_ptr->print_c_condition (stdout, register_filters[i]);
+ printf (")\n"
+ " SET_HARD_REG_BIT (%s[%d], regno);\n",
+ "this_target_constraints->register_filters", i);
+diff --git a/gcc/genrecog.cc b/gcc/genrecog.cc
+index ba09ec3b6005..7f7ca728bbe0 100644
+--- a/gcc/genrecog.cc
++++ b/gcc/genrecog.cc
+@@ -4255,9 +4255,9 @@ match_pattern (state *s, md_rtx_info *info, rtx pattern,
+ /* Begin the output file. */
+
+ static void
+-write_header (void)
++write_header (FILE *f, const char *header_filename)
+ {
+- puts ("\
++ fprintf (f, "%s", "\
+ /* Generated automatically by the program `genrecog' from the target\n\
+ machine description file. */\n\
+ \n\
+@@ -4281,10 +4281,12 @@ write_header (void)
+ #include \"diagnostic-core.h\"\n\
+ #include \"reload.h\"\n\
+ #include \"regs.h\"\n\
+-#include \"tm-constrs.h\"\n\
+-\n");
++#include \"tm-constrs.h\"\n");
+
+- puts ("\n\
++ fprintf (f, "#include \"%s\"\n", header_filename);
++ fprintf (f, "%s", "\n");
++
++ fprintf (f, "%s", "\n\
+ /* `recog' contains a decision tree that recognizes whether the rtx\n\
+ X0 is a valid instruction.\n\
+ \n\
+@@ -4293,19 +4295,19 @@ write_header (void)
+ pattern that matched. This is the same as the order in the machine\n\
+ description of the entry that matched. This number can be used as an\n\
+ index into `insn_data' and other tables.\n");
+- puts ("\
++ fprintf (f, "%s", "\
+ The third parameter to recog is an optional pointer to an int. If\n\
+ present, recog will accept a pattern if it matches except for missing\n\
+ CLOBBER expressions at the end. In that case, the value pointed to by\n\
+ the optional pointer will be set to the number of CLOBBERs that need\n\
+ to be added (it should be initialized to zero by the caller). If it");
+- puts ("\
++ fprintf (f, "%s", "\
+ is set nonzero, the caller should allocate a PARALLEL of the\n\
+ appropriate size, copy the initial entries, and call add_clobbers\n\
+ (found in insn-emit.cc) to fill in the CLOBBERs.\n\
+ ");
+
+- puts ("\n\
++ fprintf (f, "%s", "\n\
+ The function split_insns returns 0 if the rtl could not\n\
+ be split or the split rtl as an INSN list if it can be.\n\
+ \n\
+@@ -4463,13 +4465,13 @@ test_position_available_p (output_state *os, const rtx_test &test)
+
+ /* Like printf, but print INDENT spaces at the beginning. */
+
+-static void ATTRIBUTE_PRINTF_2
+-printf_indent (unsigned int indent, const char *format, ...)
++static void ATTRIBUTE_PRINTF_3
++printf_indent (FILE *f, unsigned int indent, const char *format, ...)
+ {
+ va_list ap;
+ va_start (ap, format);
+- printf ("%*s", indent, "");
+- vprintf (format, ap);
++ fprintf (f, "%*s", indent, "");
++ vfprintf (f, format, ap);
+ va_end (ap);
+ }
+
+@@ -4478,7 +4480,7 @@ printf_indent (unsigned int indent, const char *format, ...)
+ OS with the new state. */
+
+ static void
+-change_state (output_state *os, position *pos, unsigned int indent)
++change_state (FILE *f, output_state *os, position *pos, unsigned int indent)
+ {
+ unsigned int var = os->id_to_var[pos->id];
+ gcc_assert (var < os->var_to_id.length () && os->var_to_id[var] == pos->id);
+@@ -4487,19 +4489,19 @@ change_state (output_state *os, position *pos, unsigned int indent)
+ switch (pos->type)
+ {
+ case POS_PEEP2_INSN:
+- printf_indent (indent, "x%d = PATTERN (peep2_next_insn (%d));\n",
++ printf_indent (f, indent, "x%d = PATTERN (peep2_next_insn (%d));\n",
+ var, pos->arg);
+ break;
+
+ case POS_XEXP:
+- change_state (os, pos->base, indent);
+- printf_indent (indent, "x%d = XEXP (x%d, %d);\n",
++ change_state (f, os, pos->base, indent);
++ printf_indent (f, indent, "x%d = XEXP (x%d, %d);\n",
+ var, os->id_to_var[pos->base->id], pos->arg);
+ break;
+
+ case POS_XVECEXP0:
+- change_state (os, pos->base, indent);
+- printf_indent (indent, "x%d = XVECEXP (x%d, 0, %d);\n",
++ change_state (f, os, pos->base, indent);
++ printf_indent (f, indent, "x%d = XVECEXP (x%d, 0, %d);\n",
+ var, os->id_to_var[pos->base->id], pos->arg);
+ break;
+ }
+@@ -4510,11 +4512,11 @@ change_state (output_state *os, position *pos, unsigned int indent)
+ the name. */
+
+ static void
+-print_code (enum rtx_code code)
++print_code (FILE *f, enum rtx_code code)
+ {
+ const char *p;
+ for (p = GET_RTX_NAME (code); *p; p++)
+- putchar (TOUPPER (*p));
++ fprintf (f, "%c", TOUPPER (*p));
+ }
+
+ /* Emit a uint64_t as an integer constant expression. We need to take
+@@ -4522,22 +4524,22 @@ print_code (enum rtx_code code)
+ warnings in the resulting code. */
+
+ static void
+-print_host_wide_int (uint64_t val)
++print_host_wide_int (FILE *f, uint64_t val)
+ {
+ uint64_t min = uint64_t (1) << (HOST_BITS_PER_WIDE_INT - 1);
+ if (val == min)
+- printf ("(" HOST_WIDE_INT_PRINT_DEC_C " - 1)", val + 1);
++ fprintf (f, "(" HOST_WIDE_INT_PRINT_DEC_C " - 1)", val + 1);
+ else
+- printf (HOST_WIDE_INT_PRINT_DEC_C, val);
++ fprintf (f, HOST_WIDE_INT_PRINT_DEC_C, val);
+ }
+
+ /* Print the C expression for actual parameter PARAM. */
+
+ static void
+-print_parameter_value (const parameter &param)
++print_parameter_value (FILE *f, const parameter &param)
+ {
+ if (param.is_param)
+- printf ("i%d", (int) param.value + 1);
++ fprintf (f, "i%d", (int) param.value + 1);
+ else
+ switch (param.type)
+ {
+@@ -4546,23 +4548,23 @@ print_parameter_value (const parameter &param)
+ break;
+
+ case parameter::CODE:
+- print_code ((enum rtx_code) param.value);
++ print_code (f, (enum rtx_code) param.value);
+ break;
+
+ case parameter::MODE:
+- printf ("E_%smode", GET_MODE_NAME ((machine_mode) param.value));
++ fprintf (f, "E_%smode", GET_MODE_NAME ((machine_mode) param.value));
+ break;
+
+ case parameter::INT:
+- printf ("%d", (int) param.value);
++ fprintf (f, "%d", (int) param.value);
+ break;
+
+ case parameter::UINT:
+- printf ("%u", (unsigned int) param.value);
++ fprintf (f, "%u", (unsigned int) param.value);
+ break;
+
+ case parameter::WIDE_INT:
+- print_host_wide_int (param.value);
++ print_host_wide_int (f, param.value);
+ break;
+ }
+ }
+@@ -4570,90 +4572,90 @@ print_parameter_value (const parameter &param)
+ /* Print the C expression for the rtx tested by TEST. */
+
+ static void
+-print_test_rtx (output_state *os, const rtx_test &test)
++print_test_rtx (FILE *f, output_state *os, const rtx_test &test)
+ {
+ if (test.pos_operand >= 0)
+- printf ("operands[%d]", test.pos_operand);
++ fprintf (f, "operands[%d]", test.pos_operand);
+ else
+- printf ("x%d", os->id_to_var[test.pos->id]);
++ fprintf (f, "x%d", os->id_to_var[test.pos->id]);
+ }
+
+ /* Print the C expression for non-boolean test TEST. */
+
+ static void
+-print_nonbool_test (output_state *os, const rtx_test &test)
++print_nonbool_test (FILE *f, output_state *os, const rtx_test &test)
+ {
+ switch (test.kind)
+ {
+ case rtx_test::CODE:
+- printf ("GET_CODE (");
+- print_test_rtx (os, test);
+- printf (")");
++ fprintf (f, "GET_CODE (");
++ print_test_rtx (f, os, test);
++ fprintf (f, ")");
+ break;
+
+ case rtx_test::MODE:
+- printf ("GET_MODE (");
+- print_test_rtx (os, test);
+- printf (")");
++ fprintf (f, "GET_MODE (");
++ print_test_rtx (f, os, test);
++ fprintf (f, ")");
+ break;
+
+ case rtx_test::VECLEN:
+- printf ("XVECLEN (");
+- print_test_rtx (os, test);
+- printf (", 0)");
++ fprintf (f, "XVECLEN (");
++ print_test_rtx (f, os, test);
++ fprintf (f, ", 0)");
+ break;
+
+ case rtx_test::INT_FIELD:
+- printf ("XINT (");
+- print_test_rtx (os, test);
+- printf (", %d)", test.u.opno);
++ fprintf (f, "XINT (");
++ print_test_rtx (f, os, test);
++ fprintf (f, ", %d)", test.u.opno);
+ break;
+
+ case rtx_test::REGNO_FIELD:
+- printf ("REGNO (");
+- print_test_rtx (os, test);
+- printf (")");
++ fprintf (f, "REGNO (");
++ print_test_rtx (f, os, test);
++ fprintf (f, ")");
+ break;
+
+ case rtx_test::SUBREG_FIELD:
+- printf ("SUBREG_BYTE (");
+- print_test_rtx (os, test);
+- printf (")");
++ fprintf (f, "SUBREG_BYTE (");
++ print_test_rtx (f, os, test);
++ fprintf (f, ")");
+ break;
+
+ case rtx_test::WIDE_INT_FIELD:
+- printf ("XWINT (");
+- print_test_rtx (os, test);
+- printf (", %d)", test.u.opno);
++ fprintf (f, "XWINT (");
++ print_test_rtx (f, os, test);
++ fprintf (f, ", %d)", test.u.opno);
+ break;
+
+ case rtx_test::PATTERN:
+ {
+ pattern_routine *routine = test.u.pattern->routine;
+- printf ("pattern%d (", routine->pattern_id);
++ fprintf (f, "pattern%d (", routine->pattern_id);
+ const char *sep = "";
+ if (test.pos)
+ {
+- print_test_rtx (os, test);
++ print_test_rtx (f, os, test);
+ sep = ", ";
+ }
+ if (routine->insn_p)
+ {
+- printf ("%sinsn", sep);
++ fprintf (f, "%sinsn", sep);
+ sep = ", ";
+ }
+ if (routine->pnum_clobbers_p)
+ {
+- printf ("%spnum_clobbers", sep);
++ fprintf (f, "%spnum_clobbers", sep);
+ sep = ", ";
+ }
+ for (unsigned int i = 0; i < test.u.pattern->params.length (); ++i)
+ {
+- fputs (sep, stdout);
+- print_parameter_value (test.u.pattern->params[i]);
++ fprintf (f, "%s\n", sep);
++ print_parameter_value (f, test.u.pattern->params[i]);
+ sep = ", ";
+ }
+- printf (")");
++ fprintf (f, ")");
+ break;
+ }
+
+@@ -4674,10 +4676,11 @@ print_nonbool_test (output_state *os, const rtx_test &test)
+ decision performs TEST. Print the C code for the label. */
+
+ static void
+-print_label_value (const rtx_test &test, bool is_param, uint64_t value)
++print_label_value (FILE *f, const rtx_test &test, bool is_param,
++ uint64_t value)
+ {
+- print_parameter_value (parameter (transition_parameter_type (test.kind),
+- is_param, value));
++ print_parameter_value (f, parameter (transition_parameter_type (test.kind),
++ is_param, value));
+ }
+
+ /* If IS_PARAM, print code to compare TEST with the C variable i<VALUE+1>.
+@@ -4685,7 +4688,7 @@ print_label_value (const rtx_test &test, bool is_param, uint64_t value)
+ Test for inequality if INVERT_P, otherwise test for equality. */
+
+ static void
+-print_test (output_state *os, const rtx_test &test, bool is_param,
++print_test (FILE *f, output_state *os, const rtx_test &test, bool is_param,
+ uint64_t value, bool invert_p)
+ {
+ switch (test.kind)
+@@ -4698,71 +4701,71 @@ print_test (output_state *os, const rtx_test &test, bool is_param,
+ case rtx_test::INT_FIELD:
+ case rtx_test::WIDE_INT_FIELD:
+ case rtx_test::PATTERN:
+- print_nonbool_test (os, test);
+- printf (" %s ", invert_p ? "!=" : "==");
+- print_label_value (test, is_param, value);
++ print_nonbool_test (f, os, test);
++ fprintf (f, " %s ", invert_p ? "!=" : "==");
++ print_label_value (f, test, is_param, value);
+ break;
+
+ case rtx_test::SUBREG_FIELD:
+- printf ("%s (", invert_p ? "maybe_ne" : "known_eq");
+- print_nonbool_test (os, test);
+- printf (", ");
+- print_label_value (test, is_param, value);
+- printf (")");
++ fprintf (f, "%s (", invert_p ? "maybe_ne" : "known_eq");
++ print_nonbool_test (f, os, test);
++ fprintf (f, ", ");
++ print_label_value (f, test, is_param, value);
++ fprintf (f, ")");
+ break;
+
+ case rtx_test::SAVED_CONST_INT:
+ gcc_assert (!is_param && value == 1);
+- print_test_rtx (os, test);
+- printf (" %s const_int_rtx[MAX_SAVED_CONST_INT + ",
+- invert_p ? "!=" : "==");
+- print_parameter_value (parameter (parameter::INT,
+- test.u.integer.is_param,
+- test.u.integer.value));
+- printf ("]");
++ print_test_rtx (f, os, test);
++ fprintf (f, " %s const_int_rtx[MAX_SAVED_CONST_INT + ",
++ invert_p ? "!=" : "==");
++ print_parameter_value (f, parameter (parameter::INT,
++ test.u.integer.is_param,
++ test.u.integer.value));
++ fprintf (f, "]");
+ break;
+
+ case rtx_test::PEEP2_COUNT:
+ gcc_assert (!is_param && value == 1);
+- printf ("peep2_current_count %s %d", invert_p ? "<" : ">=",
+- test.u.min_len);
++ fprintf (f, "peep2_current_count %s %d", invert_p ? "<" : ">=",
++ test.u.min_len);
+ break;
+
+ case rtx_test::VECLEN_GE:
+ gcc_assert (!is_param && value == 1);
+- printf ("XVECLEN (");
+- print_test_rtx (os, test);
+- printf (", 0) %s %d", invert_p ? "<" : ">=", test.u.min_len);
++ fprintf (f, "XVECLEN (");
++ print_test_rtx (f, os, test);
++ fprintf (f, ", 0) %s %d", invert_p ? "<" : ">=", test.u.min_len);
+ break;
+
+ case rtx_test::PREDICATE:
+ gcc_assert (!is_param && value == 1);
+- printf ("%s%s (", invert_p ? "!" : "", test.u.predicate.data->name);
+- print_test_rtx (os, test);
+- printf (", ");
+- print_parameter_value (parameter (parameter::MODE,
+- test.u.predicate.mode_is_param,
+- test.u.predicate.mode));
+- printf (")");
++ fprintf (f, "%s%s (", invert_p ? "!" : "", test.u.predicate.data->name);
++ print_test_rtx (f, os, test);
++ fprintf (f, ", ");
++ print_parameter_value (f, parameter (parameter::MODE,
++ test.u.predicate.mode_is_param,
++ test.u.predicate.mode));
++ fprintf (f, ")");
+ break;
+
+ case rtx_test::DUPLICATE:
+ gcc_assert (!is_param && value == 1);
+- printf ("%srtx_equal_p (", invert_p ? "!" : "");
+- print_test_rtx (os, test);
+- printf (", operands[%d])", test.u.opno);
++ fprintf (f, "%srtx_equal_p (", invert_p ? "!" : "");
++ print_test_rtx (f, os, test);
++ fprintf (f, ", operands[%d])", test.u.opno);
+ break;
+
+ case rtx_test::HAVE_NUM_CLOBBERS:
+ gcc_assert (!is_param && value == 1);
+- printf ("pnum_clobbers %s NULL", invert_p ? "==" : "!=");
++ fprintf (f, "pnum_clobbers %s NULL", invert_p ? "==" : "!=");
+ break;
+
+ case rtx_test::C_TEST:
+ gcc_assert (!is_param && value == 1);
+ if (invert_p)
+- printf ("!");
+- rtx_reader_ptr->print_c_condition (test.u.string);
++ fprintf (f, "!");
++ rtx_reader_ptr->print_c_condition (f, test.u.string);
+ break;
+
+ case rtx_test::ACCEPT:
+@@ -4771,7 +4774,7 @@ print_test (output_state *os, const rtx_test &test, bool is_param,
+ }
+ }
+
+-static exit_state print_decision (output_state *, decision *,
++static exit_state print_decision (FILE *f, output_state *, decision *,
+ unsigned int, bool);
+
+ /* Print code to perform S, indent each line by INDENT spaces.
+@@ -4779,14 +4782,15 @@ static exit_state print_decision (output_state *, decision *,
+ if the state fails then the entire routine fails. */
+
+ static exit_state
+-print_state (output_state *os, state *s, unsigned int indent, bool is_final)
++print_state (FILE *f, output_state *os, state *s, unsigned int indent,
++ bool is_final)
+ {
+ exit_state es = ES_FALLTHROUGH;
+ for (decision *d = s->first; d; d = d->next)
+- es = print_decision (os, d, indent, is_final && !d->next);
++ es = print_decision (f, os, d, indent, is_final && !d->next);
+ if (es != ES_RETURNED && is_final)
+ {
+- printf_indent (indent, "return %s;\n", get_failure_return (os->type));
++ printf_indent (f, indent, "return %s;\n", get_failure_return (os->type));
+ es = ES_RETURNED;
+ }
+ return es;
+@@ -4797,7 +4801,7 @@ print_state (output_state *os, state *s, unsigned int indent, bool is_final)
+ match. */
+
+ static const char *
+-print_subroutine_call (const acceptance_type &acceptance)
++print_subroutine_call (FILE *f, const acceptance_type &acceptance)
+ {
+ switch (acceptance.type)
+ {
+@@ -4805,17 +4809,17 @@ print_subroutine_call (const acceptance_type &acceptance)
+ gcc_unreachable ();
+
+ case RECOG:
+- printf ("recog_%d (x1, insn, pnum_clobbers)",
+- acceptance.u.subroutine_id);
++ fprintf (f, "recog_%d (x1, insn, pnum_clobbers)",
++ acceptance.u.subroutine_id);
+ return ">= 0";
+
+ case SPLIT:
+- printf ("split_%d (x1, insn)", acceptance.u.subroutine_id);
++ fprintf (f, "split_%d (x1, insn)", acceptance.u.subroutine_id);
+ return "!= NULL_RTX";
+
+ case PEEPHOLE2:
+- printf ("peephole2_%d (x1, insn, pmatch_len_)",
+- acceptance.u.subroutine_id);
++ fprintf (f, "peephole2_%d (x1, insn, pmatch_len_)",
++ acceptance.u.subroutine_id);
+ return "!= NULL_RTX";
+ }
+ gcc_unreachable ();
+@@ -4825,63 +4829,65 @@ print_subroutine_call (const acceptance_type &acceptance)
+ INDENT and IS_FINAL are as for print_state. */
+
+ static exit_state
+-print_acceptance (const acceptance_type &acceptance, unsigned int indent,
+- bool is_final)
++print_acceptance (FILE *f, const acceptance_type &acceptance,
++ unsigned int indent, bool is_final)
+ {
+ if (acceptance.partial_p)
+ {
+ /* Defer the rest of the match to a subroutine. */
+ if (is_final)
+ {
+- printf_indent (indent, "return ");
+- print_subroutine_call (acceptance);
+- printf (";\n");
++ printf_indent (f, indent, "return ");
++ print_subroutine_call (f, acceptance);
++ fprintf (f, ";\n");
+ return ES_RETURNED;
+ }
+ else
+ {
+- printf_indent (indent, "res = ");
+- const char *res_test = print_subroutine_call (acceptance);
+- printf (";\n");
+- printf_indent (indent, "if (res %s)\n", res_test);
+- printf_indent (indent + 2, "return res;\n");
++ printf_indent (f, indent, "res = ");
++ const char *res_test = print_subroutine_call (f, acceptance);
++ fprintf (f, ";\n");
++ printf_indent (f, indent, "if (res %s)\n", res_test);
++ printf_indent (f, indent + 2, "return res;\n");
+ return ES_FALLTHROUGH;
+ }
+ }
+ switch (acceptance.type)
+ {
+ case SUBPATTERN:
+- printf_indent (indent, "return %d;\n", acceptance.u.full.code);
++ printf_indent (f, indent, "return %d;\n", acceptance.u.full.code);
+ return ES_RETURNED;
+
+ case RECOG:
+ if (acceptance.u.full.u.num_clobbers != 0)
+- printf_indent (indent, "*pnum_clobbers = %d;\n",
++ printf_indent (f, indent, "*pnum_clobbers = %d;\n",
+ acceptance.u.full.u.num_clobbers);
+- printf_indent (indent, "return %d; /* %s */\n", acceptance.u.full.code,
++ printf_indent (f, indent, "return %d; /* %s */\n", acceptance.u.full.code,
+ get_insn_name (acceptance.u.full.code));
+ return ES_RETURNED;
+
+ case SPLIT:
+- printf_indent (indent, "return gen_split_%d (insn, operands);\n",
++ printf_indent (f, indent, "return gen_split_%d (insn, operands);\n",
+ acceptance.u.full.code);
+ return ES_RETURNED;
+
+ case PEEPHOLE2:
+- printf_indent (indent, "*pmatch_len_ = %d;\n",
++ printf_indent (f, indent, "*pmatch_len_ = %d;\n",
+ acceptance.u.full.u.match_len);
+ if (is_final)
+ {
+- printf_indent (indent, "return gen_peephole2_%d (insn, operands);\n",
++ printf_indent (f, indent,
++ "return gen_peephole2_%d (insn, operands);\n",
+ acceptance.u.full.code);
+ return ES_RETURNED;
+ }
+ else
+ {
+- printf_indent (indent, "res = gen_peephole2_%d (insn, operands);\n",
++ printf_indent (f,
++ indent, "res = gen_peephole2_%d (insn, operands);\n",
+ acceptance.u.full.code);
+- printf_indent (indent, "if (res != NULL_RTX)\n");
+- printf_indent (indent + 2, "return res;\n");
++ printf_indent (f, indent, "if (res != NULL_RTX)\n");
++ printf_indent (f, indent + 2, "return res;\n");
+ return ES_FALLTHROUGH;
+ }
+ }
+@@ -4891,7 +4897,7 @@ print_acceptance (const acceptance_type &acceptance, unsigned int indent,
+ /* Print code to perform D. INDENT and IS_FINAL are as for print_state. */
+
+ static exit_state
+-print_decision (output_state *os, decision *d, unsigned int indent,
++print_decision (FILE *f, output_state *os, decision *d, unsigned int indent,
+ bool is_final)
+ {
+ uint64_t label;
+@@ -4900,7 +4906,7 @@ print_decision (output_state *os, decision *d, unsigned int indent,
+ /* Make sure the rtx under test is available either in operands[] or
+ in an xN variable. */
+ if (d->test.pos && d->test.pos_operand < 0)
+- change_state (os, d->test.pos, indent);
++ change_state (f, os, d->test.pos, indent);
+
+ /* Look for cases where a pattern routine P1 calls another pattern routine
+ P2 and where P1 returns X + BASE whenever P2 returns X. If IS_FINAL
+@@ -4924,32 +4930,32 @@ print_decision (output_state *os, decision *d, unsigned int indent,
+ {
+ if (is_final && base == 0)
+ {
+- printf_indent (indent, "return ");
+- print_nonbool_test (os, d->test);
+- printf ("; /* [-1, %d] */\n", count - 1);
++ printf_indent (f, indent, "return ");
++ print_nonbool_test (f, os, d->test);
++ fprintf (f, "; /* [-1, %d] */\n", count - 1);
+ return ES_RETURNED;
+ }
+ else
+ {
+- printf_indent (indent, "res = ");
+- print_nonbool_test (os, d->test);
+- printf (";\n");
+- printf_indent (indent, "if (res >= 0)\n");
+- printf_indent (indent + 2, "return res");
++ printf_indent (f, indent, "res = ");
++ print_nonbool_test (f, os, d->test);
++ fprintf (f, ";\n");
++ printf_indent (f, indent, "if (res >= 0)\n");
++ printf_indent (f, indent + 2, "return res");
+ if (base != 0)
+- printf (" + %d", base);
+- printf ("; /* [%d, %d] */\n", base, base + count - 1);
++ fprintf (f, " + %d", base);
++ fprintf (f, "; /* [%d, %d] */\n", base, base + count - 1);
+ return ES_FALLTHROUGH;
+ }
+ }
+ else if (d->test.kind == rtx_test::ACCEPT)
+- return print_acceptance (d->test.u.acceptance, indent, is_final);
++ return print_acceptance (f, d->test.u.acceptance, indent, is_final);
+ else if (d->test.kind == rtx_test::SET_OP)
+ {
+- printf_indent (indent, "operands[%d] = ", d->test.u.opno);
+- print_test_rtx (os, d->test);
+- printf (";\n");
+- return print_state (os, d->singleton ()->to, indent, is_final);
++ printf_indent (f, indent, "operands[%d] = ", d->test.u.opno);
++ print_test_rtx (f, os, d->test);
++ fprintf (f, ";\n");
++ return print_state (f, os, d->singleton ()->to, indent, is_final);
+ }
+ /* Handle decisions with a single transition and a single transition
+ label. */
+@@ -4957,13 +4963,13 @@ print_decision (output_state *os, decision *d, unsigned int indent,
+ {
+ transition *trans = d->singleton ();
+ if (mark_optional_transitions_p && trans->optional)
+- printf_indent (indent, "/* OPTIONAL IF */\n");
++ printf_indent (f, indent, "/* OPTIONAL IF */\n");
+
+ /* Print the condition associated with TRANS. Invert it if IS_FINAL,
+ so that we return immediately on failure and fall through on
+ success. */
+- printf_indent (indent, "if (");
+- print_test (os, d->test, trans->is_param, label, is_final);
++ printf_indent (f, indent, "if (");
++ print_test (f, os, d->test, trans->is_param, label, is_final);
+
+ /* Look for following states that would be handled by this code
+ on recursion. If they don't need any preparatory statements,
+@@ -4979,13 +4985,13 @@ print_decision (output_state *os, decision *d, unsigned int indent,
+ || !test_position_available_p (os, d->test))
+ break;
+ trans = d->first;
+- printf ("\n");
++ fprintf (f, "\n");
+ if (mark_optional_transitions_p && trans->optional)
+- printf_indent (indent + 4, "/* OPTIONAL IF */\n");
+- printf_indent (indent + 4, "%s ", is_final ? "||" : "&&");
+- print_test (os, d->test, trans->is_param, label, is_final);
++ printf_indent (f, indent + 4, "/* OPTIONAL IF */\n");
++ printf_indent (f, indent + 4, "%s ", is_final ? "||" : "&&");
++ print_test (f, os, d->test, trans->is_param, label, is_final);
+ }
+- printf (")\n");
++ fprintf (f, ")\n");
+
+ /* Print the conditional code with INDENT + 2 and the fallthrough
+ code with indent INDENT. */
+@@ -4994,9 +5000,9 @@ print_decision (output_state *os, decision *d, unsigned int indent,
+ {
+ /* We inverted the condition above, so return failure in the
+ "if" body and fall through to the target of the transition. */
+- printf_indent (indent + 2, "return %s;\n",
++ printf_indent (f, indent + 2, "return %s;\n",
+ get_failure_return (os->type));
+- return print_state (os, to, indent, is_final);
++ return print_state (f, os, to, indent, is_final);
+ }
+ else if (to->singleton ()
+ && to->first->test.kind == rtx_test::ACCEPT
+@@ -5004,7 +5010,7 @@ print_decision (output_state *os, decision *d, unsigned int indent,
+ {
+ /* The target of the transition is a simple "return" statement.
+ It doesn't need any braces and doesn't fall through. */
+- if (print_acceptance (to->first->test.u.acceptance,
++ if (print_acceptance (f, to->first->test.u.acceptance,
+ indent + 2, true) != ES_RETURNED)
+ gcc_unreachable ();
+ return ES_FALLTHROUGH;
+@@ -5018,9 +5024,9 @@ print_decision (output_state *os, decision *d, unsigned int indent,
+ auto_vec <bool, 32> old_seen;
+ old_seen.safe_splice (os->seen_vars);
+
+- printf_indent (indent + 2, "{\n");
+- print_state (os, trans->to, indent + 4, is_final);
+- printf_indent (indent + 2, "}\n");
++ printf_indent (f, indent + 2, "{\n");
++ print_state (f, os, trans->to, indent + 4, is_final);
++ printf_indent (f, indent + 2, "}\n");
+
+ os->seen_vars.truncate (0);
+ os->seen_vars.splice (old_seen);
+@@ -5030,48 +5036,48 @@ print_decision (output_state *os, decision *d, unsigned int indent,
+ else
+ {
+ /* Output the decision as a switch statement. */
+- printf_indent (indent, "switch (");
+- print_nonbool_test (os, d->test);
+- printf (")\n");
++ printf_indent (f, indent, "switch (");
++ print_nonbool_test (f, os, d->test);
++ fprintf (f, ")\n");
+
+ /* Each case statement starts with the same set of valid variables.
+ These are also the only variables will be valid on fallthrough. */
+ auto_vec <bool, 32> old_seen;
+ old_seen.safe_splice (os->seen_vars);
+
+- printf_indent (indent + 2, "{\n");
++ printf_indent (f, indent + 2, "{\n");
+ for (transition *trans = d->first; trans; trans = trans->next)
+ {
+ gcc_assert (!trans->is_param);
+ if (mark_optional_transitions_p && trans->optional)
+- printf_indent (indent + 2, "/* OPTIONAL CASE */\n");
++ printf_indent (f, indent + 2, "/* OPTIONAL CASE */\n");
+ for (int_set::iterator j = trans->labels.begin ();
+ j != trans->labels.end (); ++j)
+ {
+- printf_indent (indent + 2, "case ");
+- print_label_value (d->test, trans->is_param, *j);
+- printf (":\n");
++ printf_indent (f, indent + 2, "case ");
++ print_label_value (f, d->test, trans->is_param, *j);
++ fprintf (f, ":\n");
+ }
+- if (print_state (os, trans->to, indent + 4, is_final))
++ if (print_state (f, os, trans->to, indent + 4, is_final))
+ {
+ /* The state can fall through. Add an explicit break. */
+ gcc_assert (!is_final);
+- printf_indent (indent + 4, "break;\n");
++ printf_indent (f, indent + 4, "break;\n");
+ }
+- printf ("\n");
++ fprintf (f, "\n");
+
+ /* Restore the original set of valid variables. */
+ os->seen_vars.truncate (0);
+ os->seen_vars.splice (old_seen);
+ }
+ /* Add a default case. */
+- printf_indent (indent + 2, "default:\n");
++ printf_indent (f, indent + 2, "default:\n");
+ if (is_final)
+- printf_indent (indent + 4, "return %s;\n",
++ printf_indent (f, indent + 4, "return %s;\n",
+ get_failure_return (os->type));
+ else
+- printf_indent (indent + 4, "break;\n");
+- printf_indent (indent + 2, "}\n");
++ printf_indent (f, indent + 4, "break;\n");
++ printf_indent (f, indent + 2, "}\n");
+ return is_final ? ES_RETURNED : ES_FALLTHROUGH;
+ }
+ }
+@@ -5114,10 +5120,10 @@ assign_position_vars (output_state *os, state *s)
+ only ROOT's variable has a valid value. */
+
+ static void
+-print_subroutine_start (output_state *os, state *s, position *root)
++print_subroutine_start (FILE *f, output_state *os, state *s, position *root)
+ {
+- printf ("{\n rtx * const operands ATTRIBUTE_UNUSED"
+- " = &recog_data.operand[0];\n");
++ fprintf (f, "{\n rtx * const operands ATTRIBUTE_UNUSED"
++ " = &recog_data.operand[0];\n");
+ os->var_to_id.truncate (0);
+ os->seen_vars.truncate (0);
+ if (root)
+@@ -5140,9 +5146,9 @@ print_subroutine_start (output_state *os, state *s, position *root)
+ {
+ for (unsigned int i = 2; i < num_vars; ++i)
+ /* Print 8 rtx variables to a line. */
+- printf ("%s x%d",
++ fprintf (f, "%s x%d",
+ i == 2 ? " rtx" : (i - 2) % 8 == 0 ? ";\n rtx" : ",", i);
+- printf (";\n");
++ fprintf (f, ";\n");
+ }
+
+ /* Say that x1 is valid and the rest aren't. */
+@@ -5150,22 +5156,26 @@ print_subroutine_start (output_state *os, state *s, position *root)
+ os->seen_vars[1] = true;
+ }
+ if (os->type == SUBPATTERN || os->type == RECOG)
+- printf (" int res ATTRIBUTE_UNUSED;\n");
++ fprintf (f, " int res ATTRIBUTE_UNUSED;\n");
+ else
+- printf (" rtx_insn *res ATTRIBUTE_UNUSED;\n");
++ fprintf (f, " rtx_insn *res ATTRIBUTE_UNUSED;\n");
+ }
+
+ /* Output the definition of pattern routine ROUTINE. */
+
+ static void
+-print_pattern (output_state *os, pattern_routine *routine)
++print_pattern (FILE *f, output_state *os, pattern_routine *routine,
++ bool in_header = false)
+ {
+- printf ("\nstatic int\npattern%d (", routine->pattern_id);
++ if (!in_header)
++ fprintf (f, "\nint\npattern%d (", routine->pattern_id);
++ else
++ fprintf (f, "\nextern int\npattern%d (", routine->pattern_id);
+ const char *sep = "";
+ /* Add the top-level rtx parameter, if any. */
+ if (routine->pos)
+ {
+- printf ("%srtx x1", sep);
++ fprintf (f, "%srtx x1", sep);
+ sep = ", ";
+ }
+ /* Add the optional parameters. */
+@@ -5173,26 +5183,34 @@ print_pattern (output_state *os, pattern_routine *routine)
+ {
+ /* We can't easily tell whether a C condition actually reads INSN,
+ so add an ATTRIBUTE_UNUSED just in case. */
+- printf ("%srtx_insn *insn ATTRIBUTE_UNUSED", sep);
++ fprintf (f, "%srtx_insn *insn ATTRIBUTE_UNUSED", sep);
+ sep = ", ";
+ }
+ if (routine->pnum_clobbers_p)
+ {
+- printf ("%sint *pnum_clobbers", sep);
++ fprintf (f, "%sint *pnum_clobbers", sep);
+ sep = ", ";
+ }
+ /* Add the "i" parameters. */
+ for (unsigned int i = 0; i < routine->param_types.length (); ++i)
+ {
+- printf ("%s%s i%d", sep,
+- parameter_type_string (routine->param_types[i]), i + 1);
++ fprintf (f, "%s%s i%d", sep,
++ parameter_type_string (routine->param_types[i]), i + 1);
+ sep = ", ";
+ }
+- printf (")\n");
++
++ if (!in_header)
++ fprintf (f, ")\n");
++ else
++ {
++ fprintf (f, ");\n");
++ return;
++ }
++
+ os->type = SUBPATTERN;
+- print_subroutine_start (os, routine->s, routine->pos);
+- print_state (os, routine->s, 2, true);
+- printf ("}\n");
++ print_subroutine_start (f, os, routine->s, routine->pos);
++ print_state (f, os, routine->s, 2, true);
++ fprintf (f, "}\n");
+ }
+
+ /* Output a routine of type TYPE that implements S. PROC_ID is the
+@@ -5200,9 +5218,26 @@ print_pattern (output_state *os, pattern_routine *routine)
+ routine. */
+
+ static void
+-print_subroutine (output_state *os, state *s, int proc_id)
+-{
+- printf ("\n");
++print_subroutine (FILE *f, output_state *os, state *s, int proc_id,
++ bool in_header = false)
++{
++ fprintf (f, "\n");
++ const char *specifier_ext = "extern";
++ const char *specifier_default = "";
++ const char *specifier;
++ if (!in_header)
++ specifier = specifier_default;
++ else
++ specifier = specifier_ext;
++
++ const char *end;
++ const char *end_default = "";
++ const char *end_header = ";";
++ if (!in_header)
++ end = end_default;
++ else
++ end = end_header;
++
+ switch (os->type)
+ {
+ case SUBPATTERN:
+@@ -5210,46 +5245,54 @@ print_subroutine (output_state *os, state *s, int proc_id)
+
+ case RECOG:
+ if (proc_id)
+- printf ("static int\nrecog_%d", proc_id);
++ fprintf (f, "%s int\nrecog_%d", specifier, proc_id);
+ else
+- printf ("int\nrecog");
+- printf (" (rtx x1 ATTRIBUTE_UNUSED,\n"
+- "\trtx_insn *insn ATTRIBUTE_UNUSED,\n"
+- "\tint *pnum_clobbers ATTRIBUTE_UNUSED)\n");
++ fprintf (f, "%s int\nrecog", specifier);
++ fprintf (f, " (rtx x1 ATTRIBUTE_UNUSED,\n"
++ "\trtx_insn *insn ATTRIBUTE_UNUSED,\n"
++ "\tint *pnum_clobbers ATTRIBUTE_UNUSED)%s\n", end);
+ break;
+
+ case SPLIT:
+ if (proc_id)
+- printf ("static rtx_insn *\nsplit_%d", proc_id);
++ fprintf (f, "%s rtx_insn *\nsplit_%d", specifier, proc_id);
+ else
+- printf ("rtx_insn *\nsplit_insns");
+- printf (" (rtx x1 ATTRIBUTE_UNUSED, rtx_insn *insn ATTRIBUTE_UNUSED)\n");
++ fprintf (f, "%s rtx_insn *\nsplit_insns", specifier);
++ fprintf (f, " (rtx x1 ATTRIBUTE_UNUSED, "
++ "rtx_insn *insn ATTRIBUTE_UNUSED)%s\n", end);
+ break;
+
+ case PEEPHOLE2:
+ if (proc_id)
+- printf ("static rtx_insn *\npeephole2_%d", proc_id);
++ fprintf (f, "%s rtx_insn *\npeephole2_%d", specifier, proc_id);
+ else
+- printf ("rtx_insn *\npeephole2_insns");
+- printf (" (rtx x1 ATTRIBUTE_UNUSED,\n"
+- "\trtx_insn *insn ATTRIBUTE_UNUSED,\n"
+- "\tint *pmatch_len_ ATTRIBUTE_UNUSED)\n");
++ fprintf (f, "%s rtx_insn *\npeephole2_insns", specifier);
++ fprintf (f, " (rtx x1 ATTRIBUTE_UNUSED,\n"
++ "\trtx_insn *insn ATTRIBUTE_UNUSED,\n"
++ "\tint *pmatch_len_ ATTRIBUTE_UNUSED)%s\n", end);
+ break;
+ }
+- print_subroutine_start (os, s, &root_pos);
++
++ if (in_header)
++ return;
++
++ print_subroutine_start (f, os, s, &root_pos);
+ if (proc_id == 0)
+ {
+- printf (" recog_data.insn = NULL;\n");
++ fprintf (f, " recog_data.insn = NULL;\n");
+ }
+- print_state (os, s, 2, true);
+- printf ("}\n");
++ print_state (f, os, s, 2, true);
++ fprintf (f, "}\n");
+ }
+
+ /* Print out a routine of type TYPE that performs ROOT. */
+
+ static void
+-print_subroutine_group (output_state *os, routine_type type, state *root)
++print_subroutine_group (vec<FILE *> &vec, FILE *header, output_state *os,
++ routine_type type, state *root)
+ {
++ FILE *f;
++ unsigned idx;
+ os->type = type;
+ if (use_subroutines_p)
+ {
+@@ -5261,11 +5304,20 @@ print_subroutine_group (output_state *os, routine_type type, state *root)
+ /* Output the subroutines (but not ROOT itself). */
+ unsigned int i;
+ state *s;
++
++ FILE *f = header;
++ FOR_EACH_VEC_ELT (subroutines, i, s)
++ print_subroutine (header, os, s, i + 1, true);
++
+ FOR_EACH_VEC_ELT (subroutines, i, s)
+- print_subroutine (os, s, i + 1);
++ {
++ f = choose_output (vec, idx);
++ print_subroutine (f, os, s, i + 1);
++ }
+ }
+ /* Output the main routine. */
+- print_subroutine (os, root, 0);
++ f = choose_output (vec, idx);
++ print_subroutine (f, os, root, 0);
+ }
+
+ /* Return the rtx pattern for the list of rtxes in a define_peephole2. */
+@@ -5336,6 +5388,29 @@ remove_clobbers (acceptance_type *acceptance_ptr, rtx *pattern_ptr)
+ return true;
+ }
+
++auto_vec<FILE *, 10> output_files;
++char header_name[255];
++FILE *header = NULL;
++
++static bool
++handle_arg (const char *arg)
++{
++ printf ("%s\n", arg);
++ if (arg[1] == 'O')
++ {
++ FILE *file = fopen (&arg[2], "w");
++ output_files.safe_push (file);
++ return true;
++ }
++ if (arg[1] == 'H')
++ {
++ snprintf (header_name, 255, "%s", &arg[2]);
++ header = fopen (header_name, "w");
++ return true;
++ }
++ return false;
++}
++
+ int
+ main (int argc, const char **argv)
+ {
+@@ -5343,10 +5418,17 @@ main (int argc, const char **argv)
+
+ progname = "genrecog";
+
+- if (!init_rtx_reader_args (argc, argv))
++ if (!init_rtx_reader_args_cb (argc, argv, handle_arg))
+ return (FATAL_EXIT_CODE);
+
+- write_header ();
++ if (output_files.is_empty ())
++ output_files.safe_push (stdout);
++
++ for (auto f : output_files)
++ write_header (f, header_name);
++
++ FILE *file = NULL;
++ unsigned file_idx;
+
+ /* Read the machine description. */
+
+@@ -5354,6 +5436,7 @@ main (int argc, const char **argv)
+ while (read_md_rtx (&info))
+ {
+ rtx def = info.def;
++ file = choose_output (output_files, file_idx);
+
+ acceptance_type acceptance;
+ acceptance.partial_p = false;
+@@ -5387,8 +5470,8 @@ main (int argc, const char **argv)
+
+ /* Declare the gen_split routine that we'll call if the
+ pattern matches. The definition comes from insn-emit.cc. */
+- printf ("extern rtx_insn *gen_split_%d (rtx_insn *, rtx *);\n",
+- info.index);
++ fprintf (header, "extern rtx_insn *gen_split_%d "
++ "(rtx_insn *, rtx *);\n", info.index);
+ break;
+
+ case DEFINE_PEEPHOLE2:
+@@ -5399,8 +5482,8 @@ main (int argc, const char **argv)
+
+ /* Declare the gen_peephole2 routine that we'll call if the
+ pattern matches. The definition comes from insn-emit.cc. */
+- printf ("extern rtx_insn *gen_peephole2_%d (rtx_insn *, rtx *);\n",
+- info.index);
++ fprintf (header, "extern rtx_insn *gen_peephole2_%d "
++ "(rtx_insn *, rtx *);\n", info.index);
+ break;
+
+ default:
+@@ -5411,7 +5494,8 @@ main (int argc, const char **argv)
+ if (have_error)
+ return FATAL_EXIT_CODE;
+
+- puts ("\n\n");
++ for (auto f : output_files)
++ fprintf (f, "%s", "\n\n");
+
+ /* Optimize each routine in turn. */
+ optimize_subroutine_group ("recog", &insn_root);
+@@ -5433,15 +5517,27 @@ main (int argc, const char **argv)
+ /* Print out the routines that we just created. */
+ unsigned int i;
+ pattern_routine *routine;
++
+ FOR_EACH_VEC_ELT (patterns, i, routine)
+- print_pattern (&os, routine);
++ print_pattern (header, &os, routine, true);
++
++ FOR_EACH_VEC_ELT (patterns, i, routine)
++ {
++ file = choose_output (output_files, file_idx);
++ print_pattern (file, &os, routine);
++ }
+ }
+
+ /* Print out the matching routines. */
+- print_subroutine_group (&os, RECOG, &insn_root);
+- print_subroutine_group (&os, SPLIT, &split_root);
+- print_subroutine_group (&os, PEEPHOLE2, &peephole2_root);
++ print_subroutine_group (output_files, header, &os, RECOG, &insn_root);
++ print_subroutine_group (output_files, header, &os, SPLIT, &split_root);
++ print_subroutine_group (output_files, header, &os, PEEPHOLE2, &peephole2_root);
++
++ fclose (header);
+
+- fflush (stdout);
+- return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
++ int ret = SUCCESS_EXIT_CODE;
++ for (FILE *f : output_files)
++ if (fclose (f) != 0)
++ ret = FATAL_EXIT_CODE;
++ return ret;
+ }
+diff --git a/gcc/gentarget-def.cc b/gcc/gentarget-def.cc
+index 061b1e7247c1..3a462560cc1b 100644
+--- a/gcc/gentarget-def.cc
++++ b/gcc/gentarget-def.cc
+@@ -191,7 +191,7 @@ def_target_insn (const char *name, const char *prototype)
+ printf ("target_have_%s (void)\n", name);
+ printf ("{\n");
+ printf (" return ");
+- rtx_reader_ptr->print_c_condition (test);
++ rtx_reader_ptr->print_c_condition (stdout, test);
+ printf (";\n");
+ printf ("}\n");
+ }
+diff --git a/gcc/read-md.cc b/gcc/read-md.cc
+index 93d1ea437812..aeb1cced00d0 100644
+--- a/gcc/read-md.cc
++++ b/gcc/read-md.cc
+@@ -192,9 +192,9 @@ md_reader::fprint_c_condition (FILE *outf, const char *cond)
+ /* Special fprint_c_condition for writing to STDOUT. */
+
+ void
+-md_reader::print_c_condition (const char *cond)
++md_reader::print_c_condition (FILE *outf, const char *cond)
+ {
+- fprint_c_condition (stdout, cond);
++ fprint_c_condition (outf, cond);
+ }
+
+ /* A vfprintf-like function for reporting an error against line LINENO
+diff --git a/gcc/read-md.h b/gcc/read-md.h
+index e613c42b7241..b42add391ed8 100644
+--- a/gcc/read-md.h
++++ b/gcc/read-md.h
+@@ -205,7 +205,7 @@ class md_reader
+
+ const char *join_c_conditions (const char *cond1, const char *cond2);
+ void fprint_c_condition (FILE *outf, const char *cond);
+- void print_c_condition (const char *cond);
++ void print_c_condition (FILE *outf, const char *cond);
+
+ /* Defined in read-rtl.cc. */
+ const char *apply_iterator_to_string (const char *string);
+
+base-commit: a22dfe208d94105a6e587a3b25e8fe8d62444d8a
+--
+2.47.1
+
diff --git a/15.0.0/gentoo/72_all_PR117628-libgcc-c23.patch b/15.0.0/gentoo/72_all_PR117628-libgcc-c23.patch
deleted file mode 100644
index ddfb652..0000000
--- a/15.0.0/gentoo/72_all_PR117628-libgcc-c23.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From b750323260c1ceb47c64e98ddab7095696b00a6d Mon Sep 17 00:00:00 2001
-Message-ID: <b750323260c1ceb47c64e98ddab7095696b00a6d.1731921825.git.sam@gentoo.org>
-From: Sam James <sam@gentoo.org>
-Date: Mon, 18 Nov 2024 09:22:33 +0000
-Subject: [PATCH] libgcc: fix C23 issues
-
-This includes Jeff's patch from https://inbox.sourceware.org/gcc-patches/9cb69002-9754-476a-a525-68dcca9c23d8@gmail.com/.
-
-Bug: https://gcc.gnu.org/PR117628
---- a/libgcc/config/arm/linux-atomic-64bit.c
-+++ b/libgcc/config/arm/linux-atomic-64bit.c
-@@ -141,9 +141,7 @@ __sync_val_compare_and_swap_8 (long long *ptr, long long oldval,
- }
- }
-
--typedef unsigned char bool;
--
--bool HIDDEN
-+unsigned char HIDDEN
- __sync_bool_compare_and_swap_8 (long long *ptr, long long oldval,
- long long newval)
- {
---- a/libgcc/config/arm/linux-atomic.c
-+++ b/libgcc/config/arm/linux-atomic.c
-@@ -249,9 +249,7 @@ __sync_val_compare_and_swap_4 (int *ptr, int oldval, int newval)
- SUBWORD_VAL_CAS (short, 2)
- SUBWORD_VAL_CAS (signed char, 1)
-
--typedef unsigned char bool;
--
--bool HIDDEN
-+unsigned char HIDDEN
- __sync_bool_compare_and_swap_4 (int *ptr, int oldval, int newval)
- {
- int failure = __kernel_cmpxchg (oldval, newval, ptr);
-@@ -259,7 +257,7 @@ __sync_bool_compare_and_swap_4 (int *ptr, int oldval, int newval)
- }
-
- #define SUBWORD_BOOL_CAS(TYPE, WIDTH) \
-- bool HIDDEN \
-+ unsigned char HIDDEN \
- __sync_bool_compare_and_swap_##WIDTH (TYPE *ptr, TYPE oldval, \
- TYPE newval) \
- { \
---- a/libgcc/config/csky/linux-atomic.c
-+++ b/libgcc/config/csky/linux-atomic.c
-@@ -215,8 +215,6 @@ __sync_val_compare_and_swap_4 (int *ptr, int oldval, int newval)
- SUBWORD_VAL_CAS (unsigned short, 2)
- SUBWORD_VAL_CAS (unsigned char, 1)
-
--typedef unsigned char bool;
--
- bool HIDDEN
- __sync_bool_compare_and_swap_4 (int *ptr, int oldval, int newval)
- {
---- a/libgcc/unwind-arm-common.inc
-+++ b/libgcc/unwind-arm-common.inc
-@@ -52,8 +52,6 @@
-
- /* Definitions for C++ runtime support routines. We make these weak
- declarations to avoid pulling in libsupc++ unnecessarily. */
--typedef unsigned char bool;
--
- typedef struct _ZSt9type_info type_info; /* This names C++ type_info type */
- enum __cxa_type_match_result
- {
-
-base-commit: 45a3277149d95a51cf9109cab87ee39a7dce73e2
---
-2.47.0
-
diff --git a/15.0.0/gentoo/README.history b/15.0.0/gentoo/README.history
index a17533c..5fb36c9 100644
--- a/15.0.0/gentoo/README.history
+++ b/15.0.0/gentoo/README.history
@@ -1,5 +1,18 @@
-??
+29 1 December 2024
+ - 72_all_PR111600-genemit-Distribute-evenly-to-files.patch
+ U 04_all_nossp-on-nostdlib.patch
+ U 26_all_enable-cet.patch
+ U 28_all_drop_CFLAGS_sed.patch
+
+28 25 November 2024
+
+ + 72_all_PR111600-genemit-Distribute-evenly-to-files.patch
+
+27 24 November 2024
+
+ + 34_all_time64_ssemath.patch
+ - 72_all_PR117628-libgcc-c23.patch
- 73_all_PR117646-match-Fix-the-max-a-b-0-pattern-for-pointers.patch
26 18 November 2024