diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-02-21 18:30:37 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-02-21 18:30:37 +0000 |
commit | eb4071aec871d3feb560410306cc9bab8177d6cb (patch) | |
tree | d06b5d850ee53d4ec20bbdfc14b0cbeb32def76c /gcc/genattrtab.c | |
parent | 88e449ea996c99f10e531bb8adec9ef13346ebb4 (diff) | |
download | gcc-eb4071aec871d3feb560410306cc9bab8177d6cb.tar.gz |
* genattrtab.c (check_attr_value): Allow negative const_int if
negative_ok. Accept integral arithmetic operators. Accept
direct references to other attributes. Accept symbol_ref in
non-constant attributes.
(max_attr_value): Add new argument `unknownp'. Update all callers.
(or_attr_value): Likewise.
(simplify_knowing): Don't optimize if max_attr_value unknown.
(write_length_unit_log): Likewise with or_attr_value.
(find_and_mark_used_attributes): Don't fallthru case.
(write_attr_set): Pass thru all non-cond expressions.
(write_attr_value): Handle symbol_ref, attr, and arithmetic.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@25348 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/genattrtab.c')
-rw-r--r-- | gcc/genattrtab.c | 235 |
1 files changed, 161 insertions, 74 deletions
diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c index 523d073397a..f6008df07f7 100644 --- a/gcc/genattrtab.c +++ b/gcc/genattrtab.c @@ -426,8 +426,8 @@ static void gen_insn PROTO((rtx)); static void gen_delay PROTO((rtx)); static void gen_unit PROTO((rtx)); static void write_test_expr PROTO((rtx, int)); -static int max_attr_value PROTO((rtx)); -static int or_attr_value PROTO((rtx)); +static int max_attr_value PROTO((rtx, int*)); +static int or_attr_value PROTO((rtx, int*)); static void walk_attr_value PROTO((rtx)); static void write_attr_get PROTO((struct attr_desc *)); static rtx eliminate_known_true PROTO((rtx, rtx, int, int)); @@ -1083,7 +1083,7 @@ check_attr_value (exp, attr) fatal ("CONST_INT not valid for non-numeric `%s' attribute", attr->name); - if (INTVAL (exp) < 0) + if (INTVAL (exp) < 0 && ! attr->negative_ok) fatal ("Negative numeric value specified for `%s' attribute", attr->name); @@ -1123,6 +1123,16 @@ check_attr_value (exp, attr) XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr); break; + case PLUS: + case MINUS: + case MULT: + case DIV: + case MOD: + if (attr && !attr->is_numeric) + fatal ("Invalid operation `%s' for non-numeric attribute value", + GET_RTX_NAME (GET_CODE (exp))); + /* FALLTHRU */ + case IOR: case AND: XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr); @@ -1148,12 +1158,27 @@ check_attr_value (exp, attr) XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr); break; + case ATTR: + { + struct attr_desc *attr2 = find_attr (XSTR (exp, 0), 0); + if (attr2 == NULL) + fatal ("Unknown attribute `%s' in ATTR", XSTR (exp, 0)); + else if ((attr && attr->is_const) && ! attr2->is_const) + fatal ("Non-constant attribute `%s' referenced from `%s'", + XSTR (exp, 0), attr->name); + else if (attr + && (attr->is_numeric != attr2->is_numeric + || (! attr->negative_ok && attr2->negative_ok))) + fatal ("Numeric attribute mismatch calling `%s' from `%s'", + XSTR (exp, 0), attr->name); + } + break; + case SYMBOL_REF: - if (attr && attr->is_const) - /* A constant SYMBOL_REF is valid as a constant attribute test and - is expanded later by make_canonical into a COND. */ - return attr_rtx (SYMBOL_REF, XSTR (exp, 0)); - /* Otherwise, fall through... */ + /* A constant SYMBOL_REF is valid as a constant attribute test and + is expanded later by make_canonical into a COND. In a non-constant + attribute test, it is left be. */ + return attr_rtx (SYMBOL_REF, XSTR (exp, 0)); default: fatal ("Invalid operation `%s' for attribute value", @@ -2101,7 +2126,10 @@ expand_units () } /* Record MAX (BLOCKAGE (*,*)). */ - unit->max_blockage = max_attr_value (max_blockage); + { + int unknown; + unit->max_blockage = max_attr_value (max_blockage, &unknown); + } /* See if the upper and lower bounds of BLOCKAGE (E,*) are the same. If so, the blockage function carries no additional @@ -2186,9 +2214,14 @@ simplify_knowing (exp, known_true) { if (GET_CODE (exp) != CONST_STRING) { - exp = attr_rtx (IF_THEN_ELSE, known_true, exp, - make_numeric_value (max_attr_value (exp))); - exp = simplify_by_exploding (exp); + int unknown, max; + max = max_attr_value (exp, &unknown); + if (! unknown) + { + exp = attr_rtx (IF_THEN_ELSE, known_true, exp, + make_numeric_value (max)); + exp = simplify_by_exploding (exp); + } } return exp; } @@ -2458,7 +2491,8 @@ static rtx max_fn (exp) rtx exp; { - return make_numeric_value (max_attr_value (exp)); + int unknown; + return make_numeric_value (max_attr_value (exp, &unknown)); } static void @@ -2468,16 +2502,23 @@ write_length_unit_log () struct attr_value *av; struct insn_ent *ie; unsigned int length_unit_log, length_or; + int unknown = 0; if (length_attr == 0) return; - length_or = or_attr_value (length_attr->default_val->value); - for (av = length_attr->first_value; av; av = av->next) - for (ie = av->first_insn; ie; ie = ie->next) - length_or |= or_attr_value (av->value); - length_or = ~length_or; - for (length_unit_log = 0; length_or & 1; length_or >>= 1) - length_unit_log++; + length_or = or_attr_value (length_attr->default_val->value, &unknown); + for (av = length_attr->first_value; av; av = av->next) + for (ie = av->first_insn; ie; ie = ie->next) + length_or |= or_attr_value (av->value, &unknown); + + if (unknown) + length_unit_log = 0; + else + { + length_or = ~length_or; + for (length_unit_log = 0; length_or & 1; length_or >>= 1) + length_unit_log++; + } printf ("int length_unit_log = %u;\n", length_unit_log); } @@ -3703,6 +3744,8 @@ find_and_mark_used_attributes (exp, terms, nterms) *nterms += 1; MEM_VOLATILE_P (exp) = 1; } + return 1; + case CONST_STRING: case CONST_INT: return 1; @@ -4106,7 +4149,7 @@ gen_attr (exp) fatal ("Duplicate definition for `%s' attribute", attr->name); if (*XSTR (exp, 1) == '\0') - attr->is_numeric = 1; + attr->is_numeric = 1; else { name_ptr = XSTR (exp, 1); @@ -4652,80 +4695,83 @@ write_test_expr (exp, flags) } /* Given an attribute value, return the maximum CONST_STRING argument - encountered. It is assumed that they are all numeric. */ + encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */ static int -max_attr_value (exp) +max_attr_value (exp, unknownp) rtx exp; + int *unknownp; { - int current_max = 0; - int n; - int i; - - if (GET_CODE (exp) == CONST_STRING) - return atoi (XSTR (exp, 0)); + int current_max; + int i, n; - else if (GET_CODE (exp) == COND) + switch (GET_CODE (exp)) { + case CONST_STRING: + current_max = atoi (XSTR (exp, 0)); + break; + + case COND: + current_max = max_attr_value (XEXP (exp, 1), unknownp); for (i = 0; i < XVECLEN (exp, 0); i += 2) { - n = max_attr_value (XVECEXP (exp, 0, i + 1)); + n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp); if (n > current_max) current_max = n; } + break; - n = max_attr_value (XEXP (exp, 1)); + case IF_THEN_ELSE: + current_max = max_attr_value (XEXP (exp, 1), unknownp); + n = max_attr_value (XEXP (exp, 2), unknownp); if (n > current_max) current_max = n; - } + break; - else if (GET_CODE (exp) == IF_THEN_ELSE) - { - current_max = max_attr_value (XEXP (exp, 1)); - n = max_attr_value (XEXP (exp, 2)); - if (n > current_max) - current_max = n; + default: + *unknownp = 1; + current_max = INT_MAX; + break; } - else - abort (); - return current_max; } /* Given an attribute value, return the result of ORing together all - CONST_STRING arguments encountered. It is assumed that they are - all numeric. */ + CONST_STRING arguments encountered. Set *UNKNOWNP and return -1 + if the numeric value is not known. */ static int -or_attr_value (exp) +or_attr_value (exp, unknownp) rtx exp; + int *unknownp; { - int current_or = 0; + int current_or; int i; - if (GET_CODE (exp) == CONST_STRING) - return atoi (XSTR (exp, 0)); - - else if (GET_CODE (exp) == COND) + switch (GET_CODE (exp)) { + case CONST_STRING: + current_or = atoi (XSTR (exp, 0)); + break; + + case COND: + current_or = or_attr_value (XEXP (exp, 1), unknownp); for (i = 0; i < XVECLEN (exp, 0); i += 2) - { - current_or |= or_attr_value (XVECEXP (exp, 0, i + 1)); - } + current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp); + break; - current_or |= or_attr_value (XEXP (exp, 1)); - } + case IF_THEN_ELSE: + current_or = or_attr_value (XEXP (exp, 1), unknownp); + current_or |= or_attr_value (XEXP (exp, 2), unknownp); + break; - else if (GET_CODE (exp) == IF_THEN_ELSE) - { - current_or = or_attr_value (XEXP (exp, 1)); - current_or |= or_attr_value (XEXP (exp, 2)); + default: + *unknownp = 1; + current_or = -1; + break; } - else - abort (); - return current_or; } @@ -4928,14 +4974,7 @@ write_attr_set (attr, indent, value, prefix, suffix, known_true, rtx known_true; int insn_code, insn_index; { - if (GET_CODE (value) == CONST_STRING) - { - write_indent (indent); - printf ("%s ", prefix); - write_attr_value (attr, value); - printf ("%s\n", suffix); - } - else if (GET_CODE (value) == COND) + if (GET_CODE (value) == COND) { /* Assume the default value will be the default of the COND unless we find an always true expression. */ @@ -5009,7 +5048,12 @@ write_attr_set (attr, indent, value, prefix, suffix, known_true, } } else - abort (); + { + write_indent (indent); + printf ("%s ", prefix); + write_attr_value (attr, value); + printf ("%s\n", suffix); + } } /* Write out the computation for one attribute value. */ @@ -5244,10 +5288,53 @@ write_attr_value (attr, value) struct attr_desc *attr; rtx value; { - if (GET_CODE (value) != CONST_STRING) - abort (); + int op; + + switch (GET_CODE (value)) + { + case CONST_STRING: + write_attr_valueq (attr, XSTR (value, 0)); + break; + + case SYMBOL_REF: + fputs (XSTR (value, 0), stdout); + break; + + case ATTR: + { + struct attr_desc *attr2 = find_attr (XSTR (value, 0), 0); + printf ("get_attr_%s (%s)", attr2->name, + (attr2->is_const ? "" : "insn")); + } + break; - write_attr_valueq (attr, XSTR (value, 0)); + case PLUS: + op = '+'; + goto do_operator; + case MINUS: + op = '-'; + goto do_operator; + case MULT: + op = '*'; + goto do_operator; + case DIV: + op = '/'; + goto do_operator; + case MOD: + op = '%'; + goto do_operator; + + do_operator: + write_attr_value (attr, XEXP (value, 0)); + putchar (' '); + putchar (op); + putchar (' '); + write_attr_value (attr, XEXP (value, 1)); + break; + + default: + abort (); + } } static void |