diff options
author | J"orn Rennecke <joern.rennecke@superh.com> | 2003-01-09 17:28:49 +0000 |
---|---|---|
committer | Joern Rennecke <amylaar@gcc.gnu.org> | 2003-01-09 17:28:49 +0000 |
commit | 97488870283d923cea932db7763346087cbd9452 (patch) | |
tree | 71e3146782ec281fdcd5e689d1f1cbbe5f3c2286 /gcc/genoutput.c | |
parent | e2c734c181b1235369d02d76b554925faec4753b (diff) | |
download | gcc-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.c | 87 |
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 +} |