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:
Richard Sandiford 2015-07-16 13:52:22 +00:00 committed by Richard Sandiford
parent c9f84f2e1d
commit 5d2d3e43b9
22 changed files with 701 additions and 703 deletions

View File

@ -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

View File

@ -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))

View File

@ -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;
}
}

View File

@ -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. */

View File

@ -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;

View File

@ -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\

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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. */

View File

@ -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)

View File

@ -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;

View File

@ -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");
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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");

View File

@ -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:

View File

@ -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:

View File

@ -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. */

View File

@ -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.

View File

@ -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");

View File

@ -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. */

View 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;