/* 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.
definitions (each would be accessed through a pointer).
We use the flags in an RTX as follows:
- `unchanging' (RTX_UNCHANGING_P): This rtx is fully simplified
+ `unchanging' (ATTR_IND_SIMPLIFIED_P): This rtx is fully simplified
independent of the insn code.
- `in_struct' (MEM_IN_STRUCT_P): This rtx is fully simplified
+ `in_struct' (ATTR_CURR_SIMPLIFIED_P): This rtx is fully simplified
for the insn code currently being processed (see optimize_attrs).
- `integrated' (RTX_INTEGRATED_P): This rtx is permanent and unique
+ `integrated' (ATTR_PERMANENT_P): This rtx is permanent and unique
(see attr_rtx).
- `volatil' (MEM_VOLATILE_P): During simplify_by_exploding the value of an
+ `volatil' (ATTR_EQ_ATTR_P): During simplify_by_exploding the value of an
EQ_ATTR rtx is true if !volatil and false if volatil. */
-#include "hconfig.h"
+#define ATTR_IND_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), unchanging))
+#define ATTR_CURR_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), in_struct))
+#define ATTR_PERMANENT_P(RTX) (RTX_FLAG((RTX), integrated))
+#define ATTR_EQ_ATTR_P(RTX) (RTX_FLAG((RTX), volatil))
+
+#include "bconfig.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "ggc.h"
#include "gensupport.h"
struct obstack *hash_obstack = &obstack1;
struct obstack *temp_obstack = &obstack2;
-#define obstack_chunk_alloc xmalloc
-#define obstack_chunk_free free
-
/* enough space to reserve for printing out ints */
#define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
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. */
The algorithm relies on sharing EQ_ATTR nodes: if two nodes in an
expression are the same, the will also have the same address. We find
- all the EQ_ATTR nodes by marking them MEM_VOLATILE_P. This bit later
+ all the EQ_ATTR nodes by marking them ATTR_EQ_ATTR_P. This bit later
represents the value of an EQ_ATTR node, so once all nodes are marked,
they are also given an initial value of FALSE.
/* Simplify an expression. Only call the routine if there is something to
simplify. */
#define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
- (RTX_UNCHANGING_P (EXP) || MEM_IN_STRUCT_P (EXP) ? (EXP) \
+ (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \
: simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
/* Simplify (eq_attr ("alternative") ...)
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_string PARAMS ((const char *, int));
static rtx check_attr_value PARAMS ((rtx, struct attr_desc *));
static rtx convert_set_attr_alternative PARAMS ((rtx, struct insn_def *));
static rtx simplify_knowing PARAMS ((rtx, rtx));
static rtx encode_units_mask PARAMS ((rtx));
static void fill_attr PARAMS ((struct attr_desc *));
-/* dpx2 compiler chokes if we specify the arg types of the args. */
static rtx substitute_address PARAMS ((rtx, rtx (*) (rtx), rtx (*) (rtx)));
static void make_length_attrs PARAMS ((void));
static rtx identity_fn PARAMS ((rtx));
static int write_expr_attr_cache PARAMS ((rtx, struct attr_desc *));
static void write_toplevel_expr PARAMS ((rtx));
static void write_const_num_delay_slots PARAMS ((void));
-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 struct attr_value *find_most_used PARAMS ((struct attr_desc *));
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));
}
/* Generate an RTL expression, but avoid duplicates.
- Set the RTX_INTEGRATED_P flag for these permanent objects.
+ Set the ATTR_PERMANENT_P flag for these permanent objects.
In some cases we cannot uniquify; then we return an ordinary
- impermanent rtx with RTX_INTEGRATED_P clear.
+ impermanent rtx with ATTR_PERMANENT_P clear.
Args are like gen_rtx, but without the mode:
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. */
rtx arg0 = va_arg (p, rtx);
/* A permanent object cannot point to impermanent ones. */
- if (! RTX_INTEGRATED_P (arg0))
+ if (! ATTR_PERMANENT_P (arg0))
{
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)
{
rtx arg1 = va_arg (p, rtx);
/* A permanent object cannot point to impermanent ones. */
- if (! RTX_INTEGRATED_P (arg0) || ! RTX_INTEGRATED_P (arg1))
+ if (! ATTR_PERMANENT_P (arg0) || ! ATTR_PERMANENT_P (arg1))
{
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;
+ ATTR_PERMANENT_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, ...))
+attr_printf VPARAMS ((unsigned int len, const char *fmt, ...))
{
-#ifndef ANSI_PROTOTYPES
- register int len;
- const char *fmt;
-#endif
- va_list p;
char str[256];
- VA_START (p, fmt);
-
-#ifndef ANSI_PROTOTYPES
- len = va_arg (p, int);
- fmt = va_arg (p, const char *);
-#endif
-
- if (len > 255) /* leave room for \0 */
+ VA_OPEN (p, fmt);
+ VA_FIXEDARG (p, unsigned int, len);
+ VA_FIXEDARG (p, const char *, fmt);
+
+ if (len > sizeof str - 1) /* Leave room for \0. */
abort ();
vsprintf (str, fmt, p);
- va_end (p);
+ VA_CLOSE (p);
return attr_string (str, strlen (str));
}
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];
attr_equal_p (x, y)
rtx x, y;
{
- return (x == y || (! (RTX_INTEGRATED_P (x) && RTX_INTEGRATED_P (y))
+ return (x == y || (! (ATTR_PERMANENT_P (x) && ATTR_PERMANENT_P (y))
&& rtx_equal_p (x, y)));
}
\f
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))
+ if (ATTR_PERMANENT_P (orig))
return orig;
code = GET_CODE (orig);
case QUEUED:
case CONST_INT:
case CONST_DOUBLE:
+ case CONST_VECTOR:
case SYMBOL_REF:
case CODE_LABEL:
case PC:
copy = rtx_alloc (code);
PUT_MODE (copy, GET_MODE (orig));
- copy->in_struct = orig->in_struct;
- copy->volatil = orig->volatil;
- copy->unchanging = orig->unchanging;
- copy->integrated = orig->integrated;
+ ATTR_IND_SIMPLIFIED_P (copy) = ATTR_IND_SIMPLIFIED_P (orig);
+ ATTR_CURR_SIMPLIFIED_P (copy) = ATTR_CURR_SIMPLIFIED_P (orig);
+ ATTR_PERMANENT_P (copy) = ATTR_PERMANENT_P (orig);
+ ATTR_EQ_ATTR_P (copy) = ATTR_EQ_ATTR_P (orig);
format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
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
check_attr_test (exp, is_const, lineno)
{
XSTR (exp, 0) = alternative_name;
/* This can't be simplified any further. */
- RTX_UNCHANGING_P (exp) = 1;
+ ATTR_IND_SIMPLIFIED_P (exp) = 1;
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,
constant attribute, so don't expand this until it's time to
write the test expression. */
if (attr->is_const)
- RTX_UNCHANGING_P (exp) = 1;
+ ATTR_IND_SIMPLIFIED_P (exp) = 1;
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));
}
}
fatal ("RTL operator \"%s\" not valid in constant attribute test",
GET_RTX_NAME (GET_CODE (exp)));
/* These cases can't be simplified. */
- RTX_UNCHANGING_P (exp) = 1;
+ ATTR_IND_SIMPLIFIED_P (exp) = 1;
break;
case LE: case LT: case GT: case GE:
attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),
attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));
/* These cases can't be simplified. */
- RTX_UNCHANGING_P (exp) = 1;
+ ATTR_IND_SIMPLIFIED_P (exp) = 1;
break;
case SYMBOL_REF:
/* These cases are valid for constant attributes, but can't be
simplified. */
exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));
- RTX_UNCHANGING_P (exp) = 1;
+ ATTR_IND_SIMPLIFIED_P (exp) = 1;
break;
}
default:
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",
break;
case FFS:
+ case CLZ:
+ case CTZ:
+ case POPCOUNT:
+ case PARITY:
XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
break;
*p = TOUPPER (*p);
value = attr_rtx (SYMBOL_REF, string);
- RTX_UNCHANGING_P (value) = 1;
+ ATTR_IND_SIMPLIFIED_P (value) = 1;
XVECEXP (condexp, 0, 2 * i) = attr_rtx (EQ, exp, value);
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;
}
break;
case SYMBOL_REF:
- if (!attr->is_const || RTX_UNCHANGING_P (exp))
+ if (!attr->is_const || ATTR_IND_SIMPLIFIED_P (exp))
break;
/* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
This makes the COND something that won't be considered an arbitrary
expression by walk_attr_value. */
- RTX_UNCHANGING_P (exp) = 1;
+ ATTR_IND_SIMPLIFIED_P (exp) = 1;
#if 0
/* ??? Why do we do this? With attribute values { A B C D E }, this
tends to generate (!(x==A) && !(x==B) && !(x==C) && !(x==D)) rather
than (x==E). */
exp = convert_const_symbol_ref (exp, attr);
- RTX_UNCHANGING_P (exp) = 1;
+ ATTR_IND_SIMPLIFIED_P (exp) = 1;
exp = check_attr_value (exp, attr);
/* Goto COND case since this is now a COND. Note that while the
new expression is rescanned, all symbol_ref notes are marked as
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;
}
The first produces a function `function_units_used' which is given an
insn and produces an encoding showing which function units are required
for the execution of that insn. If the value is non-negative, the insn
- uses that unit; otherwise, the value is a one's compliment mask of units
+ uses that unit; otherwise, the value is a one's complement mask of units
used.
The second produces a function `result_ready_cost' which is used to
!= 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);
}
every possible C.
The issue delay function for C is op->issue_exp and is used to
- write the `<name>_unit_conflict_cost' function. Symbolicly
+ write the `<name>_unit_conflict_cost' function. Symbolically
this is "ISSUE-DELAY (E,C)".
The pipeline delay results form the FIFO constraint on the
fill the unit given the minimum issue delay. FILL-TIME is the
constant "MIN (ISSUE-DELAY (*,*)) * (SIMULTANEITY - 1)", and
the simultaneity constraint is "READY-COST (E) - FILL-TIME"
- if SIMULTANEITY is non-zero and zero otherwise.
+ if SIMULTANEITY is nonzero and zero otherwise.
Thus, BLOCKAGE (E,C) when SIMULTANEITY is zero is
}
/* 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);
}
/* Translate the CONST_STRING expressions in X to change the encoding of
value. On input, the value is a bitmask with a one bit for each unit
used; on output, the value is the unit number (zero based) if one
- and only one unit is used or the one's compliment of the bitmask. */
+ and only one unit is used or the one's complement of the bitmask. */
static rtx
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 CONST_STRING:
i = atoi (XSTR (x, 0));
if (i < 0)
- /* The sign bit encodes a one's compliment mask. */
+ /* The sign bit encodes a one's complement mask. */
abort ();
else if (i != 0 && i == (i & -i))
/* Only one bit is set, so yield that unit number. */
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;
int len = XVECLEN (exp, 0);
rtx *tests = (rtx *) xmalloc (len * sizeof (rtx));
int allsame = 1;
- char *first_spacer;
rtx ret;
/* This lets us free all storage allocated below, if appropriate. */
- first_spacer = (char *) obstack_finish (rtl_obstack);
+ obstack_finish (rtl_obstack);
memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx));
;
newexp = attr_rtx (EQ_ATTR, alternative_name, attr_numeral (i));
- RTX_UNCHANGING_P (newexp) = 1;
+ ATTR_IND_SIMPLIFIED_P (newexp) = 1;
return newexp;
}
abort ();
/* If uses an address, must return original expression. But set the
- RTX_UNCHANGING_P bit so we don't try to simplify it again. */
+ ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
address_used = 0;
walk_attr_value (newexp);
if (address_used)
{
/* This had `&& current_alternative_string', which seems to be wrong. */
- if (! RTX_UNCHANGING_P (exp))
+ if (! ATTR_IND_SIMPLIFIED_P (exp))
return copy_rtx_unchanging (exp);
return exp;
}
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;
\f
/* Simplify test expression and use temporary obstack in order to avoid
- memory bloat. Use RTX_UNCHANGING_P to avoid unnecesary simplifications
- and avoid unnecesary copying if possible. */
+ memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
+ and avoid unnecessary copying if possible. */
static rtx
simplify_test_exp_in_temp (exp, insn_code, insn_index)
{
rtx x;
struct obstack *old;
- if (RTX_UNCHANGING_P (exp))
+ if (ATTR_IND_SIMPLIFIED_P (exp))
return exp;
old = rtl_obstack;
rtl_obstack = temp_obstack;
rtx newexp = exp;
/* Don't re-simplify something we already simplified. */
- if (RTX_UNCHANGING_P (exp) || MEM_IN_STRUCT_P (exp))
+ if (ATTR_IND_SIMPLIFIED_P (exp) || ATTR_CURR_SIMPLIFIED_P (exp))
return exp;
switch (GET_CODE (exp))
{
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)
won't buy anything unless we weren't given a valid insn code
to process (i.e., we are canonicalizing something.). */
if (insn_code != -2 /* Seems wrong: && current_alternative_string. */
- && ! RTX_UNCHANGING_P (newexp))
+ && ! ATTR_IND_SIMPLIFIED_P (newexp))
return copy_rtx_unchanging (newexp);
return newexp;
/* Process one insn code at a time. */
for (i = -2; i < insn_code_number; i++)
{
- /* Clear the MEM_IN_STRUCT_P flag everywhere relevant.
+ /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
We use it to mean "already simplified for this insn". */
for (iv = insn_code_values[i]; iv; iv = iv->next)
clear_struct_flag (iv->av->value);
most_tests = -1;
for (i = num_marks = 0; i < total; i++)
if (GET_CODE (condval[i]) == CONST_STRING
- && ! MEM_VOLATILE_P (condval[i]))
+ && ! ATTR_EQ_ATTR_P (condval[i]))
{
/* Mark the unmarked constant value and count how many are marked. */
- MEM_VOLATILE_P (condval[i]) = 1;
+ ATTR_EQ_ATTR_P (condval[i]) = 1;
for (j = new_marks = 0; j < total; j++)
if (GET_CODE (condval[j]) == CONST_STRING
- && MEM_VOLATILE_P (condval[j]))
+ && ATTR_EQ_ATTR_P (condval[j]))
new_marks++;
if (new_marks - num_marks > most_tests)
{
}
/* Clear all the marks. */
for (i = 0; i < total; i++)
- MEM_VOLATILE_P (condval[i]) = 0;
+ ATTR_EQ_ATTR_P (condval[i]) = 0;
/* Give up if nothing is constant. */
if (num_marks == 0)
return ret;
}
-/* Set the MEM_VOLATILE_P flag for all EQ_ATTR expressions in EXP and
+/* Set the ATTR_EQ_ATTR_P flag for all EQ_ATTR expressions in EXP and
verify that EXP can be simplified to a constant term if all the EQ_ATTR
tests have known value. */
switch (GET_CODE (exp))
{
case EQ_ATTR:
- if (! MEM_VOLATILE_P (exp))
+ if (! ATTR_EQ_ATTR_P (exp))
{
rtx link = rtx_alloc (EXPR_LIST);
XEXP (link, 0) = exp;
XEXP (link, 1) = *terms;
*terms = link;
*nterms += 1;
- MEM_VOLATILE_P (exp) = 1;
+ ATTR_EQ_ATTR_P (exp) = 1;
}
return 1;
}
}
-/* Clear the MEM_VOLATILE_P flag in all EQ_ATTR expressions on LIST and
+/* Clear the ATTR_EQ_ATTR_P flag in all EQ_ATTR expressions on LIST and
in the values of the NDIM-dimensional attribute space SPACE. */
static void
{
exp = XEXP (link, 0);
if (GET_CODE (exp) == EQ_ATTR)
- MEM_VOLATILE_P (exp) = 0;
+ ATTR_EQ_ATTR_P (exp) = 0;
}
}
if (GET_CODE (av->value) == CONST_STRING)
{
exp = attr_eq (dim->attr->name, XSTR (av->value, 0));
- if (MEM_VOLATILE_P (exp))
+ if (ATTR_EQ_ATTR_P (exp))
continue;
link = rtx_alloc (EXPR_LIST);
{
x = XEXP (space[i].current_value, 0);
if (GET_CODE (x) == EQ_ATTR)
- MEM_VOLATILE_P (x) = 0;
+ ATTR_EQ_ATTR_P (x) = 0;
}
exp = simplify_with_current_value_aux (exp);
{
x = XEXP (space[i].current_value, 0);
if (GET_CODE (x) == EQ_ATTR)
- MEM_VOLATILE_P (x) = 1;
+ ATTR_EQ_ATTR_P (x) = 1;
}
return exp;
}
-/* Reduce the expression EXP based on the MEM_VOLATILE_P settings of
+/* Reduce the expression EXP based on the ATTR_EQ_ATTR_P settings of
all EQ_ATTR expressions. */
static rtx
simplify_with_current_value_aux (exp)
rtx exp;
{
- register int i;
+ int i;
rtx cond;
switch (GET_CODE (exp))
{
case EQ_ATTR:
- if (MEM_VOLATILE_P (exp))
+ if (ATTR_EQ_ATTR_P (exp))
return false_rtx;
else
return true_rtx;
}
}
\f
-/* Clear the MEM_IN_STRUCT_P flag in EXP and its subexpressions. */
+/* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
static void
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))
+ ATTR_CURR_SIMPLIFIED_P (x) = 0;
+ if (ATTR_IND_SIMPLIFIED_P (x))
return;
code = GET_CODE (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:
return 0;
}
\f
-/* Returns non-zero if the given expression contains an EQ_ATTR with the
+/* Returns nonzero if the given expression contains an EQ_ATTR with the
`alternative' attribute. */
static int
return 0;
}
\f
-/* Returns non-zero is INNER is contained in EXP. */
+/* Returns nonzero is INNER is contained in EXP. */
static int
contained_in_p (inner, exp)
/* Given a piece of RTX, print a C expression to test its truth value.
We use AND and IOR both for logical and bit-wise operations, so
interpret them as logical unless they are inside a comparison expression.
- The first bit of FLAGS will be non-zero in that case.
+ The first bit of FLAGS will be nonzero in that case.
Set the second bit of FLAGS to make references to attribute values use
a cached local variable instead of calling a function. */
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)
switch (code)
{
case SYMBOL_REF:
- if (! RTX_UNCHANGING_P (exp))
+ if (! ATTR_IND_SIMPLIFIED_P (exp))
/* Since this is an arbitrary expression, it can look at anything.
However, constant expressions do not depend on any particular
insn. */
return;
}
- printf (" rtx insn;\n");
+ printf (" rtx insn ATTRIBUTE_UNUSED;\n");
printf ("{\n");
if (GET_CODE (common_av->value) == FFS)
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)
{
}
\f
/* Write a subroutine that is given an insn that requires a delay slot, a
- delay slot ordinal, and a candidate insn. It returns non-zero if the
+ delay slot ordinal, and a candidate insn. It returns nonzero if the
candidate can be placed in the specified delay slot of the insn.
We can write as many as three subroutines. `eligible_for_delay'
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. */
printf ("}, \n");
}
+ if (num_units == 0)
+ printf ("{\"dummy\", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} /* a dummy element */");
printf ("};\n\n");
}
\f
/* This page contains miscellaneous utility routines. */
-/* Given a string, return the number of comma-separated elements in it.
- Return 0 for the null string. */
-
-static int
-n_comma_elts (s)
- const char *s;
-{
- int n;
-
- if (*s == '\0')
- return 0;
-
- for (n = 1; *s; s++)
- if (*s == ',')
- n++;
-
- return n;
-}
-
/* Given a pointer to a (char *), return a malloc'ed string containing the
next comma-separated element. Advance the pointer to after the string
scanned, or the end-of-string. Return NULL if at end of string. */
next_comma_elt (pstr)
const char **pstr;
{
- char *out_str;
- const char *p;
-
- if (**pstr == '\0')
- return NULL;
-
- /* Find end of string to compute length. */
- for (p = *pstr; *p != ',' && *p != '\0'; p++)
- ;
+ const char *start;
- out_str = attr_string (*pstr, p - *pstr);
- *pstr = p;
+ start = scan_comma_elt (pstr);
- if (**pstr == ',')
- (*pstr)++;
+ if (start == NULL)
+ return NULL;
- return out_str;
+ return attr_string (start, *pstr - start);
}
/* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
- is non-zero, build a new attribute, if one does not exist. */
+ is nonzero, build a new attribute, if one does not exist. */
static struct attr_desc *
find_attr (name, create)
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))
+ if (ATTR_IND_SIMPLIFIED_P (orig) || ATTR_CURR_SIMPLIFIED_P (orig))
return orig;
- MEM_IN_STRUCT_P (orig) = 1;
+ ATTR_CURR_SIMPLIFIED_P (orig) = 1;
return orig;
#if 0
copy = rtx_alloc (code);
PUT_MODE (copy, GET_MODE (orig));
- RTX_UNCHANGING_P (copy) = 1;
+ ATTR_IND_SIMPLIFIED_P (copy) = 1;
memcpy (&XEXP (copy, 0), &XEXP (orig, 0),
GET_RTX_LENGTH (GET_CODE (copy)) * sizeof (rtx));
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);
XWINT (true_rtx, 0) = 1;
false_rtx = rtx_alloc (CONST_INT);
XWINT (false_rtx, 0) = 0;
- RTX_UNCHANGING_P (true_rtx) = RTX_UNCHANGING_P (false_rtx) = 1;
- RTX_INTEGRATED_P (true_rtx) = RTX_INTEGRATED_P (false_rtx) = 1;
+ ATTR_IND_SIMPLIFIED_P (true_rtx) = ATTR_IND_SIMPLIFIED_P (false_rtx) = 1;
+ ATTR_PERMANENT_P (true_rtx) = ATTR_PERMANENT_P (false_rtx) = 1;
alternative_name = attr_string ("alternative", strlen ("alternative"));
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;
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 \"tm_p.h\"\n");
printf ("#include \"insn-config.h\"\n");
printf ("#include \"insn-attr.h\"\n");
printf ("#include \"toplev.h\"\n");
printf ("#include \"flags.h\"\n");
+ printf ("#include \"function.h\"\n");
printf ("\n");
printf ("#define operands recog_data.operand\n\n");
for (attr = attrs[i]; attr; attr = attr->next)
{
if (! attr->is_special && ! attr->is_const)
- write_attr_get (attr);
+ {
+ 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 out delay eligibility information, if DEFINE_DELAY present.
/* Write out information about function units. */
write_function_unit_info ();
/* Output code for pipeline hazards recognition based on DFA
- (deterministic finite state automata. */
+ (deterministic finite state automata. */
write_automata ();
}