X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fgenattrtab.c;h=385779afc2af3702f071d057106cf9521d39e2a3;hb=88c5930813da1b875a27bd64b1cd3209d57eebe2;hp=78a61e86981cfb4dd1335a06bf4f8fdfd46bae4f;hpb=5df34b555877d95cbee3b6ee74ca4e5bf08cbdd3;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c index 78a61e86981..385779afc2a 100644 --- a/gcc/genattrtab.c +++ b/gcc/genattrtab.c @@ -1,13 +1,13 @@ /* 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 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 +16,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. @@ -109,23 +108,17 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #include "coretypes.h" #include "tm.h" #include "rtl.h" -#include "ggc.h" #include "gensupport.h" - -#ifdef HAVE_SYS_RESOURCE_H -# include -#endif - -/* We must include obstack.h after , to avoid lossage with - /usr/include/sys/stdtypes.h on Sun OS 4.x. */ #include "obstack.h" #include "errors.h" -#include "genattrtab.h" +/* Flags for make_internal_attr's `special' parameter. */ +#define ATTR_NONE 0 +#define ATTR_SPECIAL (1 << 0) static struct obstack obstack1, obstack2; -struct obstack *hash_obstack = &obstack1; -struct obstack *temp_obstack = &obstack2; +static struct obstack *hash_obstack = &obstack1; +static struct obstack *temp_obstack = &obstack2; /* enough space to reserve for printing out ints */ #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3) @@ -183,7 +176,6 @@ struct attr_desc unsigned is_numeric : 1; /* Values of this attribute are numeric. */ unsigned is_const : 1; /* Attribute value constant for each run. */ unsigned is_special : 1; /* Don't call `write_attr_set'. */ - unsigned static_p : 1; /* Make the output function static. */ }; /* Structure for each DEFINE_DELAY. */ @@ -196,6 +188,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. */ @@ -203,6 +203,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. */ @@ -217,8 +218,6 @@ static int num_delays; static int have_annul_true, have_annul_false; static int num_insn_ents; -int num_dfa_decls; - /* Stores, for each insn code, the number of constraint alternatives. */ static int *insn_n_alternatives; @@ -240,16 +239,6 @@ static const char *delay_type_str; static const char *delay_1_0_str; static const char *num_delay_slots_str; -/* Indicate that REG_DEAD notes are valid if dead_or_set_p is ever - called. */ - -int reload_completed = 0; - -/* Some machines test `optimize' in macros called from rtlanal.c, so we need - to define it here. */ - -int optimize = 0; - /* Simplify an expression. Only call the routine if there is something to simplify. */ #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \ @@ -258,86 +247,44 @@ int optimize = 0; #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S))) -/* These are referenced by rtlanal.c and hence need to be defined somewhere. - They won't actually be used. */ - -rtx global_rtl[GR_MAX]; -rtx pic_offset_table_rtx; - -static void attr_hash_add_rtx (int, rtx); -static void attr_hash_add_string (int, char *); -static rtx attr_rtx (enum rtx_code, ...); -static rtx attr_rtx_1 (enum rtx_code, va_list); -static char *attr_string (const char *, int); -static rtx check_attr_value (rtx, struct attr_desc *); -static rtx convert_set_attr_alternative (rtx, struct insn_def *); -static rtx convert_set_attr (rtx, struct insn_def *); -static void check_defs (void); -static rtx make_canonical (struct attr_desc *, rtx); -static struct attr_value *get_attr_value (rtx, struct attr_desc *, int); -static rtx copy_rtx_unchanging (rtx); -static rtx copy_boolean (rtx); -static void expand_delays (void); -static void fill_attr (struct attr_desc *); -static rtx substitute_address (rtx, rtx (*) (rtx), rtx (*) (rtx)); -static void make_length_attrs (void); -static rtx identity_fn (rtx); -static rtx zero_fn (rtx); -static rtx one_fn (rtx); -static rtx max_fn (rtx); -static void write_length_unit_log (void); -static rtx simplify_cond (rtx, int, int); -static void clear_struct_flag (rtx); -static void remove_insn_ent (struct attr_value *, struct insn_ent *); -static void insert_insn_ent (struct attr_value *, struct insn_ent *); -static rtx insert_right_side (enum rtx_code, rtx, rtx, int, int); -static rtx make_alternative_compare (int); -static int compute_alternative_mask (rtx, enum rtx_code); -static rtx evaluate_eq_attr (rtx, rtx, int, int); -static rtx simplify_and_tree (rtx, rtx *, int, int); -static rtx simplify_or_tree (rtx, rtx *, int, int); -static rtx simplify_test_exp (rtx, int, int); -static rtx simplify_test_exp_in_temp (rtx, int, int); -static void optimize_attrs (void); -static void gen_attr (rtx, int); -static int count_alternatives (rtx); -static int compares_alternatives_p (rtx); -static int contained_in_p (rtx, rtx); -static void gen_insn (rtx, int); -static void gen_delay (rtx, int); -static void write_test_expr (rtx, int); -static int max_attr_value (rtx, int*); -static int or_attr_value (rtx, int*); -static void walk_attr_value (rtx); -static void write_attr_get (struct attr_desc *); -static rtx eliminate_known_true (rtx, rtx, int, int); -static void write_attr_set (struct attr_desc *, int, rtx, - const char *, const char *, rtx, - int, int); -static void write_insn_cases (struct insn_ent *, int); -static void write_attr_case (struct attr_desc *, struct attr_value *, - int, const char *, const char *, int, rtx); -static void write_attr_valueq (struct attr_desc *, const char *); -static void write_attr_value (struct attr_desc *, rtx); -static void write_upcase (const char *); -static void write_indent (int); -static void write_eligible_delay (const char *); -static int write_expr_attr_cache (rtx, struct attr_desc *); -static void write_const_num_delay_slots (void); -static char *next_comma_elt (const char **); +/* Forward declarations of functions used before their definitions, only. */ +static char *attr_string (const char *, int); +static char *attr_printf (unsigned int, const char *, ...) + ATTRIBUTE_PRINTF_2; +static rtx make_numeric_value (int); static struct attr_desc *find_attr (const char **, int); -static struct attr_value *find_most_used (struct attr_desc *); -static rtx attr_eq (const char *, const char *); -static const char *attr_numeral (int); -static int attr_equal_p (rtx, rtx); -static rtx attr_copy_rtx (rtx); -static int attr_rtx_cost (rtx); -static bool attr_alt_subset_p (rtx, rtx); +static rtx mk_attr_alt (int); +static char *next_comma_elt (const char **); +static rtx insert_right_side (enum rtx_code, rtx, rtx, int, int); +static rtx copy_boolean (rtx); +static int compares_alternatives_p (rtx); +static void make_internal_attr (const char *, rtx, int); +static void insert_insn_ent (struct attr_value *, struct insn_ent *); +static void walk_attr_value (rtx); +static int max_attr_value (rtx, int*); +static int min_attr_value (rtx, int*); +static int or_attr_value (rtx, int*); +static rtx simplify_test_exp (rtx, int, int); +static rtx simplify_test_exp_in_temp (rtx, int, int); +static rtx copy_rtx_unchanging (rtx); +static bool attr_alt_subset_p (rtx, rtx); static bool attr_alt_subset_of_compl_p (rtx, rtx); -static rtx attr_alt_intersection (rtx, rtx); -static rtx attr_alt_union (rtx, rtx); -static rtx attr_alt_complement (rtx); -static rtx mk_attr_alt (int); +static void clear_struct_flag (rtx); +static void write_attr_valueq (struct attr_desc *, const char *); +static struct attr_value *find_most_used (struct attr_desc *); +static void write_attr_set (struct attr_desc *, int, rtx, + const char *, const char *, rtx, + int, int); +static void write_attr_case (struct attr_desc *, struct attr_value *, + int, const char *, const char *, int, rtx); +static void write_attr_value (struct attr_desc *, rtx); +static void write_upcase (const char *); +static void write_indent (int); +static rtx identity_fn (rtx); +static rtx zero_fn (rtx); +static rtx one_fn (rtx); +static rtx max_fn (rtx); +static rtx min_fn (rtx); #define oballoc(size) obstack_alloc (hash_obstack, size) @@ -366,7 +313,7 @@ struct attr_hash for each. */ #define RTL_HASH_SIZE 4093 -struct attr_hash *attr_hash_table[RTL_HASH_SIZE]; +static struct attr_hash *attr_hash_table[RTL_HASH_SIZE]; /* Here is how primitive or already-shared RTL's hash codes are made. */ @@ -601,7 +548,7 @@ attr_rtx (enum rtx_code code, ...) rtx attr_printf (len, format, [arg1, ..., argn]) */ -char * +static char * attr_printf (unsigned int len, const char *fmt, ...) { char str[256]; @@ -642,7 +589,7 @@ attr_string (const char *str, int len) /* Compute the hash code. */ hashcode = (len + 1) * 613 + (unsigned) str[0]; - for (i = 1; i <= len; i += 2) + for (i = 1; i < len; i += 2) hashcode = ((hashcode * 613) + (unsigned) str[i]); if (hashcode < 0) hashcode = -hashcode; @@ -771,7 +718,7 @@ attr_copy_rtx (rtx orig) Return the new expression, if any. */ -rtx +static rtx check_attr_test (rtx exp, int is_const, int lineno) { struct attr_desc *attr; @@ -1020,6 +967,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; @@ -1583,11 +1531,14 @@ make_length_attrs (void) static const char *new_names[] = { "*insn_default_length", + "*insn_min_length", "*insn_variable_length_p", "*insn_current_length" }; - static rtx (*const no_address_fn[]) (rtx) = {identity_fn, zero_fn, zero_fn}; - static rtx (*const address_fn[]) (rtx) = {max_fn, one_fn, identity_fn}; + static rtx (*const no_address_fn[]) (rtx) + = {identity_fn,identity_fn, zero_fn, zero_fn}; + static rtx (*const address_fn[]) (rtx) + = {max_fn, min_fn, one_fn, identity_fn}; size_t i; struct attr_desc *length_attr, *new_attr; struct attr_value *av, *new_av; @@ -1654,6 +1605,13 @@ max_fn (rtx exp) return make_numeric_value (max_attr_value (exp, &unknown)); } +static rtx +min_fn (rtx exp) +{ + int unknown; + return make_numeric_value (min_attr_value (exp, &unknown)); +} + static void write_length_unit_log (void) { @@ -1678,7 +1636,7 @@ write_length_unit_log (void) for (length_unit_log = 0; length_or & 1; length_or >>= 1) length_unit_log++; } - printf ("int length_unit_log = %u;\n", length_unit_log); + printf ("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 @@ -1698,7 +1656,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; @@ -2498,6 +2456,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; @@ -2768,16 +2727,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: @@ -2806,14 +2785,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; @@ -2824,13 +2795,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) @@ -2891,6 +2861,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. */ @@ -3084,37 +3055,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 @@ -3531,6 +3471,47 @@ max_attr_value (rtx exp, int *unknownp) return current_max; } +/* Given an attribute value, return the minimum CONST_STRING argument + encountered. Set *UNKNOWNP and return 0 if the value is unknown. */ + +static int +min_attr_value (rtx exp, int *unknownp) +{ + int current_min; + int i, n; + + switch (GET_CODE (exp)) + { + case CONST_STRING: + current_min = atoi (XSTR (exp, 0)); + break; + + case COND: + current_min = min_attr_value (XEXP (exp, 1), unknownp); + for (i = 0; i < XVECLEN (exp, 0); i += 2) + { + n = min_attr_value (XVECEXP (exp, 0, i + 1), unknownp); + if (n < current_min) + current_min = n; + } + break; + + case IF_THEN_ELSE: + current_min = min_attr_value (XEXP (exp, 1), unknownp); + n = min_attr_value (XEXP (exp, 2), unknownp); + if (n < current_min) + current_min = n; + break; + + default: + *unknownp = 1; + current_min = INT_MAX; + break; + } + + return current_min; +} + /* Given an attribute value, return the result of ORing together all CONST_STRING arguments encountered. Set *UNKNOWNP and return -1 if the numeric value is not known. */ @@ -3658,8 +3639,6 @@ write_attr_get (struct attr_desc *attr) /* Write out start of function, then all values with explicit `case' lines, then a `default', then the value with the most uses. */ - if (attr->static_p) - printf ("static "); if (!attr->is_numeric) printf ("enum attr_%s\n", attr->name); else @@ -3901,51 +3880,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 @@ -4228,7 +4162,6 @@ find_attr (const char **name_p, int create) attr->name = DEF_ATTR_STRING (name); attr->first_value = attr->default_val = NULL; attr->is_numeric = attr->is_const = attr->is_special = 0; - attr->static_p = 0; attr->next = attrs[index]; attrs[index] = attr; @@ -4239,7 +4172,7 @@ find_attr (const char **name_p, int create) /* Create internal attribute with the given default value. */ -void +static void make_internal_attr (const char *name, rtx value, int special) { struct attr_desc *attr; @@ -4250,7 +4183,6 @@ make_internal_attr (const char *name, rtx value, int special) attr->is_numeric = 1; attr->is_const = 0; attr->is_special = (special & ATTR_SPECIAL) != 0; - attr->static_p = (special & ATTR_STATIC) != 0; attr->default_val = get_attr_value (value, attr, -2); } @@ -4275,7 +4207,7 @@ find_most_used (struct attr_desc *attr) /* Return (attr_value "n") */ -rtx +static rtx make_numeric_value (int n) { static rtx int_values[20]; @@ -4335,6 +4267,171 @@ write_const_num_delay_slots (void) printf (" }\n}\n\n"); } } + +/* Synthetic attributes used by insn-automata.c and the scheduler. + These are primarily concerned with (define_insn_reservation) + patterns. */ + +struct insn_reserv +{ + struct insn_reserv *next; + + const char *name; + int default_latency; + rtx condexp; + + /* Sequence number of this insn. */ + int insn_num; + + /* Whether a (define_bypass) construct names this insn in its + output list. */ + bool bypassed; +}; + +static struct insn_reserv *all_insn_reservs = 0; +static struct insn_reserv **last_insn_reserv_p = &all_insn_reservs; +static size_t n_insn_reservs; + +/* Store information from a DEFINE_INSN_RESERVATION for future + attribute generation. */ +static void +gen_insn_reserv (rtx def) +{ + struct insn_reserv *decl = oballoc (sizeof (struct insn_reserv)); + + decl->name = DEF_ATTR_STRING (XSTR (def, 0)); + decl->default_latency = XINT (def, 1); + decl->condexp = check_attr_test (XEXP (def, 2), 0, 0); + 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++; +} + +/* Store information from a DEFINE_BYPASS for future attribute + generation. The only thing we care about is the list of output + insns, which will later be used to tag reservation structures with + a 'bypassed' bit. */ + +struct bypass_list +{ + struct bypass_list *next; + const char *insn; +}; + +static struct bypass_list *all_bypasses; +static size_t n_bypasses; + +static void +gen_bypass_1 (const char *s, size_t len) +{ + struct bypass_list *b; + + if (len == 0) + return; + + s = attr_string (s, len); + for (b = all_bypasses; b; b = b->next) + if (s == b->insn) + return; /* already got that one */ + + b = oballoc (sizeof (struct bypass_list)); + b->insn = s; + b->next = all_bypasses; + all_bypasses = b; + n_bypasses++; +} + +static void +gen_bypass (rtx def) +{ + const char *p, *base; + + for (p = base = XSTR (def, 1); *p; p++) + if (*p == ',') + { + gen_bypass_1 (base, p - base); + do + p++; + while (ISSPACE (*p)); + base = p; + } + gen_bypass_1 (base, p - base); +} + +/* Find and mark all of the bypassed insns. */ +static void +process_bypasses (void) +{ + struct bypass_list *b; + struct insn_reserv *r; + + /* The reservation list is likely to be much longer than the bypass + list. */ + for (r = all_insn_reservs; r; r = r->next) + for (b = all_bypasses; b; b = b->next) + if (r->name == b->insn) + r->bypassed = true; +} + +/* Create all of the attributes that describe automaton properties. */ +static void +make_automaton_attrs (void) +{ + int i; + struct insn_reserv *decl; + rtx code_exp, lats_exp, byps_exp; + + if (n_insn_reservs == 0) + return; + + 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); + + XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1); + XEXP (lats_exp, 1) = make_numeric_value (0); + + for (decl = all_insn_reservs, i = 0; + decl; + decl = decl->next, i += 2) + { + 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); + } + + if (n_bypasses == 0) + byps_exp = make_numeric_value (0); + else + { + process_bypasses (); + + byps_exp = rtx_alloc (COND); + XVEC (byps_exp, 0) = rtvec_alloc (n_bypasses * 2); + XEXP (byps_exp, 1) = make_numeric_value (0); + for (decl = all_insn_reservs, i = 0; + decl; + decl = decl->next) + if (decl->bypassed) + { + XVECEXP (byps_exp, 0, i) = decl->condexp; + XVECEXP (byps_exp, 0, i+1) = make_numeric_value (1); + i += 2; + } + } + + make_internal_attr ("*internal_dfa_insn_code", code_exp, ATTR_NONE); + make_internal_attr ("*insn_default_latency", lats_exp, ATTR_NONE); + make_internal_attr ("*bypass_p", byps_exp, ATTR_NONE); +} int main (int argc, char **argv) @@ -4372,7 +4469,6 @@ from the machine description file `md'. */\n\n"); /* Read the machine description. */ - initiate_automaton_gen (argc, argv); while (1) { int lineno; @@ -4397,54 +4493,14 @@ from the machine description file `md'. */\n\n"); gen_delay (desc, lineno); break; - case DEFINE_CPU_UNIT: - gen_cpu_unit (desc); - break; - - case DEFINE_QUERY_CPU_UNIT: - gen_query_cpu_unit (desc); + case DEFINE_INSN_RESERVATION: + gen_insn_reserv (desc); break; case DEFINE_BYPASS: gen_bypass (desc); break; - case EXCLUSION_SET: - gen_excl_set (desc); - break; - - case PRESENCE_SET: - gen_presence_set (desc); - break; - - case FINAL_PRESENCE_SET: - gen_final_presence_set (desc); - break; - - case ABSENCE_SET: - gen_absence_set (desc); - break; - - case FINAL_ABSENCE_SET: - gen_final_absence_set (desc); - break; - - case DEFINE_AUTOMATON: - gen_automaton (desc); - break; - - case AUTOMATA_OPTION: - gen_automata_option (desc); - break; - - case DEFINE_RESERVATION: - gen_reserv (desc); - break; - - case DEFINE_INSN_RESERVATION: - gen_insn_reserv (desc); - break; - default: break; } @@ -4469,23 +4525,18 @@ from the machine description file `md'. */\n\n"); if (num_delays) expand_delays (); - /* Build DFA, output some functions and expand DFA information - to new attributes. */ - if (num_dfa_decls) - expand_automata (); - printf ("#include \"config.h\"\n"); printf ("#include \"system.h\"\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"); @@ -4504,6 +4555,9 @@ from the machine description file `md'. */\n\n"); if (id->insn_code >= 0) insn_n_alternatives[id->insn_code] = id->num_alternatives; + /* Construct extra attributes for automata. */ + make_automaton_attrs (); + /* Prepare to write out attribute subroutines by checking everything stored away and building the attribute cases. */ @@ -4534,18 +4588,7 @@ from the machine description file `md'. */\n\n"); for (attr = attrs[i]; attr; attr = attr->next) { if (! attr->is_special && ! attr->is_const) - { - int insn_alts_p; - - insn_alts_p - = (attr->name [0] == '*' - && strcmp (&attr->name[1], INSN_ALTS_FUNC_NAME) == 0); - if (insn_alts_p) - printf ("\n#if AUTOMATON_ALTS\n"); - write_attr_get (attr); - if (insn_alts_p) - printf ("#endif\n\n"); - } + write_attr_get (attr); } /* Write out delay eligibility information, if DEFINE_DELAY present. @@ -4560,11 +4603,6 @@ from the machine description file `md'. */\n\n"); write_eligible_delay ("annul_false"); } - /* Output code for pipeline hazards recognition based on DFA - (deterministic finite-state automata). */ - if (num_dfa_decls) - write_automata (); - /* Write out constant delay slot info. */ write_const_num_delay_slots (); @@ -4573,10 +4611,3 @@ from the machine description file `md'. */\n\n"); fflush (stdout); return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); } - -/* Define this so we can link with print-rtl.o to get debug_rtx function. */ -const char * -get_insn_name (int code ATTRIBUTE_UNUSED) -{ - return NULL; -}