diff options
Diffstat (limited to 'gcc/genoutput.c')
-rw-r--r-- | gcc/genoutput.c | 84 |
1 files changed, 69 insertions, 15 deletions
diff --git a/gcc/genoutput.c b/gcc/genoutput.c index 39fc590f01f..673e13fa1af 100644 --- a/gcc/genoutput.c +++ b/gcc/genoutput.c @@ -243,7 +243,10 @@ output_prologue (void) printf ("#include \"toplev.h\"\n"); printf ("#include \"output.h\"\n"); printf ("#include \"target.h\"\n"); - printf ("#include \"tm-constrs.h\"\n"); + printf ("#include \"multi-target.h\"\n"); + printf ("#include \"tm-constrs.h\"\n\n"); + + printf ("START_TARGET_SPECIFIC\n"); } static void @@ -680,19 +683,55 @@ process_template (struct data *d, const char *template_code) list of assembler code templates, one for each alternative. */ else if (template_code[0] == '@') { - d->template_code = 0; - d->output_format = INSN_OUTPUT_FORMAT_MULTI; + int found_star = 0; - printf ("\nstatic const char * const output_%d[] = {\n", d->code_number); + for (cp = &template_code[1]; *cp; ) + { + while (ISSPACE (*cp)) + cp++; + if (*cp == '*') + found_star = 1; + while (!IS_VSPACE (*cp) && *cp != '\0') + ++cp; + } + d->template_code = 0; + if (found_star) + { + d->output_format = INSN_OUTPUT_FORMAT_FUNCTION; + puts ("\nstatic const char *"); + printf ("output_%d (rtx *operands ATTRIBUTE_UNUSED, " + "rtx insn ATTRIBUTE_UNUSED)\n", d->code_number); + puts ("{"); + puts (" switch (which_alternative)\n {"); + } + else + { + d->output_format = INSN_OUTPUT_FORMAT_MULTI; + printf ("\nstatic const char * const output_%d[] = {\n", + d->code_number); + } for (i = 0, cp = &template_code[1]; *cp; ) { - const char *ep, *sp; + const char *ep, *sp, *bp; while (ISSPACE (*cp)) cp++; - printf (" \""); + bp = cp; + if (found_star) + { + printf (" case %d:", i); + if (*cp == '*') + { + printf ("\n "); + cp++; + } + else + printf (" return \""); + } + else + printf (" \""); for (ep = sp = cp; !IS_VSPACE (*ep) && *ep != '\0'; ++ep) if (!ISSPACE (*ep)) @@ -708,7 +747,18 @@ process_template (struct data *d, const char *template_code) cp++; } - printf ("\",\n"); + if (!found_star) + puts ("\","); + else if (*bp != '*') + puts ("\";"); + else + { + /* The usual action will end with a return. + If there is neither break or return at the end, this is + assumed to be intentional; this allows to have multiple + consecutive alternatives share some code. */ + puts (""); + } i++; } if (i == 1) @@ -721,7 +771,10 @@ process_template (struct data *d, const char *template_code) have_error = 1; } - printf ("};\n"); + if (found_star) + puts (" default: gcc_unreachable ();\n }\n}"); + else + printf ("};\n"); } else { @@ -1064,6 +1117,8 @@ main (int argc, char **argv) output_insn_data (); output_get_insn_name (); + printf ("\nEND_TARGET_SPECIFIC\n"); + fflush (stdout); return (ferror (stdout) != 0 || have_error ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); @@ -1112,8 +1167,12 @@ strip_whitespace (const char *s) /* Record just enough information about a constraint to allow checking of operand constraint strings above, in validate_insn_alternatives. Does not validate most properties of the constraint itself; does + enforce no overlap with MI constraints, and no prefixes. + Check for no duplicate names is left to genpreds.c, since only there + is enough information to check for overloading. + Does not validate most properties of the constraint itself; does enforce no duplicate names, no overlap with MI constraints, and no - prefixes. EXP is the define_*constraint form, LINENO the line number +EXP is the define_*constraint form, LINENO the line number reported by the reader. */ static void note_constraint (rtx exp, int lineno) @@ -1150,12 +1209,7 @@ note_constraint (rtx exp, int lineno) slot = iter; if (!strcmp ((*iter)->name, name)) - { - message_with_line (lineno, "redefinition of constraint '%s'", name); - message_with_line ((*iter)->lineno, "previous definition is here"); - have_error = 1; - return; - } + ; /* Ignore here, see more detailed check in genpreds. */ else if (!strncmp ((*iter)->name, name, (*iter)->namelen)) { message_with_line (lineno, "defining constraint '%s' here", name); |