aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam James <sam@gentoo.org>2023-10-31 19:56:42 +0000
committerSam James <sam@gentoo.org>2023-10-31 19:56:42 +0000
commit2b02f083e67e97f8187d3ec023c3d281f49232c0 (patch)
tree54239f00091df1f2d01a25579645ae28321f69df
parent14.0.0: update 75_all_PR54179_genemit-Split-insn-emit.cc-into-ten-files.patch (diff)
downloadgcc-patches-2b02f083.tar.gz
gcc-patches-2b02f083.tar.bz2
gcc-patches-2b02f083.zip
14.0.0: drop upstreamed 75_all_PR54179_genemit-Split-insn-emit.cc-into-ten-files.patch
For the benefit of 9999 users. Signed-off-by: Sam James <sam@gentoo.org>
-rw-r--r--14.0.0/gentoo/75_all_PR54179_genemit-Split-insn-emit.cc-into-ten-files.patch1405
1 files changed, 0 insertions, 1405 deletions
diff --git a/14.0.0/gentoo/75_all_PR54179_genemit-Split-insn-emit.cc-into-ten-files.patch b/14.0.0/gentoo/75_all_PR54179_genemit-Split-insn-emit.cc-into-ten-files.patch
deleted file mode 100644
index bd31760..0000000
--- a/14.0.0/gentoo/75_all_PR54179_genemit-Split-insn-emit.cc-into-ten-files.patch
+++ /dev/null
@@ -1,1405 +0,0 @@
-https://gcc.gnu.org/PR54179
-https://inbox.sourceware.org/gcc-patches/de0f7bdc-d236-4f5b-9504-d5bfb215d023@gmail.com/
-
-From a3804c98c5f73c02b3732b06a15dc4a397e60dad Mon Sep 17 00:00:00 2001
-From: Robin Dapp <rdapp.gcc@gmail.com>
-Date: Fri, 27 Oct 2023 21:04:25 +0200
-Subject: [PATCH] genemit: Split insn-emit.cc into ten files.
-
-After working with Sam off-list (thanks) I managed to get hppa to
-build. Initially it looked as if hppa just had a very small number of
-instruction patterns so we wouldn't generate all 10 output files.
-However, the actual issue (which we will only hit with a low
-pattern count) was with counting all the patterns vs only counting
-the patterns that will be output. A wrong pattern count lead to
-prematurely stopping to write output files.
-
-With that corrected, hppa "just works" until I hit linker errors
-due to relocations - most likely unrelated:
-
-bin/ld: unwind-dw2-fde-dip_s.o(.data.rel.ro+0): cannot handle
-R_PARISC_FPTR64 for __pthread_key_create@@GLIBC_2.34
-
-Attached is v3 that has been bootstrapped and tested on x86 and power10,
-aarch64 bootstrap was ok, testsuite is still running. A riscv build and
-testsuite run was successful as well.
-
-Regards
- Robin
-
->From 248744c328440bff9cc339d2bf622852cbaac343 Mon Sep 17 00:00:00 2001
-From: Robin Dapp <rdapp@ventanamicro.com>
-Date: Thu, 12 Oct 2023 11:23:26 +0200
-Subject: [PATCH v3] genemit: Split insn-emit.cc into several partitions.
-
-On riscv insn-emit.cc has grown to over 1.2 mio lines of code and
-compiling it takes considerable time.
-Therefore, this patch adjust genemit to create several partitions
-(insn-emit-1.cc to insn-emit-n.cc). The available patterns are
-written to the given files in a sequential fashion.
-
-Similar to match.pd a configure option --with-emitinsn-partitions=num
-is introduced that makes the number of partition configurable.
-
-gcc/ChangeLog:
-
- PR bootstrap/84402
- PR target/111600
-
- * Makefile.in: Handle split insn-emit.cc.
- * configure: Regenerate.
- * configure.ac: Add --with-insnemit-partitions.
- * genemit.cc (output_peephole2_scratches): Print to file instead
- of stdout.
- (print_code): Ditto.
- (gen_rtx_scratch): Ditto.
- (gen_exp): Ditto.
- (gen_emit_seq): Ditto.
- (emit_c_code): Ditto.
- (gen_insn): Ditto.
- (gen_expand): Ditto.
- (gen_split): Ditto.
- (output_add_clobbers): Ditto.
- (output_added_clobbers_hard_reg_p): Ditto.
- (print_overload_arguments): Ditto.
- (print_overload_test): Ditto.
- (handle_overloaded_code_for): Ditto.
- (handle_overloaded_gen): Ditto.
- (print_header): New function.
- (handle_arg): New function.
- (main): Split output into 10 files.
- * gensupport.cc (count_patterns): New function.
- * gensupport.h (count_patterns): Define.
- * read-md.cc (md_reader::print_md_ptr_loc): Add file argument.
- * read-md.h (class md_reader): Change definition.
----
- gcc/Makefile.in | 36 ++-
- gcc/configure | 24 +-
- gcc/configure.ac | 13 ++
- gcc/genemit.cc | 542 +++++++++++++++++++++++++---------------------
- gcc/gensupport.cc | 55 +++++
- gcc/gensupport.h | 1 +
- gcc/read-md.cc | 4 +-
- gcc/read-md.h | 2 +-
- 8 files changed, 422 insertions(+), 255 deletions(-)
-
-diff --git a/gcc/Makefile.in b/gcc/Makefile.in
-index 91d6bfbea4d0..d8bfad8de154 100644
---- a/gcc/Makefile.in
-+++ b/gcc/Makefile.in
-@@ -236,6 +236,13 @@ GIMPLE_MATCH_PD_SEQ_O = $(patsubst %, gimple-match-%.o, $(MATCH_SPLITS_SEQ))
- GENERIC_MATCH_PD_SEQ_SRC = $(patsubst %, generic-match-%.cc, $(MATCH_SPLITS_SEQ))
- GENERIC_MATCH_PD_SEQ_O = $(patsubst %, generic-match-%.o, $(MATCH_SPLITS_SEQ))
-
-+# The number of splits to be made for the insn-emit files.
-+NUM_INSNEMIT_SPLITS = @DEFAULT_INSNEMIT_PARTITIONS@
-+INSNEMIT_SPLITS_SEQ = $(wordlist 1,$(NUM_INSNEMIT_SPLITS),$(one_to_9999))
-+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))
-+
- # 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
-@@ -1356,7 +1363,7 @@ OBJS = \
- insn-attrtab.o \
- insn-automata.o \
- insn-dfatab.o \
-- insn-emit.o \
-+ $(INSNEMIT_SEQ_O) \
- insn-extract.o \
- insn-latencytab.o \
- insn-modes.o \
-@@ -1857,7 +1864,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 insn-emit.cc insn-extract.cc insn-peep.cc \
-+ insn-output.cc insn-recog.cc $(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) \
-@@ -2489,11 +2497,11 @@ $(common_out_object_file): $(common_out_file)
- # and compile them.
-
- .PRECIOUS: insn-config.h insn-flags.h insn-codes.h insn-constants.h \
-- insn-emit.cc insn-recog.cc 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) gimple-match-auto.h generic-match-auto.h \
-- insn-target-def.h
-+ $(INSNEMIT_SEQ_SRC) insn-recog.cc 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) \
-+ gimple-match-auto.h generic-match-auto.h insn-target-def.h
-
- # Dependencies for the md file. The first time through, we just assume
- # the md file itself and the generated dependency file (in order to get
-@@ -2516,7 +2524,7 @@ s-mddeps: $(md_file) $(MD_INCLUDES) build/genmddeps$(build_exeext)
- simple_rtl_generated_h = insn-attr.h insn-attr-common.h insn-codes.h \
- insn-config.h insn-flags.h insn-target-def.h
-
--simple_rtl_generated_c = insn-automata.cc insn-emit.cc \
-+simple_rtl_generated_c = insn-automata.cc \
- insn-extract.cc insn-output.cc \
- insn-peep.cc insn-recog.cc
-
-@@ -2545,8 +2553,20 @@ $(simple_generated_c:insn-%.cc=s-%): s-%: build/gen%$(build_exeext)
- $(SHELL) $(srcdir)/../move-if-change tmp-$*.cc insn-$*.cc
- $(STAMP) s-$*
-
-+# genemit splits its output into different files and doesn't write to
-+# stdout. (but rather to tmp-emit-01.cc..tmp-emit-10.cc)
-+$(INSNEMIT_SEQ_SRC): s-tmp-emit; @true
-+s-tmp-emit: build/genemit$(build_exeext) $(MD_DEPS) insn-conditions.md
-+ $(RUN_GEN) build/genemit$(build_exeext) $(md_file) insn-conditions.md \
-+ $(addprefix -O,${INSNEMIT_SEQ_TMP})
-+ $(foreach id, $(INSNEMIT_SPLITS_SEQ), \
-+ $(SHELL) $(srcdir)/../move-if-change tmp-emit-$(id).cc \
-+ insn-emit-$(id).cc;)
-+ $(STAMP) s-tmp-emit
-+
- # gencheck doesn't read the machine description, and the file produced
- # doesn't use the insn-* convention.
-+
- tree-check.h: s-check ; @true
- s-check : build/gencheck$(build_exeext)
- $(RUN_GEN) build/gencheck$(build_exeext) > tmp-check.h
-diff --git a/gcc/configure b/gcc/configure
-index 77f33ee4df6f..d4ad988000f0 100755
---- a/gcc/configure
-+++ b/gcc/configure
-@@ -844,6 +844,7 @@ enable_gcov
- enable_shared
- enable_fixed_point
- enable_decimal_float
-+DEFAULT_INSNEMIT_PARTITIONS
- DEFAULT_MATCHPD_PARTITIONS
- with_float
- with_cpu
-@@ -973,6 +974,7 @@ enable_multilib
- enable_multiarch
- with_stack_clash_protection_guard_size
- with_matchpd_partitions
-+with_insnemit_partitions
- enable___cxa_atexit
- enable_decimal_float
- enable_fixed_point
-@@ -1846,6 +1848,9 @@ Optional Packages:
- --with-matchpd-partitions=num
- Set the number of partitions to make for gimple and
- generic when splitting match.pd. [default=10]
-+ --with-insnemit-partitions=num
-+ Set the number of partitions of insn-emit.cc for
-+ genemit to create. [default=10]
- --with-dwarf2 force the default debug format to be DWARF 2 (or
- later)
- --with-specs=SPECS add SPECS to driver command-line processing
-@@ -7948,6 +7953,21 @@ fi
-
-
-
-+# Specify the number of splits of insn-emit.cc to generate.
-+
-+# Check whether --with-insnemit-partitions was given.
-+if test "${with_insnemit_partitions+set}" = set; then :
-+ withval=$with_insnemit_partitions; DEFAULT_INSNEMIT_PARTITIONS="$with_insnemit_partitions"
-+else
-+ DEFAULT_INSNEMIT_PARTITIONS=10
-+fi
-+
-+if (test $DEFAULT_INSNEMIT_PARTITIONS -lt 1); then
-+ as_fn_error $? "Invalid value $DEFAULT_INSNEMIT_PARTITIONS for --with-insnemit-partitions. Cannot be negative." "$LINENO" 5
-+fi
-+
-+
-+
- # Enable __cxa_atexit for C++.
- # Check whether --enable-__cxa_atexit was given.
- if test "${enable___cxa_atexit+set}" = set; then :
-@@ -19980,7 +20000,7 @@ else
- lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
- lt_status=$lt_dlunknown
- cat > conftest.$ac_ext <<_LT_EOF
--#line 19983 "configure"
-+#line 19995 "configure"
- #include "confdefs.h"
-
- #if HAVE_DLFCN_H
-@@ -20086,7 +20106,7 @@ else
- lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
- lt_status=$lt_dlunknown
- cat > conftest.$ac_ext <<_LT_EOF
--#line 20089 "configure"
-+#line 20101 "configure"
- #include "confdefs.h"
-
- #if HAVE_DLFCN_H
-diff --git a/gcc/configure.ac b/gcc/configure.ac
-index 10982cdfc099..dc8cb6a33de2 100644
---- a/gcc/configure.ac
-+++ b/gcc/configure.ac
-@@ -956,6 +956,19 @@ fi
-
- AC_SUBST(DEFAULT_MATCHPD_PARTITIONS)
-
-+# Specify the number of splits of insn-emit.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]])],
-+[DEFAULT_INSNEMIT_PARTITIONS="$with_insnemit_partitions"], [DEFAULT_INSNEMIT_PARTITIONS=10])
-+if (test $DEFAULT_INSNEMIT_PARTITIONS -lt 1); then
-+ AC_MSG_ERROR(m4_normalize([
-+ Invalid value $DEFAULT_INSNEMIT_PARTITIONS for --with-insnemit-partitions. \
-+ Cannot be negative.]))
-+fi
-+
-+AC_SUBST(DEFAULT_INSNEMIT_PARTITIONS)
-+
- # Enable __cxa_atexit for C++.
- AC_ARG_ENABLE(__cxa_atexit,
- [AS_HELP_STRING([--enable-__cxa_atexit], [enable __cxa_atexit for C++])],
-diff --git a/gcc/genemit.cc b/gcc/genemit.cc
-index 1ce0564076d8..471fd46a10b4 100644
---- a/gcc/genemit.cc
-+++ b/gcc/genemit.cc
-@@ -49,29 +49,29 @@ struct clobber_ent
- struct clobber_ent *next;
- };
-
--static void output_peephole2_scratches (rtx);
-+static void output_peephole2_scratches (rtx, FILE*);
-
- /* True for <X>_optab if that optab isn't allowed to fail. */
- static bool nofail_optabs[NUM_OPTABS];
-
- static void
--print_code (RTX_CODE code)
-+print_code (RTX_CODE code, FILE *file)
- {
- const char *p1;
- for (p1 = GET_RTX_NAME (code); *p1; p1++)
-- putchar (TOUPPER (*p1));
-+ fprintf (file, "%c", TOUPPER (*p1));
- }
-
- static void
--gen_rtx_scratch (rtx x, enum rtx_code subroutine_type)
-+gen_rtx_scratch (rtx x, enum rtx_code subroutine_type, FILE *file)
- {
- if (subroutine_type == DEFINE_PEEPHOLE2)
- {
-- printf ("operand%d", XINT (x, 0));
-+ fprintf (file, "operand%d", XINT (x, 0));
- }
- else
- {
-- printf ("gen_rtx_SCRATCH (%smode)", GET_MODE_NAME (GET_MODE (x)));
-+ fprintf (file, "gen_rtx_SCRATCH (%smode)", GET_MODE_NAME (GET_MODE (x)));
- }
- }
-
-@@ -79,7 +79,8 @@ gen_rtx_scratch (rtx x, enum rtx_code subroutine_type)
- substituting any operand references appearing within. */
-
- static void
--gen_exp (rtx x, enum rtx_code subroutine_type, char *used, md_rtx_info *info)
-+gen_exp (rtx x, enum rtx_code subroutine_type, char *used, md_rtx_info *info,
-+ FILE *file)
- {
- RTX_CODE code;
- int i;
-@@ -89,7 +90,7 @@ gen_exp (rtx x, enum rtx_code subroutine_type, char *used, md_rtx_info *info)
-
- if (x == 0)
- {
-- printf ("NULL_RTX");
-+ fprintf (file, "NULL_RTX");
- return;
- }
-
-@@ -103,67 +104,67 @@ gen_exp (rtx x, enum rtx_code subroutine_type, char *used, md_rtx_info *info)
- {
- if (used[XINT (x, 0)])
- {
-- printf ("copy_rtx (operand%d)", XINT (x, 0));
-+ fprintf (file, "copy_rtx (operand%d)", XINT (x, 0));
- return;
- }
- used[XINT (x, 0)] = 1;
- }
-- printf ("operand%d", XINT (x, 0));
-+ fprintf (file, "operand%d", XINT (x, 0));
- return;
-
- case MATCH_OP_DUP:
-- printf ("gen_rtx_fmt_");
-+ fprintf (file, "gen_rtx_fmt_");
- for (i = 0; i < XVECLEN (x, 1); i++)
-- printf ("e");
-- printf (" (GET_CODE (operand%d), ", XINT (x, 0));
-+ fprintf (file, "e");
-+ fprintf (file, " (GET_CODE (operand%d), ", XINT (x, 0));
- if (GET_MODE (x) == VOIDmode)
-- printf ("GET_MODE (operand%d)", XINT (x, 0));
-+ fprintf (file, "GET_MODE (operand%d)", XINT (x, 0));
- else
-- printf ("%smode", GET_MODE_NAME (GET_MODE (x)));
-+ fprintf (file, "%smode", GET_MODE_NAME (GET_MODE (x)));
- for (i = 0; i < XVECLEN (x, 1); i++)
- {
-- printf (",\n\t\t");
-- gen_exp (XVECEXP (x, 1, i), subroutine_type, used, info);
-+ fprintf (file, ",\n\t\t");
-+ gen_exp (XVECEXP (x, 1, i), subroutine_type, used, info, file);
- }
-- printf (")");
-+ fprintf (file, ")");
- return;
-
- case MATCH_OPERATOR:
-- printf ("gen_rtx_fmt_");
-+ fprintf (file, "gen_rtx_fmt_");
- for (i = 0; i < XVECLEN (x, 2); i++)
-- printf ("e");
-- printf (" (GET_CODE (operand%d)", XINT (x, 0));
-- printf (", %smode", GET_MODE_NAME (GET_MODE (x)));
-+ fprintf (file, "e");
-+ fprintf (file, " (GET_CODE (operand%d)", XINT (x, 0));
-+ fprintf (file, ", %smode", GET_MODE_NAME (GET_MODE (x)));
- for (i = 0; i < XVECLEN (x, 2); i++)
- {
-- printf (",\n\t\t");
-- gen_exp (XVECEXP (x, 2, i), subroutine_type, used, info);
-+ fprintf (file, ",\n\t\t");
-+ gen_exp (XVECEXP (x, 2, i), subroutine_type, used, info, file);
- }
-- printf (")");
-+ fprintf (file, ")");
- return;
-
- case MATCH_PARALLEL:
- case MATCH_PAR_DUP:
-- printf ("operand%d", XINT (x, 0));
-+ fprintf (file, "operand%d", XINT (x, 0));
- return;
-
- case MATCH_SCRATCH:
-- gen_rtx_scratch (x, subroutine_type);
-+ gen_rtx_scratch (x, subroutine_type, file);
- return;
-
- case PC:
-- printf ("pc_rtx");
-+ fprintf (file, "pc_rtx");
- return;
- case RETURN:
-- printf ("ret_rtx");
-+ fprintf (file, "ret_rtx");
- return;
- case SIMPLE_RETURN:
-- printf ("simple_return_rtx");
-+ fprintf (file, "simple_return_rtx");
- return;
- case CLOBBER:
- if (REG_P (XEXP (x, 0)))
- {
-- printf ("gen_hard_reg_clobber (%smode, %i)",
-+ fprintf (file, "gen_hard_reg_clobber (%smode, %i)",
- GET_MODE_NAME (GET_MODE (XEXP (x, 0))),
- REGNO (XEXP (x, 0)));
- return;
-@@ -172,22 +173,22 @@ gen_exp (rtx x, enum rtx_code subroutine_type, char *used, md_rtx_info *info)
-
- case CONST_INT:
- if (INTVAL (x) == 0)
-- printf ("const0_rtx");
-+ fprintf (file, "const0_rtx");
- else if (INTVAL (x) == 1)
-- printf ("const1_rtx");
-+ fprintf (file, "const1_rtx");
- else if (INTVAL (x) == -1)
-- printf ("constm1_rtx");
-+ fprintf (file, "constm1_rtx");
- else if (-MAX_SAVED_CONST_INT <= INTVAL (x)
- && INTVAL (x) <= MAX_SAVED_CONST_INT)
-- printf ("const_int_rtx[MAX_SAVED_CONST_INT + (%d)]",
-+ fprintf (file, "const_int_rtx[MAX_SAVED_CONST_INT + (%d)]",
- (int) INTVAL (x));
- else if (INTVAL (x) == STORE_FLAG_VALUE)
-- printf ("const_true_rtx");
-+ fprintf (file, "const_true_rtx");
- else
- {
-- printf ("GEN_INT (");
-- printf (HOST_WIDE_INT_PRINT_DEC_C, INTVAL (x));
-- printf (")");
-+ fprintf (file, "GEN_INT (");
-+ fprintf (file, HOST_WIDE_INT_PRINT_DEC_C, INTVAL (x));
-+ fprintf (file, ")");
- }
- return;
-
-@@ -195,7 +196,7 @@ gen_exp (rtx x, enum rtx_code subroutine_type, char *used, md_rtx_info *info)
- /* Handle `const_double_zero' rtx. */
- if (CONST_DOUBLE_REAL_VALUE (x)->cl == rvc_zero)
- {
-- printf ("CONST_DOUBLE_ATOF (\"0\", %smode)",
-+ fprintf (file, "CONST_DOUBLE_ATOF (\"0\", %smode)",
- GET_MODE_NAME (GET_MODE (x)));
- return;
- }
-@@ -210,12 +211,12 @@ gen_exp (rtx x, enum rtx_code subroutine_type, char *used, md_rtx_info *info)
- break;
- }
-
-- printf ("gen_rtx_");
-- print_code (code);
-- printf (" (");
-+ fprintf (file, "gen_rtx_");
-+ print_code (code, file);
-+ fprintf (file, " (");
- if (!always_void_p (code))
- {
-- printf ("%smode", GET_MODE_NAME (GET_MODE (x)));
-+ fprintf (file, "%smode", GET_MODE_NAME (GET_MODE (x)));
- sep = ",\n\t";
- }
-
-@@ -225,41 +226,41 @@ gen_exp (rtx x, enum rtx_code subroutine_type, char *used, md_rtx_info *info)
- {
- if (fmt[i] == '0')
- break;
-- fputs (sep, stdout);
-+ fputs (sep, file);
- switch (fmt[i])
- {
- case 'e': case 'u':
-- gen_exp (XEXP (x, i), subroutine_type, used, info);
-+ gen_exp (XEXP (x, i), subroutine_type, used, info, file);
- break;
-
- case 'i':
-- printf ("%u", XINT (x, i));
-+ fprintf (file, "%u", XINT (x, i));
- break;
-
- case 'r':
-- printf ("%u", REGNO (x));
-+ fprintf (file, "%u", REGNO (x));
- break;
-
- case 'p':
- /* We don't have a way of parsing polynomial offsets yet,
- and hopefully never will. */
-- printf ("%d", SUBREG_BYTE (x).to_constant ());
-+ fprintf (file, "%d", SUBREG_BYTE (x).to_constant ());
- break;
-
- case 's':
-- printf ("\"%s\"", XSTR (x, i));
-+ fprintf (file, "\"%s\"", XSTR (x, i));
- break;
-
- case 'E':
- {
- int j;
-- printf ("gen_rtvec (%d", XVECLEN (x, i));
-+ fprintf (file, "gen_rtvec (%d", XVECLEN (x, i));
- for (j = 0; j < XVECLEN (x, i); j++)
- {
-- printf (",\n\t\t");
-- gen_exp (XVECEXP (x, i, j), subroutine_type, used, info);
-+ fprintf (file, ",\n\t\t");
-+ gen_exp (XVECEXP (x, i, j), subroutine_type, used, info, file);
- }
-- printf (")");
-+ fprintf (file, ")");
- break;
- }
-
-@@ -268,14 +269,14 @@ gen_exp (rtx x, enum rtx_code subroutine_type, char *used, md_rtx_info *info)
- }
- sep = ",\n\t";
- }
-- printf (")");
-+ fprintf (file, ")");
- }
-
- /* Output code to emit the instruction patterns in VEC, with each element
- becoming a separate instruction. USED is as for gen_exp. */
-
- static void
--gen_emit_seq (rtvec vec, char *used, md_rtx_info *info)
-+gen_emit_seq (rtvec vec, char *used, md_rtx_info *info, FILE *file)
- {
- for (int i = 0, len = GET_NUM_ELEM (vec); i < len; ++i)
- {
-@@ -283,17 +284,17 @@ gen_emit_seq (rtvec vec, char *used, md_rtx_info *info)
- rtx next = RTVEC_ELT (vec, i);
- if (const char *name = get_emit_function (next))
- {
-- printf (" %s (", name);
-- gen_exp (next, DEFINE_EXPAND, used, info);
-- printf (");\n");
-+ fprintf (file, " %s (", name);
-+ gen_exp (next, DEFINE_EXPAND, used, info, file);
-+ fprintf (file, ");\n");
- if (!last_p && needs_barrier_p (next))
-- printf (" emit_barrier ();");
-+ fprintf (file, " emit_barrier ();");
- }
- else
- {
-- printf (" emit (");
-- gen_exp (next, DEFINE_EXPAND, used, info);
-- printf (", %s);\n", last_p ? "false" : "true");
-+ fprintf (file, " emit (");
-+ gen_exp (next, DEFINE_EXPAND, used, info, file);
-+ fprintf (file, ", %s);\n", last_p ? "false" : "true");
- }
- }
- }
-@@ -303,27 +304,27 @@ gen_emit_seq (rtvec vec, char *used, md_rtx_info *info)
- for use in error messages. */
-
- static void
--emit_c_code (const char *code, bool can_fail_p, const char *name)
-+emit_c_code (const char *code, bool can_fail_p, const char *name, FILE *file)
- {
- if (can_fail_p)
-- printf ("#define FAIL return (end_sequence (), _val)\n");
-+ fprintf (file, "#define FAIL return (end_sequence (), _val)\n");
- else
-- printf ("#define FAIL _Pragma (\"GCC error \\\"%s cannot FAIL\\\"\")"
-+ fprintf (file, "#define FAIL _Pragma (\"GCC error \\\"%s cannot FAIL\\\"\")"
- " (void)0\n", name);
-- printf ("#define DONE return (_val = get_insns (), "
-+ fprintf (file, "#define DONE return (_val = get_insns (), "
- "end_sequence (), _val)\n");
-
-- rtx_reader_ptr->print_md_ptr_loc (code);
-- printf ("%s\n", code);
-+ rtx_reader_ptr->print_md_ptr_loc (code, file);
-+ fprintf (file, "%s\n", code);
-
-- printf ("#undef DONE\n");
-- printf ("#undef FAIL\n");
-+ fprintf (file, "#undef DONE\n");
-+ fprintf (file, "#undef FAIL\n");
- }
-
- /* Generate the `gen_...' function for a DEFINE_INSN. */
-
- static void
--gen_insn (md_rtx_info *info)
-+gen_insn (md_rtx_info *info, FILE *file)
- {
- struct pattern_stats stats;
- int i;
-@@ -409,7 +410,7 @@ gen_insn (md_rtx_info *info)
- if (XSTR (insn, 0)[0] == 0 || XSTR (insn, 0)[0] == '*')
- return;
-
-- printf ("/* %s:%d */\n", info->loc.filename, info->loc.lineno);
-+ fprintf (file, "/* %s:%d */\n", info->loc.filename, info->loc.lineno);
-
- /* Find out how many operands this function has. */
- get_pattern_stats (&stats, XVEC (insn, 1));
-@@ -417,17 +418,17 @@ gen_insn (md_rtx_info *info)
- fatal_at (info->loc, "match_dup operand number has no match_operand");
-
- /* Output the function name and argument declarations. */
-- printf ("rtx\ngen_%s (", XSTR (insn, 0));
-+ fprintf (file, "rtx\ngen_%s (", XSTR (insn, 0));
- if (stats.num_generator_args)
- for (i = 0; i < stats.num_generator_args; i++)
- if (i)
-- printf (",\n\trtx operand%d ATTRIBUTE_UNUSED", i);
-+ fprintf (file, ",\n\trtx operand%d ATTRIBUTE_UNUSED", i);
- else
-- printf ("rtx operand%d ATTRIBUTE_UNUSED", i);
-+ fprintf (file, "rtx operand%d ATTRIBUTE_UNUSED", i);
- else
-- printf ("void");
-- printf (")\n");
-- printf ("{\n");
-+ fprintf (file, "void");
-+ fprintf (file, ")\n");
-+ fprintf (file, "{\n");
-
- /* Output code to construct and return the rtl for the instruction body. */
-
-@@ -436,16 +437,16 @@ gen_insn (md_rtx_info *info)
- char *used = (XVECLEN (insn, 1) == 1
- ? NULL
- : XCNEWVEC (char, stats.num_generator_args));
-- printf (" return ");
-- gen_exp (pattern, DEFINE_INSN, used, info);
-- printf (";\n}\n\n");
-+ fprintf (file, " return ");
-+ gen_exp (pattern, DEFINE_INSN, used, info, file);
-+ fprintf (file, ";\n}\n\n");
- XDELETEVEC (used);
- }
-
- /* Generate the `gen_...' function for a DEFINE_EXPAND. */
-
- static void
--gen_expand (md_rtx_info *info)
-+gen_expand (md_rtx_info *info, FILE *file)
- {
- struct pattern_stats stats;
- int i;
-@@ -466,17 +467,17 @@ gen_expand (md_rtx_info *info)
- "numbers above all other operands", XSTR (expand, 0));
-
- /* Output the function name and argument declarations. */
-- printf ("rtx\ngen_%s (", XSTR (expand, 0));
-+ fprintf (file, "rtx\ngen_%s (", XSTR (expand, 0));
- if (stats.num_generator_args)
- for (i = 0; i < stats.num_generator_args; i++)
- if (i)
-- printf (",\n\trtx operand%d", i);
-+ fprintf (file, ",\n\trtx operand%d", i);
- else
-- printf ("rtx operand%d", i);
-+ fprintf (file, "rtx operand%d", i);
- else
-- printf ("void");
-- printf (")\n");
-- printf ("{\n");
-+ fprintf (file, "void");
-+ fprintf (file, ")\n");
-+ fprintf (file, "{\n");
-
- /* If we don't have any C code to write, only one insn is being written,
- and no MATCH_DUPs are present, we can just return the desired insn
-@@ -485,18 +486,18 @@ gen_expand (md_rtx_info *info)
- && stats.max_opno >= stats.max_dup_opno
- && XVECLEN (expand, 1) == 1)
- {
-- printf (" return ");
-- gen_exp (XVECEXP (expand, 1, 0), DEFINE_EXPAND, NULL, info);
-- printf (";\n}\n\n");
-+ fprintf (file, " return ");
-+ gen_exp (XVECEXP (expand, 1, 0), DEFINE_EXPAND, NULL, info, file);
-+ fprintf (file, ";\n}\n\n");
- return;
- }
-
- /* For each operand referred to only with MATCH_DUPs,
- make a local variable. */
- for (i = stats.num_generator_args; i <= stats.max_dup_opno; i++)
-- printf (" rtx operand%d;\n", i);
-- printf (" rtx_insn *_val = 0;\n");
-- printf (" start_sequence ();\n");
-+ fprintf (file, " rtx operand%d;\n", i);
-+ fprintf (file, " rtx_insn *_val = 0;\n");
-+ fprintf (file, " start_sequence ();\n");
-
- /* The fourth operand of DEFINE_EXPAND is some code to be executed
- before the actual construction.
-@@ -506,13 +507,13 @@ gen_expand (md_rtx_info *info)
- So copy the operand values there before executing it. */
- if (XSTR (expand, 3) && *XSTR (expand, 3))
- {
-- printf (" {\n");
-+ fprintf (file, " {\n");
- if (stats.num_operand_vars > 0)
-- printf (" rtx operands[%d];\n", stats.num_operand_vars);
-+ fprintf (file, " rtx operands[%d];\n", stats.num_operand_vars);
-
- /* Output code to copy the arguments into `operands'. */
- for (i = 0; i < stats.num_generator_args; i++)
-- printf (" operands[%d] = operand%d;\n", i, i);
-+ fprintf (file, " operands[%d] = operand%d;\n", i, i);
-
- /* Output the special code to be executed before the sequence
- is generated. */
-@@ -524,7 +525,7 @@ gen_expand (md_rtx_info *info)
- if (nofail_optabs[p.op])
- can_fail_p = false;
- }
-- emit_c_code (XSTR (expand, 3), can_fail_p, XSTR (expand, 0));
-+ emit_c_code (XSTR (expand, 3), can_fail_p, XSTR (expand, 0), file);
-
- /* Output code to copy the arguments back out of `operands'
- (unless we aren't going to use them at all). */
-@@ -532,29 +533,29 @@ gen_expand (md_rtx_info *info)
- {
- for (i = 0; i <= MAX (stats.max_opno, stats.max_dup_opno); i++)
- {
-- printf (" operand%d = operands[%d];\n", i, i);
-- printf (" (void) operand%d;\n", i);
-+ fprintf (file, " operand%d = operands[%d];\n", i, i);
-+ fprintf (file, " (void) operand%d;\n", i);
- }
- }
-- printf (" }\n");
-+ fprintf (file, " }\n");
- }
-
- used = XCNEWVEC (char, stats.num_operand_vars);
-- gen_emit_seq (XVEC (expand, 1), used, info);
-+ gen_emit_seq (XVEC (expand, 1), used, info, file);
- XDELETEVEC (used);
-
- /* Call `get_insns' to extract the list of all the
- insns emitted within this gen_... function. */
-
-- printf (" _val = get_insns ();\n");
-- printf (" end_sequence ();\n");
-- printf (" return _val;\n}\n\n");
-+ fprintf (file, " _val = get_insns ();\n");
-+ fprintf (file, " end_sequence ();\n");
-+ fprintf (file, " return _val;\n}\n\n");
- }
-
- /* Like gen_expand, but generates insns resulting from splitting SPLIT. */
-
- static void
--gen_split (md_rtx_info *info)
-+gen_split (md_rtx_info *info, FILE *file)
- {
- struct pattern_stats stats;
- int i;
-@@ -580,62 +581,62 @@ gen_split (md_rtx_info *info)
- /* Output the prototype, function name and argument declarations. */
- if (GET_CODE (split) == DEFINE_PEEPHOLE2)
- {
-- printf ("extern rtx_insn *gen_%s_%d (rtx_insn *, rtx *);\n",
-+ fprintf (file, "extern rtx_insn *gen_%s_%d (rtx_insn *, rtx *);\n",
- name, info->index);
-- printf ("rtx_insn *\ngen_%s_%d (rtx_insn *curr_insn ATTRIBUTE_UNUSED,"
-+ fprintf (file, "rtx_insn *\ngen_%s_%d (rtx_insn *curr_insn ATTRIBUTE_UNUSED,"
- " rtx *operands%s)\n",
- name, info->index, unused);
- }
- else
- {
-- printf ("extern rtx_insn *gen_split_%d (rtx_insn *, rtx *);\n",
-+ fprintf (file, "extern rtx_insn *gen_split_%d (rtx_insn *, rtx *);\n",
- info->index);
-- printf ("rtx_insn *\ngen_split_%d "
-+ fprintf (file, "rtx_insn *\ngen_split_%d "
- "(rtx_insn *curr_insn ATTRIBUTE_UNUSED, rtx *operands%s)\n",
- info->index, unused);
- }
-- printf ("{\n");
-+ fprintf (file, "{\n");
-
- /* Declare all local variables. */
- for (i = 0; i < stats.num_operand_vars; i++)
-- printf (" rtx operand%d;\n", i);
-- printf (" rtx_insn *_val = NULL;\n");
-+ fprintf (file, " rtx operand%d;\n", i);
-+ fprintf (file, " rtx_insn *_val = NULL;\n");
-
- if (GET_CODE (split) == DEFINE_PEEPHOLE2)
-- output_peephole2_scratches (split);
-+ output_peephole2_scratches (split, file);
-
- const char *fn = info->loc.filename;
- for (const char *p = fn; *p; p++)
- if (*p == '/')
- fn = p + 1;
-
-- printf (" if (dump_file)\n");
-- printf (" fprintf (dump_file, \"Splitting with gen_%s_%d (%s:%d)\\n\");\n",
-+ fprintf (file, " if (dump_file)\n");
-+ fprintf (file, " fprintf (dump_file, \"Splitting with gen_%s_%d (%s:%d)\\n\");\n",
- name, info->index, fn, info->loc.lineno);
-
-- printf (" start_sequence ();\n");
-+ fprintf (file, " start_sequence ();\n");
-
- /* The fourth operand of DEFINE_SPLIT is some code to be executed
- before the actual construction. */
-
- if (XSTR (split, 3))
-- emit_c_code (XSTR (split, 3), true, name);
-+ emit_c_code (XSTR (split, 3), true, name, file);
-
- /* Output code to copy the arguments back out of `operands' */
- for (i = 0; i < stats.num_operand_vars; i++)
- {
-- printf (" operand%d = operands[%d];\n", i, i);
-- printf (" (void) operand%d;\n", i);
-+ fprintf (file, " operand%d = operands[%d];\n", i, i);
-+ fprintf (file, " (void) operand%d;\n", i);
- }
-
-- gen_emit_seq (XVEC (split, 2), used, info);
-+ gen_emit_seq (XVEC (split, 2), used, info, file);
-
- /* Call `get_insns' to make a list of all the
- insns emitted within this gen_... function. */
-
-- printf (" _val = get_insns ();\n");
-- printf (" end_sequence ();\n");
-- printf (" return _val;\n}\n\n");
-+ fprintf (file, " _val = get_insns ();\n");
-+ fprintf (file, " end_sequence ();\n");
-+ fprintf (file, " return _val;\n}\n\n");
-
- free (used);
- }
-@@ -645,37 +646,37 @@ gen_split (md_rtx_info *info)
- the end of the vector. */
-
- static void
--output_add_clobbers (md_rtx_info *info)
-+output_add_clobbers (md_rtx_info *info, FILE *file)
- {
- struct clobber_pat *clobber;
- struct clobber_ent *ent;
- int i;
-
-- printf ("\n\nvoid\nadd_clobbers (rtx pattern ATTRIBUTE_UNUSED, int insn_code_number)\n");
-- printf ("{\n");
-- printf (" switch (insn_code_number)\n");
-- printf (" {\n");
-+ fprintf (file, "\n\nvoid\nadd_clobbers (rtx pattern ATTRIBUTE_UNUSED, int insn_code_number)\n");
-+ fprintf (file, "{\n");
-+ fprintf (file, " switch (insn_code_number)\n");
-+ fprintf (file, " {\n");
-
- for (clobber = clobber_list; clobber; clobber = clobber->next)
- {
- for (ent = clobber->insns; ent; ent = ent->next)
-- printf (" case %d:\n", ent->code_number);
-+ fprintf (file, " case %d:\n", ent->code_number);
-
- for (i = clobber->first_clobber; i < XVECLEN (clobber->pattern, 1); i++)
- {
-- printf (" XVECEXP (pattern, 0, %d) = ", i);
-+ fprintf (file, " XVECEXP (pattern, 0, %d) = ", i);
- gen_exp (XVECEXP (clobber->pattern, 1, i),
-- GET_CODE (clobber->pattern), NULL, info);
-- printf (";\n");
-+ GET_CODE (clobber->pattern), NULL, info, file);
-+ fprintf (file, ";\n");
- }
-
-- printf (" break;\n\n");
-+ fprintf (file, " break;\n\n");
- }
-
-- printf (" default:\n");
-- printf (" gcc_unreachable ();\n");
-- printf (" }\n");
-- printf ("}\n");
-+ fprintf (file, " default:\n");
-+ fprintf (file, " gcc_unreachable ();\n");
-+ fprintf (file, " }\n");
-+ fprintf (file, "}\n");
- }
-
- /* Write a function, `added_clobbers_hard_reg_p' that is given an insn_code
-@@ -684,17 +685,17 @@ output_add_clobbers (md_rtx_info *info)
- SCRATCH. */
-
- static void
--output_added_clobbers_hard_reg_p (void)
-+output_added_clobbers_hard_reg_p (FILE *file)
- {
- struct clobber_pat *clobber;
- struct clobber_ent *ent;
- int clobber_p;
- bool used;
-
-- printf ("\n\nbool\nadded_clobbers_hard_reg_p (int insn_code_number)\n");
-- printf ("{\n");
-- printf (" switch (insn_code_number)\n");
-- printf (" {\n");
-+ fprintf (file, "\n\nbool\nadded_clobbers_hard_reg_p (int insn_code_number)\n");
-+ fprintf (file, "{\n");
-+ fprintf (file, " switch (insn_code_number)\n");
-+ fprintf (file, " {\n");
-
- for (clobber_p = 0; clobber_p <= 1; clobber_p++)
- {
-@@ -703,25 +704,25 @@ output_added_clobbers_hard_reg_p (void)
- if (clobber->has_hard_reg == clobber_p)
- for (ent = clobber->insns; ent; ent = ent->next)
- {
-- printf (" case %d:\n", ent->code_number);
-+ fprintf (file, " case %d:\n", ent->code_number);
- used = true;
- }
-
- if (used)
-- printf (" return %s;\n\n", clobber_p ? "true" : "false");
-+ fprintf (file, " return %s;\n\n", clobber_p ? "true" : "false");
- }
-
-- printf (" default:\n");
-- printf (" gcc_unreachable ();\n");
-- printf (" }\n");
-- printf ("}\n");
-+ fprintf (file, " default:\n");
-+ fprintf (file, " gcc_unreachable ();\n");
-+ fprintf (file, " }\n");
-+ fprintf (file, "}\n");
- }
-
- /* Generate code to invoke find_free_register () as needed for the
- scratch registers used by the peephole2 pattern in SPLIT. */
-
- static void
--output_peephole2_scratches (rtx split)
-+output_peephole2_scratches (rtx split, FILE *file)
- {
- int i;
- int insn_nr = 0;
-@@ -746,12 +747,12 @@ output_peephole2_scratches (rtx split)
-
- if (first)
- {
-- printf (" HARD_REG_SET _regs_allocated;\n");
-- printf (" CLEAR_HARD_REG_SET (_regs_allocated);\n");
-+ fprintf (file, " HARD_REG_SET _regs_allocated;\n");
-+ fprintf (file, " CLEAR_HARD_REG_SET (_regs_allocated);\n");
- first = false;
- }
-
-- printf (" if ((operands[%d] = peep2_find_free_register (%d, %d, \"%s\", %smode, &_regs_allocated)) == NULL_RTX)\n\
-+ fprintf (file, " if ((operands[%d] = peep2_find_free_register (%d, %d, \"%s\", %smode, &_regs_allocated)) == NULL_RTX)\n\
- return NULL;\n",
- XINT (elt, 0),
- insn_nr, last_insn_nr,
-@@ -767,50 +768,50 @@ output_peephole2_scratches (rtx split)
- /* Print "arg<N>" parameter declarations for each argument N of ONAME. */
-
- static void
--print_overload_arguments (overloaded_name *oname)
-+print_overload_arguments (overloaded_name *oname, FILE *file)
- {
- for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
-- printf ("%s%s arg%d", i == 0 ? "" : ", ", oname->arg_types[i], i);
-+ fprintf (file, "%s%s arg%d", i == 0 ? "" : ", ", oname->arg_types[i], i);
- }
-
- /* Print code to test whether INSTANCE should be chosen, given that
- argument N of the overload is available as "arg<N>". */
-
- static void
--print_overload_test (overloaded_instance *instance)
-+print_overload_test (overloaded_instance *instance, FILE *file)
- {
- for (unsigned int i = 0; i < instance->arg_values.length (); ++i)
-- printf ("%sarg%d == %s", i == 0 ? " if (" : "\n && ",
-+ fprintf (file, "%sarg%d == %s", i == 0 ? " if (" : "\n && ",
- i, instance->arg_values[i]);
-- printf (")\n");
-+ fprintf (file, ")\n");
- }
-
- /* Emit a maybe_code_for_* function for ONAME. */
-
- static void
--handle_overloaded_code_for (overloaded_name *oname)
-+handle_overloaded_code_for (overloaded_name *oname, FILE *file)
- {
- /* Print the function prototype. */
-- printf ("\ninsn_code\nmaybe_code_for_%s (", oname->name);
-- print_overload_arguments (oname);
-- printf (")\n{\n");
-+ fprintf (file, "\ninsn_code\nmaybe_code_for_%s (", oname->name);
-+ print_overload_arguments (oname, file);
-+ fprintf (file, ")\n{\n");
-
- /* Use a sequence of "if" statements for each instance. */
- for (overloaded_instance *instance = oname->first_instance;
- instance; instance = instance->next)
- {
-- print_overload_test (instance);
-- printf (" return CODE_FOR_%s;\n", instance->name);
-+ print_overload_test (instance, file);
-+ fprintf (file, " return CODE_FOR_%s;\n", instance->name);
- }
-
- /* Return null if no match was found. */
-- printf (" return CODE_FOR_nothing;\n}\n");
-+ fprintf (file, " return CODE_FOR_nothing;\n}\n");
- }
-
- /* Emit a maybe_gen_* function for ONAME. */
-
- static void
--handle_overloaded_gen (overloaded_name *oname)
-+handle_overloaded_gen (overloaded_name *oname, FILE *file)
- {
- unsigned HOST_WIDE_INT seen = 0;
- /* All patterns must have the same number of operands. */
-@@ -827,25 +828,25 @@ handle_overloaded_gen (overloaded_name *oname)
- seen |= mask;
-
- /* Print the function prototype. */
-- printf ("\nrtx\nmaybe_gen_%s (", oname->name);
-- print_overload_arguments (oname);
-+ fprintf (file, "\nrtx\nmaybe_gen_%s (", oname->name);
-+ print_overload_arguments (oname, file);
- for (int i = 0; i < stats.num_generator_args; ++i)
-- printf (", rtx x%d", i);
-- printf (")\n{\n");
-+ fprintf (file, ", rtx x%d", i);
-+ fprintf (file, ")\n{\n");
-
- /* Use maybe_code_for_*, instead of duplicating the selection
- logic here. */
-- printf (" insn_code code = maybe_code_for_%s (", oname->name);
-+ fprintf (file, " insn_code code = maybe_code_for_%s (", oname->name);
- for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
-- printf ("%sarg%d", i == 0 ? "" : ", ", i);
-- printf (");\n"
-+ fprintf (file, "%sarg%d", i == 0 ? "" : ", ", i);
-+ fprintf (file, ");\n"
- " if (code != CODE_FOR_nothing)\n"
- " {\n"
- " gcc_assert (insn_data[code].n_generator_args == %d);\n"
- " return GEN_FCN (code) (", stats.num_generator_args);
- for (int i = 0; i < stats.num_generator_args; ++i)
-- printf ("%sx%d", i == 0 ? "" : ", ", i);
-- printf (");\n"
-+ fprintf (file, "%sx%d", i == 0 ? "" : ", ", i);
-+ fprintf (file, ");\n"
- " }\n"
- " else\n"
- " return NULL_RTX;\n"
-@@ -853,12 +854,68 @@ handle_overloaded_gen (overloaded_name *oname)
- }
- }
-
-+void
-+print_header (FILE *file)
-+{
-+ fprintf (file, "/* Generated automatically by the program `genemit'\n\
-+from the machine description file `md'. */\n\n");
-+
-+ fprintf (file, "#define IN_TARGET_CODE 1\n");
-+ fprintf (file, "#include \"config.h\"\n");
-+ fprintf (file, "#include \"system.h\"\n");
-+ fprintf (file, "#include \"coretypes.h\"\n");
-+ fprintf (file, "#include \"backend.h\"\n");
-+ fprintf (file, "#include \"predict.h\"\n");
-+ fprintf (file, "#include \"tree.h\"\n");
-+ fprintf (file, "#include \"rtl.h\"\n");
-+ fprintf (file, "#include \"alias.h\"\n");
-+ fprintf (file, "#include \"varasm.h\"\n");
-+ fprintf (file, "#include \"stor-layout.h\"\n");
-+ fprintf (file, "#include \"calls.h\"\n");
-+ fprintf (file, "#include \"memmodel.h\"\n");
-+ fprintf (file, "#include \"tm_p.h\"\n");
-+ fprintf (file, "#include \"flags.h\"\n");
-+ fprintf (file, "#include \"insn-config.h\"\n");
-+ fprintf (file, "#include \"expmed.h\"\n");
-+ fprintf (file, "#include \"dojump.h\"\n");
-+ fprintf (file, "#include \"explow.h\"\n");
-+ fprintf (file, "#include \"emit-rtl.h\"\n");
-+ fprintf (file, "#include \"stmt.h\"\n");
-+ fprintf (file, "#include \"expr.h\"\n");
-+ fprintf (file, "#include \"insn-codes.h\"\n");
-+ fprintf (file, "#include \"optabs.h\"\n");
-+ fprintf (file, "#include \"dfp.h\"\n");
-+ fprintf (file, "#include \"output.h\"\n");
-+ fprintf (file, "#include \"recog.h\"\n");
-+ fprintf (file, "#include \"df.h\"\n");
-+ fprintf (file, "#include \"resource.h\"\n");
-+ fprintf (file, "#include \"reload.h\"\n");
-+ fprintf (file, "#include \"diagnostic-core.h\"\n");
-+ fprintf (file, "#include \"regs.h\"\n");
-+ fprintf (file, "#include \"tm-constrs.h\"\n");
-+ fprintf (file, "#include \"ggc.h\"\n");
-+ fprintf (file, "#include \"target.h\"\n\n");
-+}
-+
-+auto_vec<const char *, 10> output_files;
-+
-+static bool
-+handle_arg (const char *arg)
-+{
-+ if (arg[1] == 'O')
-+ {
-+ output_files.safe_push (&arg[2]);
-+ return true;
-+ }
-+ return false;
-+}
-+
- int
- main (int argc, const char **argv)
- {
- progname = "genemit";
-
-- if (!init_rtx_reader_args (argc, argv))
-+ if (!init_rtx_reader_args_cb (argc, argv, handle_arg))
- return (FATAL_EXIT_CODE);
-
- #define DEF_INTERNAL_OPTAB_FN(NAME, FLAGS, OPTAB, TYPE) \
-@@ -868,86 +925,87 @@ main (int argc, const char **argv)
- /* Assign sequential codes to all entries in the machine description
- in parallel with the tables in insn-output.cc. */
-
-- printf ("/* Generated automatically by the program `genemit'\n\
--from the machine description file `md'. */\n\n");
-+ int npatterns = count_patterns ();
-+ md_rtx_info info;
-+
-+ bool to_stdout = false;
-+ int npatterns_per_file = npatterns;
-+ if (!output_files.is_empty ())
-+ npatterns_per_file = npatterns / output_files.length () + 1;
-+ else
-+ to_stdout = true;
-
-- printf ("#define IN_TARGET_CODE 1\n");
-- printf ("#include \"config.h\"\n");
-- printf ("#include \"system.h\"\n");
-- printf ("#include \"coretypes.h\"\n");
-- printf ("#include \"backend.h\"\n");
-- printf ("#include \"predict.h\"\n");
-- printf ("#include \"tree.h\"\n");
-- printf ("#include \"rtl.h\"\n");
-- printf ("#include \"alias.h\"\n");
-- printf ("#include \"varasm.h\"\n");
-- printf ("#include \"stor-layout.h\"\n");
-- printf ("#include \"calls.h\"\n");
-- printf ("#include \"memmodel.h\"\n");
-- printf ("#include \"tm_p.h\"\n");
-- printf ("#include \"flags.h\"\n");
-- printf ("#include \"insn-config.h\"\n");
-- printf ("#include \"expmed.h\"\n");
-- printf ("#include \"dojump.h\"\n");
-- printf ("#include \"explow.h\"\n");
-- printf ("#include \"emit-rtl.h\"\n");
-- printf ("#include \"stmt.h\"\n");
-- printf ("#include \"expr.h\"\n");
-- printf ("#include \"insn-codes.h\"\n");
-- printf ("#include \"optabs.h\"\n");
-- printf ("#include \"dfp.h\"\n");
-- printf ("#include \"output.h\"\n");
-- printf ("#include \"recog.h\"\n");
-- printf ("#include \"df.h\"\n");
-- printf ("#include \"resource.h\"\n");
-- printf ("#include \"reload.h\"\n");
-- printf ("#include \"diagnostic-core.h\"\n");
-- printf ("#include \"regs.h\"\n");
-- printf ("#include \"tm-constrs.h\"\n");
-- printf ("#include \"ggc.h\"\n");
-- printf ("#include \"target.h\"\n\n");
-+ gcc_assert (npatterns_per_file > 1);
-
-- /* Read the machine description. */
-+ /* Reverse so we can pop the first-added element. */
-+ output_files.reverse ();
-
-- md_rtx_info info;
-+ int count = 0;
-+ FILE *file = NULL;
-+
-+ /* Read the machine description. */
- while (read_md_rtx (&info))
-- switch (GET_CODE (info.def))
-- {
-- case DEFINE_INSN:
-- gen_insn (&info);
-- break;
-+ {
-+ if (count == 0 || count == npatterns_per_file)
-+ {
-+ bool is_last = !to_stdout && output_files.is_empty ();
-+ if (file && !is_last)
-+ if (fclose (file) != 0)
-+ return FATAL_EXIT_CODE;
-
-- case DEFINE_EXPAND:
-- printf ("/* %s:%d */\n", info.loc.filename, info.loc.lineno);
-- gen_expand (&info);
-- break;
-+ if (!output_files.is_empty ())
-+ {
-+ const char *const filename = output_files.pop ();
-+ file = fopen (filename, "w");
-+ }
-+ else if (to_stdout)
-+ file = stdout;
-+ else
-+ break;
-
-- case DEFINE_SPLIT:
-- printf ("/* %s:%d */\n", info.loc.filename, info.loc.lineno);
-- gen_split (&info);
-- break;
-+ print_header (file);
-+ count = 0;
-+ }
-
-- case DEFINE_PEEPHOLE2:
-- printf ("/* %s:%d */\n", info.loc.filename, info.loc.lineno);
-- gen_split (&info);
-- break;
-+ switch (GET_CODE (info.def))
-+ {
-+ case DEFINE_INSN:
-+ gen_insn (&info, file);
-+ break;
-
-- default:
-- break;
-- }
-+ case DEFINE_EXPAND:
-+ fprintf (file, "/* %s:%d */\n", info.loc.filename, info.loc.lineno);
-+ gen_expand (&info, file);
-+ break;
-+
-+ case DEFINE_SPLIT:
-+ fprintf (file, "/* %s:%d */\n", info.loc.filename, info.loc.lineno);
-+ gen_split (&info, file);
-+ break;
-+
-+ case DEFINE_PEEPHOLE2:
-+ fprintf (file, "/* %s:%d */\n", info.loc.filename, info.loc.lineno);
-+ gen_split (&info, file);
-+ break;
-+
-+ default:
-+ break;
-+ }
-+
-+ count++;
-+ }
-
- /* Write out the routines to add CLOBBERs to a pattern and say whether they
- clobber a hard reg. */
-- output_add_clobbers (&info);
-- output_added_clobbers_hard_reg_p ();
-+ output_add_clobbers (&info, file);
-+ output_added_clobbers_hard_reg_p (file);
-
- for (overloaded_name *oname = rtx_reader_ptr->get_overloads ();
- oname; oname = oname->next)
- {
-- handle_overloaded_code_for (oname);
-- handle_overloaded_gen (oname);
-+ handle_overloaded_code_for (oname, file);
-+ handle_overloaded_gen (oname, file);
- }
-
-- fflush (stdout);
-- return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
-+ return (fclose (file) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
- }
-diff --git a/gcc/gensupport.cc b/gcc/gensupport.cc
-index dd920d673b45..688808c7d12b 100644
---- a/gcc/gensupport.cc
-+++ b/gcc/gensupport.cc
-@@ -3131,6 +3131,61 @@ init_rtx_reader_args (int argc, const char **argv)
- return init_rtx_reader_args_cb (argc, argv, 0);
- }
-
-+/* Count the number of patterns in all queues and return the count. */
-+int
-+count_patterns ()
-+{
-+ int count = 0, truth = 1;
-+ rtx def;
-+ class queue_elem *cur = define_attr_queue;
-+ while (cur)
-+ {
-+ def = cur->data;
-+
-+ truth = maybe_eval_c_test (get_c_test (def));
-+ if (truth || !insn_elision)
-+ count++;
-+ cur = cur->next;
-+ }
-+
-+ cur = define_pred_queue;
-+ while (cur)
-+ {
-+ def = cur->data;
-+
-+ truth = maybe_eval_c_test (get_c_test (def));
-+ if (truth || !insn_elision)
-+ count++;
-+ cur = cur->next;
-+ }
-+
-+ cur = define_insn_queue;
-+ truth = 1;
-+ while (cur)
-+ {
-+ def = cur->data;
-+
-+ truth = maybe_eval_c_test (get_c_test (def));
-+ if (truth || !insn_elision)
-+ count++;
-+ cur = cur->next;
-+ }
-+
-+ cur = other_queue;
-+ truth = 1;
-+ while (cur)
-+ {
-+ def = cur->data;
-+
-+ truth = maybe_eval_c_test (get_c_test (def));
-+ if (truth || !insn_elision)
-+ count++;
-+ cur = cur->next;
-+ }
-+
-+ return count;
-+}
-+
- /* Try to read a single rtx from the file. Return true on success,
- describing it in *INFO. */
-
-diff --git a/gcc/gensupport.h b/gcc/gensupport.h
-index 7925e22ed418..7396118714bc 100644
---- a/gcc/gensupport.h
-+++ b/gcc/gensupport.h
-@@ -130,6 +130,7 @@ extern rtx add_implicit_parallel (rtvec);
- extern rtx_reader *init_rtx_reader_args_cb (int, const char **,
- bool (*)(const char *));
- extern rtx_reader *init_rtx_reader_args (int, const char **);
-+extern int count_patterns ();
- extern bool read_md_rtx (md_rtx_info *);
- extern unsigned int get_num_insn_codes ();
-
-diff --git a/gcc/read-md.cc b/gcc/read-md.cc
-index fd38818e3a3e..46ab9065e3e4 100644
---- a/gcc/read-md.cc
-+++ b/gcc/read-md.cc
-@@ -132,9 +132,9 @@ md_reader::fprint_md_ptr_loc (FILE *outf, const void *ptr)
-
- /* Special fprint_md_ptr_loc for writing to STDOUT. */
- void
--md_reader::print_md_ptr_loc (const void *ptr)
-+md_reader::print_md_ptr_loc (const void *ptr, FILE *file)
- {
-- fprint_md_ptr_loc (stdout, ptr);
-+ fprint_md_ptr_loc (file, ptr);
- }
-
- /* Return a condition that satisfies both COND1 and COND2. Either string
-diff --git a/gcc/read-md.h b/gcc/read-md.h
-index b309c9c3deb6..2adcb58478fe 100644
---- a/gcc/read-md.h
-+++ b/gcc/read-md.h
-@@ -194,7 +194,7 @@ class md_reader
- const struct ptr_loc *get_md_ptr_loc (const void *ptr);
- void copy_md_ptr_loc (const void *new_ptr, const void *old_ptr);
- void fprint_md_ptr_loc (FILE *outf, const void *ptr);
-- void print_md_ptr_loc (const void *ptr);
-+ void print_md_ptr_loc (const void *ptr, FILE * = stdout);
-
- struct enum_type *lookup_enum_type (const char *name);
- void traverse_enum_types (htab_trav callback, void *info);
---
-2.42.0
-