aboutsummaryrefslogtreecommitdiff
path: root/gcc/genpreds.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/genpreds.c')
-rw-r--r--gcc/genpreds.c65
1 files changed, 53 insertions, 12 deletions
diff --git a/gcc/genpreds.c b/gcc/genpreds.c
index a1232e9573f..beae9bbb92b 100644
--- a/gcc/genpreds.c
+++ b/gcc/genpreds.c
@@ -674,6 +674,7 @@ struct constraint_data
unsigned int is_extra : 1;
unsigned int is_memory : 1;
unsigned int is_address : 1;
+ unsigned int is_overloaded : 1; /* Set for all but the first definition. */
};
/* Overview of all constraints beginning with a given letter. */
@@ -757,6 +758,7 @@ add_constraint (const char *name, const char *regclass,
bool is_const_int;
bool is_const_dbl;
size_t namelen;
+ bool is_overloaded = 0;
if (exp && validate_exp (exp, name, lineno))
return;
@@ -816,10 +818,29 @@ add_constraint (const char *name, const char *regclass,
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;
+ /* An exact match is OK if the purpose is to overload the constraint.
+ */
+ if (is_overloaded)
+ ; /* We've already warned against the 1st definition. */
+ else if ((*iter)->is_register != (regclass != 0)
+ || (*iter)->is_memory != is_memory
+ || (*iter)->is_address != is_address)
+ {
+ message_with_line (lineno,
+ "overloading of constraint '%s'", name);
+ message_with_line ((*iter)->lineno,
+ "previous definition is here");
+ is_overloaded = 1;
+ }
+ else
+ {
+ message_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))
{
@@ -910,6 +931,7 @@ add_constraint (const char *name, const char *regclass,
c->is_extra = !(regclass || is_const_int || is_const_dbl);
c->is_memory = is_memory;
c->is_address = is_address;
+ c->is_overloaded = is_overloaded;
c->next_this_letter = *slot;
*slot = c;
@@ -958,7 +980,8 @@ write_enum_constraint_num (void)
"{\n"
" CONSTRAINT__UNKNOWN = 0", stdout);
FOR_ALL_CONSTRAINTS (c)
- printf (",\n CONSTRAINT_%s", c->c_name);
+ if (!c->is_overloaded)
+ printf (",\n CONSTRAINT_%s", c->c_name);
puts (",\n CONSTRAINT__LIMIT\n};\n");
}
@@ -987,9 +1010,10 @@ write_lookup_constraint (void)
{
do
{
- printf (" if (!strncmp (str, \"%s\", %lu))\n"
- " return CONSTRAINT_%s;\n",
- c->name, (unsigned long int) c->namelen, c->c_name);
+ if (!c->is_overloaded)
+ printf (" if (!strncmp (str, \"%s\", %lu))\n"
+ " return CONSTRAINT_%s;\n",
+ c->name, (unsigned long int) c->namelen, c->c_name);
c = c->next_this_letter;
}
while (c);
@@ -1084,7 +1108,11 @@ write_tm_constrs_h (void)
puts ("\
#ifndef GCC_TM_CONSTRS_H\n\
-#define GCC_TM_CONSTRS_H\n");
+#define GCC_TM_CONSTRS_H\n\
+\n\
+#include \"multi-target.h\"\n\
+\n\
+START_TARGET_SPECIFIC\n");
FOR_ALL_CONSTRAINTS (c)
if (!c->is_register)
@@ -1129,7 +1157,10 @@ write_tm_constrs_h (void)
write_predicate_stmts (c->exp);
fputs ("}\n", stdout);
}
- puts ("#endif /* tm-constrs.h */");
+ puts ("\
+END_TARGET_SPECIFIC\n\
+\n\
+#endif /* tm-constrs.h */");
}
/* Write out the wrapper function, constraint_satisfied_p, that maps
@@ -1254,6 +1285,10 @@ write_tm_preds_h (void)
#ifndef GCC_TM_PREDS_H\n\
#define GCC_TM_PREDS_H\n\
\n\
+#include \"multi-target.h\"\n\
+\n\
+START_TARGET_SPECIFIC\n\
+\n\
#ifdef HAVE_MACHINE_MODES");
FOR_ALL_PREDICATES (p)
@@ -1312,7 +1347,9 @@ write_tm_preds_h (void)
puts ("#define EXTRA_ADDRESS_CONSTRAINT(c_,s_) false\n");
}
- puts ("#endif /* tm-preds.h */");
+ puts ("END_TARGET_SPECIFIC\n"
+ "\n"
+ "#endif /* tm-preds.h */");
}
/* Write insn-preds.c.
@@ -1351,7 +1388,10 @@ write_insn_preds_c (void)
#include \"toplev.h\"\n\
#include \"reload.h\"\n\
#include \"regs.h\"\n\
-#include \"tm-constrs.h\"\n");
+#include \"multi-target.h\"\n\
+#include \"tm-constrs.h\"\n\
+\n\
+START_TARGET_SPECIFIC\n");
FOR_ALL_PREDICATES (p)
write_one_predicate_function (p);
@@ -1371,6 +1411,7 @@ write_insn_preds_c (void)
if (have_address_constraints)
write_insn_extra_address_constraint ();
}
+ puts ("END_TARGET_SPECIFIC");
}
/* Argument parsing. */