X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fgenemit.c;h=45a102ebf229dba08b84403c455c2f32354f8922;hb=d8fc4d0b60e9beedaee917b2a0f66df2fc348ec1;hp=747001bb1aa8185dfde4173e2e231c626b6342c7;hpb=38330f30a2865c1f371c1399622686a9abefaa1d;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/genemit.c b/gcc/genemit.c index 747001bb1aa..45a102ebf22 100644 --- a/gcc/genemit.c +++ b/gcc/genemit.c @@ -1,5 +1,6 @@ /* Generate code from machine description to emit insns as rtl. - Copyright (C) 1987, 88, 91, 94, 95, 97, 98, 1999 Free Software Foundation, Inc. + Copyright (C) 1987, 1988, 1991, 1994, 1995, 1997, 1998, 1999, 2000, 2001 + Free Software Foundation, Inc. This file is part of GNU CC. @@ -22,17 +23,9 @@ Boston, MA 02111-1307, USA. */ #include "hconfig.h" #include "system.h" #include "rtl.h" -#include "obstack.h" #include "errors.h" +#include "gensupport.h" -static struct obstack obstack; -struct obstack *rtl_obstack = &obstack; - -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -/* Define this so we can link with print-rtl.o to get debug_rtx function. */ -char **insn_name_ptr = 0; static int max_opno; static int max_dup_opno; @@ -51,6 +44,7 @@ struct clobber_pat rtx pattern; int first_clobber; struct clobber_pat *next; + int has_hard_reg; } *clobber_list; /* Records one insn that uses the clobber list. */ @@ -61,16 +55,17 @@ struct clobber_ent struct clobber_ent *next; }; -static void max_operand_1 PROTO((rtx)); -static int max_operand_vec PROTO((rtx, int)); -static void print_code PROTO((RTX_CODE)); -static void gen_exp PROTO((rtx, enum rtx_code)); -static void gen_insn PROTO((rtx)); -static void gen_expand PROTO((rtx)); -static void gen_split PROTO((rtx)); -static void output_add_clobbers PROTO((void)); -static void gen_rtx_scratch PROTO((rtx, enum rtx_code)); -static void output_peephole2_scratches PROTO((rtx)); +static void max_operand_1 PARAMS ((rtx)); +static int max_operand_vec PARAMS ((rtx, int)); +static void print_code PARAMS ((RTX_CODE)); +static void gen_exp PARAMS ((rtx, enum rtx_code)); +static void gen_insn PARAMS ((rtx)); +static void gen_expand PARAMS ((rtx)); +static void gen_split PARAMS ((rtx)); +static void output_add_clobbers PARAMS ((void)); +static void output_added_clobbers_hard_reg_p PARAMS ((void)); +static void gen_rtx_scratch PARAMS ((rtx, enum rtx_code)); +static void output_peephole2_scratches PARAMS ((rtx)); static void @@ -138,12 +133,7 @@ print_code (code) { register const char *p1; for (p1 = GET_RTX_NAME (code); *p1; p1++) - { - if (ISLOWER(*p1)) - putchar (toupper(*p1)); - else - putchar (*p1); - } + putchar (TOUPPER(*p1)); } static void @@ -309,11 +299,18 @@ gen_insn (insn) if (XVEC (insn, 1)) { + int has_hard_reg = 0; + for (i = XVECLEN (insn, 1) - 1; i > 0; i--) - if (GET_CODE (XVECEXP (insn, 1, i)) != CLOBBER - || (GET_CODE (XEXP (XVECEXP (insn, 1, i), 0)) != REG - && GET_CODE (XEXP (XVECEXP (insn, 1, i), 0)) != MATCH_SCRATCH)) - break; + { + if (GET_CODE (XVECEXP (insn, 1, i)) != CLOBBER) + break; + + if (GET_CODE (XEXP (XVECEXP (insn, 1, i), 0)) == REG) + has_hard_reg = 1; + else if (GET_CODE (XEXP (XVECEXP (insn, 1, i), 0)) != MATCH_SCRATCH) + break; + } if (i != XVECLEN (insn, 1) - 1) { @@ -361,6 +358,7 @@ gen_insn (insn) p->pattern = insn; p->first_clobber = i + 1; p->next = clobber_list; + p->has_hard_reg = has_hard_reg; clobber_list = p; } @@ -385,7 +383,10 @@ gen_insn (insn) /* Output the function name and argument declarations. */ printf ("rtx\ngen_%s (", XSTR (insn, 0)); for (i = 0; i < operands; i++) - printf (i ? ", operand%d" : "operand%d", i); + if (i) + printf (", operand%d", i); + else + printf ("operand%d", i); printf (")\n"); for (i = 0; i < operands; i++) printf (" rtx operand%d;\n", i); @@ -436,7 +437,10 @@ gen_expand (expand) /* Output the function name and argument declarations. */ printf ("rtx\ngen_%s (", XSTR (expand, 0)); for (i = 0; i < operands; i++) - printf (i ? ", operand%d" : "operand%d", i); + if (i) + printf (", operand%d", i); + else + printf ("operand%d", i); printf (")\n"); for (i = 0; i < operands; i++) printf (" rtx operand%d;\n", i); @@ -554,7 +558,8 @@ gen_split (split) { register int i; int operands; - char *name = "split"; + const char *name = "split"; + const char *unused; if (GET_CODE (split) == DEFINE_PEEPHOLE2) name = "peephole2"; @@ -570,22 +575,23 @@ gen_split (split) max_operand_vec (split, 2); operands = MAX (max_opno, MAX (max_dup_opno, max_scratch_opno)) + 1; + unused = (operands == 0 ? " ATTRIBUTE_UNUSED" : ""); /* Output the prototype, function name and argument declarations. */ if (GET_CODE (split) == DEFINE_PEEPHOLE2) { - printf ("extern rtx gen_%s_%d PROTO ((rtx, rtx *));\n", + printf ("extern rtx gen_%s_%d PARAMS ((rtx, rtx *));\n", name, insn_code_number); - printf ("rtx\ngen_%s_%d (curr_insn, operands)\n\ - rtx curr_insn ATTRIBUTE_UNUSED;\n\ - rtx *operands;\n", + printf ("rtx\ngen_%s_%d (curr_insn, operands)\n", name, insn_code_number); + printf (" rtx curr_insn ATTRIBUTE_UNUSED;\n"); + printf (" rtx *operands%s;\n", unused); } else { - printf ("extern rtx gen_split_%d PROTO ((rtx *));\n", insn_code_number); - printf ("rtx\ngen_%s_%d (operands)\n rtx *operands;\n", name, - insn_code_number); + printf ("extern rtx gen_split_%d PARAMS ((rtx *));\n", insn_code_number); + printf ("rtx\ngen_%s_%d (operands)\n", name, insn_code_number); + printf (" rtx *operands%s;\n", unused); } printf ("{\n"); @@ -695,8 +701,41 @@ output_add_clobbers () printf ("}\n"); } +/* Write a function, `added_clobbers_hard_reg_p' this is given an insn_code + number that needs clobbers and returns 1 if they include a clobber of a + hard reg and 0 if they just clobber SCRATCH. */ + +static void +output_added_clobbers_hard_reg_p () +{ + struct clobber_pat *clobber; + struct clobber_ent *ent; + int clobber_p; + + printf ("\n\nint\nadded_clobbers_hard_reg_p (insn_code_number)\n"); + printf (" int insn_code_number;\n"); + printf ("{\n"); + printf (" switch (insn_code_number)\n"); + printf (" {\n"); + + for (clobber_p = 0; clobber_p <= 1; clobber_p++) + { + for (clobber = clobber_list; clobber; clobber = clobber->next) + if (clobber->has_hard_reg == clobber_p) + for (ent = clobber->insns; ent; ent = ent->next) + printf (" case %d:\n", ent->code_number); + + printf (" return %d;\n\n", clobber_p); + } + + printf (" default:\n"); + printf (" abort ();\n"); + printf (" }\n"); + printf ("}\n"); +} + /* Generate code to invoke find_free_register () as needed for the - scratch registers used by the peephole2 pattern in SPLIT. */ + scratch registers used by the peephole2 pattern in SPLIT. */ static void output_peephole2_scratches (split) @@ -705,10 +744,7 @@ output_peephole2_scratches (split) int i; int insn_nr = 0; - printf (" rtx first_insn ATTRIBUTE_UNUSED;\n"); - printf (" rtx last_insn ATTRIBUTE_UNUSED;\n"); printf (" HARD_REG_SET _regs_allocated;\n"); - printf (" CLEAR_HARD_REG_SET (_regs_allocated);\n"); for (i = 0; i < XVECLEN (split, 0); i++) @@ -727,15 +763,11 @@ output_peephole2_scratches (split) } else if (GET_CODE (XVECEXP (split, 0, j)) != MATCH_SCRATCH) cur_insn_nr++; - printf (" first_insn = recog_next_insn (curr_insn, %d);\n", insn_nr); - if (last_insn_nr > insn_nr) - printf (" last_insn = recog_next_insn (curr_insn, %d);\n", - last_insn_nr - 1); - else - printf (" last_insn = 0;\n"); - printf (" if ((operands[%d] = find_free_register (first_insn, last_insn, \"%s\", %smode, &_regs_allocated)) == NULL_RTX)\n\ + + printf (" 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, XSTR (elt, 1), GET_MODE_NAME (GET_MODE (elt))); @@ -744,33 +776,8 @@ output_peephole2_scratches (split) insn_nr++; } } - -PTR -xmalloc (size) - size_t size; -{ - register PTR val = (PTR) malloc (size); - - if (val == 0) - fatal ("virtual memory exhausted"); - - return val; -} -PTR -xrealloc (old, size) - PTR old; - size_t size; -{ - register PTR ptr; - if (old) - ptr = (PTR) realloc (old, size); - else - ptr = (PTR) malloc (size); - if (!ptr) - fatal ("virtual memory exhausted"); - return ptr; -} +extern int main PARAMS ((int, char **)); int main (argc, argv) @@ -778,21 +785,14 @@ main (argc, argv) char **argv; { rtx desc; - FILE *infile; - register int c; progname = "genemit"; - obstack_init (rtl_obstack); if (argc <= 1) fatal ("No input file name."); - infile = fopen (argv[1], "r"); - if (infile == 0) - { - perror (argv[1]); - exit (FATAL_EXIT_CODE); - } + if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE) + return (FATAL_EXIT_CODE); /* Assign sequential codes to all entries in the machine description in parallel with the tables in insn-output.c. */ @@ -806,19 +806,20 @@ from the machine description file `md'. */\n\n"); printf ("#include \"config.h\"\n"); printf ("#include \"system.h\"\n"); printf ("#include \"rtl.h\"\n"); + printf ("#include \"tm_p.h\"\n"); printf ("#include \"function.h\"\n"); printf ("#include \"expr.h\"\n"); + printf ("#include \"optabs.h\"\n"); printf ("#include \"real.h\"\n"); printf ("#include \"flags.h\"\n"); printf ("#include \"output.h\"\n"); printf ("#include \"insn-config.h\"\n"); - printf ("#include \"insn-flags.h\"\n"); - printf ("#include \"insn-codes.h\"\n"); - printf ("#include \"recog.h\"\n"); printf ("#include \"hard-reg-set.h\"\n"); + printf ("#include \"recog.h\"\n"); printf ("#include \"resource.h\"\n"); - printf ("#include \"reload.h\"\n\n"); - printf ("extern rtx recog_operand[];\n"); + printf ("#include \"reload.h\"\n"); + printf ("#include \"toplev.h\"\n"); + printf ("#include \"ggc.h\"\n\n"); printf ("#define FAIL return (end_sequence (), _val)\n"); printf ("#define DONE return (_val = gen_sequence (), end_sequence (), _val)\n"); @@ -826,45 +827,49 @@ from the machine description file `md'. */\n\n"); while (1) { - c = read_skip_spaces (infile); - if (c == EOF) - break; - ungetc (c, infile); + int line_no; - desc = read_rtx (infile); + desc = read_md_rtx (&line_no, &insn_code_number); + if (desc == NULL) + break; - if (GET_CODE (desc) == DEFINE_INSN) - { - gen_insn (desc); - ++insn_code_number; - } - if (GET_CODE (desc) == DEFINE_EXPAND) + switch (GET_CODE (desc)) { - gen_expand (desc); - ++insn_code_number; - } - if (GET_CODE (desc) == DEFINE_SPLIT) - { - gen_split (desc); - ++insn_code_number; - } - if (GET_CODE (desc) == DEFINE_PEEPHOLE2) - { - gen_split (desc); - ++insn_code_number; - } - if (GET_CODE (desc) == DEFINE_PEEPHOLE) - { - ++insn_code_number; - } + case DEFINE_INSN: + gen_insn (desc); + break; + + case DEFINE_EXPAND: + gen_expand (desc); + break; + + case DEFINE_SPLIT: + gen_split (desc); + break; + + case DEFINE_PEEPHOLE2: + gen_split (desc); + break; + + default: + break; + } ++insn_index_number; } - /* Write out the routine to add CLOBBERs to a pattern. */ + /* Write out the routines to add CLOBBERs to a pattern and say whether they + clobber a hard reg. */ output_add_clobbers (); + output_added_clobbers_hard_reg_p (); fflush (stdout); - exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); - /* NOTREACHED */ - return 0; + return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); +} + +/* Define this so we can link with print-rtl.o to get debug_rtx function. */ +const char * +get_insn_name (code) + int code ATTRIBUTE_UNUSED; +{ + return NULL; }