Mercurial > hg > CbC > CbC_gcc
diff gcc/genemit.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
line wrap: on
line diff
--- a/gcc/genemit.c Fri Oct 27 22:46:09 2017 +0900 +++ b/gcc/genemit.c Thu Oct 25 07:37:49 2018 +0900 @@ -1,5 +1,5 @@ /* Generate code from machine description to emit insns as rtl. - Copyright (C) 1987-2017 Free Software Foundation, Inc. + Copyright (C) 1987-2018 Free Software Foundation, Inc. This file is part of GCC. @@ -79,7 +79,7 @@ substituting any operand references appearing within. */ static void -gen_exp (rtx x, enum rtx_code subroutine_type, char *used) +gen_exp (rtx x, enum rtx_code subroutine_type, char *used, md_rtx_info *info) { RTX_CODE code; int i; @@ -123,7 +123,7 @@ for (i = 0; i < XVECLEN (x, 1); i++) { printf (",\n\t\t"); - gen_exp (XVECEXP (x, 1, i), subroutine_type, used); + gen_exp (XVECEXP (x, 1, i), subroutine_type, used, info); } printf (")"); return; @@ -137,7 +137,7 @@ for (i = 0; i < XVECLEN (x, 2); i++) { printf (",\n\t\t"); - gen_exp (XVECEXP (x, 2, i), subroutine_type, used); + gen_exp (XVECEXP (x, 2, i), subroutine_type, used, info); } printf (")"); return; @@ -163,12 +163,21 @@ case CLOBBER: if (REG_P (XEXP (x, 0))) { - printf ("gen_hard_reg_clobber (%smode, %i)", GET_MODE_NAME (GET_MODE (XEXP (x, 0))), - REGNO (XEXP (x, 0))); + printf ("gen_hard_reg_clobber (%smode, %i)", + GET_MODE_NAME (GET_MODE (XEXP (x, 0))), + REGNO (XEXP (x, 0))); return; } break; - + case CLOBBER_HIGH: + if (!REG_P (XEXP (x, 0))) + error ("CLOBBER_HIGH argument is not a register expr, at %s:%d", + info->loc.filename, info->loc.lineno); + printf ("gen_hard_reg_clobber_high (%smode, %i)", + GET_MODE_NAME (GET_MODE (XEXP (x, 0))), + REGNO (XEXP (x, 0))); + return; + break; case CC0: printf ("cc0_rtx"); return; @@ -224,7 +233,7 @@ switch (fmt[i]) { case 'e': case 'u': - gen_exp (XEXP (x, i), subroutine_type, used); + gen_exp (XEXP (x, i), subroutine_type, used, info); break; case 'i': @@ -235,6 +244,12 @@ printf ("%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 ()); + break; + case 's': printf ("\"%s\"", XSTR (x, i)); break; @@ -246,7 +261,7 @@ for (j = 0; j < XVECLEN (x, i); j++) { printf (",\n\t\t"); - gen_exp (XVECEXP (x, i, j), subroutine_type, used); + gen_exp (XVECEXP (x, i, j), subroutine_type, used, info); } printf (")"); break; @@ -264,7 +279,7 @@ becoming a separate instruction. USED is as for gen_exp. */ static void -gen_emit_seq (rtvec vec, char *used) +gen_emit_seq (rtvec vec, char *used, md_rtx_info *info) { for (int i = 0, len = GET_NUM_ELEM (vec); i < len; ++i) { @@ -273,7 +288,7 @@ if (const char *name = get_emit_function (next)) { printf (" %s (", name); - gen_exp (next, DEFINE_EXPAND, used); + gen_exp (next, DEFINE_EXPAND, used, info); printf (");\n"); if (!last_p && needs_barrier_p (next)) printf (" emit_barrier ();"); @@ -281,7 +296,7 @@ else { printf (" emit ("); - gen_exp (next, DEFINE_EXPAND, used); + gen_exp (next, DEFINE_EXPAND, used, info); printf (", %s);\n", last_p ? "false" : "true"); } } @@ -328,7 +343,8 @@ for (i = XVECLEN (insn, 1) - 1; i > 0; i--) { - if (GET_CODE (XVECEXP (insn, 1, i)) != CLOBBER) + if (GET_CODE (XVECEXP (insn, 1, i)) != CLOBBER + && GET_CODE (XVECEXP (insn, 1, i)) != CLOBBER_HIGH) break; if (REG_P (XEXP (XVECEXP (insn, 1, i), 0))) @@ -362,7 +378,8 @@ /* OLD and NEW_INSN are the same if both are to be a SCRATCH of the same mode, or if both are registers of the same mode and number. */ - if (! (GET_MODE (old_rtx) == GET_MODE (new_rtx) + if (! (GET_CODE (old_rtx) == GET_CODE (new_rtx) + && GET_MODE (old_rtx) == GET_MODE (new_rtx) && ((GET_CODE (old_rtx) == MATCH_SCRATCH && GET_CODE (new_rtx) == MATCH_SCRATCH) || (REG_P (old_rtx) && REG_P (new_rtx) @@ -425,7 +442,7 @@ ? NULL : XCNEWVEC (char, stats.num_generator_args)); printf (" return "); - gen_exp (pattern, DEFINE_INSN, used); + gen_exp (pattern, DEFINE_INSN, used, info); printf (";\n}\n\n"); XDELETEVEC (used); } @@ -474,7 +491,7 @@ && XVECLEN (expand, 1) == 1) { printf (" return "); - gen_exp (XVECEXP (expand, 1, 0), DEFINE_EXPAND, NULL); + gen_exp (XVECEXP (expand, 1, 0), DEFINE_EXPAND, NULL, info); printf (";\n}\n\n"); return; } @@ -528,7 +545,7 @@ } used = XCNEWVEC (char, stats.num_operand_vars); - gen_emit_seq (XVEC (expand, 1), used); + gen_emit_seq (XVEC (expand, 1), used, info); XDELETEVEC (used); /* Call `get_insns' to extract the list of all the @@ -611,7 +628,7 @@ printf (" (void) operand%d;\n", i); } - gen_emit_seq (XVEC (split, 2), used); + gen_emit_seq (XVEC (split, 2), used, info); /* Call `get_insns' to make a list of all the insns emitted within this gen_... function. */ @@ -628,7 +645,7 @@ the end of the vector. */ static void -output_add_clobbers (void) +output_add_clobbers (md_rtx_info *info) { struct clobber_pat *clobber; struct clobber_ent *ent; @@ -648,7 +665,7 @@ { printf (" XVECEXP (pattern, 0, %d) = ", i); gen_exp (XVECEXP (clobber->pattern, 1, i), - GET_CODE (clobber->pattern), NULL); + GET_CODE (clobber->pattern), NULL, info); printf (";\n"); } @@ -746,6 +763,92 @@ } } +/* Print "arg<N>" parameter declarations for each argument N of ONAME. */ + +static void +print_overload_arguments (overloaded_name *oname) +{ + for (unsigned int i = 0; i < oname->arg_types.length (); ++i) + printf ("%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) +{ + for (unsigned int i = 0; i < instance->arg_values.length (); ++i) + printf ("%sarg%d == %s", i == 0 ? " if (" : "\n && ", + i, instance->arg_values[i]); + printf (")\n"); +} + +/* Emit a maybe_code_for_* function for ONAME. */ + +static void +handle_overloaded_code_for (overloaded_name *oname) +{ + /* Print the function prototype. */ + printf ("\ninsn_code\nmaybe_code_for_%s (", oname->name); + print_overload_arguments (oname); + printf (")\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); + } + + /* Return null if no match was found. */ + printf (" return CODE_FOR_nothing;\n}\n"); +} + +/* Emit a maybe_gen_* function for ONAME. */ + +static void +handle_overloaded_gen (overloaded_name *oname) +{ + /* All patterns must have the same number of operands. */ + pattern_stats stats; + get_pattern_stats (&stats, XVEC (oname->first_instance->insn, 1)); + for (overloaded_instance *instance = oname->first_instance->next; + instance; instance = instance->next) + { + pattern_stats stats2; + get_pattern_stats (&stats2, XVEC (instance->insn, 1)); + if (stats.num_generator_args != stats2.num_generator_args) + fatal_at (get_file_location (instance->insn), + "inconsistent number of operands for '%s'; " + "this instance has %d, but previous instances had %d", + oname->name, stats2.num_generator_args, + stats.num_generator_args); + } + + /* Print the function prototype. */ + printf ("\nrtx\nmaybe_gen_%s (", oname->name); + print_overload_arguments (oname); + for (int i = 0; i < stats.num_generator_args; ++i) + printf (", rtx x%d", i); + printf (")\n{\n"); + + /* Use maybe_code_for_*, instead of duplicating the selection logic here. */ + printf (" 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" + " if (code != CODE_FOR_nothing)\n" + " return GEN_FCN (code) ("); + for (int i = 0; i < stats.num_generator_args; ++i) + printf ("%sx%d", i == 0 ? "" : ", ", i); + printf (");\n" + " else\n" + " return NULL_RTX;\n" + "}\n"); +} + int main (int argc, const char **argv) { @@ -764,6 +867,7 @@ printf ("/* Generated automatically by the program `genemit'\n\ from the machine description file `md'. */\n\n"); + printf ("#define IN_TARGET_CODE 1\n"); printf ("#include \"config.h\"\n"); printf ("#include \"system.h\"\n"); printf ("#include \"coretypes.h\"\n"); @@ -830,9 +934,16 @@ /* Write out the routines to add CLOBBERs to a pattern and say whether they clobber a hard reg. */ - output_add_clobbers (); + output_add_clobbers (&info); output_added_clobbers_hard_reg_p (); + for (overloaded_name *oname = rtx_reader_ptr->get_overloads (); + oname; oname = oname->next) + { + handle_overloaded_code_for (oname); + handle_overloaded_gen (oname); + } + fflush (stdout); return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); }