If the attribute `alternative', or a random C expression is present,
`constrain_operands' is called. If either of these cases of a reference to
- an operand is found, `insn_extract' is called.
+ an operand is found, `extract_insn' is called.
The special attribute `length' is also recognized. For this operand,
expressions involving the address of an operand or the current insn,
#include "hconfig.h"
-/* varargs must always be included after *config.h. */
-#ifdef __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
#include "system.h"
#include "rtl.h"
#include "insn-config.h" /* For REGISTER_CONSTRAINTS */
/* Define this so we can link with print-rtl.o to get debug_rtx function. */
char **insn_name_ptr = 0;
-static void fatal ();
-void fancy_abort PROTO((void));
+static void fatal PVPROTO ((char *, ...))
+ ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
+void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN;
/* enough space to reserve for printing out ints */
#define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
{
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'. */
+ unsigned is_numeric : 1; /* Values of this attribute are numeric. */
+ unsigned negative_ok : 1; /* Allow negative numeric values. */
+ unsigned unsigned_p : 1; /* Make the output function unsigned int. */
+ unsigned is_const : 1; /* Attribute value constant for each run. */
+ unsigned is_special : 1; /* Don't call `write_attr_set'. */
+ unsigned func_units_p : 1; /* this is the function_units attribute */
+ unsigned blockage_p : 1; /* this is the blockage range function */
struct attr_value *first_value; /* First value of this attribute. */
struct attr_value *default_val; /* Default value for this attribute. */
};
int reload_completed = 0;
-/* Similarly since PRESERVE_DEATH_INFO_REGNO_P might reference "optimize". */
+/* 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
struct _global_rtl global_rtl;
rtx pic_offset_table_rtx;
+static void attr_hash_add_rtx PROTO((int, rtx));
+static void attr_hash_add_string PROTO((int, char *));
static rtx attr_rtx PVPROTO((enum rtx_code, ...));
-#ifdef HAVE_VPRINTF
static char *attr_printf PVPROTO((int, char *, ...));
-#else
-static char *attr_printf ();
-#endif
-
static char *attr_string PROTO((char *, int));
static rtx check_attr_test PROTO((rtx, int));
static rtx check_attr_value PROTO((rtx, struct attr_desc *));
-static rtx convert_set_attr_alternative PROTO((rtx, int, int, int));
-static rtx convert_set_attr PROTO((rtx, int, int, int));
+static rtx convert_set_attr_alternative PROTO((rtx, int, int));
+static rtx convert_set_attr PROTO((rtx, int, int));
static void check_defs PROTO((void));
#if 0
static rtx convert_const_symbol_ref PROTO((rtx, struct attr_desc *));
static rtx zero_fn PROTO((rtx));
static rtx one_fn PROTO((rtx));
static rtx max_fn PROTO((rtx));
+static void write_length_unit_log PROTO ((void));
static rtx simplify_cond PROTO((rtx, int, int));
#if 0
static rtx simplify_by_alternatives PROTO((rtx, int, int));
char *, rtx, int, int));
static void write_attr_case PROTO((struct attr_desc *, struct attr_value *,
int, char *, char *, int, rtx));
+static void write_unit_name PROTO((char *, int, char *));
static void write_attr_valueq PROTO((struct attr_desc *, char *));
static void write_attr_value PROTO((struct attr_desc *, rtx));
static void write_upcase PROTO((char *));
rtx attr_printf (len, format, [arg1, ..., argn]) */
-#ifdef HAVE_VPRINTF
-
/*VARARGS2*/
static char *
attr_printf VPROTO((register int len, char *fmt, ...))
return attr_string (str, strlen (str));
}
-#else /* not HAVE_VPRINTF */
-
-static char *
-attr_printf (len, fmt, arg1, arg2, arg3)
- int len;
- char *fmt;
- char *arg1, *arg2, *arg3; /* also int */
-{
- register char *str;
-
- /* Print the string into a temporary location. */
- str = (char *) alloca (len);
- sprintf (str, fmt, arg1, arg2, arg3);
-
- return attr_string (str, strlen (str));
-}
-#endif /* not HAVE_VPRINTF */
-
rtx
attr_eq (name, value)
char *name, *value;
return exp;
}
else
- fatal ("Unknown attribute `%s' in EQ_ATTR", XEXP (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",
- XEXP (exp, 0));
+ XSTR (exp, 0));
/* Copy this just to make it permanent,
so expressions using it can be permanent too. */
for (p = XSTR (exp, 1); *p; p++)
if (*p < '0' || *p > '9')
fatal ("Attribute `%s' takes only numeric values",
- XEXP (exp, 0));
+ XSTR (exp, 0));
}
else
{
if (av == NULL)
fatal ("Unknown value `%s' for `%s' attribute",
- XEXP (exp, 1), XEXP (exp, 0));
+ XSTR (exp, 1), XSTR (exp, 0));
}
}
else
It becomes a COND with each test being (eq_attr "alternative "n") */
static rtx
-convert_set_attr_alternative (exp, num_alt, insn_code, insn_index)
+convert_set_attr_alternative (exp, num_alt, insn_index)
rtx exp;
int num_alt;
- int insn_code, insn_index;
+ int insn_index;
{
rtx condexp;
int i;
list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
static rtx
-convert_set_attr (exp, num_alt, insn_code, insn_index)
+convert_set_attr (exp, num_alt, insn_index)
rtx exp;
int num_alt;
- int insn_code, insn_index;
+ int insn_index;
{
rtx newexp;
char *name_ptr;
while ((p = next_comma_elt (&name_ptr)) != NULL)
XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
- return convert_set_attr_alternative (newexp, num_alt, insn_code, insn_index);
+ return convert_set_attr_alternative (newexp, num_alt, insn_index);
}
\f
/* Scan all definitions, checking for validity. Also, convert any SET_ATTR
case SET_ATTR_ALTERNATIVE:
value = convert_set_attr_alternative (value,
id->num_alternatives,
- id->insn_code,
id->insn_index);
break;
case SET_ATTR:
value = convert_set_attr (value, id->num_alternatives,
- id->insn_code, id->insn_index);
+ id->insn_index);
break;
default:
unitsmask = attr_rtx (FFS, unitsmask);
}
- make_internal_attr ("*function_units_used", unitsmask, 2);
+ make_internal_attr ("*function_units_used", unitsmask, 10);
/* Create an array of ops for each unit. Add an extra unit for the
result_ready_cost function that has the ops of all other units. */
if (unit->needs_range_function)
{
/* Compute the blockage range function and make an attribute
- for writing it's value. */
+ for writing its value. */
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"),
"*%s_unit_blockage_range", unit->name);
- make_internal_attr (str, newexp, 4);
+ make_internal_attr (str, newexp, 20);
}
str = attr_printf (strlen (unit->name) + sizeof ("*_unit_ready_cost"),
"*insn_current_length"};
static rtx (*no_address_fn[]) PROTO((rtx)) = {identity_fn, zero_fn, zero_fn};
static rtx (*address_fn[]) PROTO((rtx)) = {max_fn, one_fn, identity_fn};
- int i;
+ size_t i;
struct attr_desc *length_attr, *new_attr;
struct attr_value *av, *new_av;
struct insn_ent *ie, *new_ie;
static rtx
zero_fn (exp)
- rtx exp;
+ rtx exp ATTRIBUTE_UNUSED;
{
return make_numeric_value (0);
}
static rtx
one_fn (exp)
- rtx exp;
+ rtx exp ATTRIBUTE_UNUSED;
{
return make_numeric_value (1);
}
}
/* Return the number of RTX objects making up the expression X.
- But if we count more more than MAX objects, stop counting. */
+ But if we count more than MAX objects, stop counting. */
static int
count_sub_rtxs (x, max)
unit->condexp = insert_right_side (IOR, unit->condexp, op->condexp, -2, -2);
}
\f
-/* Given a piece of RTX, print a C expression to test it's truth value.
-
+/* 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.
if (must_extract)
{
write_indent (indent + 2);
- printf ("insn_extract (insn);\n");
+ printf ("extract_insn (insn);\n");
}
if (must_constrain)
{
#ifdef REGISTER_CONSTRAINTS
write_indent (indent + 2);
- printf ("if (! constrain_operands (INSN_CODE (insn), reload_completed))\n");
+ printf ("if (! constrain_operands (reload_completed))\n");
write_indent (indent + 2);
printf (" fatal_insn_not_found (insn);\n");
#endif
/* Utilities to write names in various forms. */
static void
+write_unit_name (prefix, num, suffix)
+ char *prefix;
+ int num;
+ char *suffix;
+{
+ struct function_unit *unit;
+
+ for (unit = units; unit; unit = unit->next)
+ if (unit->num == num)
+ {
+ printf ("%s%s%s", prefix, unit->name, suffix);
+ return;
+ }
+
+ printf ("%s<unknown>%s", prefix, suffix);
+}
+
+static void
write_attr_valueq (attr, s)
struct attr_desc *attr;
char *s;
{
if (attr->is_numeric)
{
- printf ("%s", s);
- /* Make the blockage range values easier to read. */
- if (strlen (s) > 1)
- printf (" /* 0x%x */", atoi (s));
+ int num = atoi (s);
+
+ printf ("%d", num);
+
+ /* Make the blockage range values and function units used values easier
+ to read. */
+ if (attr->func_units_p)
+ {
+ if (num == -1)
+ printf (" /* units: none */");
+ else if (num >= 0)
+ write_unit_name (" /* units: ", num, " */");
+ else
+ {
+ int i;
+ char *sep = " /* units: ";
+ for (i = 0, num = ~num; num; i++, num >>= 1)
+ if (num & 1)
+ {
+ write_unit_name (sep, i, (num == 1) ? " */" : "");
+ sep = ", ";
+ }
+ }
+ }
+
+ else if (attr->blockage_p)
+ printf (" /* min %d, max %d */", num >> (HOST_BITS_PER_INT / 2),
+ num & ((1 << (HOST_BITS_PER_INT / 2)) - 1));
+
+ else if (num > 9 || num < 0)
+ printf (" /* 0x%x */", num);
}
else
{
attr->is_special = (special & 1) != 0;
attr->negative_ok = (special & 2) != 0;
attr->unsigned_p = (special & 4) != 0;
+ attr->func_units_p = (special & 8) != 0;
+ attr->blockage_p = (special & 16) != 0;
attr->default_val = get_attr_value (value, attr, -2);
}
}
static void
-fatal (s, a1, a2)
- char *s;
- char *a1, *a2;
+fatal VPROTO ((char *format, ...))
{
+#ifndef __STDC__
+ char *format;
+#endif
+ va_list ap;
+
+ VA_START (ap, format);
+
+#ifndef __STDC__
+ format = va_arg (ap, char *);
+#endif
+
fprintf (stderr, "genattrtab: ");
- fprintf (stderr, s, a1, a2);
+ vfprintf (stderr, format, ap);
+ va_end (ap);
fprintf (stderr, "\n");
exit (FATAL_EXIT_CODE);
}
printf ("#include \"real.h\"\n");
printf ("#include \"output.h\"\n");
printf ("#include \"insn-attr.h\"\n");
+ printf ("#include \"toplev.h\"\n");
printf ("\n");
printf ("#define operands recog_operand\n\n");