/* Generate code from machine description to compute values of attributes.
Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000 Free Software Foundation, Inc.
+ 1999, 2000, 2002 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
This file is part of GCC.
#include "obstack.h"
#include "errors.h"
-#include "genattrtab.h"
-
static struct obstack obstack1, obstack2;
struct obstack *hash_obstack = &obstack1;
struct obstack *temp_obstack = &obstack2;
struct function_unit_op *ops; /* Pointer to first operation type. */
int needs_conflict_function; /* Nonzero if a conflict function required. */
int needs_blockage_function; /* Nonzero if a blockage function required. */
- int needs_range_function; /* Nonzero if blockage range function needed.*/
+ int needs_range_function; /* Nonzero if blockage range function needed. */
rtx default_cost; /* Conflict cost, if constant. */
struct range issue_delay; /* Range of issue delay values. */
int max_blockage; /* Maximum time an insn blocks the unit. */
static int num_units, num_unit_opclasses;
static int num_insn_ents;
-int num_dfa_decls;
-
/* Used as operand to `operate_exp': */
enum operator {PLUS_OP, MINUS_OP, POS_MINUS_OP, EQ_OP, OR_OP, ORX_OP, MAX_OP, MIN_OP, RANGE_OP};
static void attr_hash_add_rtx PARAMS ((int, rtx));
static void attr_hash_add_string PARAMS ((int, char *));
static rtx attr_rtx PARAMS ((enum rtx_code, ...));
+static rtx attr_rtx_1 PARAMS ((enum rtx_code, va_list));
+static char *attr_printf PARAMS ((unsigned int, const char *, ...))
+ ATTRIBUTE_PRINTF_2;
static char *attr_string PARAMS ((const char *, int));
+static rtx check_attr_test PARAMS ((rtx, int, int));
static rtx check_attr_value PARAMS ((rtx, struct attr_desc *));
static rtx convert_set_attr_alternative PARAMS ((rtx, struct insn_def *));
static rtx convert_set_attr PARAMS ((rtx, struct insn_def *));
static int n_comma_elts PARAMS ((const char *));
static char *next_comma_elt PARAMS ((const char **));
static struct attr_desc *find_attr PARAMS ((const char *, int));
+static void make_internal_attr PARAMS ((const char *, rtx, int));
static struct attr_value *find_most_used PARAMS ((struct attr_desc *));
static rtx find_single_value PARAMS ((struct attr_desc *));
+static rtx make_numeric_value PARAMS ((int));
static void extend_range PARAMS ((struct range *, int, int));
static rtx attr_eq PARAMS ((const char *, const char *));
static const char *attr_numeral PARAMS ((int));
int hashcode;
rtx rtl;
{
- register struct attr_hash *h;
+ struct attr_hash *h;
h = (struct attr_hash *) obstack_alloc (hash_obstack,
sizeof (struct attr_hash));
int hashcode;
char *str;
{
- register struct attr_hash *h;
+ struct attr_hash *h;
h = (struct attr_hash *) obstack_alloc (hash_obstack,
sizeof (struct attr_hash));
rtx attr_rtx (code, [element1, ..., elementn]) */
static rtx
-attr_rtx VPARAMS ((enum rtx_code code, ...))
+attr_rtx_1 (code, p)
+ enum rtx_code code;
+ va_list p;
{
-#ifndef ANSI_PROTOTYPES
- enum rtx_code code;
-#endif
- va_list p;
- register int i; /* Array indices... */
- register const char *fmt; /* Current rtx's format... */
- register rtx rt_val = NULL_RTX;/* RTX to return to caller... */
+ rtx rt_val = NULL_RTX;/* RTX to return to caller... */
int hashcode;
- register struct attr_hash *h;
+ struct attr_hash *h;
struct obstack *old_obstack = rtl_obstack;
- VA_START (p, code);
-
-#ifndef ANSI_PROTOTYPES
- code = va_arg (p, enum rtx_code);
-#endif
-
/* For each of several cases, search the hash table for an existing entry.
Use that entry if one is found; otherwise create a new RTL and add it
to the table. */
{
rt_val = rtx_alloc (code);
XEXP (rt_val, 0) = arg0;
- va_end (p);
return rt_val;
}
if (h->hashcode == hashcode
&& GET_CODE (h->u.rtl) == code
&& XEXP (h->u.rtl, 0) == arg0)
- goto found;
+ return h->u.rtl;
if (h == 0)
{
rt_val = rtx_alloc (code);
XEXP (rt_val, 0) = arg0;
XEXP (rt_val, 1) = arg1;
- va_end (p);
return rt_val;
}
&& GET_CODE (h->u.rtl) == code
&& XEXP (h->u.rtl, 0) == arg0
&& XEXP (h->u.rtl, 1) == arg1)
- goto found;
+ return h->u.rtl;
if (h == 0)
{
if (h->hashcode == hashcode
&& GET_CODE (h->u.rtl) == code
&& XSTR (h->u.rtl, 0) == arg0)
- goto found;
+ return h->u.rtl;
if (h == 0)
{
&& GET_CODE (h->u.rtl) == code
&& XSTR (h->u.rtl, 0) == arg0
&& XSTR (h->u.rtl, 1) == arg1)
- goto found;
+ return h->u.rtl;
if (h == 0)
{
{
HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
if (arg0 == 0)
- {
- va_end (p);
- return false_rtx;
- }
- if (arg0 == 1)
- {
- va_end (p);
- return true_rtx;
- }
- goto nohash;
+ return false_rtx;
+ else if (arg0 == 1)
+ return true_rtx;
+ else
+ goto nohash;
}
else
{
+ int i; /* Array indices... */
+ const char *fmt; /* Current rtx's format... */
nohash:
rt_val = rtx_alloc (code); /* Allocate the storage space. */
abort ();
}
}
- va_end (p);
return rt_val;
}
rtl_obstack = old_obstack;
- va_end (p);
attr_hash_add_rtx (hashcode, rt_val);
RTX_INTEGRATED_P (rt_val) = 1;
return rt_val;
+}
- found:
- va_end (p);
- return h->u.rtl;
+static rtx
+attr_rtx VPARAMS ((enum rtx_code code, ...))
+{
+ rtx result;
+
+ VA_OPEN (p, code);
+ VA_FIXEDARG (p, enum rtx_code, code);
+ result = attr_rtx_1 (code, p);
+ VA_CLOSE (p);
+ return result;
}
/* Create a new string printed with the printf line arguments into a space
rtx attr_printf (len, format, [arg1, ..., argn]) */
-char *
-attr_printf VPARAMS ((register int len, const char *fmt, ...))
+static char *
+attr_printf VPARAMS ((unsigned int len, const char *fmt, ...))
{
char str[256];
VA_OPEN (p, fmt);
- VA_FIXEDARG (p, int, len);
+ VA_FIXEDARG (p, unsigned int, len);
VA_FIXEDARG (p, const char *, fmt);
- if (len > (sizeof(str) - 1)) /* leave room for \0 */
+ if (len > sizeof str - 1) /* Leave room for \0. */
abort ();
vsprintf (str, fmt, p);
const char *str;
int len;
{
- register struct attr_hash *h;
+ struct attr_hash *h;
int hashcode;
int i;
- register char *new_str;
+ char *new_str;
/* Compute the hash code. */
hashcode = (len + 1) * 613 + (unsigned) str[0];
static rtx
attr_copy_rtx (orig)
- register rtx orig;
+ rtx orig;
{
- register rtx copy;
- register int i, j;
- register RTX_CODE code;
- register const char *format_ptr;
+ rtx copy;
+ int i, j;
+ RTX_CODE code;
+ const char *format_ptr;
/* No need to copy a permanent object. */
if (RTX_INTEGRATED_P (orig))
case QUEUED:
case CONST_INT:
case CONST_DOUBLE:
+ case CONST_VECTOR:
case SYMBOL_REF:
case CODE_LABEL:
case PC:
in the attribute (or `alternative_name') to speed up subsequent
`find_attr' calls and eliminate most `strcmp' calls.
- Return the new expression, if any. */
+ Return the new expression, if any. */
-rtx
+static rtx
check_attr_test (exp, is_const, lineno)
rtx exp;
int is_const;
return exp;
}
else
- fatal ("Unknown attribute `%s' in EQ_ATTR", XSTR (exp, 0));
+ fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp, 0));
}
if (is_const && ! attr->is_const)
- fatal ("Constant expression uses insn attribute `%s' in EQ_ATTR",
+ fatal ("constant expression uses insn attribute `%s' in EQ_ATTR",
XSTR (exp, 0));
/* Copy this just to make it permanent,
if (attr->is_numeric)
{
for (p = XSTR (exp, 1); *p; p++)
- if (*p < '0' || *p > '9')
- fatal ("Attribute `%s' takes only numeric values",
+ if (! ISDIGIT (*p))
+ fatal ("attribute `%s' takes only numeric values",
XSTR (exp, 0));
}
else
break;
if (av == NULL)
- fatal ("Unknown value `%s' for `%s' attribute",
+ fatal ("unknown value `%s' for `%s' attribute",
XSTR (exp, 1), XSTR (exp, 0));
}
}
if (attr && attr->negative_ok && *p == '-')
p++;
for (; *p; p++)
- if (*p > '9' || *p < '0')
+ if (! ISDIGIT (*p))
{
message_with_line (attr ? attr->lineno : 0,
"non-numeric value for numeric attribute %s",
if (! strcmp (XSTR (exp, 0), "*"))
{
if (attr == 0 || attr->default_val == 0)
- fatal ("(attr_value \"*\") used in invalid context.");
+ fatal ("(attr_value \"*\") used in invalid context");
exp = attr->default_val->value;
}
newexp = attr_rtx (IF_THEN_ELSE, condexp,
make_numeric_value (1), make_numeric_value (0));
- p = attr_printf (sizeof ("*delay__") + MAX_DIGITS * 2,
- "*delay_%d_%d",
- delay->num, i / 3);
+ p = attr_printf (sizeof "*delay__" + MAX_DIGITS * 2,
+ "*delay_%d_%d", delay->num, i / 3);
make_internal_attr (p, newexp, 1);
if (have_annul_true)
newexp = attr_rtx (IF_THEN_ELSE, condexp,
make_numeric_value (1),
make_numeric_value (0));
- p = attr_printf (sizeof ("*annul_true__") + MAX_DIGITS * 2,
+ p = attr_printf (sizeof "*annul_true__" + MAX_DIGITS * 2,
"*annul_true_%d_%d", delay->num, i / 3);
make_internal_attr (p, newexp, 1);
}
newexp = attr_rtx (IF_THEN_ELSE, condexp,
make_numeric_value (1),
make_numeric_value (0));
- p = attr_printf (sizeof ("*annul_false__") + MAX_DIGITS * 2,
+ p = attr_printf (sizeof "*annul_false__" + MAX_DIGITS * 2,
"*annul_false_%d_%d", delay->num, i / 3);
make_internal_attr (p, newexp, 1);
}
return newexp;
}
else
- fatal ("Badly formed attribute value");
+ fatal ("badly formed attribute value");
}
/* A hack to prevent expand_units from completely blowing up: ORX_OP does
}
else
- fatal ("Badly formed attribute value.");
+ fatal ("badly formed attribute value");
/* NOTREACHED */
return NULL;
}
!= unit->issue_delay.max);
if (unit->needs_conflict_function)
{
- str = attr_printf (strlen (unit->name) + sizeof ("*_cost_") + MAX_DIGITS,
+ str = attr_printf ((strlen (unit->name) + sizeof "*_cost_"
+ + MAX_DIGITS),
"*%s_cost_%d", unit->name, op->num);
make_internal_attr (str, issue_exp, 1);
}
}
/* Make an attribute for use in the blockage function. */
- str = attr_printf (strlen (unit->name) + sizeof ("*_block_") + MAX_DIGITS,
+ str = attr_printf ((strlen (unit->name) + sizeof "*_block_"
+ + MAX_DIGITS),
"*%s_block_%d", unit->name, op->num);
make_internal_attr (str, blockage, 1);
}
newexp = operate_exp (RANGE_OP, min_blockage, max_blockage);
newexp = simplify_knowing (newexp, unit->condexp);
- str = attr_printf (strlen (unit->name) + sizeof ("*_unit_blockage_range"),
+ str = attr_printf ((strlen (unit->name)
+ + sizeof "*_unit_blockage_range"),
"*%s_unit_blockage_range", unit->name);
make_internal_attr (str, newexp, 20);
}
- str = attr_printf (strlen (unit->name) + sizeof ("*_unit_ready_cost"),
+ str = attr_printf (strlen (unit->name) + sizeof "*_unit_ready_cost",
"*%s_unit_ready_cost", unit->name);
}
else
}
/* Simplifying caseexp with simplify_by_exploding doesn't win. */
- str = attr_printf (strlen (unit->name) + sizeof ("*_cases"),
+ str = attr_printf (strlen (unit->name) + sizeof "*_cases",
"*%s_cases", unit->name);
make_internal_attr (str, caseexp, 1);
}
encode_units_mask (x)
rtx x;
{
- register int i;
- register int j;
- register enum rtx_code code;
- register const char *fmt;
+ int i;
+ int j;
+ enum rtx_code code;
+ const char *fmt;
code = GET_CODE (x);
case QUEUED:
case CONST_INT:
case CONST_DOUBLE:
+ case CONST_VECTOR:
case SYMBOL_REF:
case CODE_LABEL:
case PC:
static void
make_length_attrs ()
{
- static const char *new_names[] = {"*insn_default_length",
+ static const char *const new_names[] = {"*insn_default_length",
"*insn_variable_length_p",
"*insn_current_length"};
- static rtx (*no_address_fn[]) PARAMS ((rtx)) = {identity_fn, zero_fn, zero_fn};
- static rtx (*address_fn[]) PARAMS ((rtx)) = {max_fn, one_fn, identity_fn};
+ static rtx (*const no_address_fn[]) PARAMS ((rtx)) = {identity_fn, zero_fn, zero_fn};
+ static rtx (*const address_fn[]) PARAMS ((rtx)) = {max_fn, one_fn, identity_fn};
size_t i;
struct attr_desc *length_attr, *new_attr;
struct attr_value *av, *new_av;
return;
if (! length_attr->is_numeric)
- fatal ("length attribute must be numeric.");
+ fatal ("length attribute must be numeric");
length_attr->is_const = 0;
length_attr->is_special = 1;
return exp;
}
/* Compute approximate cost of the expression. Used to decide whether
- expression is cheap enought for inline. */
+ expression is cheap enough for inline. */
static int
attr_rtx_cost (x)
rtx x;
{
i = compute_alternative_mask (exp, AND);
if (i & ~insn_alternatives[insn_code])
- fatal ("Invalid alternative specified for pattern number %d",
+ fatal ("invalid alternative specified for pattern number %d",
insn_index);
/* If all alternatives are excluded, this is false. */
{
i = compute_alternative_mask (exp, IOR);
if (i & ~insn_alternatives[insn_code])
- fatal ("Invalid alternative specified for pattern number %d",
+ fatal ("invalid alternative specified for pattern number %d",
insn_index);
/* If all alternatives are included, this is true. */
/* Look at the value for this insn code in the specified attribute.
We normally can replace this comparison with the condition that
- would give this insn the values being tested for. */
+ would give this insn the values being tested for. */
if (XSTR (exp, 0) != alternative_name
&& (attr = find_attr (XSTR (exp, 0), 0)) != NULL)
for (av = attr->first_value; av; av = av->next)
simplify_with_current_value_aux (exp)
rtx exp;
{
- register int i;
+ int i;
rtx cond;
switch (GET_CODE (exp))
clear_struct_flag (x)
rtx x;
{
- register int i;
- register int j;
- register enum rtx_code code;
- register const char *fmt;
+ int i;
+ int j;
+ enum rtx_code code;
+ const char *fmt;
MEM_IN_STRUCT_P (x) = 0;
if (RTX_UNCHANGING_P (x))
case QUEUED:
case CONST_INT:
case CONST_DOUBLE:
+ case CONST_VECTOR:
case SYMBOL_REF:
case CODE_LABEL:
case PC:
rtx x;
int max;
{
- register int i;
- register int j;
- register enum rtx_code code;
- register const char *fmt;
+ int i;
+ int j;
+ enum rtx_code code;
+ const char *fmt;
int total = 0;
code = GET_CODE (x);
case QUEUED:
case CONST_INT:
case CONST_DOUBLE:
+ case CONST_VECTOR:
case SYMBOL_REF:
case CODE_LABEL:
case PC:
if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
{
if (GET_MODE (exp) == VOIDmode)
- fatal ("Null MATCH_OPERAND specified as test");
+ fatal ("null MATCH_OPERAND specified as test");
else
printf ("GET_MODE (operands[%d]) == %smode",
XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
walk_attr_value (exp)
rtx exp;
{
- register int i, j;
- register const char *fmt;
+ int i, j;
+ const char *fmt;
RTX_CODE code;
if (exp == NULL)
return 0;
if (!attr->is_numeric)
- printf (" register enum attr_%s ", attr->name);
+ printf (" enum attr_%s ", attr->name);
else if (attr->unsigned_p)
- printf (" register unsigned int ");
+ printf (" unsigned int ");
else
- printf (" register int ");
+ printf (" int ");
printf ("attr_%s = get_attr_%s (insn);\n", attr->name, attr->name);
return 1;
if (!attr->is_const)
write_expr_attr_cache (p, attr);
- printf (" register unsigned long accum = 0;\n\n");
+ printf (" unsigned long accum = 0;\n\n");
while (GET_CODE (p) == IOR)
{
printf ("int\n");
printf ("eligible_for_%s (delay_insn, slot, candidate_insn, flags)\n",
kind);
- printf (" rtx delay_insn;\n");
+ printf (" rtx delay_insn ATTRIBUTE_UNUSED;\n");
printf (" int slot;\n");
printf (" rtx candidate_insn;\n");
printf (" int flags ATTRIBUTE_UNUSED;\n");
the function units. The name is included for documentation purposes
only. */
- printf ("struct function_unit_desc function_units[] = {\n");
+ printf ("const struct function_unit_desc function_units[] = {\n");
/* Write out the descriptions in numeric order, but don't force that order
on the list. Doing so increases the runtime of genattrtab.c. */
/* Create internal attribute with the given default value. */
-void
+static void
make_internal_attr (name, value, special)
const char *name;
rtx value;
/* Return (attr_value "n") */
-rtx
+static rtx
make_numeric_value (n)
int n;
{
static rtx
copy_rtx_unchanging (orig)
- register rtx orig;
+ rtx orig;
{
#if 0
- register rtx copy;
- register RTX_CODE code;
+ rtx copy;
+ RTX_CODE code;
#endif
if (RTX_UNCHANGING_P (orig) || MEM_IN_STRUCT_P (orig))
progname = "genattrtab";
if (argc <= 1)
- fatal ("No input file name.");
+ fatal ("no input file name");
- if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
+ if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
return (FATAL_EXIT_CODE);
obstack_init (hash_obstack);
/* Read the machine description. */
- initiate_automaton_gen (argc, argv);
while (1)
{
int lineno;
gen_unit (desc, lineno);
break;
- case DEFINE_CPU_UNIT:
- gen_cpu_unit (desc);
- break;
-
- case DEFINE_QUERY_CPU_UNIT:
- gen_query_cpu_unit (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 ABSENCE_SET:
- gen_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;
}
if (num_delays)
expand_delays ();
- if (num_units || num_dfa_decls)
- {
- /* Expand DEFINE_FUNCTION_UNIT information into new attributes. */
- expand_units ();
- /* Build DFA, output some functions and expand DFA information
- into new attributes. */
- expand_automata ();
- }
+ /* Expand DEFINE_FUNCTION_UNIT information into new attributes. */
+ if (num_units)
+ expand_units ();
printf ("#include \"config.h\"\n");
printf ("#include \"system.h\"\n");
write_eligible_delay ("annul_false");
}
- if (num_units || num_dfa_decls)
- {
- /* Write out information about function units. */
- write_function_unit_info ();
- /* Output code for pipeline hazards recognition based on DFA
- (deterministic finite state automata. */
- write_automata ();
- }
+ /* Write out information about function units. */
+ if (num_units)
+ write_function_unit_info ();
/* Write out constant delay slot info */
write_const_num_delay_slots ();