summaryrefslogtreecommitdiff
path: root/gcc/genoutput.c
diff options
context:
space:
mode:
authorJ"orn Rennecke <joern.rennecke@superh.com>2003-01-09 17:28:49 +0000
committerJoern Rennecke <amylaar@gcc.gnu.org>2003-01-09 17:28:49 +0000
commit97488870283d923cea932db7763346087cbd9452 (patch)
tree71e3146782ec281fdcd5e689d1f1cbbe5f3c2286 /gcc/genoutput.c
parente2c734c181b1235369d02d76b554925faec4753b (diff)
downloadgcc-97488870283d923cea932db7763346087cbd9452.tar.gz
defaults.h (EXTRA_MEMORY_CONSTRAINT): Add STR argument.
* defaults.h (EXTRA_MEMORY_CONSTRAINT): Add STR argument. (EXTRA_ADDRESS_CONSTRAINT): Likewise. (CONSTRAINT_LEN): Provide default definition. (CONST_OK_FOR_CONSTRAINT_P): Likewise. (CONST_DOUBLE_OK_FOR_CONSTRAINT_P): Likewise. (EXTRA_CONSTRAINT_STR): Likewise. (REG_CLASS_FROM_CONSTRAINT): Define. * genoutput.c (check_constraint_len, constraint_len): New functions. (validate_insn_alternatives): Check CONSTRAINT_LEN for each constraint / modifier. (gen_insn): Call check_constraint_len. * local-alloc.c (block_alloc): Update to use new macros / pass second argument to EXTRA_{MEMORY,ADDRESS}_CONSTRAINT. * ra-build.c (handle_asm_insn): Likewise. * recog.c (asm_operand_ok, preprocess_constraints): Likewise. (constrain_operands, peep2_find_free_register): Likewise. * regclass.c (record_operand_costs, record_reg_classes): Likewise. * regmove.c (find_matches): Likewise. * reload.c (push_secondary_reload, find_reloads): Likewise. (alternative_allows_memconst): Likewise. * reload1.c (maybe_fix_stack_asms): Likewise. (reload_cse_simplify_operands): Likewise. * stmt.c (parse_output_constraint, parse_input_constraint): Likewise. * doc/tm.texi (CONSTRAINT_LEN, REG_CLASS_FROM_CONSTRAINT): Document. (CONST_OK_FOR_CONSTRAINT_P): Likewise. (CONST_DOUBLE_OK_FOR_CONSTRAINT_P, EXTRA_CONSTRAINT_STR): Likewise. (EXTRA_MEMORY_CONSTRAINT, EXTRA_ADDRESS_CONSTRAINT): Add STR argument. * config/s390/s390.h (EXTRA_MEMORY_CONSTRAINT): Likewise. From-SVN: r61119
Diffstat (limited to 'gcc/genoutput.c')
-rw-r--r--gcc/genoutput.c87
1 files changed, 86 insertions, 1 deletions
diff --git a/gcc/genoutput.c b/gcc/genoutput.c
index 662a6b0465b..3a1ad817908 100644
--- a/gcc/genoutput.c
+++ b/gcc/genoutput.c
@@ -189,6 +189,8 @@ static void gen_insn PARAMS ((rtx, int));
static void gen_peephole PARAMS ((rtx, int));
static void gen_expand PARAMS ((rtx, int));
static void gen_split PARAMS ((rtx, int));
+static void check_constraint_len PARAMS ((void));
+static int constraint_len PARAMS ((const char *, int));
const char *
get_insn_name (index)
@@ -749,7 +751,51 @@ validate_insn_alternatives (d)
for (start = 0; start < d->n_operands; start++)
if (d->operand[start].n_alternatives > 0)
{
- if (n == 0)
+ int len, i;
+ const char *p;
+ char c;
+ int which_alternative = 0;
+ int alternative_count_unsure = 0;
+
+ for (p = d->operand[start].constraint; (c = *p); p += len)
+ {
+ len = CONSTRAINT_LEN (c, p);
+
+ if (len < 1 || (len > 1 && strchr (",#*+=&%!0123456789", c)))
+ {
+ message_with_line (d->lineno,
+ "invalid length %d for char '%c' in alternative %d of operand %d",
+ len, c, which_alternative, start);
+ len = 1;
+ have_error = 1;
+ }
+
+ if (c == ',')
+ {
+ which_alternative++;
+ continue;
+ }
+
+ for (i = 1; i < len; i++)
+ if (p[i] == '\0')
+ {
+ message_with_line (d->lineno,
+ "NUL in alternative %d of operand %d",
+ which_alternative, start);
+ alternative_count_unsure = 1;
+ break;
+ }
+ else if (strchr (",#*", p[i]))
+ {
+ message_with_line (d->lineno,
+ "'%c' in alternative %d of operand %d",
+ p[i], which_alternative, start);
+ alternative_count_unsure = 1;
+ }
+ }
+ if (alternative_count_unsure)
+ have_error = 1;
+ else if (n == 0)
n = d->operand[start].n_alternatives;
else if (n != d->operand[start].n_alternatives)
{
@@ -816,6 +862,7 @@ gen_insn (insn, lineno)
d->n_operands = max_opno + 1;
d->n_dups = num_dups;
+ check_constraint_len ();
validate_insn_operands (d);
validate_insn_alternatives (d);
place_operands (d);
@@ -1043,3 +1090,41 @@ strip_whitespace (s)
*p = '\0';
return q;
}
+
+/* Verify that DEFAULT_CONSTRAINT_LEN is used properly and not
+ tampered with. This isn't bullet-proof, but it should catch
+ most genuine mistakes. */
+static void
+check_constraint_len ()
+{
+ const char *p;
+ int d;
+
+ for (p = ",#*+=&%!1234567890"; *p; p++)
+ for (d = -9; d < 9; d++)
+ if (constraint_len (p, d) != d)
+ abort ();
+}
+
+static int
+constraint_len (p, genoutput_default_constraint_len)
+ const char *p;
+ int genoutput_default_constraint_len;
+{
+ /* Check that we still match defaults.h . First we do a generation-time
+ check that fails if the value is not the expected one... */
+ if (DEFAULT_CONSTRAINT_LEN (*p, p) != 1)
+ abort ();
+ /* And now a comile-time check that should give a diagnostic if the
+ definition doesn't exactly match. */
+#define DEFAULT_CONSTRAINT_LEN(C,STR) 1
+ /* Now re-define DEFAULT_CONSTRAINT_LEN so that we can verify it is
+ being used. */
+#undef DEFAULT_CONSTRAINT_LEN
+#define DEFAULT_CONSTRAINT_LEN(C,STR) \
+ ((C) != *p || STR != p ? -1 : genoutput_default_constraint_len)
+ return CONSTRAINT_LEN (*p, p);
+ /* And set it back. */
+#undef DEFAULT_CONSTRAINT_LEN
+#define DEFAULT_CONSTRAINT_LEN(C,STR) 1
+}