Commit 5d2d3e43 by Richard Sandiford Committed by Richard Sandiford

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
parent c9f84f2e
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
than a line number.
* gensupport.c (compute_test_codes): Likewise. Use *_at functions
......
......@@ -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;
md_rtx_info info;
while (read_md_rtx (&info))
switch (GET_CODE (info.def))
{
case DEFINE_ATTR:
gen_attr (&info);
break;
desc = read_md_rtx (&line_no, &insn_code_number);
if (desc == NULL)
case DEFINE_DELAY:
if (!have_delay)
{
printf ("#define DELAY_SLOTS\n");
have_delay = true;
}
break;
if (GET_CODE (desc) == DEFINE_ATTR)
gen_attr (desc);
case DEFINE_INSN_RESERVATION:
if (!have_sched)
{
printf ("#define INSN_SCHEDULING\n");
have_sched = true;
}
break;
if (GET_CODE (desc) == DEFINE_DELAY)
{
if (!have_delay)
{
printf ("#define DELAY_SLOTS\n");
have_delay = true;
}
}
else if (GET_CODE (desc) == DEFINE_INSN_RESERVATION)
{
if (!have_sched)
{
printf ("#define INSN_SCHEDULING\n");
have_sched = true;
}
}
}
default:
break;
}
puts ("\n#endif /* GCC_INSN_ATTR_COMMON_H */");
if (ferror (stdout) || fflush (stdout) || fclose (stdout))
......
......@@ -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;
desc = read_md_rtx (&line_no, &insn_code_number);
if (desc == NULL)
break;
if (GET_CODE (desc) == DEFINE_ATTR
|| GET_CODE (desc) == DEFINE_ENUM_ATTR)
gen_attr (desc);
rtx def = info.def;
switch (GET_CODE (def))
{
case DEFINE_ATTR:
case DEFINE_ENUM_ATTR:
gen_attr (&info);
break;
else if (GET_CODE (desc) == DEFINE_DELAY)
{
case DEFINE_DELAY:
if (! have_delay)
{
printf ("extern int num_delay_slots (rtx_insn *);\n");
......@@ -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;
}
}
......
......@@ -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;
md_rtx_info info;
while (read_md_rtx (&info))
switch (GET_CODE (info.def))
{
case DEFINE_INSN:
gen_insn (&info);
break;
desc = read_md_rtx (&line_no, &insn_code_number);
if (desc == NULL)
case DEFINE_EXPAND:
gen_expand (&info);
break;
switch (GET_CODE (desc))
{
case DEFINE_INSN:
gen_insn (desc);
break;
case DEFINE_EXPAND:
gen_expand (desc);
break;
case DEFINE_SPLIT:
gen_split (desc);
break;
case DEFINE_PEEPHOLE2:
have_peephole2_flag = 1;
gen_peephole2 (desc);
break;
case DEFINE_PEEPHOLE:
have_peephole_flag = 1;
gen_peephole (desc);
break;
default:
break;
}
}
case DEFINE_SPLIT:
gen_split (&info);
break;
case DEFINE_PEEPHOLE2:
have_peephole2_flag = 1;
gen_peephole2 (&info);
break;
case DEFINE_PEEPHOLE:
have_peephole_flag = 1;
gen_peephole (&info);
break;
default:
break;
}
printf ("#define MAX_RECOG_OPERANDS %d\n", max_recog_operands + 1);
printf ("#define MAX_DUP_OPERANDS %d\n", max_dup_operands);
......
......@@ -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", read_md_filename, line_no);
gen_expand (desc);
break;
case DEFINE_EXPAND:
printf ("/* %s:%d */\n", info.loc.filename, info.loc.lineno);
gen_expand (&info);
break;
case DEFINE_SPLIT:
printf ("/* %s:%d */\n", read_md_filename, line_no);
gen_split (desc);
break;
case DEFINE_SPLIT:
printf ("/* %s:%d */\n", info.loc.filename, info.loc.lineno);
gen_split (&info);
break;
case DEFINE_PEEPHOLE2:
printf ("/* %s:%d */\n", read_md_filename, line_no);
gen_split (desc);
break;
case DEFINE_PEEPHOLE2:
printf ("/* %s:%d */\n", info.loc.filename, info.loc.lineno);
gen_split (&info);
break;
default:
break;
}
++insn_index_number;
}
default:
break;
}
/* Write out the routines to add CLOBBERs to a pattern and say whether they
clobber a hard reg. */
......
......@@ -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;
md_rtx_info info;
while (read_md_rtx (&info))
switch (GET_CODE (info.def))
{
case DEFINE_INSN:
case DEFINE_EXPAND:
gen_insn (&info);
break;
desc = read_md_rtx (&line_no, &insn_code_number);
if (desc == NULL)
default:
break;
if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
gen_insn (line_no, desc);
}
}
/* Print out the prototypes now. */
dummy = (rtx) 0;
......
......@@ -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);
......
......@@ -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 (desc, line_no);
break;
case DEFINE_PEEPHOLE:
gen_peephole (&info);
break;
case DEFINE_EXPAND:
gen_expand (desc, line_no);
break;
case DEFINE_EXPAND:
gen_expand (&info);
break;
case DEFINE_SPLIT:
case DEFINE_PEEPHOLE2:
gen_split (desc, line_no);
break;
case DEFINE_SPLIT:
case DEFINE_PEEPHOLE2:
gen_split (&info);
break;
case DEFINE_CONSTRAINT:
case DEFINE_REGISTER_CONSTRAINT:
case DEFINE_ADDRESS_CONSTRAINT:
case DEFINE_MEMORY_CONSTRAINT:
note_constraint (desc, line_no);
break;
case DEFINE_CONSTRAINT:
case DEFINE_REGISTER_CONSTRAINT:
case DEFINE_ADDRESS_CONSTRAINT:
case DEFINE_MEMORY_CONSTRAINT:
note_constraint (&info);
break;
default:
break;
}
}
default:
break;
}
printf ("\n\n");
output_operand_data ();
......@@ -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:
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment