X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;ds=sidebyside;f=gcc%2Fgenattrtab.c;h=14ecac1f1e55969078bd8395e535be489e6af7c8;hb=1045c81583528e3b5603c64bc6113461be8e4538;hp=bacdafb8e12dbd76a5ce73f92b864d051fd59c43;hpb=6503f78200b1a8dda24ef3fd46c59f6d20720598;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c index bacdafb8e12..14ecac1f1e5 100644 --- a/gcc/genattrtab.c +++ b/gcc/genattrtab.c @@ -1,5 +1,5 @@ /* Generate code from machine description to compute values of attributes. - Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc. + Copyright (C) 1991, 1993, 1994, 1995, 1996 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) This file is part of GNU CC. @@ -16,7 +16,8 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ /* This program handles insn attributes and the DEFINE_DELAY and DEFINE_FUNCTION_UNIT definitions. @@ -145,12 +146,12 @@ void fancy_abort (); struct insn_def { - int insn_code; /* Instruction number. */ - int insn_index; /* Expression numer in file, for errors. */ - 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. */ + struct insn_def *next; /* Next insn in chain. */ + rtx def; /* The DEFINE_... */ int num_alternatives; /* Number of alternatives. */ - int vec_idx; /* Index of attribute vector in `def'. */ + int vec_idx; /* Index of attribute vector in `def'. */ }; /* Once everything has been read in, we store in each attribute value a list @@ -181,15 +182,15 @@ struct attr_value struct attr_desc { - char *name; /* Name of attribute. */ - struct attr_desc *next; /* Next attribute. */ - int is_numeric; /* Values of this attribute are numeric. */ + char *name; /* Name of attribute. */ + struct attr_desc *next; /* Next attribute. */ + int is_numeric; /* Values of this attribute are numeric. */ int negative_ok; /* Allow negative numeric values. */ int unsigned_p; /* Make the output function unsigned int. */ int is_const; /* Attribute value constant for each run. */ - int is_special; /* Don't call `write_attr_set'. */ - struct attr_value *first_value; /* First value of this attribute. */ - struct attr_value *default_val; /* Default value for this attribute. */ + int is_special; /* Don't call `write_attr_set'. */ + struct attr_value *first_value; /* First value of this attribute. */ + struct attr_value *default_val; /* Default value for this attribute. */ }; #define NULL_ATTR (struct attr_desc *) NULL @@ -207,7 +208,7 @@ struct range struct delay_desc { rtx def; /* DEFINE_DELAY expression. */ - struct delay_desc *next; /* Next DEFINE_DELAY. */ + struct delay_desc *next; /* Next DEFINE_DELAY. */ int num; /* Number of DEFINE_DELAY, starting at 1. */ }; @@ -235,7 +236,7 @@ struct function_unit int multiplicity; /* Number of units of this type. */ int simultaneity; /* Maximum number of simultaneous insns on this function unit or 0 if unlimited. */ - rtx condexp; /* Expression TRUE for insn needing unit. */ + rtx condexp; /* Expression TRUE for insn needing unit. */ int num_opclasses; /* Number of different operation types. */ struct function_unit_op *ops; /* Pointer to first operation type. */ int needs_conflict_function; /* Nonzero if a conflict function required. */ @@ -298,7 +299,7 @@ struct dimension int num_values; /* Length of the values list. */ }; -/* Other variables. */ +/* Other variables. */ static int insn_code_number; static int insn_index_number; @@ -310,6 +311,7 @@ static int length_used; static int num_delays; static int have_annul_true, have_annul_false; static int num_units; +static int num_insn_ents; /* Used as operand to `operate_exp': */ @@ -739,7 +741,7 @@ attr_printf VPROTO((register int len, char *fmt, ...)) #ifndef __STDC__ len = va_arg (p, int); - fmt = va_arg (p, char*); + fmt = va_arg (p, char *); #endif /* Print the string into a temporary location. */ @@ -1150,10 +1152,10 @@ check_attr_value (exp, attr) /* 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... */ + /* Otherwise, fall through... */ default: - fatal ("Illegal operation `%s' for attribute value", + fatal ("Invalid operation `%s' for attribute value", GET_RTX_NAME (GET_CODE (exp))); } @@ -1237,7 +1239,7 @@ convert_set_attr (exp, num_alt, insn_code, insn_index) /* Scan all definitions, checking for validity. Also, convert any SET_ATTR and SET_ATTR_ALTERNATIVE expressions to the corresponding SET - expressions. */ + expressions. */ static void check_defs () @@ -1401,7 +1403,7 @@ make_canonical (attr, exp) int allsame = 1; rtx defval; - /* First, check for degenerate COND. */ + /* First, check for degenerate COND. */ if (XVECLEN (exp, 0) == 0) return make_canonical (attr, XEXP (exp, 1)); defval = XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1)); @@ -1883,7 +1885,7 @@ expand_units () * sizeof (struct function_unit_op *)); for (unit = units, i = 0; unit; i += unit->num_opclasses, unit = unit->next) - bcopy (unit_ops[unit->num], &op_array[i], + bcopy ((char *) unit_ops[unit->num], (char *) &op_array[i], unit->num_opclasses * sizeof (struct function_unit_op *)); /* Compute the ready cost function for each unit by computing the @@ -2416,16 +2418,15 @@ simplify_cond (exp, insn_code, insn_index) then build a new expression if they don't match EXP. */ rtx defval = XEXP (exp, 1); rtx new_defval = XEXP (exp, 1); - int len = XVECLEN (exp, 0); - rtx *tests = (rtx *) alloca (len * sizeof (rtx)); + rtunion *tests = (rtunion *) alloca (len * sizeof (rtunion)); int allsame = 1; char *first_spacer; /* This lets us free all storage allocated below, if appropriate. */ first_spacer = (char *) obstack_finish (rtl_obstack); - bcopy (&XVECEXP (exp, 0, 0), tests, len * sizeof (rtx)); + bcopy ((char *) XVEC (exp, 0)->elem, (char *) tests, len * sizeof (rtunion)); /* See if default value needs simplification. */ if (GET_CODE (defval) == COND) @@ -2438,10 +2439,10 @@ simplify_cond (exp, insn_code, insn_index) rtx newtest, newval; /* Simplify this test. */ - newtest = SIMPLIFY_TEST_EXP (tests[i], insn_code, insn_index); - tests[i] = newtest; + newtest = SIMPLIFY_TEST_EXP (tests[i].rtx, insn_code, insn_index); + tests[i].rtx = newtest; - newval = tests[i + 1]; + newval = tests[i + 1].rtx; /* See if this value may need simplification. */ if (GET_CODE (newval) == COND) newval = simplify_cond (newval, insn_code, insn_index); @@ -2452,7 +2453,7 @@ simplify_cond (exp, insn_code, insn_index) /* If test is true, make this value the default and discard this + any following tests. */ len = i; - defval = tests[i + 1]; + defval = tests[i + 1].rtx; new_defval = newval; } @@ -2460,33 +2461,33 @@ simplify_cond (exp, insn_code, insn_index) { /* If test is false, discard it and its value. */ for (j = i; j < len - 2; j++) - tests[j] = tests[j + 2]; + tests[j].rtx = tests[j + 2].rtx; len -= 2; } - else if (i > 0 && attr_equal_p (newval, tests[i - 1])) + else if (i > 0 && attr_equal_p (newval, tests[i - 1].rtx)) { /* If this value and the value for the prev test are the same, merge the tests. */ - tests[i - 2] - = insert_right_side (IOR, tests[i - 2], newtest, + tests[i - 2].rtx + = insert_right_side (IOR, tests[i - 2].rtx, newtest, insn_code, insn_index); /* Delete this test/value. */ for (j = i; j < len - 2; j++) - tests[j] = tests[j + 2]; + tests[j].rtx = tests[j + 2].rtx; len -= 2; } else - tests[i + 1] = newval; + tests[i + 1].rtx = newval; } /* If the last test in a COND has the same value as the default value, that test isn't needed. */ - while (len > 0 && attr_equal_p (tests[len - 1], new_defval)) + while (len > 0 && attr_equal_p (tests[len - 1].rtx, new_defval)) len -= 2; /* See if we changed anything. */ @@ -2494,7 +2495,7 @@ simplify_cond (exp, insn_code, insn_index) allsame = 0; else for (i = 0; i < len; i++) - if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i))) + if (! attr_equal_p (tests[i].rtx, XVECEXP (exp, 0, i))) { allsame = 0; break; @@ -2517,7 +2518,8 @@ simplify_cond (exp, insn_code, insn_index) rtx newexp = rtx_alloc (COND); XVEC (newexp, 0) = rtvec_alloc (len); - bcopy (tests, &XVECEXP (newexp, 0, 0), len * sizeof (rtx)); + bcopy ((char *) tests, (char *) XVEC (newexp, 0)->elem, + len * sizeof (rtunion)); XEXP (newexp, 1) = new_defval; return newexp; } @@ -2544,6 +2546,8 @@ remove_insn_ent (av, ie) av->num_insns--; if (ie->insn_code == -1) av->has_asm_insn = 0; + + num_insn_ents--; } /* Insert an insn entry in an attribute value list. */ @@ -2558,6 +2562,8 @@ insert_insn_ent (av, ie) av->num_insns++; if (ie->insn_code == -1) av->has_asm_insn = 1; + + num_insn_ents++; } /* This is a utility routine to take an expression that is a tree of either @@ -2721,7 +2727,7 @@ evaluate_eq_attr (exp, value, insn_code, insn_index) For each possible COND value, call ourselves recursively. The extra TRUE and FALSE expressions will be eliminated by another - call to the simplification routine. */ + call to the simplification routine. */ orexp = false_rtx; andexp = true_rtx; @@ -3079,10 +3085,10 @@ simplify_test_exp (exp, insn_code, insn_index) { i = compute_alternative_mask (exp, AND); if (i & ~insn_alternatives[insn_code]) - fatal ("Illegal alternative specified for pattern number %d", + fatal ("Invalid alternative specified for pattern number %d", insn_index); - /* If all alternatives are excluded, this is false. */ + /* If all alternatives are excluded, this is false. */ i ^= insn_alternatives[insn_code]; if (i == 0) return false_rtx; @@ -3172,10 +3178,10 @@ simplify_test_exp (exp, insn_code, insn_index) { i = compute_alternative_mask (exp, IOR); if (i & ~insn_alternatives[insn_code]) - fatal ("Illegal alternative specified for pattern number %d", + fatal ("Invalid alternative specified for pattern number %d", insn_index); - /* If all alternatives are included, this is true. */ + /* If all alternatives are included, this is true. */ i ^= insn_alternatives[insn_code]; if (i == 0) return true_rtx; @@ -3292,34 +3298,48 @@ optimize_attrs () 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; /* For each insn code, make a list of all the insn_ent's for it, for all values for all attributes. */ + if (num_insn_ents == 0) + return; + /* Make 2 extra elements, for "code" values -2 and -1. */ insn_code_values = (struct attr_value_list **) alloca ((insn_code_number + 2) * sizeof (struct attr_value_list *)); - bzero (insn_code_values, + bzero ((char *) insn_code_values, (insn_code_number + 2) * sizeof (struct attr_value_list *)); + /* Offset the table address so we can index by -2 or -1. */ insn_code_values += 2; + /* Allocate the attr_value_list structures using xmalloc rather than + alloca, because using alloca can overflow the maximum permitted + stack limit on SPARC Lynx. */ + iv = ivbuf = ((struct attr_value_list *) + xmalloc (num_insn_ents * sizeof (struct attr_value_list))); + for (i = 0; i < MAX_ATTRS_INDEX; i++) for (attr = attrs[i]; attr; attr = attr->next) for (av = attr->first_value; av; av = av->next) for (ie = av->first_insn; ie; ie = ie->next) { - iv = ((struct attr_value_list *) - alloca (sizeof (struct attr_value_list))); iv->attr = attr; iv->av = av; iv->ie = ie; iv->next = insn_code_values[ie->insn_code]; insn_code_values[ie->insn_code] = iv; + iv++; } + /* Sanity check on num_insn_ents. */ + if (iv != ivbuf + num_insn_ents) + abort (); + /* Process one insn code at a time. */ for (i = -2; i < insn_code_number; i++) { @@ -3369,6 +3389,8 @@ optimize_attrs () } } } + + free (ivbuf); } #if 0 @@ -3996,7 +4018,7 @@ gen_attr (exp) if (! strcmp (attr->name, "length") && ! attr->is_numeric) fatal ("`length' attribute must take numeric values"); - /* Set up the default value. */ + /* Set up the default value. */ XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr); attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2); } @@ -4449,7 +4471,7 @@ write_test_expr (exp, in_comparison) XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp))); break; - /* Constant integer. */ + /* Constant integer. */ case CONST_INT: #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT printf ("%d", XWINT (exp, 0)); @@ -4458,14 +4480,15 @@ write_test_expr (exp, in_comparison) #endif break; - /* A random C expression. */ + /* A random C expression. */ case SYMBOL_REF: printf ("%s", XSTR (exp, 0)); break; /* The address of the branch target. */ case MATCH_DUP: - printf ("insn_addresses[INSN_UID (JUMP_LABEL (insn))]"); + printf ("insn_addresses[INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])]", + XINT (exp, 0), XINT (exp, 0), XINT (exp, 0)); break; /* The address of the current insn. It would be more consistent with @@ -4570,6 +4593,10 @@ walk_attr_value (exp) return; case MATCH_DUP: + must_extract = 1; + address_used = 1; + return; + case PC: address_used = 1; return; @@ -4603,7 +4630,7 @@ write_attr_get (attr) struct attr_value *av, *common_av; /* Find the most used attribute value. Handle that as the `default' of the - switch we will generate. */ + switch we will generate. */ common_av = find_most_used (attr); /* Write out start of function, then all values with explicit `case' lines, @@ -5436,7 +5463,7 @@ copy_rtx_unchanging (orig) PUT_MODE (copy, GET_MODE (orig)); RTX_UNCHANGING_P (copy) = 1; - bcopy (&XEXP (orig, 0), &XEXP (copy, 0), + bcopy ((char *) &XEXP (orig, 0), (char *) &XEXP (copy, 0), GET_RTX_LENGTH (GET_CODE (copy)) * sizeof (rtx)); return copy; #endif @@ -5445,6 +5472,7 @@ copy_rtx_unchanging (orig) static void fatal (s, a1, a2) char *s; + char *a1, *a2; { fprintf (stderr, "genattrtab: "); fprintf (stderr, s, a1, a2); @@ -5518,7 +5546,7 @@ main (argc, argv) { struct rlimit rlim; - /* Set the stack limit huge so that alloca does not fail. */ + /* Set the stack limit huge so that alloca does not fail. */ getrlimit (RLIMIT_STACK, &rlim); rlim.rlim_cur = rlim.rlim_max; setrlimit (RLIMIT_STACK, &rlim); @@ -5648,7 +5676,7 @@ from the machine description file `md'. */\n\n"); /* Construct extra attributes for `length'. */ make_length_attrs (); - /* Perform any possible optimizations to speed up compilation. */ + /* Perform any possible optimizations to speed up compilation. */ optimize_attrs (); /* Now write out all the `gen_attr_...' routines. Do these before the