X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fgenpreds.c;h=02379d67f34a7f668148e171bf317b0f1d7fc914;hb=5672b7f8b134fa65319353041e024e66f3bd6ad1;hp=93ce942e50a6567cfab4ba939f61b5b6ded71b49;hpb=ed5217e6bf374c480de6484fa051cb6cf22bfad1;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/genpreds.c b/gcc/genpreds.c index 93ce942e50a..02379d67f34 100644 --- a/gcc/genpreds.c +++ b/gcc/genpreds.c @@ -2,14 +2,14 @@ - prototype declarations for operand predicates (tm-preds.h) - function definitions of operand predicates, if defined new-style (insn-preds.c) - Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007 + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) +the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, @@ -18,9 +18,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING. If not, write to -the Free Software Foundation, 51 Franklin Street, Fifth Floor, -Boston, MA 02110-1301, USA. */ +along with GCC; see the file COPYING3. If not see +. */ #include "bconfig.h" #include "system.h" @@ -29,6 +28,7 @@ Boston, MA 02110-1301, USA. */ #include "rtl.h" #include "errors.h" #include "obstack.h" +#include "read-md.h" #include "gensupport.h" /* Given a predicate expression EXP, from form NAME at line LINENO, @@ -67,9 +67,8 @@ validate_exp (rtx exp, const char *name, int lineno) { if (!ISDIGIT (*p) && !ISLOWER (*p)) { - message_with_line (lineno, "%s: invalid character in path " - "string '%s'", name, XSTR (exp, 1)); - have_error = 1; + error_with_line (lineno, "%s: invalid character in path " + "string '%s'", name, XSTR (exp, 1)); return true; } } @@ -82,10 +81,9 @@ validate_exp (rtx exp, const char *name, int lineno) return false; default: - message_with_line (lineno, - "%s: cannot use '%s' in a predicate expression", - name, GET_RTX_NAME (GET_CODE (exp))); - have_error = 1; + error_with_line (lineno, + "%s: cannot use '%s' in a predicate expression", + name, GET_RTX_NAME (GET_CODE (exp))); return true; } } @@ -103,7 +101,7 @@ process_define_predicate (rtx defn, int lineno) for (p = XSTR (defn, 0) + 1; *p; p++) if (!ISALNUM (*p) && *p != '_') goto bad_name; - + if (validate_exp (XEXP (defn, 1), XSTR (defn, 0), lineno)) return; @@ -119,10 +117,9 @@ process_define_predicate (rtx defn, int lineno) return; bad_name: - message_with_line (lineno, - "%s: predicate name must be a valid C function name", - XSTR (defn, 0)); - have_error = 1; + error_with_line (lineno, + "%s: predicate name must be a valid C function name", + XSTR (defn, 0)); return; } @@ -154,7 +151,7 @@ process_define_predicate (rtx defn, int lineno) The only wart is that there's no way to insist on a { } string in an RTL template, so we have to handle "" strings. */ - + static void write_predicate_subfunction (struct pred_data *p) { @@ -184,7 +181,7 @@ write_predicate_subfunction (struct pred_data *p) printf ("static inline int\n" "%s_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)\n", p->name); - print_rtx_ptr_loc (p->c_block); + print_md_ptr_loc (p->c_block); if (p->c_block[0] == '{') fputs (p->c_block, stdout); else @@ -235,7 +232,7 @@ needs_variable (rtx exp, const char *var) if (q != p && (ISALNUM (q[-1]) || q[-1] == '_')) return false; q += strlen (var); - if (ISALNUM (q[0] || q[0] == '_')) + if (ISALNUM (q[0]) || q[0] == '_') return false; } return true; @@ -291,7 +288,7 @@ mark_mode_tests (rtx exp) NO_MODE_TEST (exp) = (NO_MODE_TEST (XEXP (exp, 0)) && NO_MODE_TEST (XEXP (exp, 1))); break; - + case IOR: mark_mode_tests (XEXP (exp, 0)); mark_mode_tests (XEXP (exp, 1)); @@ -384,23 +381,23 @@ add_mode_tests (struct pred_data *p) { int test0 = NO_MODE_TEST (XEXP (subexp, 0)); int test1 = NO_MODE_TEST (XEXP (subexp, 1)); - + gcc_assert (test0 || test1); - + if (test0 && test1) goto break_loop; pos = test0 ? &XEXP (subexp, 0) : &XEXP (subexp, 1); } break; - + case IF_THEN_ELSE: { int test0 = NO_MODE_TEST (XEXP (subexp, 0)); int test1 = NO_MODE_TEST (XEXP (subexp, 1)); int test2 = NO_MODE_TEST (XEXP (subexp, 2)); - + gcc_assert ((test0 && test1) || test2); - + if (test0 && test1 && test2) goto break_loop; if (test0 && test1) @@ -412,7 +409,7 @@ add_mode_tests (struct pred_data *p) pos = &XEXP (subexp, 2); } break; - + default: goto break_loop; } @@ -474,7 +471,7 @@ write_match_code (const char *path, const char *codes) putchar (TOUPPER (*code)); code++; } - + if (*codes == ',') fputs (" || ", stdout); } @@ -494,7 +491,7 @@ write_predicate_expr (rtx exp) write_predicate_expr (XEXP (exp, 1)); putchar (')'); break; - + case IOR: putchar ('('); write_predicate_expr (XEXP (exp, 0)); @@ -691,8 +688,11 @@ static struct constraint_data **last_constraint_ptr = &first_constraint; for (iter_ = first_constraint; iter_; iter_ = iter_->next_textual) /* These letters, and all names beginning with them, are reserved for - generic constraints. */ -static const char generic_constraint_letters[] = "EFVXgimnoprs"; + generic constraints. + The 'm' constraint is not mentioned here since that constraint + letter can be overridden by the back end by defining the + TARGET_MEM_CONSTRAINT macro. */ +static const char generic_constraint_letters[] = "EFVXginoprs"; /* Machine-independent code expects that constraints with these (initial) letters will allow only (a subset of all) CONST_INTs. */ @@ -730,7 +730,7 @@ mangle (const char *name) } obstack_1grow (rtl_obstack, '\0'); - return obstack_finish (rtl_obstack); + return XOBFINISH (rtl_obstack, const char *); } /* Add one constraint, of any sort, to the tables. NAME is its name; @@ -762,12 +762,11 @@ add_constraint (const char *name, const char *regclass, if (!ISALPHA (name[0]) && name[0] != '_') { if (name[1] == '\0') - message_with_line (lineno, "constraint name '%s' is not " - "a letter or underscore", name); + error_with_line (lineno, "constraint name '%s' is not " + "a letter or underscore", name); else - message_with_line (lineno, "constraint name '%s' does not begin " - "with a letter or underscore", name); - have_error = 1; + error_with_line (lineno, "constraint name '%s' does not begin " + "with a letter or underscore", name); return; } for (p = name; *p; p++) @@ -777,11 +776,10 @@ add_constraint (const char *name, const char *regclass, need_mangled_name = true; else { - message_with_line (lineno, - "constraint name '%s' must be composed of " - "letters, digits, underscores, and " - "angle brackets", name); - have_error = 1; + error_with_line (lineno, + "constraint name '%s' must be composed of " + "letters, digits, underscores, and " + "angle brackets", name); return; } } @@ -789,17 +787,16 @@ add_constraint (const char *name, const char *regclass, if (strchr (generic_constraint_letters, name[0])) { if (name[1] == '\0') - message_with_line (lineno, "constraint letter '%s' cannot be " - "redefined by the machine description", name); + error_with_line (lineno, "constraint letter '%s' cannot be " + "redefined by the machine description", name); else - message_with_line (lineno, "constraint name '%s' cannot be defined by " - "the machine description, as it begins with '%c'", - name, name[0]); - have_error = 1; + error_with_line (lineno, "constraint name '%s' cannot be defined by " + "the machine description, as it begins with '%c'", + name, name[0]); return; } - + namelen = strlen (name); slot = &constraints_by_letter_table[(unsigned int)name[0]]; for (iter = slot; *iter; iter = &(*iter)->next_this_letter) @@ -814,25 +811,22 @@ add_constraint (const char *name, const char *regclass, if (!strcmp ((*iter)->name, name)) { - message_with_line (lineno, "redefinition of constraint '%s'", name); + error_with_line (lineno, "redefinition of constraint '%s'", name); message_with_line ((*iter)->lineno, "previous definition is here"); - have_error = 1; return; } else if (!strncmp ((*iter)->name, name, (*iter)->namelen)) { - message_with_line (lineno, "defining constraint '%s' here", name); + error_with_line (lineno, "defining constraint '%s' here", name); message_with_line ((*iter)->lineno, "renders constraint '%s' " "(defined here) a prefix", (*iter)->name); - have_error = 1; return; } else if (!strncmp ((*iter)->name, name, namelen)) { - message_with_line (lineno, "constraint '%s' is a prefix", name); + error_with_line (lineno, "constraint '%s' is a prefix", name); message_with_line ((*iter)->lineno, "of constraint '%s' " "(defined here)", (*iter)->name); - have_error = 1; return; } } @@ -853,49 +847,42 @@ add_constraint (const char *name, const char *regclass, GET_RTX_NAME (appropriate_code))) { if (name[1] == '\0') - message_with_line (lineno, "constraint letter '%c' is reserved " - "for %s constraints", - name[0], GET_RTX_NAME (appropriate_code)); + error_with_line (lineno, "constraint letter '%c' is reserved " + "for %s constraints", + name[0], GET_RTX_NAME (appropriate_code)); else - message_with_line (lineno, "constraint names beginning with '%c' " - "(%s) are reserved for %s constraints", - name[0], name, - GET_RTX_NAME (appropriate_code)); - - have_error = 1; + error_with_line (lineno, "constraint names beginning with '%c' " + "(%s) are reserved for %s constraints", + name[0], name, GET_RTX_NAME (appropriate_code)); return; } if (is_memory) { if (name[1] == '\0') - message_with_line (lineno, "constraint letter '%c' cannot be a " - "memory constraint", name[0]); + error_with_line (lineno, "constraint letter '%c' cannot be a " + "memory constraint", name[0]); else - message_with_line (lineno, "constraint name '%s' begins with '%c', " - "and therefore cannot be a memory constraint", - name, name[0]); - - have_error = 1; + error_with_line (lineno, "constraint name '%s' begins with '%c', " + "and therefore cannot be a memory constraint", + name, name[0]); return; } else if (is_address) { if (name[1] == '\0') - message_with_line (lineno, "constraint letter '%c' cannot be a " - "memory constraint", name[0]); + error_with_line (lineno, "constraint letter '%c' cannot be a " + "memory constraint", name[0]); else - message_with_line (lineno, "constraint name '%s' begins with '%c', " - "and therefore cannot be a memory constraint", - name, name[0]); - - have_error = 1; + error_with_line (lineno, "constraint name '%s' begins with '%c', " + "and therefore cannot be a memory constraint", + name, name[0]); return; } } - - c = obstack_alloc (rtl_obstack, sizeof (struct constraint_data)); + + c = XOBNEW (rtl_obstack, struct constraint_data); c->name = name; c->c_name = need_mangled_name ? mangle (name) : name; c->lineno = lineno; @@ -952,12 +939,13 @@ write_enum_constraint_num (void) { struct constraint_data *c; + fputs ("#define CONSTRAINT_NUM_DEFINED_P 1\n", stdout); fputs ("enum constraint_num\n" "{\n" " CONSTRAINT__UNKNOWN = 0", stdout); FOR_ALL_CONSTRAINTS (c) printf (",\n CONSTRAINT_%s", c->c_name); - puts ("\n};\n"); + puts (",\n CONSTRAINT__LIMIT\n};\n"); } /* Write out a function which looks at a string and determines what @@ -1001,33 +989,51 @@ write_lookup_constraint (void) "}\n"); } -/* Write out the function which computes constraint name lengths from - their enumerators. */ +/* Write out a function which looks at a string and determines what + the constraint name length is. */ static void write_insn_constraint_len (void) { - struct constraint_data *c; - - if (constraint_max_namelen == 1) - return; + unsigned int i; - puts ("size_t\n" - "insn_constraint_len (enum constraint_num c)\n" + puts ("static inline size_t\n" + "insn_constraint_len (char fc, const char *str ATTRIBUTE_UNUSED)\n" "{\n" - " switch (c)\n" + " switch (fc)\n" " {"); - FOR_ALL_CONSTRAINTS (c) - if (c->namelen > 1) - printf (" case CONSTRAINT_%s: return %lu;\n", c->c_name, - (unsigned long int) c->namelen); + for (i = 0; i < ARRAY_SIZE(constraints_by_letter_table); i++) + { + struct constraint_data *c = constraints_by_letter_table[i]; + + if (!c + || c->namelen == 1) + continue; + + /* Constraints with multiple characters should have the same + length. */ + { + struct constraint_data *c2 = c->next_this_letter; + size_t len = c->namelen; + while (c2) + { + if (c2->namelen != len) + error ("Multi-letter constraints with first letter '%c' " + "should have same length", i); + c2 = c2->next_this_letter; + } + } + + printf (" case '%c': return %lu;\n", + i, (unsigned long int) c->namelen); + } puts (" default: break;\n" " }\n" " return 1;\n" "}\n"); } - + /* Write out the function which computes the register class corresponding to a register constraint. */ static void @@ -1083,7 +1089,7 @@ write_tm_constrs_h (void) "{\n", c->c_name, needs_op ? "op" : "ARG_UNUSED (op)"); if (needs_mode) - puts ("enum machine_mode mode = GET_MODE (op);"); + puts (" enum machine_mode mode = GET_MODE (op);"); if (needs_ival) puts (" HOST_WIDE_INT ival = 0;"); if (needs_hval) @@ -1094,7 +1100,7 @@ write_tm_constrs_h (void) puts (" const REAL_VALUE_TYPE *rval = 0;"); if (needs_ival) - puts (" if (GET_CODE (op) == CONST_INT)\n" + puts (" if (CONST_INT_P (op))\n" " ival = INTVAL (op);"); if (needs_hval) puts (" if (GET_CODE (op) == CONST_DOUBLE && mode == VOIDmode)" @@ -1248,18 +1254,24 @@ write_tm_preds_h (void) "extern bool constraint_satisfied_p (rtx, enum constraint_num);\n"); if (constraint_max_namelen > 1) - puts ("extern size_t insn_constraint_len (enum constraint_num);\n" - "#define CONSTRAINT_LEN(c_,s_) " - "insn_constraint_len (lookup_constraint (s_))\n"); + { + write_insn_constraint_len (); + puts ("#define CONSTRAINT_LEN(c_,s_) " + "insn_constraint_len (c_,s_)\n"); + } else puts ("#define CONSTRAINT_LEN(c_,s_) 1\n"); if (have_register_constraints) puts ("extern enum reg_class regclass_for_constraint " "(enum constraint_num);\n" "#define REG_CLASS_FROM_CONSTRAINT(c_,s_) \\\n" - " regclass_for_constraint (lookup_constraint (s_))\n"); + " regclass_for_constraint (lookup_constraint (s_))\n" + "#define REG_CLASS_FOR_CONSTRAINT(x_) \\\n" + " regclass_for_constraint (x_)\n"); else - puts ("#define REG_CLASS_FROM_CONSTRAINT(c_,s_) NO_REGS"); + puts ("#define REG_CLASS_FROM_CONSTRAINT(c_,s_) NO_REGS\n" + "#define REG_CLASS_FOR_CONSTRAINT(x_) \\\n" + " NO_REGS\n"); if (have_const_int_constraints) puts ("extern bool insn_const_int_ok_for_constraint " "(HOST_WIDE_INT, enum constraint_num);\n" @@ -1293,7 +1305,7 @@ write_tm_preds_h (void) puts ("#endif /* tm-preds.h */"); } -/* Write insn-preds.c. +/* Write insn-preds.c. N.B. the list of headers to include was copied from genrecog; it may not be ideal. @@ -1321,11 +1333,11 @@ write_insn_preds_c (void) #include \"function.h\"\n\ #include \"insn-config.h\"\n\ #include \"recog.h\"\n\ -#include \"real.h\"\n\ #include \"output.h\"\n\ #include \"flags.h\"\n\ #include \"hard-reg-set.h\"\n\ #include \"resource.h\"\n\ +#include \"diagnostic-core.h\"\n\ #include \"toplev.h\"\n\ #include \"reload.h\"\n\ #include \"regs.h\"\n\ @@ -1340,9 +1352,6 @@ write_insn_preds_c (void) if (have_register_constraints) write_regclass_for_constraint (); write_constraint_satisfied_p (); - - if (constraint_max_namelen > 1) - write_insn_constraint_len (); if (have_const_int_constraints) write_insn_const_int_ok_for_constraint (); @@ -1385,7 +1394,7 @@ main (int argc, char **argv) progname = argv[0]; if (argc <= 1) fatal ("no input file name"); - if (init_md_reader_args_cb (argc, argv, parse_option) != SUCCESS_EXIT_CODE) + if (!init_rtx_reader_args_cb (argc, argv, parse_option)) return FATAL_EXIT_CODE; while ((defn = read_md_rtx (&pattern_lineno, &next_insn_code)) != 0)