summaryrefslogtreecommitdiff
path: root/gcc/genattrtab.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/genattrtab.c')
-rw-r--r--gcc/genattrtab.c131
1 files changed, 66 insertions, 65 deletions
diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c
index b0ebb4623e6..c41c6b273d7 100644
--- a/gcc/genattrtab.c
+++ b/gcc/genattrtab.c
@@ -211,7 +211,6 @@ struct attr_value_list **insn_code_values;
/* Other variables. */
-static int insn_code_number;
static int insn_index_number;
static int got_define_asm_attributes;
static int must_extract;
@@ -1016,7 +1015,7 @@ check_attr_value (rtx exp, struct attr_desc *attr)
struct attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
if (attr2 == NULL)
error_at (attr->loc, "unknown attribute `%s' in ATTR",
- XSTR (exp, 0));
+ XSTR (exp, 0));
else if (attr->is_const && ! attr2->is_const)
error_at (attr->loc,
"non-constant attribute `%s' referenced from `%s'",
@@ -2950,10 +2949,11 @@ get_attr_order (struct attr_desc ***ret)
/* Optimize the attribute lists by seeing if we can determine conditional
values from the known values of other attributes. This will save subroutine
- calls during the compilation. */
+ calls during the compilation. MAX_INSN_CODE is the number of unique
+ instruction codes. */
static void
-optimize_attrs (void)
+optimize_attrs (int max_insn_code)
{
struct attr_desc *attr;
struct attr_value *av;
@@ -2972,7 +2972,7 @@ optimize_attrs (void)
return;
/* Make 2 extra elements, for "code" values -2 and -1. */
- insn_code_values = XCNEWVEC (struct attr_value_list *, insn_code_number + 2);
+ insn_code_values = XCNEWVEC (struct attr_value_list *, max_insn_code + 2);
/* Offset the table address so we can index by -2 or -1. */
insn_code_values += 2;
@@ -3000,7 +3000,7 @@ optimize_attrs (void)
gcc_assert (iv == ivbuf + num_insn_ents);
/* Process one insn code at a time. */
- for (i = -2; i < insn_code_number; i++)
+ for (i = -2; i < max_insn_code; i++)
{
/* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
We use it to mean "already simplified for this insn". */
@@ -3126,63 +3126,64 @@ add_attr_value (struct attr_desc *attr, const char *name)
/* Create table entries for DEFINE_ATTR or DEFINE_ENUM_ATTR. */
static void
-gen_attr (rtx exp, int lineno)
+gen_attr (md_rtx_info *info)
{
struct enum_type *et;
struct enum_value *ev;
struct attr_desc *attr;
const char *name_ptr;
char *p;
+ rtx def = info->def;
/* Make a new attribute structure. Check for duplicate by looking at
attr->default_val, since it is initialized by this routine. */
- attr = find_attr (&XSTR (exp, 0), 1);
+ attr = find_attr (&XSTR (def, 0), 1);
if (attr->default_val)
{
- error_with_line (lineno, "duplicate definition for attribute %s",
- attr->name);
+ error_at (info->loc, "duplicate definition for attribute %s",
+ attr->name);
message_at (attr->loc, "previous definition");
return;
}
- attr->loc = file_location (read_md_filename, lineno);
+ attr->loc = info->loc;
- if (GET_CODE (exp) == DEFINE_ENUM_ATTR)
+ if (GET_CODE (def) == DEFINE_ENUM_ATTR)
{
- attr->enum_name = XSTR (exp, 1);
- et = lookup_enum_type (XSTR (exp, 1));
+ attr->enum_name = XSTR (def, 1);
+ et = lookup_enum_type (XSTR (def, 1));
if (!et || !et->md_p)
- error_with_line (lineno, "No define_enum called `%s' defined",
- attr->name);
+ error_at (info->loc, "No define_enum called `%s' defined",
+ attr->name);
if (et)
for (ev = et->values; ev; ev = ev->next)
add_attr_value (attr, ev->name);
}
- else if (*XSTR (exp, 1) == '\0')
+ else if (*XSTR (def, 1) == '\0')
attr->is_numeric = 1;
else
{
- name_ptr = XSTR (exp, 1);
+ name_ptr = XSTR (def, 1);
while ((p = next_comma_elt (&name_ptr)) != NULL)
add_attr_value (attr, p);
}
- if (GET_CODE (XEXP (exp, 2)) == CONST)
+ if (GET_CODE (XEXP (def, 2)) == CONST)
{
attr->is_const = 1;
if (attr->is_numeric)
- error_with_line (lineno,
- "constant attributes may not take numeric values");
+ error_at (info->loc,
+ "constant attributes may not take numeric values");
/* Get rid of the CONST node. It is allowed only at top-level. */
- XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0);
+ XEXP (def, 2) = XEXP (XEXP (def, 2), 0);
}
if (! strcmp_check (attr->name, length_str) && ! attr->is_numeric)
- error_with_line (lineno, "`length' attribute must take numeric values");
+ error_at (info->loc, "`length' attribute must take numeric values");
/* Set up the default value. */
- XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
- attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
+ XEXP (def, 2) = check_attr_value (XEXP (def, 2), attr);
+ attr->default_val = get_attr_value (XEXP (def, 2), attr, -2);
}
/* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
@@ -3258,31 +3259,32 @@ compares_alternatives_p (rtx exp)
/* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
static void
-gen_insn (rtx exp, int lineno)
+gen_insn (md_rtx_info *info)
{
struct insn_def *id;
+ rtx def = info->def;
id = oballoc (struct insn_def);
id->next = defs;
defs = id;
- id->def = exp;
- id->loc = file_location (read_md_filename, lineno);
+ id->def = def;
+ id->loc = info->loc;
- switch (GET_CODE (exp))
+ switch (GET_CODE (def))
{
case DEFINE_INSN:
- id->insn_code = insn_code_number;
+ id->insn_code = info->index;
id->insn_index = insn_index_number;
- id->num_alternatives = count_alternatives (exp);
+ id->num_alternatives = count_alternatives (def);
if (id->num_alternatives == 0)
id->num_alternatives = 1;
id->vec_idx = 4;
break;
case DEFINE_PEEPHOLE:
- id->insn_code = insn_code_number;
+ id->insn_code = info->index;
id->insn_index = insn_index_number;
- id->num_alternatives = count_alternatives (exp);
+ id->num_alternatives = count_alternatives (def);
if (id->num_alternatives == 0)
id->num_alternatives = 1;
id->vec_idx = 3;
@@ -3305,16 +3307,16 @@ gen_insn (rtx exp, int lineno)
true or annul false is specified, and make a `struct delay_desc'. */
static void
-gen_delay (rtx def, int lineno)
+gen_delay (md_rtx_info *info)
{
struct delay_desc *delay;
int i;
+ rtx def = info->def;
if (XVECLEN (def, 1) % 3 != 0)
{
- error_with_line (lineno,
- "number of elements in DEFINE_DELAY must"
- " be multiple of three");
+ error_at (info->loc, "number of elements in DEFINE_DELAY must"
+ " be multiple of three");
return;
}
@@ -3330,7 +3332,7 @@ gen_delay (rtx def, int lineno)
delay->def = def;
delay->num = ++num_delays;
delay->next = delays;
- delay->loc = file_location (read_md_filename, lineno);
+ delay->loc = info->loc;
delays = delay;
}
@@ -4723,14 +4725,14 @@ static size_t n_insn_reservs;
/* Store information from a DEFINE_INSN_RESERVATION for future
attribute generation. */
static void
-gen_insn_reserv (rtx def, int lineno)
+gen_insn_reserv (md_rtx_info *info)
{
struct insn_reserv *decl = oballoc (struct insn_reserv);
- file_location loc (read_md_filename, lineno);
+ rtx def = info->def;
decl->name = DEF_ATTR_STRING (XSTR (def, 0));
decl->default_latency = XINT (def, 1);
- decl->condexp = check_attr_test (XEXP (def, 2), 0, loc);
+ decl->condexp = check_attr_test (XEXP (def, 2), 0, info->loc);
decl->insn_num = n_insn_reservs;
decl->bypassed = false;
decl->next = 0;
@@ -4776,10 +4778,11 @@ gen_bypass_1 (const char *s, size_t len)
}
static void
-gen_bypass (rtx def)
+gen_bypass (md_rtx_info *info)
{
const char *p, *base;
+ rtx def = info->def;
for (p = base = XSTR (def, 1); *p; p++)
if (*p == ',')
{
@@ -5150,11 +5153,10 @@ handle_arg (const char *arg)
int
main (int argc, char **argv)
{
- rtx desc;
struct attr_desc *attr;
struct insn_def *id;
- rtx tem;
int i;
+ int max_insn_code = 0;
progname = "genattrtab";
@@ -5184,57 +5186,56 @@ main (int argc, char **argv)
/* Read the machine description. */
- while (1)
+ md_rtx_info info;
+ while (read_md_rtx (&info))
{
- int lineno;
-
- desc = read_md_rtx (&lineno, &insn_code_number);
- if (desc == NULL)
- break;
-
- switch (GET_CODE (desc))
+ switch (GET_CODE (info.def))
{
case DEFINE_INSN:
case DEFINE_PEEPHOLE:
case DEFINE_ASM_ATTRIBUTES:
- gen_insn (desc, lineno);
+ gen_insn (&info);
break;
case DEFINE_ATTR:
case DEFINE_ENUM_ATTR:
- gen_attr (desc, lineno);
+ gen_attr (&info);
break;
case DEFINE_DELAY:
- gen_delay (desc, lineno);
+ gen_delay (&info);
break;
case DEFINE_INSN_RESERVATION:
- gen_insn_reserv (desc, lineno);
+ gen_insn_reserv (&info);
break;
case DEFINE_BYPASS:
- gen_bypass (desc);
+ gen_bypass (&info);
break;
default:
break;
}
- if (GET_CODE (desc) != DEFINE_ASM_ATTRIBUTES)
+ if (GET_CODE (info.def) != DEFINE_ASM_ATTRIBUTES)
insn_index_number++;
+ max_insn_code = info.index;
}
if (have_error)
return FATAL_EXIT_CODE;
- insn_code_number++;
+ max_insn_code++;
/* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
if (! got_define_asm_attributes)
{
- tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
- XVEC (tem, 0) = rtvec_alloc (0);
- gen_insn (tem, 0);
+ md_rtx_info info;
+ info.def = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
+ XVEC (info.def, 0) = rtvec_alloc (0);
+ info.loc = file_location ("<internal>", 0);
+ info.index = -1;
+ gen_insn (&info);
}
/* Expand DEFINE_DELAY information into new attribute. */
@@ -5242,14 +5243,14 @@ main (int argc, char **argv)
expand_delays ();
/* Make `insn_alternatives'. */
- insn_alternatives = oballocvec (uint64_t, insn_code_number);
+ insn_alternatives = oballocvec (uint64_t, max_insn_code);
for (id = defs; id; id = id->next)
if (id->insn_code >= 0)
insn_alternatives[id->insn_code]
= (((uint64_t) 1) << id->num_alternatives) - 1;
/* Make `insn_n_alternatives'. */
- insn_n_alternatives = oballocvec (int, insn_code_number);
+ insn_n_alternatives = oballocvec (int, max_insn_code);
for (id = defs; id; id = id->next)
if (id->insn_code >= 0)
insn_n_alternatives[id->insn_code] = id->num_alternatives;
@@ -5278,7 +5279,7 @@ main (int argc, char **argv)
make_length_attrs ();
/* Perform any possible optimizations to speed up compilation. */
- optimize_attrs ();
+ optimize_attrs (max_insn_code);
/* Now write out all the `gen_attr_...' routines. Do these before the
special routines so that they get defined before they are used. */