read-md.h (message_with_line, [...]): Delete.
gcc/ * 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. From-SVN: r225883
This commit is contained in:
parent
c9f84f2e1d
commit
5d2d3e43b9
22 changed files with 701 additions and 703 deletions
|
@ -1,3 +1,86 @@
|
|||
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
|
||||
|
|
|
@ -37,10 +37,11 @@ write_upcase (const char *str)
|
|||
}
|
||||
|
||||
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')
|
||||
{
|
||||
|
@ -62,7 +63,6 @@ gen_attr (rtx attr)
|
|||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
rtx desc;
|
||||
bool have_delay = false;
|
||||
bool have_sched = false;
|
||||
|
||||
|
@ -78,34 +78,33 @@ main (int argc, char **argv)
|
|||
|
||||
/* Read the machine description. */
|
||||
|
||||
while (1)
|
||||
{
|
||||
int line_no, 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_ATTR:
|
||||
gen_attr (&info);
|
||||
break;
|
||||
|
||||
if (GET_CODE (desc) == DEFINE_ATTR)
|
||||
gen_attr (desc);
|
||||
case DEFINE_DELAY:
|
||||
if (!have_delay)
|
||||
{
|
||||
printf ("#define DELAY_SLOTS\n");
|
||||
have_delay = 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
case DEFINE_INSN_RESERVATION:
|
||||
if (!have_sched)
|
||||
{
|
||||
printf ("#define INSN_SCHEDULING\n");
|
||||
have_sched = true;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
puts ("\n#endif /* GCC_INSN_ATTR_COMMON_H */");
|
||||
|
||||
if (ferror (stdout) || fflush (stdout) || fclose (stdout))
|
||||
|
|
|
@ -29,15 +29,14 @@ along with GCC; see the file COPYING3. If not see
|
|||
#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)
|
||||
|
@ -141,7 +140,6 @@ find_tune_attr (rtx exp)
|
|||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
rtx desc;
|
||||
int have_delay = 0;
|
||||
int have_annul_true = 0;
|
||||
int have_annul_false = 0;
|
||||
|
@ -162,20 +160,18 @@ main (int argc, char **argv)
|
|||
|
||||
/* Read the machine description. */
|
||||
|
||||
while (1)
|
||||
md_rtx_info info;
|
||||
while (read_md_rtx (&info))
|
||||
{
|
||||
int line_no, insn_code_number;
|
||||
rtx def = info.def;
|
||||
switch (GET_CODE (def))
|
||||
{
|
||||
case DEFINE_ATTR:
|
||||
case DEFINE_ENUM_ATTR:
|
||||
gen_attr (&info);
|
||||
break;
|
||||
|
||||
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);
|
||||
|
||||
else if (GET_CODE (desc) == DEFINE_DELAY)
|
||||
{
|
||||
case DEFINE_DELAY:
|
||||
if (! have_delay)
|
||||
{
|
||||
printf ("extern int num_delay_slots (rtx_insn *);\n");
|
||||
|
@ -184,28 +180,31 @@ main (int argc, char **argv)
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
131
gcc/genattrtab.c
131
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. */
|
||||
|
|
|
@ -1243,16 +1243,18 @@ get_str_vect (const char *str, int *els_num, int sep, int paren_p)
|
|||
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);
|
||||
|
@ -1272,17 +1274,19 @@ gen_cpu_unit (rtx def)
|
|||
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);
|
||||
|
@ -1301,7 +1305,7 @@ gen_query_cpu_unit (rtx def)
|
|||
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;
|
||||
|
@ -1310,12 +1314,15 @@ gen_bypass (rtx def)
|
|||
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++)
|
||||
{
|
||||
|
@ -1336,7 +1343,7 @@ gen_bypass (rtx def)
|
|||
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;
|
||||
|
@ -1345,16 +1352,20 @@ gen_excl_set (rtx def)
|
|||
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;
|
||||
|
@ -1375,7 +1386,7 @@ gen_excl_set (rtx def)
|
|||
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;
|
||||
|
@ -1386,27 +1397,17 @@ gen_presence_absence_set (rtx def, int presence_p, int final_p)
|
|||
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++)
|
||||
{
|
||||
|
@ -1439,13 +1440,13 @@ gen_presence_absence_set (rtx def, int presence_p, int final_p)
|
|||
|
||||
/* 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.
|
||||
|
@ -1454,9 +1455,9 @@ gen_presence_set (rtx def)
|
|||
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.
|
||||
|
@ -1465,9 +1466,9 @@ gen_final_presence_set (rtx def)
|
|||
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.
|
||||
|
@ -1476,9 +1477,9 @@ gen_absence_set (rtx def)
|
|||
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.
|
||||
|
@ -1487,16 +1488,18 @@ gen_final_absence_set (rtx def)
|
|||
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);
|
||||
|
@ -1512,28 +1515,30 @@ gen_automaton (rtx def)
|
|||
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. */
|
||||
|
@ -1703,10 +1708,11 @@ gen_regexp (const char *str)
|
|||
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;
|
||||
|
@ -1721,10 +1727,11 @@ gen_reserv (rtx def)
|
|||
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;
|
||||
|
@ -9587,77 +9594,67 @@ write_automata (void)
|
|||
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 (&info);
|
||||
break;
|
||||
|
||||
case DEFINE_QUERY_CPU_UNIT:
|
||||
gen_query_cpu_unit (desc);
|
||||
break;
|
||||
case DEFINE_BYPASS:
|
||||
gen_bypass (&info);
|
||||
break;
|
||||
|
||||
case DEFINE_BYPASS:
|
||||
gen_bypass (desc);
|
||||
break;
|
||||
case EXCLUSION_SET:
|
||||
gen_excl_set (&info);
|
||||
break;
|
||||
|
||||
case EXCLUSION_SET:
|
||||
gen_excl_set (desc);
|
||||
break;
|
||||
case PRESENCE_SET:
|
||||
gen_presence_set (&info);
|
||||
break;
|
||||
|
||||
case PRESENCE_SET:
|
||||
gen_presence_set (desc);
|
||||
break;
|
||||
case FINAL_PRESENCE_SET:
|
||||
gen_final_presence_set (&info);
|
||||
break;
|
||||
|
||||
case FINAL_PRESENCE_SET:
|
||||
gen_final_presence_set (desc);
|
||||
break;
|
||||
case ABSENCE_SET:
|
||||
gen_absence_set (&info);
|
||||
break;
|
||||
|
||||
case ABSENCE_SET:
|
||||
gen_absence_set (desc);
|
||||
break;
|
||||
case FINAL_ABSENCE_SET:
|
||||
gen_final_absence_set (&info);
|
||||
break;
|
||||
|
||||
case FINAL_ABSENCE_SET:
|
||||
gen_final_absence_set (desc);
|
||||
break;
|
||||
case DEFINE_AUTOMATON:
|
||||
gen_automaton (&info);
|
||||
break;
|
||||
|
||||
case DEFINE_AUTOMATON:
|
||||
gen_automaton (desc);
|
||||
break;
|
||||
case AUTOMATA_OPTION:
|
||||
gen_automata_option (&info);
|
||||
break;
|
||||
|
||||
case AUTOMATA_OPTION:
|
||||
gen_automata_option (desc);
|
||||
break;
|
||||
case DEFINE_RESERVATION:
|
||||
gen_reserv (&info);
|
||||
break;
|
||||
|
||||
case DEFINE_RESERVATION:
|
||||
gen_reserv (desc);
|
||||
break;
|
||||
case DEFINE_INSN_RESERVATION:
|
||||
gen_insn_reserv (&info);
|
||||
break;
|
||||
|
||||
case DEFINE_INSN_RESERVATION:
|
||||
gen_insn_reserv (desc);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (have_error)
|
||||
return FATAL_EXIT_CODE;
|
||||
|
|
|
@ -29,10 +29,10 @@ along with GCC; see the file COPYING3. If not see
|
|||
#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
|
||||
|
@ -42,14 +42,13 @@ gen_insn (rtx insn, int code)
|
|||
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";
|
||||
|
@ -73,20 +72,18 @@ enum insn_code {\n\
|
|||
|
||||
/* 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\
|
||||
|
|
|
@ -212,42 +212,36 @@ write_writer (void)
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,11 +51,6 @@ static int clobbers_seen_this_insn;
|
|||
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.
|
||||
|
@ -179,11 +174,12 @@ walk_insn_part (rtx part, int recog_p, int non_pc_set_src)
|
|||
}
|
||||
|
||||
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)
|
||||
|
@ -199,7 +195,7 @@ gen_insn (rtx insn)
|
|||
/* Similar but scan a define_expand. */
|
||||
|
||||
static void
|
||||
gen_expand (rtx insn)
|
||||
gen_expand (md_rtx_info *info)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -207,6 +203,7 @@ gen_expand (rtx insn)
|
|||
|
||||
/* 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++)
|
||||
{
|
||||
|
@ -225,12 +222,13 @@ gen_expand (rtx insn)
|
|||
/* 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. */
|
||||
|
@ -239,23 +237,25 @@ gen_split (rtx split)
|
|||
}
|
||||
|
||||
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);
|
||||
|
||||
|
@ -271,8 +271,6 @@ gen_peephole2 (rtx peep)
|
|||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
rtx desc;
|
||||
|
||||
progname = "genconfig";
|
||||
|
||||
if (!init_rtx_reader_args (argc, argv))
|
||||
|
@ -291,42 +289,35 @@ main (int argc, char **argv)
|
|||
|
||||
/* Read the machine description. */
|
||||
|
||||
while (1)
|
||||
{
|
||||
int line_no, insn_code_number = 0;
|
||||
|
||||
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);
|
||||
break;
|
||||
case DEFINE_EXPAND:
|
||||
gen_expand (&info);
|
||||
break;
|
||||
|
||||
case DEFINE_EXPAND:
|
||||
gen_expand (desc);
|
||||
break;
|
||||
case DEFINE_SPLIT:
|
||||
gen_split (&info);
|
||||
break;
|
||||
|
||||
case DEFINE_SPLIT:
|
||||
gen_split (desc);
|
||||
break;
|
||||
case DEFINE_PEEPHOLE2:
|
||||
have_peephole2_flag = 1;
|
||||
gen_peephole2 (&info);
|
||||
break;
|
||||
|
||||
case DEFINE_PEEPHOLE2:
|
||||
have_peephole2_flag = 1;
|
||||
gen_peephole2 (desc);
|
||||
break;
|
||||
case DEFINE_PEEPHOLE:
|
||||
have_peephole_flag = 1;
|
||||
gen_peephole (&info);
|
||||
break;
|
||||
|
||||
case DEFINE_PEEPHOLE:
|
||||
have_peephole_flag = 1;
|
||||
gen_peephole (desc);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
printf ("#define MAX_RECOG_OPERANDS %d\n", max_recog_operands + 1);
|
||||
printf ("#define MAX_DUP_OPERANDS %d\n", max_dup_operands);
|
||||
|
|
|
@ -28,9 +28,6 @@ along with GCC; see the file COPYING3. If not see
|
|||
#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. */
|
||||
|
@ -299,7 +296,7 @@ gen_emit_seq (rtvec vec, char *used)
|
|||
/* 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;
|
||||
|
@ -308,6 +305,7 @@ gen_insn (rtx insn, int lineno)
|
|||
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;
|
||||
|
@ -329,7 +327,7 @@ gen_insn (rtx insn, int lineno)
|
|||
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. */
|
||||
|
@ -383,12 +381,12 @@ gen_insn (rtx insn, int lineno)
|
|||
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));
|
||||
|
@ -419,16 +417,18 @@ gen_insn (rtx insn, int lineno)
|
|||
/* 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));
|
||||
|
@ -517,21 +517,22 @@ gen_expand (rtx expand)
|
|||
/* 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. */
|
||||
|
||||
|
@ -543,17 +544,18 @@ gen_split (rtx split)
|
|||
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");
|
||||
|
||||
|
@ -567,7 +569,7 @@ gen_split (rtx split)
|
|||
|
||||
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");
|
||||
|
||||
|
@ -725,8 +727,6 @@ output_peephole2_scratches (rtx split)
|
|||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
rtx desc;
|
||||
|
||||
progname = "genemit";
|
||||
|
||||
if (!init_rtx_reader_args (argc, argv))
|
||||
|
@ -735,9 +735,6 @@ main (int argc, char **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");
|
||||
|
||||
|
@ -780,40 +777,32 @@ 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", info.loc.filename, info.loc.lineno);
|
||||
gen_expand (&info);
|
||||
break;
|
||||
|
||||
case DEFINE_EXPAND:
|
||||
printf ("/* %s:%d */\n", read_md_filename, line_no);
|
||||
gen_expand (desc);
|
||||
break;
|
||||
case DEFINE_SPLIT:
|
||||
printf ("/* %s:%d */\n", info.loc.filename, info.loc.lineno);
|
||||
gen_split (&info);
|
||||
break;
|
||||
|
||||
case DEFINE_SPLIT:
|
||||
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;
|
||||
|
||||
case DEFINE_PEEPHOLE2:
|
||||
printf ("/* %s:%d */\n", read_md_filename, line_no);
|
||||
gen_split (desc);
|
||||
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. */
|
||||
|
|
|
@ -75,13 +75,11 @@ struct accum_extract
|
|||
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;
|
||||
|
@ -97,18 +95,19 @@ gen_insn (rtx insn, int insn_code_number)
|
|||
/* 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. */
|
||||
|
||||
|
@ -178,15 +177,17 @@ gen_insn (rtx insn, int insn_code_number)
|
|||
/* 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
|
||||
|
@ -213,7 +214,7 @@ VEC_char_to_string (vec<char> v)
|
|||
}
|
||||
|
||||
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;
|
||||
|
@ -233,20 +234,20 @@ walk_rtx (rtx x, struct accum_extract *acc)
|
|||
|
||||
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;
|
||||
|
@ -264,7 +265,7 @@ walk_rtx (rtx x, struct accum_extract *acc)
|
|||
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;
|
||||
|
@ -280,7 +281,7 @@ walk_rtx (rtx x, struct accum_extract *acc)
|
|||
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')
|
||||
|
@ -289,7 +290,7 @@ walk_rtx (rtx x, struct accum_extract *acc)
|
|||
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 ();
|
||||
}
|
||||
}
|
||||
|
@ -394,12 +395,10 @@ insn_extract (rtx_insn *insn)\n{\n\
|
|||
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";
|
||||
|
||||
|
@ -408,19 +407,26 @@ main (int argc, char **argv)
|
|||
|
||||
/* 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)
|
||||
|
|
|
@ -43,7 +43,6 @@ static void max_operand_1 (rtx);
|
|||
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. */
|
||||
|
||||
|
@ -187,8 +186,9 @@ gen_proto (rtx insn)
|
|||
}
|
||||
|
||||
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;
|
||||
|
@ -198,18 +198,15 @@ gen_insn (int line_no, rtx insn)
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -249,7 +246,6 @@ gen_insn (int line_no, rtx insn)
|
|||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
rtx desc;
|
||||
rtx dummy;
|
||||
rtx *insns;
|
||||
rtx *insn_ptr;
|
||||
|
@ -271,16 +267,18 @@ main (int argc, char **argv)
|
|||
|
||||
/* Read the machine description. */
|
||||
|
||||
while (1)
|
||||
{
|
||||
int line_no, insn_code_number = 0;
|
||||
|
||||
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 (line_no, desc);
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Print out the prototypes now. */
|
||||
dummy = (rtx) 0;
|
||||
|
|
|
@ -40,22 +40,17 @@ extern int main (int, char **);
|
|||
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");
|
||||
}
|
||||
|
||||
|
|
|
@ -243,8 +243,9 @@ match_pattern (pattern *p, const char *name, const char *pat)
|
|||
}
|
||||
|
||||
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;
|
||||
|
@ -346,15 +347,18 @@ main (int argc, char **argv)
|
|||
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);
|
||||
|
|
130
gcc/genoutput.c
130
gcc/genoutput.c
|
@ -103,12 +103,6 @@ static char general_mem[] = { TARGET_MEM_CONSTRAINT, 0 };
|
|||
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;
|
||||
|
@ -184,10 +178,6 @@ static void place_operands (struct data *);
|
|||
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
|
||||
{
|
||||
|
@ -205,7 +195,7 @@ static 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 *);
|
||||
|
||||
static void
|
||||
output_prologue (void)
|
||||
|
@ -861,14 +851,15 @@ validate_optab_operands (struct data *d)
|
|||
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
|
||||
|
@ -902,14 +893,14 @@ gen_insn (rtx insn, int lineno)
|
|||
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
|
||||
|
@ -923,6 +914,7 @@ gen_peephole (rtx peep, int lineno)
|
|||
/* 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);
|
||||
|
||||
|
@ -940,14 +932,15 @@ gen_peephole (rtx peep, int lineno)
|
|||
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
|
||||
|
@ -984,14 +977,14 @@ gen_expand (rtx insn, int lineno)
|
|||
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
|
||||
|
@ -1005,6 +998,7 @@ gen_split (rtx split, int lineno)
|
|||
/* 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);
|
||||
|
||||
|
@ -1034,8 +1028,6 @@ extern int main (int, char **);
|
|||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
rtx desc;
|
||||
|
||||
progname = "genoutput";
|
||||
|
||||
init_insn_for_nothing ();
|
||||
|
@ -1047,44 +1039,37 @@ main (int argc, char **argv)
|
|||
|
||||
/* 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 (&info);
|
||||
break;
|
||||
|
||||
case DEFINE_PEEPHOLE:
|
||||
gen_peephole (desc, line_no);
|
||||
break;
|
||||
case DEFINE_EXPAND:
|
||||
gen_expand (&info);
|
||||
break;
|
||||
|
||||
case DEFINE_EXPAND:
|
||||
gen_expand (desc, line_no);
|
||||
break;
|
||||
case DEFINE_SPLIT:
|
||||
case DEFINE_PEEPHOLE2:
|
||||
gen_split (&info);
|
||||
break;
|
||||
|
||||
case DEFINE_SPLIT:
|
||||
case DEFINE_PEEPHOLE2:
|
||||
gen_split (desc, line_no);
|
||||
break;
|
||||
case DEFINE_CONSTRAINT:
|
||||
case DEFINE_REGISTER_CONSTRAINT:
|
||||
case DEFINE_ADDRESS_CONSTRAINT:
|
||||
case DEFINE_MEMORY_CONSTRAINT:
|
||||
note_constraint (&info);
|
||||
break;
|
||||
|
||||
case DEFINE_CONSTRAINT:
|
||||
case DEFINE_REGISTER_CONSTRAINT:
|
||||
case DEFINE_ADDRESS_CONSTRAINT:
|
||||
case DEFINE_MEMORY_CONSTRAINT:
|
||||
note_constraint (desc, line_no);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
printf ("\n\n");
|
||||
output_operand_data ();
|
||||
|
@ -1134,15 +1119,14 @@ strip_whitespace (const char *s)
|
|||
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;
|
||||
|
||||
|
@ -1153,12 +1137,12 @@ note_constraint (rtx exp, int lineno)
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -1175,20 +1159,20 @@ note_constraint (rtx exp, int lineno)
|
|||
|
||||
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;
|
||||
|
@ -1199,7 +1183,7 @@ note_constraint (rtx exp, int lineno)
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -46,14 +46,14 @@ static int max_opno;
|
|||
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
|
@ -66,16 +66,14 @@ gen_peephole (rtx peep, int insn_code_number)
|
|||
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");
|
||||
|
@ -83,7 +81,7 @@ gen_peephole (rtx peep, int insn_code_number)
|
|||
/* 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.
|
||||
|
@ -91,7 +89,7 @@ gen_peephole (rtx peep, int insn_code_number)
|
|||
|
||||
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.
|
||||
|
@ -103,8 +101,7 @@ gen_peephole (rtx peep, int insn_code_number)
|
|||
|
||||
/* 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)
|
||||
|
@ -114,7 +111,7 @@ gen_peephole (rtx peep, int insn_code_number)
|
|||
cannot be zero. */
|
||||
printf (" return NEXT_INSN (insn);\n");
|
||||
|
||||
printf (" L%d:\n\n", insn_code_number);
|
||||
printf (" L%d:\n\n", info->index);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -348,8 +345,6 @@ extern int main (int, char **);
|
|||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
rtx desc;
|
||||
|
||||
max_opno = -1;
|
||||
|
||||
progname = "genpeep";
|
||||
|
@ -394,18 +389,17 @@ from the machine description file `md'. */\n\n");
|
|||
|
||||
/* 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");
|
||||
|
||||
|
|
|
@ -91,10 +91,9 @@ validate_exp (rtx exp, const char *name, file_location loc)
|
|||
/* 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
|
||||
|
@ -936,20 +935,20 @@ add_constraint (const char *name, const char *regclass,
|
|||
/* 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
|
||||
|
@ -1584,31 +1583,29 @@ parse_option (const char *opt)
|
|||
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:
|
||||
|
|
199
gcc/genrecog.c
199
gcc/genrecog.c
|
@ -250,12 +250,6 @@ enum routine_type {
|
|||
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;
|
||||
|
||||
|
@ -469,12 +463,13 @@ constraints_supported_in_insn_p (rtx insn)
|
|||
|| 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;
|
||||
|
@ -488,13 +483,12 @@ validate_pattern (rtx pattern, rtx insn, rtx set, int set_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;
|
||||
}
|
||||
|
@ -506,19 +500,17 @@ validate_pattern (rtx pattern, rtx insn, rtx set, int set_code)
|
|||
&& 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:
|
||||
|
@ -527,17 +519,16 @@ validate_pattern (rtx pattern, rtx insn, rtx set, int set_code)
|
|||
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;
|
||||
|
@ -547,13 +538,12 @@ validate_pattern (rtx pattern, rtx insn, rtx set, int set_code)
|
|||
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)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -567,17 +557,16 @@ validate_pattern (rtx pattern, rtx insn, rtx set, int set_code)
|
|||
/* 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
|
||||
|
@ -597,10 +586,9 @@ validate_pattern (rtx pattern, rtx insn, rtx set, int set_code)
|
|||
|
||||
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] != ',')
|
||||
|
@ -612,9 +600,8 @@ validate_pattern (rtx pattern, rtx insn, rtx set, int set_code)
|
|||
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
|
||||
|
@ -626,7 +613,7 @@ validate_pattern (rtx pattern, rtx insn, rtx set, int set_code)
|
|||
|
||||
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
|
||||
|
@ -634,9 +621,8 @@ validate_pattern (rtx pattern, rtx insn, rtx set, int set_code)
|
|||
&& ! (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;
|
||||
}
|
||||
|
||||
|
@ -658,12 +644,12 @@ validate_pattern (rtx pattern, rtx insn, rtx set, int set_code)
|
|||
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);
|
||||
|
@ -677,9 +663,8 @@ validate_pattern (rtx pattern, rtx insn, rtx set, int set_code)
|
|||
/* 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. */
|
||||
|
@ -694,36 +679,34 @@ validate_pattern (rtx pattern, rtx insn, rtx set, int set_code)
|
|||
{
|
||||
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:
|
||||
|
@ -737,12 +720,12 @@ validate_pattern (rtx pattern, rtx insn, rtx set, int set_code)
|
|||
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':
|
||||
|
@ -3823,7 +3806,7 @@ predicate_name (rtx match_rtx)
|
|||
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;
|
||||
|
@ -3848,7 +3831,7 @@ match_pattern_2 (state *s, rtx top_pattern, position *pos, rtx pattern)
|
|||
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:
|
||||
|
@ -3865,16 +3848,13 @@ match_pattern_2 (state *s, rtx top_pattern, position *pos, rtx pattern)
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4106,7 +4086,7 @@ match_pattern_2 (state *s, rtx top_pattern, position *pos, rtx pattern)
|
|||
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)
|
||||
|
@ -4114,15 +4094,15 @@ match_pattern_1 (state *s, rtx top_pattern, const char *c_test,
|
|||
/* 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;
|
||||
}
|
||||
|
@ -4131,7 +4111,7 @@ match_pattern_1 (state *s, rtx top_pattern, const char *c_test,
|
|||
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. */
|
||||
|
@ -4152,7 +4132,7 @@ match_pattern_1 (state *s, rtx top_pattern, const char *c_test,
|
|||
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)
|
||||
|
@ -4160,11 +4140,11 @@ match_pattern (state *s, rtx top_pattern, const char *c_test,
|
|||
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. */
|
||||
|
@ -5178,9 +5158,10 @@ print_subroutine_group (output_state *os, routine_type type, state *root)
|
|||
/* 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++)
|
||||
|
@ -5195,7 +5176,7 @@ get_peephole2_pattern (rtvec vec)
|
|||
}
|
||||
XVECLEN (pattern, 0) = j;
|
||||
if (j == 0)
|
||||
error_with_line (pattern_lineno, "empty define_peephole2");
|
||||
error_at (info->loc, "empty define_peephole2");
|
||||
return pattern;
|
||||
}
|
||||
|
||||
|
@ -5245,7 +5226,6 @@ remove_clobbers (acceptance_type *acceptance_ptr, rtx *pattern_ptr)
|
|||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
rtx desc;
|
||||
state insn_root, split_root, peephole2_root;
|
||||
|
||||
progname = "genrecog";
|
||||
|
@ -5253,64 +5233,65 @@ main (int argc, char **argv)
|
|||
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:
|
||||
|
|
|
@ -2533,14 +2533,11 @@ init_rtx_reader_args (int argc, char **argv)
|
|||
return init_rtx_reader_args_cb (argc, argv, 0);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
@ -2557,14 +2554,13 @@ read_md_rtx (int *lineno, int *seqnr)
|
|||
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);
|
||||
|
||||
|
@ -2574,6 +2570,7 @@ read_md_rtx (int *lineno, int *seqnr)
|
|||
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:
|
||||
|
@ -2584,9 +2581,9 @@ read_md_rtx (int *lineno, int *seqnr)
|
|||
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:
|
||||
|
@ -2595,14 +2592,14 @@ read_md_rtx (int *lineno, int *seqnr)
|
|||
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. */
|
||||
|
|
|
@ -20,13 +20,29 @@ along with GCC; see the file COPYING3. If not see
|
|||
#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.
|
||||
|
|
|
@ -198,11 +198,27 @@ def_target_insn (const char *name, const char *prototype)
|
|||
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))
|
||||
|
@ -212,30 +228,18 @@ main (int argc, char **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");
|
||||
|
|
|
@ -290,32 +290,6 @@ fatal_at (file_location loc, const char *msg, ...)
|
|||
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. */
|
||||
|
||||
|
|
|
@ -137,8 +137,6 @@ extern void fprint_c_condition (FILE *, const char *);
|
|||
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;
|
||||
|
|
Loading…
Add table
Reference in a new issue