/* Generate code from machine description to compute values of attributes.
- Copyright (C) 1991, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
This file is part of GNU CC.
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 */
+#include "ggc.h"
#ifdef HAVE_SYS_RESOURCE_H
# include <sys/resource.h>
/* We must include obstack.h after <sys/time.h>, to avoid lossage with
/usr/include/sys/stdtypes.h on Sun OS 4.x. */
#include "obstack.h"
+#include "errors.h"
static struct obstack obstack, obstack1, obstack2;
struct obstack *rtl_obstack = &obstack;
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
-/* 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));
-
/* 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. */
};
struct function_unit
{
- char *name; /* Function unit name. */
+ const char *name; /* Function unit name. */
struct function_unit *next; /* Next function unit. */
int num; /* Ordinal of this unit type. */
int multiplicity; /* Number of units of this type. */
This is the hashed, unique string for the numeral
whose value is chosen alternative. */
-static char *current_alternative_string;
+static const char *current_alternative_string;
/* Used to simplify expressions. */
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
/* These are referenced by rtlanal.c and hence need to be defined somewhere.
They won't actually be used. */
-struct _global_rtl global_rtl;
+rtx global_rtl[GR_MAX];
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, ...));
-static char *attr_printf PVPROTO((int, char *, ...));
-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 void check_defs PROTO((void));
+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 char *attr_printf PARAMS ((int, const char *, ...))
+ ATTRIBUTE_PRINTF_2;
+static char *attr_string PARAMS ((const char *, int));
+static rtx check_attr_test PARAMS ((rtx, int));
+static rtx check_attr_value PARAMS ((rtx, struct attr_desc *));
+static rtx convert_set_attr_alternative PARAMS ((rtx, int, int));
+static rtx convert_set_attr PARAMS ((rtx, int, int));
+static void check_defs PARAMS ((void));
#if 0
-static rtx convert_const_symbol_ref PROTO((rtx, struct attr_desc *));
+static rtx convert_const_symbol_ref PARAMS ((rtx, struct attr_desc *));
#endif
-static rtx make_canonical PROTO((struct attr_desc *, rtx));
-static struct attr_value *get_attr_value PROTO((rtx, struct attr_desc *, int));
-static rtx copy_rtx_unchanging PROTO((rtx));
-static rtx copy_boolean PROTO((rtx));
-static void expand_delays PROTO((void));
-static rtx operate_exp PROTO((enum operator, rtx, rtx));
-static void expand_units PROTO((void));
-static rtx simplify_knowing PROTO((rtx, rtx));
-static rtx encode_units_mask PROTO((rtx));
-static void fill_attr PROTO((struct attr_desc *));
+static rtx make_canonical PARAMS ((struct attr_desc *, rtx));
+static struct attr_value *get_attr_value PARAMS ((rtx, struct attr_desc *, int));
+static rtx copy_rtx_unchanging PARAMS ((rtx));
+static rtx copy_boolean PARAMS ((rtx));
+static void expand_delays PARAMS ((void));
+static rtx operate_exp PARAMS ((enum operator, rtx, rtx));
+static void expand_units PARAMS ((void));
+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 PROTO((rtx, rtx (*) (), rtx (*) ()));
-static void make_length_attrs PROTO((void));
-static rtx identity_fn PROTO((rtx));
-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));
+static rtx substitute_address PARAMS ((rtx, rtx (*) (rtx), rtx (*) (rtx)));
+static void make_length_attrs PARAMS ((void));
+static rtx identity_fn PARAMS ((rtx));
+static rtx zero_fn PARAMS ((rtx));
+static rtx one_fn PARAMS ((rtx));
+static rtx max_fn PARAMS ((rtx));
+static void write_length_unit_log PARAMS ((void));
+static rtx simplify_cond PARAMS ((rtx, int, int));
#if 0
-static rtx simplify_by_alternatives PROTO((rtx, int, int));
+static rtx simplify_by_alternatives PARAMS ((rtx, int, int));
#endif
-static rtx simplify_by_exploding PROTO((rtx));
-static int find_and_mark_used_attributes PROTO((rtx, rtx *, int *));
-static void unmark_used_attributes PROTO((rtx, struct dimension *, int));
-static int add_values_to_cover PROTO((struct dimension *));
-static int increment_current_value PROTO((struct dimension *, int));
-static rtx test_for_current_value PROTO((struct dimension *, int));
-static rtx simplify_with_current_value PROTO((rtx, struct dimension *, int));
-static rtx simplify_with_current_value_aux PROTO((rtx));
-static void clear_struct_flag PROTO((rtx));
-static int count_sub_rtxs PROTO((rtx, int));
-static void remove_insn_ent PROTO((struct attr_value *, struct insn_ent *));
-static void insert_insn_ent PROTO((struct attr_value *, struct insn_ent *));
-static rtx insert_right_side PROTO((enum rtx_code, rtx, rtx, int, int));
-static rtx make_alternative_compare PROTO((int));
-static int compute_alternative_mask PROTO((rtx, enum rtx_code));
-static rtx evaluate_eq_attr PROTO((rtx, rtx, int, int));
-static rtx simplify_and_tree PROTO((rtx, rtx *, int, int));
-static rtx simplify_or_tree PROTO((rtx, rtx *, int, int));
-static rtx simplify_test_exp PROTO((rtx, int, int));
-static void optimize_attrs PROTO((void));
-static void gen_attr PROTO((rtx));
-static int count_alternatives PROTO((rtx));
-static int compares_alternatives_p PROTO((rtx));
-static int contained_in_p PROTO((rtx, rtx));
-static void gen_insn PROTO((rtx));
-static void gen_delay PROTO((rtx));
-static void gen_unit PROTO((rtx));
-static void write_test_expr PROTO((rtx, int));
-static int max_attr_value PROTO((rtx));
-static int or_attr_value PROTO((rtx));
-static void walk_attr_value PROTO((rtx));
-static void write_attr_get PROTO((struct attr_desc *));
-static rtx eliminate_known_true PROTO((rtx, rtx, int, int));
-static void write_attr_set PROTO((struct attr_desc *, int, rtx, char *,
- char *, rtx, int, int));
-static void write_attr_case PROTO((struct attr_desc *, struct attr_value *,
- int, char *, char *, int, rtx));
-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 *));
-static void write_indent PROTO((int));
-static void write_eligible_delay PROTO((char *));
-static void write_function_unit_info PROTO((void));
-static void write_complex_function PROTO((struct function_unit *, char *,
- char *));
-static int write_expr_attr_cache PROTO((rtx, struct attr_desc *));
-static void write_toplevel_expr PROTO((rtx));
-static int n_comma_elts PROTO((char *));
-static char *next_comma_elt PROTO((char **));
-static struct attr_desc *find_attr PROTO((char *, int));
-static void make_internal_attr PROTO((char *, rtx, int));
-static struct attr_value *find_most_used PROTO((struct attr_desc *));
-static rtx find_single_value PROTO((struct attr_desc *));
-static rtx make_numeric_value PROTO((int));
-static void extend_range PROTO((struct range *, int, int));
-char *xrealloc PROTO((char *, unsigned));
-char *xmalloc PROTO((unsigned));
+static rtx simplify_by_exploding PARAMS ((rtx));
+static int find_and_mark_used_attributes PARAMS ((rtx, rtx *, int *));
+static void unmark_used_attributes PARAMS ((rtx, struct dimension *, int));
+static int add_values_to_cover PARAMS ((struct dimension *));
+static int increment_current_value PARAMS ((struct dimension *, int));
+static rtx test_for_current_value PARAMS ((struct dimension *, int));
+static rtx simplify_with_current_value PARAMS ((rtx, struct dimension *, int));
+static rtx simplify_with_current_value_aux PARAMS ((rtx));
+static void clear_struct_flag PARAMS ((rtx));
+static int count_sub_rtxs PARAMS ((rtx, int));
+static void remove_insn_ent PARAMS ((struct attr_value *, struct insn_ent *));
+static void insert_insn_ent PARAMS ((struct attr_value *, struct insn_ent *));
+static rtx insert_right_side PARAMS ((enum rtx_code, rtx, rtx, int, int));
+static rtx make_alternative_compare PARAMS ((int));
+static int compute_alternative_mask PARAMS ((rtx, enum rtx_code));
+static rtx evaluate_eq_attr PARAMS ((rtx, rtx, int, int));
+static rtx simplify_and_tree PARAMS ((rtx, rtx *, int, int));
+static rtx simplify_or_tree PARAMS ((rtx, rtx *, int, int));
+static rtx simplify_test_exp PARAMS ((rtx, int, int));
+static void optimize_attrs PARAMS ((void));
+static void gen_attr PARAMS ((rtx));
+static int count_alternatives PARAMS ((rtx));
+static int compares_alternatives_p PARAMS ((rtx));
+static int contained_in_p PARAMS ((rtx, rtx));
+static void gen_insn PARAMS ((rtx));
+static void gen_delay PARAMS ((rtx));
+static void gen_unit PARAMS ((rtx));
+static void write_test_expr PARAMS ((rtx, int));
+static int max_attr_value PARAMS ((rtx, int*));
+static int or_attr_value PARAMS ((rtx, int*));
+static void walk_attr_value PARAMS ((rtx));
+static void write_attr_get PARAMS ((struct attr_desc *));
+static rtx eliminate_known_true PARAMS ((rtx, rtx, int, int));
+static void write_attr_set PARAMS ((struct attr_desc *, int, rtx,
+ const char *, const char *, rtx,
+ int, int));
+static void write_attr_case PARAMS ((struct attr_desc *, struct attr_value *,
+ int, const char *, const char *, int, rtx));
+static void write_unit_name PARAMS ((const char *, int, const char *));
+static void write_attr_valueq PARAMS ((struct attr_desc *, const char *));
+static void write_attr_value PARAMS ((struct attr_desc *, rtx));
+static void write_upcase PARAMS ((const char *));
+static void write_indent PARAMS ((int));
+static void write_eligible_delay PARAMS ((const char *));
+static void write_function_unit_info PARAMS ((void));
+static void write_complex_function PARAMS ((struct function_unit *, const char *,
+ const char *));
+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 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));
+static int attr_equal_p PARAMS ((rtx, rtx));
+static rtx attr_copy_rtx PARAMS ((rtx));
#define oballoc(size) obstack_alloc (hash_obstack, size)
/*VARARGS1*/
static rtx
-attr_rtx VPROTO((enum rtx_code code, ...))
+attr_rtx VPARAMS ((enum rtx_code code, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
enum rtx_code code;
#endif
va_list p;
register int i; /* Array indices... */
- register char *fmt; /* Current rtx's format... */
- register rtx rt_val; /* RTX to return to caller... */
+ register const char *fmt; /* Current rtx's format... */
+ register rtx rt_val = NULL_RTX;/* RTX to return to caller... */
int hashcode;
register struct attr_hash *h;
struct obstack *old_obstack = rtl_obstack;
VA_START (p, code);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
code = va_arg (p, enum rtx_code);
#endif
else if (GET_RTX_LENGTH (code) == 1
&& GET_RTX_FORMAT (code)[0] == 's')
{
- char * arg0 = va_arg (p, char *);
+ char *arg0 = va_arg (p, char *);
if (code == SYMBOL_REF)
arg0 = attr_string (arg0, strlen (arg0));
{
HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
if (arg0 == 0)
- return false_rtx;
+ {
+ va_end (p);
+ return false_rtx;
+ }
if (arg0 == 1)
- return true_rtx;
+ {
+ va_end (p);
+ return true_rtx;
+ }
goto nohash;
}
else
/*VARARGS2*/
static char *
-attr_printf VPROTO((register int len, char *fmt, ...))
+attr_printf VPARAMS ((register int len, const char *fmt, ...))
{
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
register int len;
- char *fmt;
+ const char *fmt;
#endif
va_list p;
register char *str;
VA_START (p, fmt);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
len = va_arg (p, int);
- fmt = va_arg (p, char *);
+ fmt = va_arg (p, const char *);
#endif
/* Print the string into a temporary location. */
return attr_string (str, strlen (str));
}
-rtx
+static rtx
attr_eq (name, value)
- char *name, *value;
+ const char *name, *value;
{
return attr_rtx (EQ_ATTR, attr_string (name, strlen (name)),
attr_string (value, strlen (value)));
}
-char *
+static const char *
attr_numeral (n)
int n;
{
static char *
attr_string (str, len)
- char *str;
+ const char *str;
int len;
{
register struct attr_hash *h;
taking advantage of the fact that if both are hashed
then they can't be equal unless they are the same object. */
-int
+static int
attr_equal_p (x, y)
rtx x, y;
{
descending to all depths, but not copying any
permanent hashed subexpressions. */
-rtx
+static rtx
attr_copy_rtx (orig)
register rtx orig;
{
register rtx copy;
register int i, j;
register RTX_CODE code;
- register char *format_ptr;
+ register const char *format_ptr;
/* No need to copy a permanent object. */
if (RTX_INTEGRATED_P (orig))
{
struct attr_desc *attr;
struct attr_value *av;
- char *name_ptr, *p;
+ const char *name_ptr, *p;
rtx orexp, newexp;
switch (GET_CODE (exp))
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
struct attr_desc *attr;
{
struct attr_value *av;
- char *p;
+ const char *p;
int i;
switch (GET_CODE (exp))
fatal ("CONST_INT not valid for non-numeric `%s' attribute",
attr->name);
- if (INTVAL (exp) < 0)
+ if (INTVAL (exp) < 0 && ! attr->negative_ok)
fatal ("Negative numeric value specified for `%s' attribute",
attr->name);
XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
break;
+ case PLUS:
+ case MINUS:
+ case MULT:
+ case DIV:
+ case MOD:
+ if (attr && !attr->is_numeric)
+ fatal ("Invalid operation `%s' for non-numeric attribute value",
+ GET_RTX_NAME (GET_CODE (exp)));
+ /* FALLTHRU */
+
case IOR:
case AND:
XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
break;
+ case ATTR:
+ {
+ struct attr_desc *attr2 = find_attr (XSTR (exp, 0), 0);
+ if (attr2 == NULL)
+ fatal ("Unknown attribute `%s' in ATTR", XSTR (exp, 0));
+ else if ((attr && attr->is_const) && ! attr2->is_const)
+ fatal ("Non-constant attribute `%s' referenced from `%s'",
+ XSTR (exp, 0), attr->name);
+ else if (attr
+ && (attr->is_numeric != attr2->is_numeric
+ || (! attr->negative_ok && attr2->negative_ok)))
+ fatal ("Numeric attribute mismatch calling `%s' from `%s'",
+ XSTR (exp, 0), attr->name);
+ }
+ break;
+
case SYMBOL_REF:
- if (attr && attr->is_const)
- /* 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... */
+ /* A constant SYMBOL_REF is valid as a constant attribute test and
+ is expanded later by make_canonical into a COND. In a non-constant
+ attribute test, it is left be. */
+ return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
default:
fatal ("Invalid operation `%s' for attribute value",
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;
for (i = 0; i < num_alt - 1; i++)
{
- char *p;
+ const char *p;
p = attr_numeral (i);
XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
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;
+ const char *name_ptr;
char *p;
int n;
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:
strcat (p, "_");
strcat (p, XSTR (av->value, 0));
for (; *p != '\0'; p++)
- if (*p >= 'a' && *p <= 'z')
- *p -= 'a' - 'A';
+ *p = TOUPPER (*p);
value = attr_rtx (SYMBOL_REF, string);
RTX_UNCHANGING_P (value) = 1;
give the same value), optimize it away. */
if (allsame)
{
- obstack_free (rtl_obstack, newexp);
+ if (!ggc_p)
+ obstack_free (rtl_obstack, newexp);
return operate_exp (op, left, XEXP (right, 1));
}
just use that. */
if (rtx_equal_p (newexp, right))
{
- obstack_free (rtl_obstack, newexp);
+ if (!ggc_p)
+ obstack_free (rtl_obstack, newexp);
return right;
}
optimize it away. */
if (allsame)
{
- obstack_free (rtl_obstack, newexp);
+ if (!ggc_p)
+ obstack_free (rtl_obstack, newexp);
return operate_exp (op, XEXP (left, 1), right);
}
just use that. */
if (rtx_equal_p (newexp, left))
{
- obstack_free (rtl_obstack, newexp);
+ if (!ggc_p)
+ obstack_free (rtl_obstack, newexp);
return left;
}
rtx unitsmask;
rtx readycost;
rtx newexp;
- char *str;
+ const char *str;
int i, j, u, num, nvalues;
/* Rebuild the condition for the unit to share the RTL expressions.
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. */
for (op = unit->ops; op; op = op->next)
{
-#ifdef HAIFA
rtx blockage = op->issue_exp;
-#else
- rtx blockage = operate_exp (POS_MINUS_OP, readycost,
- make_numeric_value (1));
-
- if (unit->simultaneity != 0)
- {
- rtx filltime = make_numeric_value ((unit->simultaneity - 1)
- * unit->issue_delay.min);
- blockage = operate_exp (MIN_OP, blockage, filltime);
- }
-
- blockage = operate_exp (POS_MINUS_OP,
- make_numeric_value (op->ready),
- blockage);
-
- blockage = operate_exp (MAX_OP, blockage, op->issue_exp);
-#endif
blockage = simplify_knowing (blockage, unit->condexp);
/* Add this op's contribution to MAX (BLOCKAGE (E,*)) and
}
/* Record MAX (BLOCKAGE (*,*)). */
- unit->max_blockage = max_attr_value (max_blockage);
+ {
+ int unknown;
+ unit->max_blockage = max_attr_value (max_blockage, &unknown);
+ }
/* See if the upper and lower bounds of BLOCKAGE (E,*) are the
same. If so, the blockage function carries no additional
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"),
{
if (GET_CODE (exp) != CONST_STRING)
{
- exp = attr_rtx (IF_THEN_ELSE, known_true, exp,
- make_numeric_value (max_attr_value (exp)));
- exp = simplify_by_exploding (exp);
+ int unknown = 0, max;
+ max = max_attr_value (exp, &unknown);
+ if (! unknown)
+ {
+ exp = attr_rtx (IF_THEN_ELSE, known_true, exp,
+ make_numeric_value (max));
+ exp = simplify_by_exploding (exp);
+ }
}
return exp;
}
register int i;
register int j;
register enum rtx_code code;
- register char *fmt;
+ register const char *fmt;
code = GET_CODE (x);
static rtx
substitute_address (exp, no_address_fn, address_fn)
rtx exp;
- rtx (*no_address_fn) ();
- rtx (*address_fn) ();
+ rtx (*no_address_fn) PARAMS ((rtx));
+ rtx (*address_fn) PARAMS ((rtx));
{
int i;
rtx newexp;
static void
make_length_attrs ()
{
- static char *new_names[] = {"*insn_default_length",
- "*insn_variable_length_p",
- "*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;
+ static const char *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};
+ 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);
}
max_fn (exp)
rtx exp;
{
- return make_numeric_value (max_attr_value (exp));
+ int unknown;
+ return make_numeric_value (max_attr_value (exp, &unknown));
}
static void
struct attr_value *av;
struct insn_ent *ie;
unsigned int length_unit_log, length_or;
+ int unknown = 0;
if (length_attr == 0)
return;
- length_or = or_attr_value (length_attr->default_val->value);
- for (av = length_attr->first_value; av; av = av->next)
- for (ie = av->first_insn; ie; ie = ie->next)
- length_or |= or_attr_value (av->value);
- length_or = ~length_or;
- for (length_unit_log = 0; length_or & 1; length_or >>= 1)
- length_unit_log++;
+ length_or = or_attr_value (length_attr->default_val->value, &unknown);
+ for (av = length_attr->first_value; av; av = av->next)
+ for (ie = av->first_insn; ie; ie = ie->next)
+ length_or |= or_attr_value (av->value, &unknown);
+
+ if (unknown)
+ length_unit_log = 0;
+ else
+ {
+ length_or = ~length_or;
+ for (length_unit_log = 0; length_or & 1; length_or >>= 1)
+ length_unit_log++;
+ }
printf ("int length_unit_log = %u;\n", length_unit_log);
}
\f
rtx defval = XEXP (exp, 1);
rtx new_defval = XEXP (exp, 1);
int len = XVECLEN (exp, 0);
- rtunion *tests = (rtunion *) alloca (len * sizeof (rtunion));
+ rtx *tests = (rtx *) alloca (len * sizeof (rtx));
int allsame = 1;
char *first_spacer;
/* This lets us free all storage allocated below, if appropriate. */
first_spacer = (char *) obstack_finish (rtl_obstack);
- bcopy ((char *) XVEC (exp, 0)->elem, (char *) tests, len * sizeof (rtunion));
+ bcopy ((char *) XVEC (exp, 0)->elem, (char *) tests, len * sizeof (rtx));
/* See if default value needs simplification. */
if (GET_CODE (defval) == COND)
rtx newtest, newval;
/* Simplify this test. */
- newtest = SIMPLIFY_TEST_EXP (tests[i].rtx, insn_code, insn_index);
- tests[i].rtx = newtest;
+ newtest = SIMPLIFY_TEST_EXP (tests[i], insn_code, insn_index);
+ tests[i] = newtest;
- newval = tests[i + 1].rtx;
+ newval = tests[i + 1];
/* See if this value may need simplification. */
if (GET_CODE (newval) == COND)
newval = simplify_cond (newval, 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].rtx;
+ defval = tests[i + 1];
new_defval = newval;
}
{
/* If test is false, discard it and its value. */
for (j = i; j < len - 2; j++)
- tests[j].rtx = tests[j + 2].rtx;
+ tests[j] = tests[j + 2];
len -= 2;
}
- else if (i > 0 && attr_equal_p (newval, tests[i - 1].rtx))
+ else if (i > 0 && attr_equal_p (newval, tests[i - 1]))
{
/* If this value and the value for the prev test are the same,
merge the tests. */
- tests[i - 2].rtx
- = insert_right_side (IOR, tests[i - 2].rtx, newtest,
+ tests[i - 2]
+ = insert_right_side (IOR, tests[i - 2], newtest,
insn_code, insn_index);
/* Delete this test/value. */
for (j = i; j < len - 2; j++)
- tests[j].rtx = tests[j + 2].rtx;
+ tests[j] = tests[j + 2];
len -= 2;
}
else
- tests[i + 1].rtx = newval;
+ tests[i + 1] = 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].rtx, new_defval))
+ while (len > 0 && attr_equal_p (tests[len - 1], new_defval))
len -= 2;
/* See if we changed anything. */
allsame = 0;
else
for (i = 0; i < len; i++)
- if (! attr_equal_p (tests[i].rtx, XVECEXP (exp, 0, i)))
+ if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i)))
{
allsame = 0;
break;
if (len == 0)
{
- obstack_free (rtl_obstack, first_spacer);
+ if (!ggc_p)
+ obstack_free (rtl_obstack, first_spacer);
if (GET_CODE (defval) == COND)
return simplify_cond (defval, insn_code, insn_index);
return defval;
}
else if (allsame)
{
- obstack_free (rtl_obstack, first_spacer);
+ if (!ggc_p)
+ obstack_free (rtl_obstack, first_spacer);
return exp;
}
else
XVEC (newexp, 0) = rtvec_alloc (len);
bcopy ((char *) tests, (char *) XVEC (newexp, 0)->elem,
- len * sizeof (rtunion));
+ len * sizeof (rtx));
XEXP (newexp, 1) = new_defval;
return newexp;
}
rtx exp;
enum rtx_code code;
{
- char *string;
+ const char *string;
if (GET_CODE (exp) == code)
return compute_alternative_mask (XEXP (exp, 0), code)
| compute_alternative_mask (XEXP (exp, 1), code);
strcat (string, "_");
strcat (string, XSTR (exp, 1));
for (p = string; *p ; p++)
- if (*p >= 'a' && *p <= 'z')
- *p -= 'a' - 'A';
+ *p = TOUPPER (*p);
newexp = attr_rtx (EQ, value,
attr_rtx (SYMBOL_REF,
SIMPLIFY_ALTERNATIVE (left);
if (left == false_rtx)
{
- obstack_free (rtl_obstack, spacer);
+ if (!ggc_p)
+ obstack_free (rtl_obstack, spacer);
return false_rtx;
}
right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
SIMPLIFY_ALTERNATIVE (right);
if (left == false_rtx)
{
- obstack_free (rtl_obstack, spacer);
+ if (!ggc_p)
+ obstack_free (rtl_obstack, spacer);
return false_rtx;
}
if (left == false_rtx || right == false_rtx)
{
- obstack_free (rtl_obstack, spacer);
+ if (!ggc_p)
+ obstack_free (rtl_obstack, spacer);
return false_rtx;
}
else if (left == true_rtx)
SIMPLIFY_ALTERNATIVE (left);
if (left == true_rtx)
{
- obstack_free (rtl_obstack, spacer);
+ if (!ggc_p)
+ obstack_free (rtl_obstack, spacer);
return true_rtx;
}
right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
SIMPLIFY_ALTERNATIVE (right);
if (right == true_rtx)
{
- obstack_free (rtl_obstack, spacer);
+ if (!ggc_p)
+ obstack_free (rtl_obstack, spacer);
return true_rtx;
}
if (right == true_rtx || left == true_rtx)
{
- obstack_free (rtl_obstack, spacer);
+ if (!ggc_p)
+ obstack_free (rtl_obstack, spacer);
return true_rtx;
}
else if (left == false_rtx)
if (left == false_rtx)
{
- obstack_free (rtl_obstack, spacer);
+ if (!ggc_p)
+ obstack_free (rtl_obstack, spacer);
return true_rtx;
}
else if (left == true_rtx)
{
- obstack_free (rtl_obstack, spacer);
+ if (!ggc_p)
+ obstack_free (rtl_obstack, spacer);
return false_rtx;
}
insert_insn_ent (av, ie);
something_changed = 1;
}
- obstack_free (temp_obstack, spacer);
+ if (!ggc_p)
+ obstack_free (temp_obstack, spacer);
}
}
}
{
/* Pull the first attribute value from the list and record that
attribute as another dimension in the attribute space. */
- char *name = XSTR (XEXP (list, 0), 0);
+ const char *name = XSTR (XEXP (list, 0), 0);
rtx *prev;
if ((space[ndim].attr = find_attr (name, 0)) == 0
*nterms += 1;
MEM_VOLATILE_P (exp) = 1;
}
+ return 1;
+
case CONST_STRING:
case CONST_INT:
return 1;
register int i;
register int j;
register enum rtx_code code;
- register char *fmt;
+ register const char *fmt;
MEM_IN_STRUCT_P (x) = 0;
if (RTX_UNCHANGING_P (x))
register int i;
register int j;
register enum rtx_code code;
- register char *fmt;
+ register const char *fmt;
int total = 0;
code = GET_CODE (x);
{
struct attr_desc *attr;
struct attr_value *av;
- char *name_ptr;
+ const char *name_ptr;
char *p;
/* Make a new attribute structure. Check for duplicate by looking at
fatal ("Duplicate definition for `%s' attribute", attr->name);
if (*XSTR (exp, 1) == '\0')
- attr->is_numeric = 1;
+ attr->is_numeric = 1;
else
{
name_ptr = XSTR (exp, 1);
rtx exp;
{
int i, j, n;
- char *fmt;
+ const char *fmt;
if (GET_CODE (exp) == MATCH_OPERAND)
return n_comma_elts (XSTR (exp, 2));
rtx exp;
{
int i, j;
- char *fmt;
+ const char *fmt;
if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
return 1;
rtx exp;
{
int i, j;
- char *fmt;
+ const char *fmt;
if (rtx_equal_p (inner, exp))
return 1;
{
struct function_unit *unit;
struct function_unit_op *op;
- char *name = XSTR (def, 0);
+ const char *name = XSTR (def, 0);
int multiplicity = XINT (def, 1);
int simultaneity = XINT (def, 2);
rtx condexp = XEXP (def, 3);
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.
}
\f
/* Given an attribute value, return the maximum CONST_STRING argument
- encountered. It is assumed that they are all numeric. */
+ encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
static int
-max_attr_value (exp)
+max_attr_value (exp, unknownp)
rtx exp;
+ int *unknownp;
{
- int current_max = 0;
- int n;
- int i;
-
- if (GET_CODE (exp) == CONST_STRING)
- return atoi (XSTR (exp, 0));
+ int current_max;
+ int i, n;
- else if (GET_CODE (exp) == COND)
+ switch (GET_CODE (exp))
{
+ case CONST_STRING:
+ current_max = atoi (XSTR (exp, 0));
+ break;
+
+ case COND:
+ current_max = max_attr_value (XEXP (exp, 1), unknownp);
for (i = 0; i < XVECLEN (exp, 0); i += 2)
{
- n = max_attr_value (XVECEXP (exp, 0, i + 1));
+ n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
if (n > current_max)
current_max = n;
}
+ break;
- n = max_attr_value (XEXP (exp, 1));
+ case IF_THEN_ELSE:
+ current_max = max_attr_value (XEXP (exp, 1), unknownp);
+ n = max_attr_value (XEXP (exp, 2), unknownp);
if (n > current_max)
current_max = n;
- }
+ break;
- else if (GET_CODE (exp) == IF_THEN_ELSE)
- {
- current_max = max_attr_value (XEXP (exp, 1));
- n = max_attr_value (XEXP (exp, 2));
- if (n > current_max)
- current_max = n;
+ default:
+ *unknownp = 1;
+ current_max = INT_MAX;
+ break;
}
- else
- abort ();
-
return current_max;
}
/* Given an attribute value, return the result of ORing together all
- CONST_STRING arguments encountered. It is assumed that they are
- all numeric. */
+ CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
+ if the numeric value is not known. */
static int
-or_attr_value (exp)
+or_attr_value (exp, unknownp)
rtx exp;
+ int *unknownp;
{
- int current_or = 0;
+ int current_or;
int i;
- if (GET_CODE (exp) == CONST_STRING)
- return atoi (XSTR (exp, 0));
-
- else if (GET_CODE (exp) == COND)
+ switch (GET_CODE (exp))
{
+ case CONST_STRING:
+ current_or = atoi (XSTR (exp, 0));
+ break;
+
+ case COND:
+ current_or = or_attr_value (XEXP (exp, 1), unknownp);
for (i = 0; i < XVECLEN (exp, 0); i += 2)
- {
- current_or |= or_attr_value (XVECEXP (exp, 0, i + 1));
- }
+ current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
+ break;
- current_or |= or_attr_value (XEXP (exp, 1));
- }
+ case IF_THEN_ELSE:
+ current_or = or_attr_value (XEXP (exp, 1), unknownp);
+ current_or |= or_attr_value (XEXP (exp, 2), unknownp);
+ break;
- else if (GET_CODE (exp) == IF_THEN_ELSE)
- {
- current_or = or_attr_value (XEXP (exp, 1));
- current_or |= or_attr_value (XEXP (exp, 2));
+ default:
+ *unknownp = 1;
+ current_or = -1;
+ break;
}
- else
- abort ();
-
return current_or;
}
\f
rtx exp;
{
register int i, j;
- register char *fmt;
+ register const char *fmt;
RTX_CODE code;
if (exp == NULL)
switch we will generate. */
common_av = find_most_used (attr);
+ /* Write out prototype of function. */
+ if (!attr->is_numeric)
+ printf ("extern enum attr_%s ", attr->name);
+ else if (attr->unsigned_p)
+ printf ("extern unsigned int ");
+ else
+ printf ("extern int ");
+ /* If the attribute name starts with a star, the remainder is the name of
+ the subroutine to use, instead of `get_attr_...'. */
+ if (attr->name[0] == '*')
+ printf ("%s PARAMS ((rtx));\n", &attr->name[1]);
+ else
+ printf ("get_attr_%s PARAMS ((%s));\n", attr->name,
+ (attr->is_const ? "void" : "rtx"));
+
/* Write out start of function, then all values with explicit `case' lines,
then a `default', then the value with the most uses. */
if (!attr->is_numeric)
struct attr_desc *attr;
int indent;
rtx value;
- char *prefix;
- char *suffix;
+ const char *prefix;
+ const char *suffix;
rtx known_true;
int insn_code, insn_index;
{
- if (GET_CODE (value) == CONST_STRING)
- {
- write_indent (indent);
- printf ("%s ", prefix);
- write_attr_value (attr, value);
- printf ("%s\n", suffix);
- }
- else if (GET_CODE (value) == COND)
+ if (GET_CODE (value) == COND)
{
/* Assume the default value will be the default of the COND unless we
find an always true expression. */
}
}
else
- abort ();
+ {
+ write_indent (indent);
+ printf ("%s ", prefix);
+ write_attr_value (attr, value);
+ printf ("%s\n", suffix);
+ }
}
\f
/* Write out the computation for one attribute value. */
struct attr_desc *attr;
struct attr_value *av;
int write_case_lines;
- char *prefix, *suffix;
+ const char *prefix, *suffix;
int indent;
rtx known_true;
{
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
}
write_attr_set (attr, indent + 2, av->value, prefix, suffix,
rtx p;
struct attr_desc *attr;
{
- char *fmt;
+ const char *fmt;
int i, ie, j, je;
if (GET_CODE (p) == EQ_ATTR)
/* Utilities to write names in various forms. */
static void
+write_unit_name (prefix, num, suffix)
+ const char *prefix;
+ int num;
+ const 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;
+ const 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;
+ const 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
{
struct attr_desc *attr;
rtx value;
{
- if (GET_CODE (value) != CONST_STRING)
- abort ();
+ int op;
+
+ switch (GET_CODE (value))
+ {
+ case CONST_STRING:
+ write_attr_valueq (attr, XSTR (value, 0));
+ break;
+
+ case SYMBOL_REF:
+ fputs (XSTR (value, 0), stdout);
+ break;
- write_attr_valueq (attr, XSTR (value, 0));
+ case ATTR:
+ {
+ struct attr_desc *attr2 = find_attr (XSTR (value, 0), 0);
+ printf ("get_attr_%s (%s)", attr2->name,
+ (attr2->is_const ? "" : "insn"));
+ }
+ break;
+
+ case PLUS:
+ op = '+';
+ goto do_operator;
+ case MINUS:
+ op = '-';
+ goto do_operator;
+ case MULT:
+ op = '*';
+ goto do_operator;
+ case DIV:
+ op = '/';
+ goto do_operator;
+ case MOD:
+ op = '%';
+ goto do_operator;
+
+ do_operator:
+ write_attr_value (attr, XEXP (value, 0));
+ putchar (' ');
+ putchar (op);
+ putchar (' ');
+ write_attr_value (attr, XEXP (value, 1));
+ break;
+
+ default:
+ abort ();
+ }
}
static void
write_upcase (str)
- char *str;
+ const char *str;
{
while (*str)
- if (*str < 'a' || *str > 'z')
- printf ("%c", *str++);
- else
- printf ("%c", *str++ - 'a' + 'A');
+ {
+ /* The argument of TOUPPER should not have side effects. */
+ putchar (TOUPPER(*str));
+ str++;
+ }
}
static void
static void
write_eligible_delay (kind)
- char *kind;
+ const char *kind;
{
struct delay_desc *delay;
int max_slots;
printf (" rtx delay_insn;\n");
printf (" int slot;\n");
printf (" rtx candidate_insn;\n");
- printf (" int flags;\n");
+ printf (" int flags ATTRIBUTE_UNUSED;\n");
printf ("{\n");
printf (" rtx insn;\n");
printf ("\n");
static void
write_complex_function (unit, name, connection)
struct function_unit *unit;
- char *name, *connection;
+ const char *name, *connection;
{
struct attr_desc *case_attr, *attr;
struct attr_value *av, *common_av;
int using_case;
int i;
+ printf ("static int %s_unit_%s PARAMS ((rtx, rtx));\n", unit->name, name);
printf ("static int\n");
printf ("%s_unit_%s (executing_insn, candidate_insn)\n",
unit->name, name);
static int
n_comma_elts (s)
- char *s;
+ const char *s;
{
int n;
static char *
next_comma_elt (pstr)
- char **pstr;
+ const char **pstr;
{
char *out_str;
- char *p;
+ const char *p;
if (**pstr == '\0')
return NULL;
static struct attr_desc *
find_attr (name, create)
- char *name;
+ const char *name;
int create;
{
struct attr_desc *attr;
attr->name = attr_string (name, strlen (name));
attr->first_value = attr->default_val = NULL;
attr->is_numeric = attr->negative_ok = attr->is_const = attr->is_special = 0;
+ attr->unsigned_p = attr->func_units_p = attr->blockage_p = 0;
attr->next = attrs[index];
attrs[index] = attr;
static void
make_internal_attr (name, value, special)
- char *name;
+ const char *name;
rtx value;
int special;
{
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);
}
if (range->max < max) range->max = max;
}
-char *
-xrealloc (ptr, size)
- char *ptr;
- unsigned size;
+PTR
+xrealloc (old, size)
+ PTR old;
+ size_t size;
{
- char *result = (char *) realloc (ptr, size);
- if (!result)
+ register PTR ptr;
+ if (old)
+ ptr = (PTR) realloc (old, size);
+ else
+ ptr = (PTR) malloc (size);
+ if (!ptr)
fatal ("virtual memory exhausted");
- return result;
+ return ptr;
}
-char *
+PTR
xmalloc (size)
- unsigned size;
+ size_t size;
{
- register char *val = (char *) malloc (size);
+ register PTR val = (PTR) malloc (size);
if (val == 0)
fatal ("virtual memory exhausted");
#endif
}
-static void
-fatal (s, a1, a2)
- char *s;
- char *a1, *a2;
-{
- fprintf (stderr, "genattrtab: ");
- fprintf (stderr, s, a1, a2);
- fprintf (stderr, "\n");
- exit (FATAL_EXIT_CODE);
-}
-
-/* More 'friendly' abort that prints the line and file.
- config.h can #define abort fancy_abort if you like that sort of thing. */
-
-void
-fancy_abort ()
-{
- fatal ("Internal gcc abort.");
-}
-
/* Determine if an insn has a constant number of delay slots, i.e., the
number of delay slots is not a function of the length of the insn. */
-void
+static void
write_const_num_delay_slots ()
{
struct attr_desc *attr = find_attr ("*num_delay_slots", 0);
}
\f
+extern int main PARAMS ((int, char **));
+
int
main (argc, argv)
int argc;
rtx tem;
int i;
+ progname = "genattrtab";
+
#if defined (RLIMIT_STACK) && defined (HAVE_GETRLIMIT) && defined (HAVE_SETRLIMIT)
/* Get rid of any avoidable limit on stack size. */
{
}
#endif
+ progname = "genattrtab";
obstack_init (rtl_obstack);
obstack_init (hash_obstack);
obstack_init (temp_obstack);
if (infile == 0)
{
perror (argv[1]);
- exit (FATAL_EXIT_CODE);
+ return (FATAL_EXIT_CODE);
}
-
- init_rtl ();
+ read_rtx_filename = argv[1];
/* Set up true and false rtx's */
true_rtx = rtx_alloc (CONST_INT);
else if (GET_CODE (desc) == DEFINE_SPLIT)
insn_code_number++, insn_index_number++;
+ else if (GET_CODE (desc) == DEFINE_PEEPHOLE2)
+ insn_code_number++, insn_index_number++;
+
else if (GET_CODE (desc) == DEFINE_ATTR)
{
gen_attr (desc);
printf ("#include \"config.h\"\n");
printf ("#include \"system.h\"\n");
printf ("#include \"rtl.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 ("\n");
- printf ("#define operands recog_operand\n\n");
+ printf ("#define operands recog_data.operand\n\n");
/* Make `insn_alternatives'. */
insn_alternatives = (int *) oballoc (insn_code_number * sizeof (int));
write_length_unit_log ();
fflush (stdout);
- exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
- /* NOTREACHED */
- return 0;
+ 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 (code)
+ int code ATTRIBUTE_UNUSED;
+{
+ return NULL;
}