+2015-07-16 Richard Sandiford <richard.sandiford@arm.com>
+
+ * read-md.h (message_with_line, error_with_line): Delete.
+ * read-md.c (message_with_line, error_with_line): Delete.
+ * gensupport.h: Include read-md.h.
+ (md_rtx_info): New structure.
+ (read_md_rtx): Use it. Return a bool success value.
+ * gensupport.c (read_md_rtx): Likewise.
+ * genattr-common.c (gen_attr): Take an md_rtx_info rather than an rtx.
+ (main): Update after interface changes.
+ * genattr.c (gen_attr): Take an md_rtx_info rather than an rtx.
+ (main): Update after interface changes.
+ * genattrtab.c (insn_code_number): Delete.
+ (optimize_attrs): Add a max_insn_code parameter and use it instead
+ of insn_code_number.
+ (gen_attr): Take an md_rtx_info rather than an rtx and lineno.
+ Use *_at rather than *_with_line functions.
+ (gen_insn): Likewise.
+ (gen_delay): Likewise.
+ (gen_insn_reserv): Likewise.
+ (gen_bypass): Take an md_rtx_info rather than an rtx.
+ (main): Update after interface changes. Use a local max_insn_code
+ variable instead of insn_code_number.
+ * genautomata.c (gen_cpu_unit): Take an md_rtx_info rather than
+ an rtx. Use fatal_at rather than fatal.
+ (gen_query_cpu_unit, gen_bypass, gen_excl_set)
+ (gen_presence_absence_set, gen_presence_set, gen_final_presence_set)
+ (gen_absence_set, gen_final_absence_set, gen_automaton)
+ (gen_automata_option, gen_reserv, gen_insn_reserv): Likewise.
+ (main): Update after interface changes.
+ * gencodes.c (gen_insn): Take an md_rtx_info rather than an rtx
+ and code number.
+ (main): Update after interface changes.
+ * genconditions.c (main): Use new read_md_rtx interface.
+ * genconfig.c (gen_insn): Take an md_rtx_info rather than an rtx.
+ (gen_expand, gen_split, gen_peephole, gen_peephole2): Likewise.
+ (main): Update after interface changes.
+ * genemit.c (insn_code_number, insn_index_number): Delete.
+ (gen_insn): Take an md_rtx_info rather than an rtx and lineno.
+ Use fatal_at rather than fatal.
+ (gen_expand): Take an md_rtx_info rather than an rtx. Use fatal_at
+ rather than fatal.
+ (gen_split): Likewise.
+ (main): Update after interface changes.
+ * genextract.c (line_no): Delete.
+ (gen_insn): Take an md_rtx_info rather than an rtx and lineno.
+ Update call to walk_rtx.
+ (VEC_safe_set_locstr): Add an md_rtx_info argument. Use message_at
+ rather than message_with_line.
+ (walk_rtx): Add an md_rtx_info argument. Update call to
+ VEC_safe_set_locstr.
+ (main): Update after interface changes.
+ * genflags.c (gen_insn): Take an md_rtx_info rather than an rtx
+ and lineno. Use error_at rather than separate message_with_line
+ calls and have_error assignments.
+ (main): Update after interface changes.
+ * genmddump.c (main): Use new read_md_rtx interface.
+ * genopinit.c (insn): Take an md_rtx_info rather than an rtx.
+ (main): Update after interface changes.
+ * genoutput.c (next_code_number): Delete.
+ (gen_insn): Take an md_rtx_info rather than an rtx and lineno.
+ (gen_peephole, gen_expand, gen_split): Likewise.
+ (note_constraint): Likewise. Use *_at rather than *_with_line
+ functions.
+ (main): Update after interface changes.
+ * genpeep.c (gen_peephole): Take an md_rtx_info rather than an
+ rtx and lineno.
+ (main): Update after interface changes.
+ * genpreds.c (process_define_predicate): Take an md_rtx_info rather
+ than an rtx and lineno.
+ (process_define_constraint): Likewise.
+ (process_define_register_constraint): Likewise.
+ (main): Update after interface changes.
+ * genrecog.c (next_insn_code, pattern_lineno): Delete.
+ (validate_pattern): Replace top-level rtx with an md_rtx_info.
+ Use *_at rather than *_with_line functions.
+ (match_pattern_2): Likewise.
+ (match_pattern_1, match_pattern): Add an md_rtx_info parameter.
+ (get_peephole2_pattern): Take an md_rtx_info rather than an rtvec.
+ Use *_at rather than *_with_line functions.
+ * gentarget-def.c (add_insn): New function.
+ (main): Use it. Use new read_md_rtx interface.
+
2015-07-16 Richard Sandiford <richard.sandiford@arm.com>
* gensupport.h (compute_test_codes): Take a file_location rather
}
static void
-gen_attr (rtx attr)
+gen_attr (md_rtx_info *info)
{
const char *p, *tag;
+ rtx attr = info->def;
p = XSTR (attr, 1);
if (*p != '\0')
{
int
main (int argc, char **argv)
{
- rtx desc;
bool have_delay = false;
bool have_sched = false;
/* Read the machine description. */
- while (1)
- {
- int line_no, insn_code_number;
+ md_rtx_info info;
+ while (read_md_rtx (&info))
+ switch (GET_CODE (info.def))
+ {
+ case DEFINE_ATTR:
+ gen_attr (&info);
+ break;
- desc = read_md_rtx (&line_no, &insn_code_number);
- if (desc == NULL)
+ case DEFINE_DELAY:
+ if (!have_delay)
+ {
+ printf ("#define DELAY_SLOTS\n");
+ have_delay = true;
+ }
break;
- if (GET_CODE (desc) == DEFINE_ATTR)
- gen_attr (desc);
+ case DEFINE_INSN_RESERVATION:
+ if (!have_sched)
+ {
+ printf ("#define INSN_SCHEDULING\n");
+ have_sched = true;
+ }
+ break;
- if (GET_CODE (desc) == DEFINE_DELAY)
- {
- if (!have_delay)
- {
- printf ("#define DELAY_SLOTS\n");
- have_delay = true;
- }
- }
- else if (GET_CODE (desc) == DEFINE_INSN_RESERVATION)
- {
- if (!have_sched)
- {
- printf ("#define INSN_SCHEDULING\n");
- have_sched = true;
- }
- }
- }
+ default:
+ break;
+ }
puts ("\n#endif /* GCC_INSN_ATTR_COMMON_H */");
if (ferror (stdout) || fflush (stdout) || fclose (stdout))
#include "gensupport.h"
-static void gen_attr (rtx);
-
static vec<rtx> const_attrs, reservations;
static void
-gen_attr (rtx attr)
+gen_attr (md_rtx_info *info)
{
const char *p;
+ rtx attr = info->def;
int is_const = GET_CODE (XEXP (attr, 2)) == CONST;
if (is_const)
int
main (int argc, char **argv)
{
- rtx desc;
int have_delay = 0;
int have_annul_true = 0;
int have_annul_false = 0;
/* Read the machine description. */
- while (1)
+ md_rtx_info info;
+ while (read_md_rtx (&info))
{
- int line_no, insn_code_number;
-
- desc = read_md_rtx (&line_no, &insn_code_number);
- if (desc == NULL)
- break;
-
- if (GET_CODE (desc) == DEFINE_ATTR
- || GET_CODE (desc) == DEFINE_ENUM_ATTR)
- gen_attr (desc);
+ rtx def = info.def;
+ switch (GET_CODE (def))
+ {
+ case DEFINE_ATTR:
+ case DEFINE_ENUM_ATTR:
+ gen_attr (&info);
+ break;
- else if (GET_CODE (desc) == DEFINE_DELAY)
- {
+ case DEFINE_DELAY:
if (! have_delay)
{
printf ("extern int num_delay_slots (rtx_insn *);\n");
have_delay = 1;
}
- for (i = 0; i < XVECLEN (desc, 1); i += 3)
+ for (i = 0; i < XVECLEN (def, 1); i += 3)
{
- if (XVECEXP (desc, 1, i + 1) && ! have_annul_true)
+ if (XVECEXP (def, 1, i + 1) && ! have_annul_true)
{
printf ("#define ANNUL_IFTRUE_SLOTS\n");
printf ("extern int eligible_for_annul_true (rtx_insn *, int, rtx_insn *, int);\n");
have_annul_true = 1;
}
- if (XVECEXP (desc, 1, i + 2) && ! have_annul_false)
+ if (XVECEXP (def, 1, i + 2) && ! have_annul_false)
{
printf ("#define ANNUL_IFFALSE_SLOTS\n");
printf ("extern int eligible_for_annul_false (rtx_insn *, int, rtx_insn *, int);\n");
have_annul_false = 1;
}
}
- }
+ break;
- else if (GET_CODE (desc) == DEFINE_INSN_RESERVATION)
- {
+ case DEFINE_INSN_RESERVATION:
num_insn_reservations++;
- reservations.safe_push (desc);
+ reservations.safe_push (def);
+ break;
+
+ default:
+ break;
}
}
/* Other variables. */
-static int insn_code_number;
static int insn_index_number;
static int got_define_asm_attributes;
static int must_extract;
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'",
/* 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;
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;
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". */
/* 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
/* 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;
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;
}
delay->def = def;
delay->num = ++num_delays;
delay->next = delays;
- delay->loc = file_location (read_md_filename, lineno);
+ delay->loc = info->loc;
delays = delay;
}
/* 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;
}
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 == ',')
{
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";
/* 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. */
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;
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. */
This gives information about a unit contained in CPU. We fill a
struct unit_decl with information used later by `expand_automata'. */
static void
-gen_cpu_unit (rtx def)
+gen_cpu_unit (md_rtx_info *info)
{
decl_t decl;
char **str_cpu_units;
int vect_length;
int i;
+ rtx def = info->def;
str_cpu_units = get_str_vect (XSTR (def, 0), &vect_length, ',', FALSE);
if (str_cpu_units == NULL)
- fatal ("invalid string `%s' in define_cpu_unit", XSTR (def, 0));
+ fatal_at (info->loc, "invalid string `%s' in %s",
+ XSTR (def, 0), GET_RTX_NAME (GET_CODE (def)));
for (i = 0; i < vect_length; i++)
{
decl = XCREATENODE (struct decl);
This gives information about a unit contained in CPU. We fill a
struct unit_decl with information used later by `expand_automata'. */
static void
-gen_query_cpu_unit (rtx def)
+gen_query_cpu_unit (md_rtx_info *info)
{
decl_t decl;
char **str_cpu_units;
int vect_length;
int i;
+ rtx def = info->def;
str_cpu_units = get_str_vect (XSTR (def, 0), &vect_length, ',',
FALSE);
if (str_cpu_units == NULL)
- fatal ("invalid string `%s' in define_query_cpu_unit", XSTR (def, 0));
+ fatal_at (info->loc, "invalid string `%s' in %s",
+ XSTR (def, 0), GET_RTX_NAME (GET_CODE (def)));
for (i = 0; i < vect_length; i++)
{
decl = XCREATENODE (struct decl);
in a struct bypass_decl with information used later by
`expand_automata'. */
static void
-gen_bypass (rtx def)
+gen_bypass (md_rtx_info *info)
{
decl_t decl;
char **out_patterns;
int in_length;
int i, j;
+ rtx def = info->def;
out_patterns = get_str_vect (XSTR (def, 1), &out_length, ',', FALSE);
if (out_patterns == NULL)
- fatal ("invalid string `%s' in define_bypass", XSTR (def, 1));
+ fatal_at (info->loc, "invalid string `%s' in %s",
+ XSTR (def, 1), GET_RTX_NAME (GET_CODE (def)));
in_patterns = get_str_vect (XSTR (def, 2), &in_length, ',', FALSE);
if (in_patterns == NULL)
- fatal ("invalid string `%s' in define_bypass", XSTR (def, 2));
+ fatal_at (info->loc, "invalid string `%s' in %s",
+ XSTR (def, 2), GET_RTX_NAME (GET_CODE (def)));
for (i = 0; i < out_length; i++)
for (j = 0; j < in_length; j++)
{
struct excl_rel_decl (excl) with information used later by
`expand_automata'. */
static void
-gen_excl_set (rtx def)
+gen_excl_set (md_rtx_info *info)
{
decl_t decl;
char **first_str_cpu_units;
int length;
int i;
+ rtx def = info->def;
first_str_cpu_units
= get_str_vect (XSTR (def, 0), &first_vect_length, ',', FALSE);
if (first_str_cpu_units == NULL)
- fatal ("invalid first string `%s' in exclusion_set", XSTR (def, 0));
+ fatal_at (info->loc, "invalid string `%s' in %s",
+ XSTR (def, 0), GET_RTX_NAME (GET_CODE (def)));
second_str_cpu_units = get_str_vect (XSTR (def, 1), &length, ',',
FALSE);
if (second_str_cpu_units == NULL)
- fatal ("invalid second string `%s' in exclusion_set", XSTR (def, 1));
+ fatal_at (info->loc, "invalid string `%s' in %s",
+ XSTR (def, 1), GET_RTX_NAME (GET_CODE (def)));
length += first_vect_length;
- decl = XCREATENODEVAR (struct decl, sizeof (struct decl) + (length - 1) * sizeof (char *));
+ decl = XCREATENODEVAR (struct decl, (sizeof (struct decl)
+ + (length - 1) * sizeof (char *)));
decl->mode = dm_excl;
decl->pos = 0;
DECL_EXCL (decl)->all_names_num = length;
We fill a struct unit_pattern_rel_decl with information used later
by `expand_automata'. */
static void
-gen_presence_absence_set (rtx def, int presence_p, int final_p)
+gen_presence_absence_set (md_rtx_info *info, int presence_p, int final_p)
{
decl_t decl;
char **str_cpu_units;
int patterns_length;
int i;
+ rtx def = info->def;
str_cpu_units = get_str_vect (XSTR (def, 0), &cpu_units_length, ',',
FALSE);
if (str_cpu_units == NULL)
- fatal ((presence_p
- ? (final_p
- ? "invalid first string `%s' in final_presence_set"
- : "invalid first string `%s' in presence_set")
- : (final_p
- ? "invalid first string `%s' in final_absence_set"
- : "invalid first string `%s' in absence_set")),
- XSTR (def, 0));
+ fatal_at (info->loc, "invalid string `%s' in %s",
+ XSTR (def, 0), GET_RTX_NAME (GET_CODE (def)));
str_pattern_lists = get_str_vect (XSTR (def, 1),
&patterns_length, ',', FALSE);
if (str_pattern_lists == NULL)
- fatal ((presence_p
- ? (final_p
- ? "invalid second string `%s' in final_presence_set"
- : "invalid second string `%s' in presence_set")
- : (final_p
- ? "invalid second string `%s' in final_absence_set"
- : "invalid second string `%s' in absence_set")), XSTR (def, 1));
+ fatal_at (info->loc, "invalid string `%s' in %s",
+ XSTR (def, 1), GET_RTX_NAME (GET_CODE (def)));
str_patterns = XOBNEWVEC (&irp, char **, patterns_length);
for (i = 0; i < patterns_length; i++)
{
/* Process a PRESENCE_SET.
- This gives information about a cpu unit reservation requirements.
+ This gives information about a cpu unit reservation requirements.
We fill a struct unit_pattern_rel_decl (presence) with information
used later by `expand_automata'. */
static void
-gen_presence_set (rtx def)
+gen_presence_set (md_rtx_info *info)
{
- gen_presence_absence_set (def, TRUE, FALSE);
+ gen_presence_absence_set (info, TRUE, FALSE);
}
/* Process a FINAL_PRESENCE_SET.
We fill a struct unit_pattern_rel_decl (presence) with information
used later by `expand_automata'. */
static void
-gen_final_presence_set (rtx def)
+gen_final_presence_set (md_rtx_info *info)
{
- gen_presence_absence_set (def, TRUE, TRUE);
+ gen_presence_absence_set (info, TRUE, TRUE);
}
/* Process an ABSENCE_SET.
We fill a struct unit_pattern_rel_decl (absence) with information
used later by `expand_automata'. */
static void
-gen_absence_set (rtx def)
+gen_absence_set (md_rtx_info *info)
{
- gen_presence_absence_set (def, FALSE, FALSE);
+ gen_presence_absence_set (info, FALSE, FALSE);
}
/* Process a FINAL_ABSENCE_SET.
We fill a struct unit_pattern_rel_decl (absence) with information
used later by `expand_automata'. */
static void
-gen_final_absence_set (rtx def)
+gen_final_absence_set (md_rtx_info *info)
{
- gen_presence_absence_set (def, FALSE, TRUE);
+ gen_presence_absence_set (info, FALSE, TRUE);
}
/* Process a DEFINE_AUTOMATON.
recognizing pipeline hazards. We fill a struct automaton_decl
with information used later by `expand_automata'. */
static void
-gen_automaton (rtx def)
+gen_automaton (md_rtx_info *info)
{
decl_t decl;
char **str_automata;
int vect_length;
int i;
+ rtx def = info->def;
str_automata = get_str_vect (XSTR (def, 0), &vect_length, ',', FALSE);
if (str_automata == NULL)
- fatal ("invalid string `%s' in define_automaton", XSTR (def, 0));
+ fatal_at (info->loc, "invalid string `%s' in %s",
+ XSTR (def, 0), GET_RTX_NAME (GET_CODE (def)));
for (i = 0; i < vect_length; i++)
{
decl = XCREATENODE (struct decl);
This gives information how to generate finite state automaton used
for recognizing pipeline hazards. */
static void
-gen_automata_option (rtx def)
+gen_automata_option (md_rtx_info *info)
{
- if (strcmp (XSTR (def, 0), NO_MINIMIZATION_OPTION + 1) == 0)
+ const char *option = XSTR (info->def, 0);
+ if (strcmp (option, NO_MINIMIZATION_OPTION + 1) == 0)
no_minimization_flag = 1;
- else if (strcmp (XSTR (def, 0), TIME_OPTION + 1) == 0)
+ else if (strcmp (option, TIME_OPTION + 1) == 0)
time_flag = 1;
- else if (strcmp (XSTR (def, 0), STATS_OPTION + 1) == 0)
+ else if (strcmp (option, STATS_OPTION + 1) == 0)
stats_flag = 1;
- else if (strcmp (XSTR (def, 0), V_OPTION + 1) == 0)
+ else if (strcmp (option, V_OPTION + 1) == 0)
v_flag = 1;
- else if (strcmp (XSTR (def, 0), W_OPTION + 1) == 0)
+ else if (strcmp (option, W_OPTION + 1) == 0)
w_flag = 1;
- else if (strcmp (XSTR (def, 0), NDFA_OPTION + 1) == 0)
+ else if (strcmp (option, NDFA_OPTION + 1) == 0)
ndfa_flag = 1;
- else if (strcmp (XSTR (def, 0), COLLAPSE_OPTION + 1) == 0)
+ else if (strcmp (option, COLLAPSE_OPTION + 1) == 0)
collapse_flag = 1;
- else if (strcmp (XSTR (def, 0), NO_COMB_OPTION + 1) == 0)
+ else if (strcmp (option, NO_COMB_OPTION + 1) == 0)
no_comb_flag = 1;
- else if (strcmp (XSTR (def, 0), PROGRESS_OPTION + 1) == 0)
+ else if (strcmp (option, PROGRESS_OPTION + 1) == 0)
progress_flag = 1;
else
- fatal ("invalid option `%s' in automata_option", XSTR (def, 0));
+ fatal_at (info->loc, "invalid option `%s' in %s",
+ option, GET_RTX_NAME (GET_CODE (info->def)));
}
/* Name in reservation to denote absence reservation. */
in a struct reserv_decl with information used later by
`expand_automata'. */
static void
-gen_reserv (rtx def)
+gen_reserv (md_rtx_info *info)
{
decl_t decl;
+ rtx def = info->def;
decl = XCREATENODE (struct decl);
decl->mode = dm_reserv;
decl->pos = 0;
insn. We fill a struct insn_reserv_decl with information used
later by `expand_automata'. */
static void
-gen_insn_reserv (rtx def)
+gen_insn_reserv (md_rtx_info *info)
{
decl_t decl;
+ rtx def = info->def;
decl = XCREATENODE (struct decl);
decl->mode = dm_insn_reserv;
decl->pos = 0;
int
main (int argc, char **argv)
{
- rtx desc;
-
progname = "genautomata";
if (!init_rtx_reader_args_cb (argc, argv, parse_automata_opt))
return (FATAL_EXIT_CODE);
initiate_automaton_gen (argv);
- while (1)
- {
- int lineno;
- int insn_code_number;
-
- desc = read_md_rtx (&lineno, &insn_code_number);
- if (desc == NULL)
+ md_rtx_info info;
+ while (read_md_rtx (&info))
+ switch (GET_CODE (info.def))
+ {
+ case DEFINE_CPU_UNIT:
+ gen_cpu_unit (&info);
break;
- switch (GET_CODE (desc))
- {
- case DEFINE_CPU_UNIT:
- gen_cpu_unit (desc);
- break;
-
- case DEFINE_QUERY_CPU_UNIT:
- gen_query_cpu_unit (desc);
- break;
+ case DEFINE_QUERY_CPU_UNIT:
+ gen_query_cpu_unit (&info);
+ break;
- case DEFINE_BYPASS:
- gen_bypass (desc);
- break;
+ case DEFINE_BYPASS:
+ gen_bypass (&info);
+ break;
- case EXCLUSION_SET:
- gen_excl_set (desc);
- break;
+ case EXCLUSION_SET:
+ gen_excl_set (&info);
+ break;
- case PRESENCE_SET:
- gen_presence_set (desc);
- break;
+ case PRESENCE_SET:
+ gen_presence_set (&info);
+ break;
- case FINAL_PRESENCE_SET:
- gen_final_presence_set (desc);
- break;
+ case FINAL_PRESENCE_SET:
+ gen_final_presence_set (&info);
+ break;
- case ABSENCE_SET:
- gen_absence_set (desc);
- break;
+ case ABSENCE_SET:
+ gen_absence_set (&info);
+ break;
- case FINAL_ABSENCE_SET:
- gen_final_absence_set (desc);
- break;
+ case FINAL_ABSENCE_SET:
+ gen_final_absence_set (&info);
+ break;
- case DEFINE_AUTOMATON:
- gen_automaton (desc);
- break;
+ case DEFINE_AUTOMATON:
+ gen_automaton (&info);
+ break;
- case AUTOMATA_OPTION:
- gen_automata_option (desc);
- break;
+ case AUTOMATA_OPTION:
+ gen_automata_option (&info);
+ break;
- case DEFINE_RESERVATION:
- gen_reserv (desc);
- break;
+ case DEFINE_RESERVATION:
+ gen_reserv (&info);
+ break;
- case DEFINE_INSN_RESERVATION:
- gen_insn_reserv (desc);
- break;
+ case DEFINE_INSN_RESERVATION:
+ gen_insn_reserv (&info);
+ break;
- default:
- break;
- }
- }
+ default:
+ break;
+ }
if (have_error)
return FATAL_EXIT_CODE;
#include "gensupport.h"
static void
-gen_insn (rtx insn, int code)
+gen_insn (md_rtx_info *info)
{
- const char *name = XSTR (insn, 0);
- int truth = maybe_eval_c_test (XSTR (insn, 2));
+ const char *name = XSTR (info->def, 0);
+ int truth = maybe_eval_c_test (XSTR (info->def, 2));
/* Don't mention instructions whose names are the null string
or begin with '*'. They are in the machine description just
if (truth == 0)
printf ("#define CODE_FOR_%s CODE_FOR_nothing\n", name);
else
- printf (" CODE_FOR_%s = %d,\n", name, code);
+ printf (" CODE_FOR_%s = %d,\n", name, info->index);
}
}
int
main (int argc, char **argv)
{
- rtx desc;
int last = 1;
progname = "gencodes";
/* Read the machine description. */
- while (1)
- {
- int line_no;
- int insn_code_number;
-
- desc = read_md_rtx (&line_no, &insn_code_number);
- if (desc == NULL)
+ md_rtx_info info;
+ while (read_md_rtx (&info))
+ switch (GET_CODE (info.def))
+ {
+ case DEFINE_INSN:
+ case DEFINE_EXPAND:
+ gen_insn (&info);
+ last = info.index + 1;
break;
- if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
- {
- gen_insn (desc, insn_code_number);
- last = insn_code_number + 1;
- }
+ default:
+ break;
}
printf (" LAST_INSN_CODE = %d\n\
int
main (int argc, char **argv)
{
- rtx desc;
- int pattern_lineno; /* not used */
- int code;
-
progname = "genconditions";
if (!init_rtx_reader_args (argc, argv))
return (FATAL_EXIT_CODE);
/* Read the machine description. */
- while (1)
+ md_rtx_info info;
+ while (read_md_rtx (&info))
{
- desc = read_md_rtx (&pattern_lineno, &code);
- if (desc == NULL)
- break;
-
+ rtx def = info.def;
/* N.B. define_insn_and_split, define_cond_exec are handled
entirely within read_md_rtx; we never see them. */
- switch (GET_CODE (desc))
+ switch (GET_CODE (def))
{
- default:
- break;
-
case DEFINE_INSN:
case DEFINE_EXPAND:
- add_c_test (XSTR (desc, 2), -1);
+ add_c_test (XSTR (def, 2), -1);
/* except.h needs to know whether there is an eh_return
pattern in the machine description. */
- if (!strcmp (XSTR (desc, 0), "eh_return"))
+ if (!strcmp (XSTR (def, 0), "eh_return"))
saw_eh_return = 1;
break;
case DEFINE_SPLIT:
case DEFINE_PEEPHOLE:
case DEFINE_PEEPHOLE2:
- add_c_test (XSTR (desc, 1), -1);
+ add_c_test (XSTR (def, 1), -1);
+ break;
+
+ default:
break;
}
}
static int dup_operands_seen_this_insn;
static void walk_insn_part (rtx, int, int);
-static void gen_insn (rtx);
-static void gen_expand (rtx);
-static void gen_split (rtx);
-static void gen_peephole (rtx);
-static void gen_peephole2 (rtx);
/* RECOG_P will be nonzero if this pattern was seen in a context where it will
be used to recognize, rather than just generate an insn.
}
static void
-gen_insn (rtx insn)
+gen_insn (md_rtx_info *info)
{
int i;
/* Walk the insn pattern to gather the #define's status. */
+ rtx insn = info->def;
clobbers_seen_this_insn = 0;
dup_operands_seen_this_insn = 0;
if (XVEC (insn, 1) != 0)
/* Similar but scan a define_expand. */
static void
-gen_expand (rtx insn)
+gen_expand (md_rtx_info *info)
{
int i;
/* Note that we don't bother recording the number of MATCH_DUPs
that occur in a gen_expand, because only reload cares about that. */
+ rtx insn = info->def;
if (XVEC (insn, 1) != 0)
for (i = 0; i < XVECLEN (insn, 1); i++)
{
/* Similar but scan a define_split. */
static void
-gen_split (rtx split)
+gen_split (md_rtx_info *info)
{
int i;
/* Look through the patterns that are matched
to compute the maximum operand number. */
+ rtx split = info->def;
for (i = 0; i < XVECLEN (split, 0); i++)
walk_insn_part (XVECEXP (split, 0, i), 1, 0);
/* Look at the number of insns this insn could split into. */
}
static void
-gen_peephole (rtx peep)
+gen_peephole (md_rtx_info *info)
{
int i;
/* Look through the patterns that are matched
to compute the maximum operand number. */
+ rtx peep = info->def;
for (i = 0; i < XVECLEN (peep, 0); i++)
walk_insn_part (XVECEXP (peep, 0, i), 1, 0);
}
static void
-gen_peephole2 (rtx peep)
+gen_peephole2 (md_rtx_info *info)
{
int i, n;
/* Look through the patterns that are matched
to compute the maximum operand number. */
+ rtx peep = info->def;
for (i = XVECLEN (peep, 0) - 1; i >= 0; --i)
walk_insn_part (XVECEXP (peep, 0, i), 1, 0);
int
main (int argc, char **argv)
{
- rtx desc;
-
progname = "genconfig";
if (!init_rtx_reader_args (argc, argv))
/* Read the machine description. */
- while (1)
- {
- int line_no, insn_code_number = 0;
+ md_rtx_info info;
+ while (read_md_rtx (&info))
+ switch (GET_CODE (info.def))
+ {
+ case DEFINE_INSN:
+ gen_insn (&info);
+ break;
- desc = read_md_rtx (&line_no, &insn_code_number);
- if (desc == NULL)
+ case DEFINE_EXPAND:
+ gen_expand (&info);
break;
- switch (GET_CODE (desc))
- {
- case DEFINE_INSN:
- gen_insn (desc);
- break;
-
- case DEFINE_EXPAND:
- gen_expand (desc);
- break;
-
- case DEFINE_SPLIT:
- gen_split (desc);
- break;
-
- case DEFINE_PEEPHOLE2:
- have_peephole2_flag = 1;
- gen_peephole2 (desc);
- break;
-
- case DEFINE_PEEPHOLE:
- have_peephole_flag = 1;
- gen_peephole (desc);
- break;
-
- default:
- break;
- }
- }
+ case DEFINE_SPLIT:
+ gen_split (&info);
+ break;
+
+ case DEFINE_PEEPHOLE2:
+ have_peephole2_flag = 1;
+ gen_peephole2 (&info);
+ break;
+
+ case DEFINE_PEEPHOLE:
+ have_peephole_flag = 1;
+ gen_peephole (&info);
+ break;
+
+ default:
+ break;
+ }
printf ("#define MAX_RECOG_OPERANDS %d\n", max_recog_operands + 1);
printf ("#define MAX_DUP_OPERANDS %d\n", max_dup_operands);
#include "gensupport.h"
-static int insn_code_number;
-static int insn_index_number;
-
/* Data structure for recording the patterns of insns that have CLOBBERs.
We use this to output a function that adds these CLOBBERs to a
previously-allocated PARALLEL expression. */
/* Generate the `gen_...' function for a DEFINE_INSN. */
static void
-gen_insn (rtx insn, int lineno)
+gen_insn (md_rtx_info *info)
{
struct pattern_stats stats;
int i;
registers or MATCH_SCRATCHes. If so, store away the information for
later. */
+ rtx insn = info->def;
if (XVEC (insn, 1))
{
int has_hard_reg = 0;
struct clobber_ent *link = XNEW (struct clobber_ent);
int j;
- link->code_number = insn_code_number;
+ link->code_number = info->index;
/* See if any previous CLOBBER_LIST entry is the same as this
one. */
if (XSTR (insn, 0)[0] == 0 || XSTR (insn, 0)[0] == '*')
return;
- printf ("/* %s:%d */\n", read_md_filename, lineno);
+ printf ("/* %s:%d */\n", info->loc.filename, info->loc.lineno);
/* Find out how many operands this function has. */
get_pattern_stats (&stats, XVEC (insn, 1));
if (stats.max_dup_opno > stats.max_opno)
- fatal ("match_dup operand number has no match_operand");
+ fatal_at (info->loc, "match_dup operand number has no match_operand");
/* Output the function name and argument declarations. */
printf ("rtx\ngen_%s (", XSTR (insn, 0));
/* Generate the `gen_...' function for a DEFINE_EXPAND. */
static void
-gen_expand (rtx expand)
+gen_expand (md_rtx_info *info)
{
struct pattern_stats stats;
int i;
char *used;
+ rtx expand = info->def;
if (strlen (XSTR (expand, 0)) == 0)
- fatal ("define_expand lacks a name");
+ fatal_at (info->loc, "define_expand lacks a name");
if (XVEC (expand, 1) == 0)
- fatal ("define_expand for %s lacks a pattern", XSTR (expand, 0));
+ fatal_at (info->loc, "define_expand for %s lacks a pattern",
+ XSTR (expand, 0));
/* Find out how many operands this function has. */
get_pattern_stats (&stats, XVEC (expand, 1));
/* Like gen_expand, but generates insns resulting from splitting SPLIT. */
static void
-gen_split (rtx split)
+gen_split (md_rtx_info *info)
{
struct pattern_stats stats;
int i;
+ rtx split = info->def;
const char *const name =
((GET_CODE (split) == DEFINE_PEEPHOLE2) ? "peephole2" : "split");
const char *unused;
char *used;
if (XVEC (split, 0) == 0)
- fatal ("define_%s (definition %d) lacks a pattern", name,
- insn_index_number);
+ fatal_at (info->loc, "%s lacks a pattern",
+ GET_RTX_NAME (GET_CODE (split)));
else if (XVEC (split, 2) == 0)
- fatal ("define_%s (definition %d) lacks a replacement pattern", name,
- insn_index_number);
+ fatal_at (info->loc, "%s lacks a replacement pattern",
+ GET_RTX_NAME (GET_CODE (split)));
/* Find out how many operands this function has. */
if (GET_CODE (split) == DEFINE_PEEPHOLE2)
{
printf ("extern rtx_insn *gen_%s_%d (rtx_insn *, rtx *);\n",
- name, insn_code_number);
- printf ("rtx_insn *\ngen_%s_%d (rtx_insn *curr_insn ATTRIBUTE_UNUSED, rtx *operands%s)\n",
- name, insn_code_number, unused);
+ name, info->index);
+ printf ("rtx_insn *\ngen_%s_%d (rtx_insn *curr_insn ATTRIBUTE_UNUSED,"
+ " rtx *operands%s)\n",
+ name, info->index, unused);
}
else
{
printf ("extern rtx_insn *gen_split_%d (rtx_insn *, rtx *);\n",
- insn_code_number);
+ info->index);
printf ("rtx_insn *\ngen_split_%d "
"(rtx_insn *curr_insn ATTRIBUTE_UNUSED, rtx *operands%s)\n",
- insn_code_number, unused);
+ info->index, unused);
}
printf ("{\n");
printf (" if (dump_file)\n");
printf (" fprintf (dump_file, \"Splitting with gen_%s_%d\\n\");\n",
- name, insn_code_number);
+ name, info->index);
printf (" start_sequence ();\n");
int
main (int argc, char **argv)
{
- rtx desc;
-
progname = "genemit";
if (!init_rtx_reader_args (argc, argv))
/* Assign sequential codes to all entries in the machine description
in parallel with the tables in insn-output.c. */
- insn_code_number = 0;
- insn_index_number = 0;
-
printf ("/* Generated automatically by the program `genemit'\n\
from the machine description file `md'. */\n\n");
/* Read the machine description. */
- while (1)
- {
- int line_no;
-
- desc = read_md_rtx (&line_no, &insn_code_number);
- if (desc == NULL)
+ md_rtx_info info;
+ while (read_md_rtx (&info))
+ switch (GET_CODE (info.def))
+ {
+ case DEFINE_INSN:
+ gen_insn (&info);
break;
- switch (GET_CODE (desc))
- {
- case DEFINE_INSN:
- gen_insn (desc, line_no);
- break;
-
- case DEFINE_EXPAND:
- printf ("/* %s:%d */\n", read_md_filename, line_no);
- gen_expand (desc);
- break;
+ case DEFINE_EXPAND:
+ printf ("/* %s:%d */\n", info.loc.filename, info.loc.lineno);
+ gen_expand (&info);
+ break;
- case DEFINE_SPLIT:
- printf ("/* %s:%d */\n", read_md_filename, line_no);
- gen_split (desc);
- break;
+ case DEFINE_SPLIT:
+ printf ("/* %s:%d */\n", info.loc.filename, info.loc.lineno);
+ gen_split (&info);
+ break;
- case DEFINE_PEEPHOLE2:
- printf ("/* %s:%d */\n", read_md_filename, line_no);
- gen_split (desc);
- break;
+ case DEFINE_PEEPHOLE2:
+ printf ("/* %s:%d */\n", info.loc.filename, info.loc.lineno);
+ gen_split (&info);
+ break;
- default:
- break;
- }
- ++insn_index_number;
- }
+ default:
+ break;
+ }
/* Write out the routines to add CLOBBERs to a pattern and say whether they
clobber a hard reg. */
vec<char> pathstr;
};
-int line_no;
-
/* Forward declarations. */
-static void walk_rtx (rtx, struct accum_extract *);
+static void walk_rtx (md_rtx_info *, rtx, struct accum_extract *);
static void
-gen_insn (rtx insn, int insn_code_number)
+gen_insn (md_rtx_info *info)
{
int i;
unsigned int op_count, dup_count, j;
/* Walk the insn's pattern, remembering at all times the path
down to the walking point. */
+ rtx insn = info->def;
if (XVECLEN (insn, 1) == 1)
- walk_rtx (XVECEXP (insn, 1, 0), &acc);
+ walk_rtx (info, XVECEXP (insn, 1, 0), &acc);
else
for (i = XVECLEN (insn, 1) - 1; i >= 0; i--)
{
acc.pathstr.safe_push ('a' + i);
- walk_rtx (XVECEXP (insn, 1, i), &acc);
+ walk_rtx (info, XVECEXP (insn, 1, i), &acc);
acc.pathstr.pop ();
}
link = XNEW (struct code_ptr);
- link->insn_code = insn_code_number;
+ link->insn_code = info->index;
/* See if we find something that already had this extraction method. */
/* Helper subroutine of walk_rtx: given a vec<locstr>, an index, and a
string, insert the string at the index, which should either already
exist and be NULL, or not yet exist within the vector. In the latter
- case the vector is enlarged as appropriate. */
+ case the vector is enlarged as appropriate. INFO describes the
+ containing define_* expression. */
static void
-VEC_safe_set_locstr (vec<locstr> *vp, unsigned int ix, char *str)
+VEC_safe_set_locstr (md_rtx_info *info, vec<locstr> *vp,
+ unsigned int ix, char *str)
{
if (ix < (*vp).length ())
{
if ((*vp)[ix])
{
- message_with_line (line_no, "repeated operand number %d", ix);
+ message_at (info->loc, "repeated operand number %d", ix);
have_error = 1;
}
else
}
static void
-walk_rtx (rtx x, struct accum_extract *acc)
+walk_rtx (md_rtx_info *info, rtx x, struct accum_extract *acc)
{
RTX_CODE code;
int i, len, base;
case MATCH_OPERAND:
case MATCH_SCRATCH:
- VEC_safe_set_locstr (&acc->oplocs, XINT (x, 0),
+ VEC_safe_set_locstr (info, &acc->oplocs, XINT (x, 0),
VEC_char_to_string (acc->pathstr));
break;
case MATCH_OPERATOR:
case MATCH_PARALLEL:
- VEC_safe_set_locstr (&acc->oplocs, XINT (x, 0),
+ VEC_safe_set_locstr (info, &acc->oplocs, XINT (x, 0),
VEC_char_to_string (acc->pathstr));
base = (code == MATCH_OPERATOR ? '0' : 'a');
for (i = XVECLEN (x, 2) - 1; i >= 0; i--)
{
acc->pathstr.safe_push (base + i);
- walk_rtx (XVECEXP (x, 2, i), acc);
+ walk_rtx (info, XVECEXP (x, 2, i), acc);
acc->pathstr.pop ();
}
return;
for (i = XVECLEN (x, 1) - 1; i >= 0; i--)
{
acc->pathstr.safe_push (base + i);
- walk_rtx (XVECEXP (x, 1, i), acc);
+ walk_rtx (info, XVECEXP (x, 1, i), acc);
acc->pathstr.pop ();
}
return;
if (fmt[i] == 'e' || fmt[i] == 'u')
{
acc->pathstr.safe_push ('0' + i);
- walk_rtx (XEXP (x, i), acc);
+ walk_rtx (info, XEXP (x, i), acc);
acc->pathstr.pop ();
}
else if (fmt[i] == 'E')
for (j = XVECLEN (x, i) - 1; j >= 0; j--)
{
acc->pathstr.safe_push ('a' + j);
- walk_rtx (XVECEXP (x, i, j), acc);
+ walk_rtx (info, XVECEXP (x, i, j), acc);
acc->pathstr.pop ();
}
}
int
main (int argc, char **argv)
{
- rtx desc;
unsigned int i;
struct extraction *p;
struct code_ptr *link;
const char *name;
- int insn_code_number;
progname = "genextract";
/* Read the machine description. */
- while ((desc = read_md_rtx (&line_no, &insn_code_number)) != NULL)
- {
- if (GET_CODE (desc) == DEFINE_INSN)
- gen_insn (desc, insn_code_number);
+ md_rtx_info info;
+ while (read_md_rtx (&info))
+ switch (GET_CODE (info.def))
+ {
+ case DEFINE_INSN:
+ gen_insn (&info);
+ break;
- else if (GET_CODE (desc) == DEFINE_PEEPHOLE)
+ case DEFINE_PEEPHOLE:
{
struct code_ptr *link = XNEW (struct code_ptr);
- link->insn_code = insn_code_number;
+ link->insn_code = info.index;
link->next = peepholes;
peepholes = link;
}
+ break;
+
+ default:
+ break;
}
if (have_error)
static int num_operands (rtx);
static void gen_proto (rtx);
static void gen_macro (const char *, int, int);
-static void gen_insn (int, rtx);
/* Count the number of match_operand's found. */
}
static void
-gen_insn (int line_no, rtx insn)
+gen_insn (md_rtx_info *info)
{
+ rtx insn = info->def;
const char *name = XSTR (insn, 0);
const char *p;
const char *lt, *gt;
lt = strchr (name, '<');
if (lt && strchr (lt + 1, '>'))
{
- message_with_line (line_no, "unresolved iterator");
- have_error = 1;
+ error_at (info->loc, "unresolved iterator");
return;
}
gt = strchr (name, '>');
if (lt || gt)
{
- message_with_line (line_no,
- "unmatched angle brackets, likely "
- "an error in iterator syntax");
- have_error = 1;
+ error_at (info->loc, "unmatched angle brackets, likely "
+ "an error in iterator syntax");
return;
}
int
main (int argc, char **argv)
{
- rtx desc;
rtx dummy;
rtx *insns;
rtx *insn_ptr;
/* Read the machine description. */
- while (1)
- {
- int line_no, insn_code_number = 0;
+ md_rtx_info info;
+ while (read_md_rtx (&info))
+ switch (GET_CODE (info.def))
+ {
+ case DEFINE_INSN:
+ case DEFINE_EXPAND:
+ gen_insn (&info);
+ break;
- desc = read_md_rtx (&line_no, &insn_code_number);
- if (desc == NULL)
+ default:
break;
- if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
- gen_insn (line_no, desc);
- }
+ }
/* Print out the prototypes now. */
dummy = (rtx) 0;
int
main (int argc, char **argv)
{
- rtx desc;
- int pattern_lineno;
- int code; /* not used */
progname = "genmddump";
if (!init_rtx_reader_args (argc, argv))
return (FATAL_EXIT_CODE);
/* Read the machine description. */
- while (1)
+ md_rtx_info info;
+ while (read_md_rtx (&info))
{
- desc = read_md_rtx (&pattern_lineno, &code);
- if (desc == NULL)
- break;
- printf (";; %s: %d\n", read_md_filename, pattern_lineno);
- print_inline_rtx (stdout, desc, 0);
+ printf (";; %s: %d\n", info.loc.filename, info.loc.lineno);
+ print_inline_rtx (stdout, info.def, 0);
printf ("\n\n");
}
}
static void
-gen_insn (rtx insn)
+gen_insn (md_rtx_info *info)
{
+ rtx insn = info->def;
const char *name = XSTR (insn, 0);
pattern p;
unsigned pindex;
s_file = open_outfile (source_file_name);
/* Read the machine description. */
- while (1)
- {
- int line_no, insn_code_number = 0;
- rtx desc = read_md_rtx (&line_no, &insn_code_number);
- if (desc == NULL)
+ md_rtx_info info;
+ while (read_md_rtx (&info))
+ switch (GET_CODE (info.def))
+ {
+ case DEFINE_INSN:
+ case DEFINE_EXPAND:
+ gen_insn (&info);
break;
- if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
- gen_insn (desc);
- }
+
+ default:
+ break;
+ }
/* Sort the collected patterns. */
patterns.qsort (pattern_cmp);
static int n_occurrences (int, const char *);
static const char *strip_whitespace (const char *);
-/* insns in the machine description are assigned sequential code numbers
- that are used by insn-recog.c (produced by genrecog) to communicate
- to insn-output.c (produced by this program). */
-
-static int next_code_number;
-
/* This counts all operands used in the md file. The first is null. */
static int next_operand_number = 1;
static void process_template (struct data *, const char *);
static void validate_insn_alternatives (struct data *);
static void validate_insn_operands (struct data *);
-static void gen_insn (rtx, int);
-static void gen_peephole (rtx, int);
-static void gen_expand (rtx, int);
-static void gen_split (rtx, int);
struct constraint_data
{
constraints_by_letter_table[1 << CHAR_BIT];
static int mdep_constraint_len (const char *, file_location, int);
-static void note_constraint (rtx, int);
+static void note_constraint (md_rtx_info *);
\f
static void
output_prologue (void)
a hairy output action, output a function for now. */
static void
-gen_insn (rtx insn, int lineno)
+gen_insn (md_rtx_info *info)
{
struct pattern_stats stats;
+ rtx insn = info->def;
data *d = new data;
int i;
- d->code_number = next_code_number;
- d->loc = file_location (read_md_filename, lineno);
+ d->code_number = info->index;
+ d->loc = info->loc;
if (XSTR (insn, 0)[0])
d->name = XSTR (insn, 0);
else
If the insn has a hairy output action, output it now. */
static void
-gen_peephole (rtx peep, int lineno)
+gen_peephole (md_rtx_info *info)
{
struct pattern_stats stats;
data *d = new data;
int i;
- d->code_number = next_code_number;
- d->loc = file_location (read_md_filename, lineno);
+ d->code_number = info->index;
+ d->loc = info->loc;
d->name = 0;
/* Build up the list in the same order as the insns are seen
/* Get the number of operands by scanning all the patterns of the
peephole optimizer. But ignore all the rest of the information
thus obtained. */
+ rtx peep = info->def;
for (i = 0; i < XVECLEN (peep, 0); i++)
scan_operands (d, XVECEXP (peep, 0, i), 0, 0);
only for the purposes of `insn_gen_function'. */
static void
-gen_expand (rtx insn, int lineno)
+gen_expand (md_rtx_info *info)
{
struct pattern_stats stats;
+ rtx insn = info->def;
data *d = new data;
int i;
- d->code_number = next_code_number;
- d->loc = file_location (read_md_filename, lineno);
+ d->code_number = info->index;
+ d->loc = info->loc;
if (XSTR (insn, 0)[0])
d->name = XSTR (insn, 0);
else
only for reasons of consistency and to simplify genrecog. */
static void
-gen_split (rtx split, int lineno)
+gen_split (md_rtx_info *info)
{
struct pattern_stats stats;
data *d = new data;
int i;
- d->code_number = next_code_number;
- d->loc = file_location (read_md_filename, lineno);
+ d->code_number = info->index;
+ d->loc = info->loc;
d->name = 0;
/* Build up the list in the same order as the insns are seen
/* Get the number of operands by scanning all the patterns of the
split patterns. But ignore all the rest of the information thus
obtained. */
+ rtx split = info->def;
for (i = 0; i < XVECLEN (split, 0); i++)
scan_operands (d, XVECEXP (split, 0, i), 0, 0);
int
main (int argc, char **argv)
{
- rtx desc;
-
progname = "genoutput";
init_insn_for_nothing ();
/* Read the machine description. */
- while (1)
- {
- int line_no;
-
- desc = read_md_rtx (&line_no, &next_code_number);
- if (desc == NULL)
+ md_rtx_info info;
+ while (read_md_rtx (&info))
+ switch (GET_CODE (info.def))
+ {
+ case DEFINE_INSN:
+ gen_insn (&info);
break;
- switch (GET_CODE (desc))
- {
- case DEFINE_INSN:
- gen_insn (desc, line_no);
- break;
-
- case DEFINE_PEEPHOLE:
- gen_peephole (desc, line_no);
- break;
+ case DEFINE_PEEPHOLE:
+ gen_peephole (&info);
+ break;
- case DEFINE_EXPAND:
- gen_expand (desc, line_no);
- break;
+ case DEFINE_EXPAND:
+ gen_expand (&info);
+ break;
- case DEFINE_SPLIT:
- case DEFINE_PEEPHOLE2:
- gen_split (desc, line_no);
- break;
+ case DEFINE_SPLIT:
+ case DEFINE_PEEPHOLE2:
+ gen_split (&info);
+ break;
- case DEFINE_CONSTRAINT:
- case DEFINE_REGISTER_CONSTRAINT:
- case DEFINE_ADDRESS_CONSTRAINT:
- case DEFINE_MEMORY_CONSTRAINT:
- note_constraint (desc, line_no);
- break;
+ case DEFINE_CONSTRAINT:
+ case DEFINE_REGISTER_CONSTRAINT:
+ case DEFINE_ADDRESS_CONSTRAINT:
+ case DEFINE_MEMORY_CONSTRAINT:
+ note_constraint (&info);
+ break;
- default:
- break;
- }
- }
+ default:
+ break;
+ }
printf ("\n\n");
output_operand_data ();
return q;
}
-/* Record just enough information about a constraint to allow checking
- of operand constraint strings above, in validate_insn_alternatives.
- Does not validate most properties of the constraint itself; does
- enforce no duplicate names, no overlap with MI constraints, and no
- prefixes. EXP is the define_*constraint form, LINENO the line number
- reported by the reader. */
+/* Record just enough information about the constraint in *INFO to allow
+ checking of operand constraint strings above, in validate_insn_alternatives.
+ Does not validate most properties of the constraint itself; does enforce
+ no duplicate names, no overlap with MI constraints, and no prefixes. */
static void
-note_constraint (rtx exp, int lineno)
+note_constraint (md_rtx_info *info)
{
+ rtx exp = info->def;
const char *name = XSTR (exp, 0);
struct constraint_data **iter, **slot, *new_cdata;
if (strchr (indep_constraints, name[0]))
{
if (name[1] == '\0')
- error_with_line (lineno, "constraint letter '%s' cannot be "
- "redefined by the machine description", name);
+ error_at (info->loc, "constraint letter '%s' cannot be "
+ "redefined by the machine description", name);
else
- error_with_line (lineno, "constraint name '%s' cannot be defined by "
- "the machine description, as it begins with '%c'",
- name, name[0]);
+ error_at (info->loc, "constraint name '%s' cannot be defined by "
+ "the machine description, as it begins with '%c'",
+ name, name[0]);
return;
}
if (!strcmp ((*iter)->name, name))
{
- error_with_line (lineno, "redefinition of constraint '%s'", name);
+ error_at (info->loc, "redefinition of constraint '%s'", name);
message_at ((*iter)->loc, "previous definition is here");
return;
}
else if (!strncmp ((*iter)->name, name, (*iter)->namelen))
{
- error_with_line (lineno, "defining constraint '%s' here", name);
+ error_at (info->loc, "defining constraint '%s' here", name);
message_at ((*iter)->loc, "renders constraint '%s' "
"(defined here) a prefix", (*iter)->name);
return;
}
else if (!strncmp ((*iter)->name, name, namelen))
{
- error_with_line (lineno, "constraint '%s' is a prefix", name);
+ error_at (info->loc, "constraint '%s' is a prefix", name);
message_at ((*iter)->loc, "of constraint '%s' "
"(defined here)", (*iter)->name);
return;
new (new_cdata) constraint_data ();
strcpy (CONST_CAST (char *, new_cdata->name), name);
new_cdata->namelen = namelen;
- new_cdata->loc = file_location (read_md_filename, lineno);
+ new_cdata->loc = info->loc;
new_cdata->next_this_letter = *slot;
*slot = new_cdata;
}
static int n_operands;
-static void gen_peephole (rtx, int);
static void match_rtx (rtx, struct link *, int);
static void print_path (struct link *);
static void print_code (RTX_CODE);
\f
static void
-gen_peephole (rtx peep, int insn_code_number)
+gen_peephole (md_rtx_info *info)
{
+ rtx peep = info->def;
int ninsns = XVECLEN (peep, 0);
int i;
if (i > 0)
{
printf (" do { insn = NEXT_INSN (insn);\n");
- printf (" if (insn == 0) goto L%d; }\n",
- insn_code_number);
+ printf (" if (insn == 0) goto L%d; }\n", info->index);
printf (" while (NOTE_P (insn)\n");
printf ("\t || (NONJUMP_INSN_P (insn)\n");
printf ("\t && (GET_CODE (PATTERN (insn)) == USE\n");
printf ("\t\t || GET_CODE (PATTERN (insn)) == CLOBBER)));\n");
printf (" if (LABEL_P (insn)\n\
- || BARRIER_P (insn))\n goto L%d;\n",
- insn_code_number);
+ || BARRIER_P (insn))\n goto L%d;\n", info->index);
}
printf (" pat = PATTERN (insn);\n");
/* Walk the insn's pattern, remembering at all times the path
down to the walking point. */
- match_rtx (XVECEXP (peep, 0, i), NULL, insn_code_number);
+ match_rtx (XVECEXP (peep, 0, i), NULL, info->index);
}
/* We get this far if the pattern matches.
if (XSTR (peep, 1) && XSTR (peep, 1)[0])
printf (" if (! (%s)) goto L%d;\n",
- XSTR (peep, 1), insn_code_number);
+ XSTR (peep, 1), info->index);
/* If that matches, construct new pattern and put it in the first insn.
This new pattern will never be matched.
/* Record this define_peephole's insn code in the insn,
as if it had been recognized to match this. */
- printf (" INSN_CODE (ins1) = %d;\n",
- insn_code_number);
+ printf (" INSN_CODE (ins1) = %d;\n", info->index);
/* Delete the remaining insns. */
if (ninsns > 1)
cannot be zero. */
printf (" return NEXT_INSN (insn);\n");
- printf (" L%d:\n\n", insn_code_number);
+ printf (" L%d:\n\n", info->index);
}
\f
static void
int
main (int argc, char **argv)
{
- rtx desc;
-
max_opno = -1;
progname = "genpeep";
/* Read the machine description. */
- while (1)
- {
- int line_no;
- int insn_code_number;
-
- desc = read_md_rtx (&line_no, &insn_code_number);
- if (desc == NULL)
+ md_rtx_info info;
+ while (read_md_rtx (&info))
+ switch (GET_CODE (info.def))
+ {
+ case DEFINE_PEEPHOLE:
+ gen_peephole (&info);
break;
- if (GET_CODE (desc) == DEFINE_PEEPHOLE)
- gen_peephole (desc, insn_code_number);
- }
+ default:
+ break;
+ }
printf (" return 0;\n}\n\n");
/* Predicates are defined with (define_predicate) or
(define_special_predicate) expressions in the machine description. */
static void
-process_define_predicate (rtx defn, int lineno)
+process_define_predicate (md_rtx_info *info)
{
- validate_exp (XEXP (defn, 1), XSTR (defn, 0),
- file_location (read_md_filename, lineno));
+ validate_exp (XEXP (info->def, 1), XSTR (info->def, 0), info->loc);
}
/* Given a predicate, if it has an embedded C block, write the block
/* Process a DEFINE_CONSTRAINT, DEFINE_MEMORY_CONSTRAINT, or
DEFINE_ADDRESS_CONSTRAINT expression, C. */
static void
-process_define_constraint (rtx c, int lineno)
+process_define_constraint (md_rtx_info *info)
{
- add_constraint (XSTR (c, 0), 0, XEXP (c, 2),
- GET_CODE (c) == DEFINE_MEMORY_CONSTRAINT,
- GET_CODE (c) == DEFINE_ADDRESS_CONSTRAINT,
- file_location (read_md_filename, lineno));
+ add_constraint (XSTR (info->def, 0), 0, XEXP (info->def, 2),
+ GET_CODE (info->def) == DEFINE_MEMORY_CONSTRAINT,
+ GET_CODE (info->def) == DEFINE_ADDRESS_CONSTRAINT,
+ info->loc);
}
/* Process a DEFINE_REGISTER_CONSTRAINT expression, C. */
static void
-process_define_register_constraint (rtx c, int lineno)
+process_define_register_constraint (md_rtx_info *info)
{
- add_constraint (XSTR (c, 0), XSTR (c, 1), 0, false, false,
- file_location (read_md_filename, lineno));
+ add_constraint (XSTR (info->def, 0), XSTR (info->def, 1),
+ 0, false, false, info->loc);
}
/* Put the constraints into enum order. We want to keep constraints
int
main (int argc, char **argv)
{
- rtx defn;
- int pattern_lineno, next_insn_code = 0;
-
progname = argv[0];
if (argc <= 1)
fatal ("no input file name");
if (!init_rtx_reader_args_cb (argc, argv, parse_option))
return FATAL_EXIT_CODE;
- while ((defn = read_md_rtx (&pattern_lineno, &next_insn_code)) != 0)
- switch (GET_CODE (defn))
+ md_rtx_info info;
+ while (read_md_rtx (&info))
+ switch (GET_CODE (info.def))
{
case DEFINE_PREDICATE:
case DEFINE_SPECIAL_PREDICATE:
- process_define_predicate (defn, pattern_lineno);
+ process_define_predicate (&info);
break;
case DEFINE_CONSTRAINT:
case DEFINE_MEMORY_CONSTRAINT:
case DEFINE_ADDRESS_CONSTRAINT:
- process_define_constraint (defn, pattern_lineno);
+ process_define_constraint (&info);
break;
case DEFINE_REGISTER_CONSTRAINT:
- process_define_register_constraint (defn, pattern_lineno);
+ process_define_register_constraint (&info);
break;
default:
SUBPATTERN, RECOG, SPLIT, PEEPHOLE2
};
-/* Next number to use as an insn_code. */
-static int next_insn_code;
-
-/* The line number of the start of the pattern currently being processed. */
-static int pattern_lineno;
-
/* The root position (x0). */
static struct position root_pos;
|| GET_CODE (insn) == DEFINE_PEEPHOLE2);
}
-/* Check for various errors in patterns. SET is nonnull for a destination,
- and is the complete set pattern. SET_CODE is '=' for normal sets, and
- '+' within a context that requires in-out constraints. */
+/* Check for various errors in PATTERN, which is part of INFO.
+ SET is nonnull for a destination, and is the complete set pattern.
+ SET_CODE is '=' for normal sets, and '+' within a context that
+ requires in-out constraints. */
static void
-validate_pattern (rtx pattern, rtx insn, rtx set, int set_code)
+validate_pattern (rtx pattern, md_rtx_info *info, rtx set, int set_code)
{
const char *fmt;
RTX_CODE code;
{
const char constraints0 = XSTR (pattern, 1)[0];
- if (!constraints_supported_in_insn_p (insn))
+ if (!constraints_supported_in_insn_p (info->def))
{
if (constraints0)
{
- error_with_line (pattern_lineno,
- "constraints not supported in %s",
- rtx_name[GET_CODE (insn)]);
+ error_at (info->loc, "constraints not supported in %s",
+ GET_RTX_NAME (GET_CODE (info->def)));
}
return;
}
&& constraints0 != '='
&& constraints0 != '+')
{
- error_with_line (pattern_lineno,
- "operand %d missing output reload",
- XINT (pattern, 0));
+ error_at (info->loc, "operand %d missing output reload",
+ XINT (pattern, 0));
}
return;
}
case MATCH_DUP:
case MATCH_OP_DUP:
case MATCH_PAR_DUP:
- if (find_operand (insn, XINT (pattern, 0), pattern) == pattern)
- error_with_line (pattern_lineno,
- "operand %i duplicated before defined",
- XINT (pattern, 0));
+ if (find_operand (info->def, XINT (pattern, 0), pattern) == pattern)
+ error_at (info->loc, "operand %i duplicated before defined",
+ XINT (pattern, 0));
break;
case MATCH_OPERAND:
case MATCH_OPERATOR:
const struct pred_data *pred;
const char *c_test;
- if (GET_CODE (insn) == DEFINE_INSN)
- c_test = XSTR (insn, 2);
+ if (GET_CODE (info->def) == DEFINE_INSN)
+ c_test = XSTR (info->def, 2);
else
- c_test = XSTR (insn, 1);
+ c_test = XSTR (info->def, 1);
if (pred_name[0] != 0)
{
pred = lookup_predicate (pred_name);
if (!pred)
- error_with_line (pattern_lineno, "unknown predicate '%s'",
- pred_name);
+ error_at (info->loc, "unknown predicate '%s'", pred_name);
}
else
pred = 0;
const char *constraints = XSTR (pattern, 2);
const char constraints0 = constraints[0];
- if (!constraints_supported_in_insn_p (insn))
+ if (!constraints_supported_in_insn_p (info->def))
{
if (constraints0)
{
- error_with_line (pattern_lineno,
- "constraints not supported in %s",
- rtx_name[GET_CODE (insn)]);
+ error_at (info->loc, "constraints not supported in %s",
+ GET_RTX_NAME (GET_CODE (info->def)));
}
}
/* If we've only got an output reload for this operand,
we'd better have a matching input operand. */
else if (constraints0 == '='
- && find_matching_operand (insn, XINT (pattern, 0)))
+ && find_matching_operand (info->def,
+ XINT (pattern, 0)))
;
else
- error_with_line (pattern_lineno,
- "operand %d missing in-out reload",
- XINT (pattern, 0));
+ error_at (info->loc, "operand %d missing in-out reload",
+ XINT (pattern, 0));
}
else if (constraints0 != '=' && constraints0 != '+')
- error_with_line (pattern_lineno,
- "operand %d missing output reload",
- XINT (pattern, 0));
+ error_at (info->loc, "operand %d missing output reload",
+ XINT (pattern, 0));
}
/* For matching constraint in MATCH_OPERAND, the digit must be a
sscanf (constraints, "%d", &val);
if (val >= XINT (pattern, 0))
- error_with_line (pattern_lineno,
- "constraint digit %d is not smaller than"
- " operand %d",
- val, XINT (pattern, 0));
+ error_at (info->loc, "constraint digit %d is not"
+ " smaller than operand %d",
+ val, XINT (pattern, 0));
}
while (constraints[0] && constraints[0] != ',')
while not likely to occur at runtime, results in less efficient
code from insn-recog.c. */
if (set && pred && pred->allows_non_lvalue)
- error_with_line (pattern_lineno,
- "destination operand %d allows non-lvalue",
- XINT (pattern, 0));
+ error_at (info->loc, "destination operand %d allows non-lvalue",
+ XINT (pattern, 0));
/* A modeless MATCH_OPERAND can be handy when we can check for
multiple modes in the c_test. In most other cases, it is a
if (GET_MODE (pattern) == VOIDmode
&& code == MATCH_OPERAND
- && GET_CODE (insn) == DEFINE_INSN
+ && GET_CODE (info->def) == DEFINE_INSN
&& pred
&& !pred->special
&& pred->allows_non_const
&& ! (set
&& GET_CODE (set) == SET
&& GET_CODE (SET_SRC (set)) == CALL))
- message_with_line (pattern_lineno,
- "warning: operand %d missing mode?",
- XINT (pattern, 0));
+ message_at (info->loc, "warning: operand %d missing mode?",
+ XINT (pattern, 0));
return;
}
if (GET_CODE (dest) == MATCH_DUP
|| GET_CODE (dest) == MATCH_OP_DUP
|| GET_CODE (dest) == MATCH_PAR_DUP)
- dest = find_operand (insn, XINT (dest, 0), NULL);
+ dest = find_operand (info->def, XINT (dest, 0), NULL);
if (GET_CODE (src) == MATCH_DUP
|| GET_CODE (src) == MATCH_OP_DUP
|| GET_CODE (src) == MATCH_PAR_DUP)
- src = find_operand (insn, XINT (src, 0), NULL);
+ src = find_operand (info->def, XINT (src, 0), NULL);
dmode = GET_MODE (dest);
smode = GET_MODE (src);
/* The operands of a SET must have the same mode unless one
is VOIDmode. */
else if (dmode != VOIDmode && smode != VOIDmode && dmode != smode)
- error_with_line (pattern_lineno,
- "mode mismatch in set: %smode vs %smode",
- GET_MODE_NAME (dmode), GET_MODE_NAME (smode));
+ error_at (info->loc, "mode mismatch in set: %smode vs %smode",
+ GET_MODE_NAME (dmode), GET_MODE_NAME (smode));
/* If only one of the operands is VOIDmode, and PC or CC0 is
not involved, it's probably a mistake. */
{
const char *which;
which = (dmode == VOIDmode ? "destination" : "source");
- message_with_line (pattern_lineno,
- "warning: %s missing a mode?", which);
+ message_at (info->loc, "warning: %s missing a mode?", which);
}
if (dest != SET_DEST (pattern))
- validate_pattern (dest, insn, pattern, '=');
- validate_pattern (SET_DEST (pattern), insn, pattern, '=');
- validate_pattern (SET_SRC (pattern), insn, NULL_RTX, 0);
+ validate_pattern (dest, info, pattern, '=');
+ validate_pattern (SET_DEST (pattern), info, pattern, '=');
+ validate_pattern (SET_SRC (pattern), info, NULL_RTX, 0);
return;
}
case CLOBBER:
- validate_pattern (SET_DEST (pattern), insn, pattern, '=');
+ validate_pattern (SET_DEST (pattern), info, pattern, '=');
return;
case ZERO_EXTRACT:
- validate_pattern (XEXP (pattern, 0), insn, set, set ? '+' : 0);
- validate_pattern (XEXP (pattern, 1), insn, NULL_RTX, 0);
- validate_pattern (XEXP (pattern, 2), insn, NULL_RTX, 0);
+ validate_pattern (XEXP (pattern, 0), info, set, set ? '+' : 0);
+ validate_pattern (XEXP (pattern, 1), info, NULL_RTX, 0);
+ validate_pattern (XEXP (pattern, 2), info, NULL_RTX, 0);
return;
case STRICT_LOW_PART:
- validate_pattern (XEXP (pattern, 0), insn, set, set ? '+' : 0);
+ validate_pattern (XEXP (pattern, 0), info, set, set ? '+' : 0);
return;
case LABEL_REF:
if (GET_MODE (LABEL_REF_LABEL (pattern)) != VOIDmode)
- error_with_line (pattern_lineno,
- "operand to label_ref %smode not VOIDmode",
- GET_MODE_NAME (GET_MODE (LABEL_REF_LABEL (pattern))));
+ error_at (info->loc, "operand to label_ref %smode not VOIDmode",
+ GET_MODE_NAME (GET_MODE (LABEL_REF_LABEL (pattern))));
break;
default:
switch (fmt[i])
{
case 'e': case 'u':
- validate_pattern (XEXP (pattern, i), insn, NULL_RTX, 0);
+ validate_pattern (XEXP (pattern, i), info, NULL_RTX, 0);
break;
case 'E':
for (j = 0; j < XVECLEN (pattern, i); j++)
- validate_pattern (XVECEXP (pattern, i, j), insn, NULL_RTX, 0);
+ validate_pattern (XVECEXP (pattern, i, j), info, NULL_RTX, 0);
break;
case 'i': case 'r': case 'w': case '0': case 's':
TOP_PATTERN is the overall pattern, as passed to match_pattern_1. */
static state *
-match_pattern_2 (state *s, rtx top_pattern, position *pos, rtx pattern)
+match_pattern_2 (state *s, md_rtx_info *info, position *pos, rtx pattern)
{
auto_vec <pattern_pos, 32> worklist;
auto_vec <pattern_pos, 32> pred_and_mode_tests;
dup_tests.safe_push (pattern_pos (pattern, pos));
/* Use the same code check as the original operand. */
- pattern = find_operand (top_pattern, XINT (pattern, 0), NULL_RTX);
+ pattern = find_operand (info->def, XINT (pattern, 0), NULL_RTX);
/* Fall through. */
case MATCH_PARALLEL:
if (code == GET_CODE (pattern))
{
if (!pred)
- error_with_line (pattern_lineno,
- "unknown predicate '%s'"
- " in '%s' expression",
- pred_name, GET_RTX_NAME (code));
+ error_at (info->loc, "unknown predicate '%s' used in %s",
+ pred_name, GET_RTX_NAME (code));
else if (code == MATCH_PARALLEL
&& pred->singleton != PARALLEL)
- error_with_line (pattern_lineno,
- "predicate '%s' used in match_parallel"
- " does not allow only PARALLEL",
- pred->name);
+ error_at (info->loc, "predicate '%s' used in"
+ " match_parallel does not allow only PARALLEL",
+ pred->name);
}
}
to match, otherwise it is a single instruction pattern. */
static void
-match_pattern_1 (state *s, rtx top_pattern, const char *c_test,
+match_pattern_1 (state *s, md_rtx_info *info, rtx pattern, const char *c_test,
acceptance_type acceptance)
{
if (acceptance.type == PEEPHOLE2)
/* Match each individual instruction. */
position **subpos_ptr = &peep2_insn_pos_list;
int count = 0;
- for (int i = 0; i < XVECLEN (top_pattern, 0); ++i)
+ for (int i = 0; i < XVECLEN (pattern, 0); ++i)
{
- rtx x = XVECEXP (top_pattern, 0, i);
+ rtx x = XVECEXP (pattern, 0, i);
position *subpos = next_position (subpos_ptr, &root_pos,
POS_PEEP2_INSN, count);
if (count > 0)
s = add_decision (s, rtx_test::peep2_count (count + 1),
true, false);
- s = match_pattern_2 (s, top_pattern, subpos, x);
+ s = match_pattern_2 (s, info, subpos, x);
subpos_ptr = &subpos->next;
count += 1;
}
else
{
/* Make the rtx itself. */
- s = match_pattern_2 (s, top_pattern, &root_pos, top_pattern);
+ s = match_pattern_2 (s, info, &root_pos, pattern);
/* If the match is only valid when extra clobbers are added,
make sure we're able to pass that information to the caller. */
backtracking. */
static void
-match_pattern (state *s, rtx top_pattern, const char *c_test,
+match_pattern (state *s, md_rtx_info *info, rtx pattern, const char *c_test,
acceptance_type acceptance)
{
if (merge_states_p)
state root;
/* Add the decisions to a fresh state and then merge the full tree
into the existing one. */
- match_pattern_1 (&root, top_pattern, c_test, acceptance);
+ match_pattern_1 (&root, info, pattern, c_test, acceptance);
merge_into_state (s, &root);
}
else
- match_pattern_1 (s, top_pattern, c_test, acceptance);
+ match_pattern_1 (s, info, pattern, c_test, acceptance);
}
/* Begin the output file. */
/* Return the rtx pattern for the list of rtxes in a define_peephole2. */
static rtx
-get_peephole2_pattern (rtvec vec)
+get_peephole2_pattern (md_rtx_info *info)
{
int i, j;
+ rtvec vec = XVEC (info->def, 0);
rtx pattern = rtx_alloc (SEQUENCE);
XVEC (pattern, 0) = rtvec_alloc (GET_NUM_ELEM (vec));
for (i = j = 0; i < GET_NUM_ELEM (vec); i++)
}
XVECLEN (pattern, 0) = j;
if (j == 0)
- error_with_line (pattern_lineno, "empty define_peephole2");
+ error_at (info->loc, "empty define_peephole2");
return pattern;
}
int
main (int argc, char **argv)
{
- rtx desc;
state insn_root, split_root, peephole2_root;
progname = "genrecog";
if (!init_rtx_reader_args (argc, argv))
return (FATAL_EXIT_CODE);
- next_insn_code = 0;
-
write_header ();
/* Read the machine description. */
- while (1)
+ md_rtx_info info;
+ while (read_md_rtx (&info))
{
- desc = read_md_rtx (&pattern_lineno, &next_insn_code);
- if (desc == NULL)
- break;
+ rtx def = info.def;
acceptance_type acceptance;
acceptance.partial_p = false;
- acceptance.u.full.code = next_insn_code;
+ acceptance.u.full.code = info.index;
rtx pattern;
- switch (GET_CODE (desc))
+ switch (GET_CODE (def))
{
case DEFINE_INSN:
{
/* Match the instruction in the original .md form. */
acceptance.type = RECOG;
acceptance.u.full.u.num_clobbers = 0;
- pattern = add_implicit_parallel (XVEC (desc, 1));
- validate_pattern (pattern, desc, NULL_RTX, 0);
- match_pattern (&insn_root, pattern, XSTR (desc, 2), acceptance);
+ pattern = add_implicit_parallel (XVEC (def, 1));
+ validate_pattern (pattern, &info, NULL_RTX, 0);
+ match_pattern (&insn_root, &info, pattern,
+ XSTR (def, 2), acceptance);
/* If the pattern is a PARALLEL with trailing CLOBBERs,
allow recog_for_combine to match without the clobbers. */
if (GET_CODE (pattern) == PARALLEL
&& remove_clobbers (&acceptance, &pattern))
- match_pattern (&insn_root, pattern, XSTR (desc, 2), acceptance);
+ match_pattern (&insn_root, &info, pattern,
+ XSTR (def, 2), acceptance);
break;
}
case DEFINE_SPLIT:
acceptance.type = SPLIT;
- pattern = add_implicit_parallel (XVEC (desc, 0));
- validate_pattern (pattern, desc, NULL_RTX, 0);
- match_pattern (&split_root, pattern, XSTR (desc, 1), acceptance);
+ pattern = add_implicit_parallel (XVEC (def, 0));
+ validate_pattern (pattern, &info, NULL_RTX, 0);
+ match_pattern (&split_root, &info, pattern,
+ XSTR (def, 1), acceptance);
/* Declare the gen_split routine that we'll call if the
pattern matches. The definition comes from insn-emit.c. */
printf ("extern rtx_insn *gen_split_%d (rtx_insn *, rtx *);\n",
- next_insn_code);
+ info.index);
break;
case DEFINE_PEEPHOLE2:
acceptance.type = PEEPHOLE2;
- pattern = get_peephole2_pattern (XVEC (desc, 0));
- validate_pattern (pattern, desc, NULL_RTX, 0);
- match_pattern (&peephole2_root, pattern, XSTR (desc, 1), acceptance);
+ pattern = get_peephole2_pattern (&info);
+ validate_pattern (pattern, &info, NULL_RTX, 0);
+ match_pattern (&peephole2_root, &info, pattern,
+ XSTR (def, 1), acceptance);
/* Declare the gen_peephole2 routine that we'll call if the
pattern matches. The definition comes from insn-emit.c. */
printf ("extern rtx_insn *gen_peephole2_%d (rtx_insn *, rtx *);\n",
- next_insn_code);
+ info.index);
break;
default:
return init_rtx_reader_args_cb (argc, argv, 0);
}
\f
-/* The entry point for reading a single rtx from an md file. Return
- the rtx, or NULL if the md file has been fully processed.
- Return the line where the rtx was found in LINENO.
- Return the number of code generating rtx'en read since the start
- of the md file in SEQNR. */
+/* Try to read a single rtx from the file. Return true on success,
+ describing it in *INFO. */
-rtx
-read_md_rtx (int *lineno, int *seqnr)
+bool
+read_md_rtx (md_rtx_info *info)
{
struct queue_elem **queue, *elem;
rtx desc;
else if (other_queue != NULL)
queue = &other_queue;
else
- return NULL_RTX;
+ return false;
elem = *queue;
*queue = elem->next;
- desc = elem->data;
- read_md_filename = elem->loc.filename;
- *lineno = elem->loc.lineno;
- *seqnr = sequence_num;
+ info->def = elem->data;
+ info->loc = elem->loc;
+ info->index = sequence_num;
free (elem);
elided patterns are never counted by the sequence numbering; it
is the caller's responsibility, when insn_elision is false, not
to use elided pattern numbers for anything. */
+ desc = info->def;
switch (GET_CODE (desc))
{
case DEFINE_INSN:
else if (insn_elision)
goto discard;
- /* *seqnr is used here so the name table will match caller's
+ /* info->index is used here so the name table will match caller's
idea of insn numbering, whether or not elision is active. */
- record_insn_name (*seqnr, XSTR (desc, 0));
+ record_insn_name (info->index, XSTR (desc, 0));
break;
case DEFINE_SPLIT:
if (maybe_eval_c_test (XSTR (desc, 1)) != 0)
sequence_num++;
else if (insn_elision)
- goto discard;
+ goto discard;
break;
default:
break;
}
- return desc;
+ return true;
}
/* Helper functions for insn elision. */
#ifndef GCC_GENSUPPORT_H
#define GCC_GENSUPPORT_H
+#include "read-md.h"
+
struct obstack;
extern struct obstack *rtl_obstack;
+/* Information about an .md define_* rtx. */
+struct md_rtx_info {
+ /* The rtx itself. */
+ rtx def;
+
+ /* The location of the first line of the rtx. */
+ file_location loc;
+
+ /* The unique number attached to the rtx. Currently all define_insns,
+ define_expands, define_splits, define_peepholes and define_peephole2s
+ share the same insn_code index space. */
+ int index;
+};
+
extern rtx add_implicit_parallel (rtvec);
extern bool init_rtx_reader_args_cb (int, char **, bool (*)(const char *));
extern bool init_rtx_reader_args (int, char **);
-extern rtx read_md_rtx (int *, int *);
+extern bool read_md_rtx (md_rtx_info *);
/* Set this to 0 to disable automatic elision of insn patterns which
can never be used in this configuration. See genconditions.c.
printf ("CODE_FOR_%s\n", name);
}
+/* Record the DEFINE_INSN or DEFINE_EXPAND described by INFO. */
+
+static void
+add_insn (md_rtx_info *info)
+{
+ rtx def = info->def;
+ const char *name = XSTR (def, 0);
+ if (name[0] == 0 || name[0] == '*')
+ return;
+
+ hashval_t hash = htab_hash_string (name);
+ rtx *slot = insns->find_slot_with_hash (name, hash, INSERT);
+ if (*slot)
+ error_at (info->loc, "duplicate definition of '%s'", name);
+ else
+ *slot = def;
+}
+
int
main (int argc, char **argv)
{
- int insn_code_number = 0;
-
progname = "gentarget-def";
if (!init_rtx_reader_args (argc, argv))
stubs = new hash_table <nofree_string_hash> (31);
have_funcs = new hash_map <nofree_string_hash, const char *>;
- while (1)
- {
- int line_no;
- rtx desc = read_md_rtx (&line_no, &insn_code_number);
- if (desc == NULL)
+ md_rtx_info info;
+ while (read_md_rtx (&info))
+ switch (GET_CODE (info.def))
+ {
+ case DEFINE_INSN:
+ case DEFINE_EXPAND:
+ add_insn (&info);
break;
- if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
- {
- const char *name = XSTR (desc, 0);
- if (name[0] != 0 && name[0] != '*')
- {
- hashval_t hash = htab_hash_string (name);
- rtx *slot = insns->find_slot_with_hash (name, hash, INSERT);
- if (*slot)
- {
- message_with_line (line_no, "duplicate definition of '%s'",
- name);
- have_error = 1;
- }
- else
- *slot = desc;
- }
- }
- }
+
+ default:
+ break;
+ }
printf ("/* Generated automatically by the program `gentarget-def'. */\n");
printf ("#ifndef GCC_INSN_TARGET_DEF_H\n");
exit (1);
}
-/* A printf-like function for reporting an error against line LINENO
- in the current MD file. */
-
-void
-message_with_line (int lineno, const char *msg, ...)
-{
- va_list ap;
-
- va_start (ap, msg);
- message_at_1 (file_location (read_md_filename, lineno), msg, ap);
- va_end (ap);
-}
-
-/* Like message_with_line, but treat the condition as an error. */
-
-void
-error_with_line (int lineno, const char *msg, ...)
-{
- va_list ap;
-
- va_start (ap, msg);
- message_at_1 (file_location (read_md_filename, lineno), msg, ap);
- va_end (ap);
- have_error = 1;
-}
-
/* A printf-like function for reporting an error against the current
position in the MD file. */
extern void message_at (file_location, const char *, ...) ATTRIBUTE_PRINTF_2;
extern void error_at (file_location, const char *, ...) ATTRIBUTE_PRINTF_2;
extern void fatal_at (file_location, const char *, ...) ATTRIBUTE_PRINTF_2;
-extern void message_with_line (int, const char *, ...) ATTRIBUTE_PRINTF_2;
-extern void error_with_line (int, const char *, ...) ATTRIBUTE_PRINTF_2;
extern void fatal_with_file_and_line (const char *, ...)
ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
extern void fatal_expected_char (int, int) ATTRIBUTE_NORETURN;