X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fgenattrtab.c;h=1a9ebd22eaf313f8318d1018a41eb55b1502ade1;hb=9702264ef825c6e62581a8a2daf2c5405e480bbf;hp=6dfe0a842e69179fcfd4650768f90d384cb9696e;hpb=df2d1f4aaf2ce2b18bb8e101d9709b35030ff274;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c index 6dfe0a842e6..1a9ebd22eaf 100644 --- a/gcc/genattrtab.c +++ b/gcc/genattrtab.c @@ -1,13 +1,14 @@ /* Generate code from machine description to compute values of attributes. - Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, + 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) 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) any later +Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY @@ -16,9 +17,8 @@ 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 +. */ /* This program handles insn attributes and the DEFINE_DELAY and DEFINE_INSN_RESERVATION definitions. @@ -136,7 +136,7 @@ struct insn_def struct insn_def *next; /* Next insn in chain. */ rtx def; /* The DEFINE_... */ int insn_code; /* Instruction number. */ - int insn_index; /* Expression numer in file, for errors. */ + int insn_index; /* Expression number in file, for errors. */ int lineno; /* Line number. */ int num_alternatives; /* Number of alternatives. */ int vec_idx; /* Index of attribute vector in `def'. */ @@ -189,6 +189,14 @@ struct delay_desc int lineno; /* Line number. */ }; +struct attr_value_list +{ + struct attr_value *av; + struct insn_ent *ie; + struct attr_desc *attr; + struct attr_value_list *next; +}; + /* Listheads of above structures. */ /* This one is indexed by the first character of the attribute name. */ @@ -196,6 +204,7 @@ struct delay_desc static struct attr_desc *attrs[MAX_ATTRS_INDEX]; static struct insn_def *defs; static struct delay_desc *delays; +struct attr_value_list **insn_code_values; /* Other variables. */ @@ -278,7 +287,8 @@ static rtx one_fn (rtx); static rtx max_fn (rtx); static rtx min_fn (rtx); -#define oballoc(size) obstack_alloc (hash_obstack, size) +#define oballoc(T) XOBNEW (hash_obstack, T) +#define oballocvec(T, N) XOBNEWVEC (hash_obstack, T, (N)) /* Hash table for sharing RTL and strings. */ @@ -309,7 +319,7 @@ static struct attr_hash *attr_hash_table[RTL_HASH_SIZE]; /* Here is how primitive or already-shared RTL's hash codes are made. */ -#define RTL_HASH(RTL) ((long) (RTL) & 0777777) +#define RTL_HASH(RTL) ((intptr_t) (RTL) & 0777777) /* Add an entry to the hash table for RTL with hash code HASHCODE. */ @@ -318,7 +328,7 @@ attr_hash_add_rtx (int hashcode, rtx rtl) { struct attr_hash *h; - h = obstack_alloc (hash_obstack, sizeof (struct attr_hash)); + h = XOBNEW (hash_obstack, struct attr_hash); h->hashcode = hashcode; h->u.rtl = rtl; h->next = attr_hash_table[hashcode % RTL_HASH_SIZE]; @@ -332,7 +342,7 @@ attr_hash_add_string (int hashcode, char *str) { struct attr_hash *h; - h = obstack_alloc (hash_obstack, sizeof (struct attr_hash)); + h = XOBNEW (hash_obstack, struct attr_hash); h->hashcode = -hashcode; h->u.str = str; h->next = attr_hash_table[hashcode % RTL_HASH_SIZE]; @@ -593,7 +603,7 @@ attr_string (const char *str, int len) return h->u.str; /* <-- return if found. */ /* Not found; create a permanent copy and add it to the hash table. */ - new_str = obstack_alloc (hash_obstack, len + 1); + new_str = XOBNEWVAR (hash_obstack, char, len + 1); memcpy (new_str, str, len); new_str[len] = '\0'; attr_hash_add_string (hashcode, new_str); @@ -959,6 +969,7 @@ check_attr_value (rtx exp, struct attr_desc *attr) case CTZ: case POPCOUNT: case PARITY: + case BSWAP: XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr); break; @@ -1288,7 +1299,7 @@ get_attr_value (rtx value, struct attr_desc *attr, int insn_code) || insn_alternatives[av->first_insn->def->insn_code])) return av; - av = oballoc (sizeof (struct attr_value)); + av = oballoc (struct attr_value); av->value = value; av->next = attr->first_value; attr->first_value = av; @@ -1431,7 +1442,7 @@ fill_attr (struct attr_desc *attr) else av = get_attr_value (value, attr, id->insn_code); - ie = oballoc (sizeof (struct insn_ent)); + ie = oballoc (struct insn_ent); ie->def = id; insert_insn_ent (av, ie); } @@ -1562,7 +1573,7 @@ make_length_attrs (void) no_address_fn[i], address_fn[i]), new_attr, ie->def->insn_code); - new_ie = oballoc (sizeof (struct insn_ent)); + new_ie = oballoc (struct insn_ent); new_ie->def = ie->def; insert_insn_ent (new_av, new_ie); } @@ -1627,7 +1638,7 @@ write_length_unit_log (void) for (length_unit_log = 0; length_or & 1; length_or >>= 1) length_unit_log++; } - printf ("const int length_unit_log = %u;\n", length_unit_log); + printf ("EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log); } /* Take a COND expression and see if any of the conditions in it can be @@ -1647,7 +1658,7 @@ simplify_cond (rtx exp, int insn_code, int insn_index) rtx defval = XEXP (exp, 1); rtx new_defval = XEXP (exp, 1); int len = XVECLEN (exp, 0); - rtx *tests = xmalloc (len * sizeof (rtx)); + rtx *tests = XNEWVEC (rtx, len); int allsame = 1; rtx ret; @@ -1836,11 +1847,11 @@ insert_right_side (enum rtx_code code, rtx exp, rtx term, int insn_code, int ins if (GET_CODE (exp) == code) { - rtx new = insert_right_side (code, XEXP (exp, 1), - term, insn_code, insn_index); - if (new != XEXP (exp, 1)) + rtx new_rtx = insert_right_side (code, XEXP (exp, 1), + term, insn_code, insn_index); + if (new_rtx != XEXP (exp, 1)) /* Make a copy of this expression and call recursively. */ - newexp = attr_rtx (code, XEXP (exp, 0), new); + newexp = attr_rtx (code, XEXP (exp, 0), new_rtx); else newexp = exp; } @@ -1930,22 +1941,22 @@ evaluate_eq_attr (rtx exp, rtx value, int insn_code, int insn_index) else newexp = false_rtx; break; - + case SYMBOL_REF: { char *p; char string[256]; - + gcc_assert (GET_CODE (exp) == EQ_ATTR); gcc_assert (strlen (XSTR (exp, 0)) + strlen (XSTR (exp, 1)) + 2 <= 256); - + strcpy (string, XSTR (exp, 0)); strcat (string, "_"); strcat (string, XSTR (exp, 1)); for (p = string; *p; p++) *p = TOUPPER (*p); - + newexp = attr_rtx (EQ, value, attr_rtx (SYMBOL_REF, DEF_ATTR_STRING (string))); @@ -1956,12 +1967,12 @@ evaluate_eq_attr (rtx exp, rtx value, int insn_code, int insn_index) /* We construct an IOR of all the cases for which the requested attribute value is present. Since we start with FALSE, if it is not present, FALSE will be returned. - + Each case is the AND of the NOT's of the previous conditions with the current condition; in the default case the current condition is TRUE. - + For each possible COND value, call ourselves recursively. - + The extra TRUE and FALSE expressions will be eliminated by another call to the simplification routine. */ @@ -1970,10 +1981,10 @@ evaluate_eq_attr (rtx exp, rtx value, int insn_code, int insn_index) for (i = 0; i < XVECLEN (value, 0); i += 2) { - rtx this = simplify_test_exp_in_temp (XVECEXP (value, 0, i), - insn_code, insn_index); + rtx this_cond = simplify_test_exp_in_temp (XVECEXP (value, 0, i), + insn_code, insn_index); - right = insert_right_side (AND, andexp, this, + right = insert_right_side (AND, andexp, this_cond, insn_code, insn_index); right = insert_right_side (AND, right, evaluate_eq_attr (exp, @@ -1985,7 +1996,7 @@ evaluate_eq_attr (rtx exp, rtx value, int insn_code, int insn_index) insn_code, insn_index); /* Add this condition into the AND expression. */ - newexp = attr_rtx (NOT, this); + newexp = attr_rtx (NOT, this_cond); andexp = insert_right_side (AND, andexp, newexp, insn_code, insn_index); } @@ -2097,7 +2108,7 @@ simplify_and_tree (rtx exp, rtx *pterm, int insn_code, int insn_index) if (attr_alt_subset_p (exp, *pterm)) *pterm = true_rtx; - + return exp; } @@ -2447,6 +2458,7 @@ simplify_test_exp (rtx exp, int insn_code, int insn_index) struct attr_desc *attr; struct attr_value *av; struct insn_ent *ie; + struct attr_value_list *iv; int i; rtx newexp = exp; bool left_alt, right_alt; @@ -2717,16 +2729,36 @@ simplify_test_exp (rtx exp, int insn_code, int insn_index) would give this insn the values being tested for. */ if (insn_code >= 0 && (attr = find_attr (&XSTR (exp, 0), 0)) != NULL) - for (av = attr->first_value; av; av = av->next) - for (ie = av->first_insn; ie; ie = ie->next) - if (ie->def->insn_code == insn_code) - { - rtx x; - x = evaluate_eq_attr (exp, av->value, insn_code, insn_index); - x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index); - if (attr_rtx_cost(x) < 20) - return x; - } + { + rtx x; + + av = NULL; + if (insn_code_values) + { + for (iv = insn_code_values[insn_code]; iv; iv = iv->next) + if (iv->attr == attr) + { + av = iv->av; + break; + } + } + else + { + for (av = attr->first_value; av; av = av->next) + for (ie = av->first_insn; ie; ie = ie->next) + if (ie->def->insn_code == insn_code) + goto got_av; + } + + if (av) + { + got_av: + x = evaluate_eq_attr (exp, av->value, insn_code, insn_index); + x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index); + if (attr_rtx_cost(x) < 20) + return x; + } + } break; default: @@ -2755,14 +2787,6 @@ optimize_attrs (void) struct insn_ent *ie; rtx newexp; int i; - struct attr_value_list - { - struct attr_value *av; - struct insn_ent *ie; - struct attr_desc *attr; - struct attr_value_list *next; - }; - struct attr_value_list **insn_code_values; struct attr_value_list *ivbuf; struct attr_value_list *iv; @@ -2773,13 +2797,12 @@ optimize_attrs (void) return; /* Make 2 extra elements, for "code" values -2 and -1. */ - insn_code_values = xcalloc ((insn_code_number + 2), - sizeof (struct attr_value_list *)); + insn_code_values = XCNEWVEC (struct attr_value_list *, insn_code_number + 2); /* Offset the table address so we can index by -2 or -1. */ insn_code_values += 2; - iv = ivbuf = xmalloc (num_insn_ents * sizeof (struct attr_value_list)); + iv = ivbuf = XNEWVEC (struct attr_value_list, num_insn_ents); for (i = 0; i < MAX_ATTRS_INDEX; i++) for (attr = attrs[i]; attr; attr = attr->next) @@ -2840,6 +2863,7 @@ optimize_attrs (void) free (ivbuf); free (insn_code_values - 2); + insn_code_values = NULL; } /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */ @@ -2927,7 +2951,7 @@ gen_attr (rtx exp, int lineno) name_ptr = XSTR (exp, 1); while ((p = next_comma_elt (&name_ptr)) != NULL) { - av = oballoc (sizeof (struct attr_value)); + av = oballoc (struct attr_value); av->value = attr_rtx (CONST_STRING, p); av->next = attr->first_value; attr->first_value = av; @@ -3033,37 +3057,6 @@ compares_alternatives_p (rtx exp) return 0; } -/* Returns nonzero is INNER is contained in EXP. */ - -static int -contained_in_p (rtx inner, rtx exp) -{ - int i, j; - const char *fmt; - - if (rtx_equal_p (inner, exp)) - return 1; - - for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp)); - i < GET_RTX_LENGTH (GET_CODE (exp)); i++) - switch (*fmt++) - { - case 'e': - case 'u': - if (contained_in_p (inner, XEXP (exp, i))) - return 1; - break; - - case 'E': - for (j = 0; j < XVECLEN (exp, i); j++) - if (contained_in_p (inner, XVECEXP (exp, i, j))) - return 1; - break; - } - - return 0; -} - /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */ static void @@ -3071,7 +3064,7 @@ gen_insn (rtx exp, int lineno) { struct insn_def *id; - id = oballoc (sizeof (struct insn_def)); + id = oballoc (struct insn_def); id->next = defs; defs = id; id->def = exp; @@ -3135,7 +3128,7 @@ gen_delay (rtx def, int lineno) have_annul_false = 1; } - delay = oballoc (sizeof (struct delay_desc)); + delay = oballoc (struct delay_desc); delay->def = def; delay->num = ++num_delays; delay->next = delays; @@ -3330,7 +3323,7 @@ write_test_expr (rtx exp, int flags) } else { - printf ("%s((1 << which_alternative) & 0x%x)", + printf ("%s((1 << which_alternative) & %#x)", XINT (exp, 1) ? "!" : "", set); } } @@ -3889,51 +3882,6 @@ write_attr_case (struct attr_desc *attr, struct attr_value *av, printf ("\n"); } -/* Search for uses of non-const attributes and write code to cache them. */ - -static int -write_expr_attr_cache (rtx p, struct attr_desc *attr) -{ - const char *fmt; - int i, ie, j, je; - - if (GET_CODE (p) == EQ_ATTR) - { - if (XSTR (p, 0) != attr->name) - return 0; - - if (!attr->is_numeric) - printf (" enum attr_%s ", attr->name); - else - printf (" int "); - - printf ("attr_%s = get_attr_%s (insn);\n", attr->name, attr->name); - return 1; - } - - fmt = GET_RTX_FORMAT (GET_CODE (p)); - ie = GET_RTX_LENGTH (GET_CODE (p)); - for (i = 0; i < ie; i++) - { - switch (*fmt++) - { - case 'e': - if (write_expr_attr_cache (XEXP (p, i), attr)) - return 1; - break; - - case 'E': - je = XVECLEN (p, i); - for (j = 0; j < je; ++j) - if (write_expr_attr_cache (XVECEXP (p, i, j), attr)) - return 1; - break; - } - } - - return 0; -} - /* Utilities to write in various forms. */ static void @@ -3946,7 +3894,7 @@ write_attr_valueq (struct attr_desc *attr, const char *s) printf ("%d", num); if (num > 9 || num < 0) - printf (" /* 0x%x */", num); + printf (" /* %#x */", num); } else { @@ -4212,7 +4160,7 @@ find_attr (const char **name_p, int create) if (! create) return NULL; - attr = oballoc (sizeof (struct attr_desc)); + attr = oballoc (struct attr_desc); attr->name = DEF_ATTR_STRING (name); attr->first_value = attr->default_val = NULL; attr->is_numeric = attr->is_const = attr->is_special = 0; @@ -4351,7 +4299,7 @@ static size_t n_insn_reservs; static void gen_insn_reserv (rtx def) { - struct insn_reserv *decl = oballoc (sizeof (struct insn_reserv)); + struct insn_reserv *decl = oballoc (struct insn_reserv); decl->name = DEF_ATTR_STRING (XSTR (def, 0)); decl->default_latency = XINT (def, 1); @@ -4359,7 +4307,7 @@ gen_insn_reserv (rtx def) decl->insn_num = n_insn_reservs; decl->bypassed = false; decl->next = 0; - + *last_insn_reserv_p = decl; last_insn_reserv_p = &decl->next; n_insn_reservs++; @@ -4392,7 +4340,7 @@ gen_bypass_1 (const char *s, size_t len) if (s == b->insn) return; /* already got that one */ - b = oballoc (sizeof (struct bypass_list)); + b = oballoc (struct bypass_list); b->insn = s; b->next = all_bypasses; all_bypasses = b; @@ -4444,7 +4392,7 @@ make_automaton_attrs (void) code_exp = rtx_alloc (COND); lats_exp = rtx_alloc (COND); - + XVEC (code_exp, 0) = rtvec_alloc (n_insn_reservs * 2); XVEC (lats_exp, 0) = rtvec_alloc (n_insn_reservs * 2); @@ -4457,7 +4405,7 @@ make_automaton_attrs (void) { XVECEXP (code_exp, 0, i) = decl->condexp; XVECEXP (lats_exp, 0, i) = decl->condexp; - + XVECEXP (code_exp, 0, i+1) = make_numeric_value (decl->insn_num); XVECEXP (lats_exp, 0, i+1) = make_numeric_value (decl->default_latency); } @@ -4584,13 +4532,12 @@ from the machine description file `md'. */\n\n"); printf ("#include \"coretypes.h\"\n"); printf ("#include \"tm.h\"\n"); printf ("#include \"rtl.h\"\n"); + printf ("#include \"insn-attr.h\"\n"); printf ("#include \"tm_p.h\"\n"); printf ("#include \"insn-config.h\"\n"); printf ("#include \"recog.h\"\n"); printf ("#include \"regs.h\"\n"); - printf ("#include \"real.h\"\n"); printf ("#include \"output.h\"\n"); - printf ("#include \"insn-attr.h\"\n"); printf ("#include \"toplev.h\"\n"); printf ("#include \"flags.h\"\n"); printf ("#include \"function.h\"\n"); @@ -4598,13 +4545,13 @@ from the machine description file `md'. */\n\n"); printf ("#define operands recog_data.operand\n\n"); /* Make `insn_alternatives'. */ - insn_alternatives = oballoc (insn_code_number * sizeof (int)); + insn_alternatives = oballocvec (int, insn_code_number); for (id = defs; id; id = id->next) if (id->insn_code >= 0) insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1; /* Make `insn_n_alternatives'. */ - insn_n_alternatives = oballoc (insn_code_number * sizeof (int)); + insn_n_alternatives = oballocvec (int, insn_code_number); for (id = defs; id; id = id->next) if (id->insn_code >= 0) insn_n_alternatives[id->insn_code] = id->num_alternatives;