/* Generate code from machine description to compute values of attributes.
Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
+ 1999, 2000, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
This file is part of GCC.
`in_struct' (ATTR_CURR_SIMPLIFIED_P): This rtx is fully simplified
for the insn code currently being processed (see optimize_attrs).
`return_val' (ATTR_PERMANENT_P): This rtx is permanent and unique
- (see attr_rtx).
- `volatil' (ATTR_EQ_ATTR_P): During simplify_by_exploding the value of an
- EQ_ATTR rtx is true if !volatil and false if volatil. */
+ (see attr_rtx). */
#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), return_val))
-#define ATTR_EQ_ATTR_P(RTX) (RTX_FLAG((RTX), volatil))
#if 0
#define strcmp_check(S1, S2) ((S1) == (S2) \
? 0 \
- : (strcmp ((S1), (S2)) \
- ? 1 \
- : (abort (), 0)))
+ : (gcc_assert (strcmp ((S1), (S2))), 1))
#else
#define strcmp_check(S1, S2) ((S1) != (S2))
#endif
struct insn_ent
{
struct insn_ent *next; /* Next in chain. */
- int insn_code; /* Instruction number. */
- int insn_index; /* Index of definition in file */
- int lineno; /* Line number. */
+ struct insn_def *def; /* Instruction definition. */
};
/* Each value of an attribute (either constant or computed) is assigned a
struct attr_value *default_val; /* Default value for this attribute. */
int lineno : 24; /* Line number. */
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 static_p : 1; /* Make the output function static. */
};
-#define NULL_ATTR (struct attr_desc *) NULL
-
/* Structure for each DEFINE_DELAY. */
struct delay_desc
static void write_attr_set (struct attr_desc *, int, rtx,
const char *, const char *, rtx,
int, int);
+static void write_insn_cases (struct insn_ent *, int);
static void write_attr_case (struct attr_desc *, struct attr_value *,
int, const char *, const char *, int, rtx);
static void write_attr_valueq (struct attr_desc *, const char *);
break;
default:
- abort ();
+ gcc_unreachable ();
}
}
return rt_val;
va_start (p, fmt);
- if (len > sizeof str - 1) /* Leave room for \0. */
- abort ();
+ gcc_assert (len < sizeof str); /* Leave room for \0. */
vsprintf (str, fmt, p);
va_end (p);
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));
break;
default:
- abort ();
+ gcc_unreachable ();
}
}
return copy;
break;
}
- if (INTVAL (exp) < 0 && ! attr->negative_ok)
+ if (INTVAL (exp) < 0)
{
message_with_line (attr->lineno,
"negative numeric value specified for attribute %s",
if (attr == 0 || attr->is_numeric)
{
p = XSTR (exp, 0);
- if (attr && attr->negative_ok && *p == '-')
- p++;
for (; *p; p++)
if (! ISDIGIT (*p))
{
have_error = 1;
}
else if (attr
- && (attr->is_numeric != attr2->is_numeric
- || (! attr->negative_ok && attr2->negative_ok)))
+ && attr->is_numeric != attr2->is_numeric)
{
message_with_line (attr->lineno,
"numeric attribute mismatch calling `%s' from `%s'",
for (av = attr->first_value; av; av = av->next)
if (rtx_equal_p (value, av->value)
&& (num_alt == 0 || av->first_insn == NULL
- || insn_alternatives[av->first_insn->insn_code]))
+ || insn_alternatives[av->first_insn->def->insn_code]))
return av;
av = oballoc (sizeof (struct attr_value));
av = get_attr_value (value, attr, id->insn_code);
ie = oballoc (sizeof (struct insn_ent));
- ie->insn_code = id->insn_code;
- ie->insn_index = id->insn_code;
+ ie->def = id;
insert_insn_ent (av, ie);
}
}
new_av = get_attr_value (substitute_address (av->value,
no_address_fn[i],
address_fn[i]),
- new_attr, ie->insn_code);
+ new_attr, ie->def->insn_code);
new_ie = oballoc (sizeof (struct insn_ent));
- new_ie->insn_code = ie->insn_code;
- new_ie->insn_index = ie->insn_index;
+ new_ie->def = ie->def;
insert_insn_ent (new_av, new_ie);
}
}
}
av->num_insns--;
- if (ie->insn_code == -1)
+ if (ie->def->insn_code == -1)
av->has_asm_insn = 0;
num_insn_ents--;
ie->next = av->first_insn;
av->first_insn = ie;
av->num_insns++;
- if (ie->insn_code == -1)
+ if (ie->def->insn_code == -1)
av->has_asm_insn = 1;
num_insn_ents++;
rtx newexp;
int i;
- if (GET_CODE (value) == CONST_STRING)
+ switch (GET_CODE (value))
{
+ case CONST_STRING:
if (! strcmp_check (XSTR (value, 0), XSTR (exp, 1)))
newexp = true_rtx;
else
newexp = false_rtx;
- }
- else if (GET_CODE (value) == SYMBOL_REF)
- {
- char *p;
- char string[256];
-
- if (GET_CODE (exp) != EQ_ATTR)
- abort ();
-
- if (strlen (XSTR (exp, 0)) + strlen (XSTR (exp, 1)) + 2 > 256)
- abort ();
-
- strcpy (string, XSTR (exp, 0));
- strcat (string, "_");
- strcat (string, XSTR (exp, 1));
- for (p = string; *p; p++)
- *p = TOUPPER (*p);
-
- newexp = attr_rtx (EQ, value,
- attr_rtx (SYMBOL_REF,
- DEF_ATTR_STRING (string)));
- }
- else if (GET_CODE (value) == COND)
- {
- /* We construct an IOR of all the cases for which the requested attribute
- value is present. Since we start with FALSE, if it is not present,
- FALSE will be returned.
+ break;
+
+ case SYMBOL_REF:
+ {
+ char *p;
+ char string[256];
+
+ gcc_assert (GET_CODE (exp) == EQ_ATTR);
+ gcc_assert (strlen (XSTR (exp, 0)) + strlen (XSTR (exp, 1)) + 2
+ <= 256);
+
+ strcpy (string, XSTR (exp, 0));
+ strcat (string, "_");
+ strcat (string, XSTR (exp, 1));
+ for (p = string; *p; p++)
+ *p = TOUPPER (*p);
+
+ newexp = attr_rtx (EQ, value,
+ attr_rtx (SYMBOL_REF,
+ DEF_ATTR_STRING (string)));
+ break;
+ }
+ case COND:
+ /* We construct an IOR of all the cases for which the
+ requested attribute value is present. Since we start with
+ FALSE, if it is not present, FALSE will be returned.
+
Each case is the AND of the NOT's of the previous conditions with the
current condition; in the default case the current condition is TRUE.
-
+
For each possible COND value, call ourselves recursively.
-
+
The extra TRUE and FALSE expressions will be eliminated by another
call to the simplification routine. */
insn_code, insn_index),
insn_code, insn_index);
newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
+ break;
+
+ default:
+ gcc_unreachable ();
}
- else
- abort ();
/* If uses an address, must return original expression. But set the
ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
return !(XINT (s2, 0) &~ XINT (s1, 0));
default:
- abort ();
+ gcc_unreachable ();
}
}
/* Returns true if S1 is a subset of complement of S2. */
-static bool attr_alt_subset_of_compl_p (rtx s1, rtx s2)
+static bool
+attr_alt_subset_of_compl_p (rtx s1, rtx s2)
{
switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
{
return false;
default:
- abort ();
+ gcc_unreachable ();
}
}
XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
break;
default:
- abort ();
+ gcc_unreachable ();
}
XINT (result, 1) = XINT (s1, 1) & XINT (s2, 1);
XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
break;
default:
- abort ();
+ gcc_unreachable ();
}
XINT (result, 1) = XINT (s1, 1) | XINT (s2, 1);
&& (attr = find_attr (&XSTR (exp, 0), 0)) != NULL)
for (av = attr->first_value; av; av = av->next)
for (ie = av->first_insn; ie; ie = ie->next)
- if (ie->insn_code == insn_code)
+ if (ie->def->insn_code == insn_code)
{
rtx x;
x = evaluate_eq_attr (exp, av->value, insn_code, insn_index);
iv->attr = attr;
iv->av = av;
iv->ie = ie;
- iv->next = insn_code_values[ie->insn_code];
- insn_code_values[ie->insn_code] = iv;
+ iv->next = insn_code_values[ie->def->insn_code];
+ insn_code_values[ie->def->insn_code] = iv;
iv++;
}
/* Sanity check on num_insn_ents. */
- if (iv != ivbuf + num_insn_ents)
- abort ();
+ gcc_assert (iv == ivbuf + num_insn_ents);
/* Process one insn code at a time. */
for (i = -2; i < insn_code_number; i++)
newexp = av->value;
while (GET_CODE (newexp) == COND)
{
- rtx newexp2 = simplify_cond (newexp, ie->insn_code,
- ie->insn_index);
+ rtx newexp2 = simplify_cond (newexp, ie->def->insn_code,
+ ie->def->insn_index);
if (newexp2 == newexp)
break;
newexp = newexp2;
{
newexp = attr_copy_rtx (newexp);
remove_insn_ent (av, ie);
- av = get_attr_value (newexp, attr, ie->insn_code);
+ av = get_attr_value (newexp, attr, ie->def->insn_code);
iv->av = av;
insert_insn_ent (av, ie);
}
break;
default:
- abort ();
+ gcc_unreachable ();
}
}
printf (" >> ");
break;
default:
- abort ();
+ gcc_unreachable ();
}
write_test_expr (XEXP (exp, 1), flags | comparison_operator);
printf ("-");
break;
default:
- abort ();
+ gcc_unreachable ();
}
write_test_expr (XEXP (exp, 0), flags);
}
attr = find_attr (&XSTR (exp, 0), 0);
- if (! attr)
- abort ();
+ gcc_assert (attr);
/* Now is the time to expand the value of a constant attribute. */
if (attr->is_const)
/* A random C expression. */
case SYMBOL_REF:
- printf ("%s", XSTR (exp, 0));
+ print_c_condition (XSTR (exp, 0));
break;
/* The address of the branch target. */
printf ("static ");
if (!attr->is_numeric)
printf ("enum attr_%s\n", attr->name);
- else if (attr->unsigned_p)
- printf ("unsigned int\n");
else
printf ("int\n");
for (av = attr->first_value; av; av = av->next)
if (av->num_insns != 0)
write_attr_set (attr, 2, av->value, "return", ";",
- true_rtx, av->first_insn->insn_code,
- av->first_insn->insn_index);
+ true_rtx, av->first_insn->def->insn_code,
+ av->first_insn->def->insn_index);
printf ("}\n\n");
return;
}
}
+/* Write a series of case statements for every instruction in list IE.
+ INDENT is the amount of indentation to write before each case. */
+
+static void
+write_insn_cases (struct insn_ent *ie, int indent)
+{
+ for (; ie != 0; ie = ie->next)
+ if (ie->def->insn_code != -1)
+ {
+ write_indent (indent);
+ if (GET_CODE (ie->def->def) == DEFINE_PEEPHOLE)
+ printf ("case %d: /* define_peephole, line %d */\n",
+ ie->def->insn_code, ie->def->lineno);
+ else
+ printf ("case %d: /* %s */\n",
+ ie->def->insn_code, XSTR (ie->def->def, 0));
+ }
+}
+
/* Write out the computation for one attribute value. */
static void
int write_case_lines, const char *prefix, const char *suffix,
int indent, rtx known_true)
{
- struct insn_ent *ie;
-
if (av->num_insns == 0)
return;
}
if (write_case_lines)
- {
- for (ie = av->first_insn; ie; ie = ie->next)
- if (ie->insn_code != -1)
- {
- write_indent (indent);
- printf ("case %d:\n", ie->insn_code);
- }
- }
+ write_insn_cases (av->first_insn, indent);
else
{
write_indent (indent);
}
write_attr_set (attr, indent + 2, av->value, prefix, suffix,
- known_true, av->first_insn->insn_code,
- av->first_insn->insn_index);
+ known_true, av->first_insn->def->insn_code,
+ av->first_insn->def->insn_index);
if (strncmp (prefix, "return", 6))
{
if (!attr->is_numeric)
printf (" enum attr_%s ", attr->name);
- else if (attr->unsigned_p)
- printf (" unsigned int ");
else
printf (" int ");
break;
case SYMBOL_REF:
- fputs (XSTR (value, 0), stdout);
+ print_c_condition (XSTR (value, 0));
break;
case ATTR:
break;
default:
- abort ();
+ gcc_unreachable ();
}
}
printf ("{\n");
printf (" rtx insn;\n");
printf ("\n");
- printf (" if (slot >= %d)\n", max_slots);
- printf (" abort ();\n");
+ printf (" gcc_assert (slot < %d);\n", max_slots);
printf ("\n");
/* Allow dbr_schedule to pass labels, etc. This can happen if try_split
converts a compound instruction into a loop. */
if (num_delays > 1)
{
attr = find_attr (&delay_type_str, 0);
- if (! attr)
- abort ();
+ gcc_assert (attr);
common_av = find_most_used (attr);
printf (" insn = delay_insn;\n");
printf (" }\n\n");
/* Ensure matched. Otherwise, shouldn't have been called. */
- printf (" if (slot < %d)\n", max_slots);
- printf (" abort ();\n\n");
+ printf (" gcc_assert (slot >= %d);\n\n", max_slots);
}
/* If just one type of delay slot, write simple switch. */
printf (" {\n");
attr = find_attr (&delay_1_0_str, 0);
- if (! attr)
- abort ();
+ gcc_assert (attr);
common_av = find_most_used (attr);
for (av = attr->first_value; av; av = av->next)
sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
pstr = str;
attr = find_attr (&pstr, 0);
- if (! attr)
- abort ();
+ gcc_assert (attr);
common_av = find_most_used (attr);
for (av = attr->first_value; av; av = av->next)
}
printf (" default:\n");
- printf (" abort ();\n");
+ printf (" gcc_unreachable ();\n");
printf (" }\n");
}
attr = oballoc (sizeof (struct attr_desc));
attr->name = DEF_ATTR_STRING (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->static_p = 0;
+ attr->is_numeric = attr->is_const = attr->is_special = 0;
+ attr->static_p = 0;
attr->next = attrs[index];
attrs[index] = attr;
struct attr_desc *attr;
attr = find_attr (&name, 1);
- if (attr->default_val)
- abort ();
+ gcc_assert (!attr->default_val);
attr->is_numeric = 1;
attr->is_const = 0;
attr->is_special = (special & ATTR_SPECIAL) != 0;
- attr->negative_ok = (special & ATTR_NEGATIVE_OK) != 0;
- attr->unsigned_p = (special & ATTR_UNSIGNED) != 0;
attr->static_p = (special & ATTR_STATIC) != 0;
attr->default_val = get_attr_value (value, attr, -2);
}
rtx exp;
char *p;
- if (n < 0)
- abort ();
+ gcc_assert (n >= 0);
if (n < 20 && int_values[n])
return int_values[n];
{
struct attr_desc *attr = find_attr (&num_delay_slots_str, 0);
struct attr_value *av;
- struct insn_ent *ie;
if (attr)
{
length_used = 0;
walk_attr_value (av->value);
if (length_used)
- {
- for (ie = av->first_insn; ie; ie = ie->next)
- if (ie->insn_code != -1)
- printf (" case %d:\n", ie->insn_code);
- printf (" return 0;\n");
- }
+ write_insn_cases (av->first_insn, 4);
}
printf (" default:\n");