Commit 41723253 by Steven Bosscher

re PR other/29442 (insn-attrtab has grown too large)

	PR other/29442
	* read-md.c (fprint_md_ptr_loc, fprint_c_condition): New functions.
	(print_md_ptr_loc, print_c_condition): Use them.
	* read-md.h (fprint_md_ptr_loc, fprint_c_condition): New prototypes.
	* genattrtab.c (attr_file_name, dfa_file_name, latency_file_name,
	attr_file, dfa_file, latency_file): New global variables.
	(write_attr_valueq, write_attr_set, write_attr_case, write_attr_value,
	write_upcase, write_indent, write_length_unit_log, write_test_expr,
	write_attr_get, write_insn_cases, write_eligible_delay,
	write_const_num_delay_slots): Accept FILE pointer and toss it around.
	Update all callers.
	(write_header, open_outfile, handle_arg): New funcions.
	(make_automaton_attrs): Write prototypes as extern to the output
	files.
	(main): Use init_rtx_reader_args_cb with handle_arg to take 3 file
	names from the command line.  Open the output files and write out
	internal functions for DFA functions to dfa_file_name, insn latency
	functions to latency_file_name, and everything else to attr_file.
	* Makefile.in (OBJS): Add insn-dfatab.o and insn-latencytab.o.
	(BACKEND): Build libbackend first.
	(MOSTLYCLEANFILES): Add insn-dfatab.c and insn-latencytab.c.
	(.PRECIOUS): Likewise.
	(insn-dfatab.o): New rule.
	(insn-latencytab.o): New rule.
	(simple_rtl_generated_c): Do not include insn-attrtab.c.
	(s-attrtab): New rule.

From-SVN: r187181
parent 81e7aa8e
2012-05-04 Steven Bosscher <steven@gcc.gnu.org> 2012-05-04 Steven Bosscher <steven@gcc.gnu.org>
PR other/29442
* read-md.c (fprint_md_ptr_loc, fprint_c_condition): New functions.
(print_md_ptr_loc, print_c_condition): Use them.
* read-md.h (fprint_md_ptr_loc, fprint_c_condition): New prototypes.
* genattrtab.c (attr_file_name, dfa_file_name, latency_file_name,
attr_file, dfa_file, latency_file): New global variables.
(write_attr_valueq, write_attr_set, write_attr_case, write_attr_value,
write_upcase, write_indent, write_length_unit_log, write_test_expr,
write_attr_get, write_insn_cases, write_eligible_delay,
write_const_num_delay_slots): Accept FILE pointer and toss it around.
Update all callers.
(write_header, open_outfile, handle_arg): New funcions.
(make_automaton_attrs): Write prototypes as extern to the output
files.
(main): Use init_rtx_reader_args_cb with handle_arg to take 3 file
names from the command line. Open the output files and write out
internal functions for DFA functions to dfa_file_name, insn latency
functions to latency_file_name, and everything else to attr_file.
* Makefile.in (OBJS): Add insn-dfatab.o and insn-latencytab.o.
(BACKEND): Build libbackend first.
(MOSTLYCLEANFILES): Add insn-dfatab.c and insn-latencytab.c.
(.PRECIOUS): Likewise.
(insn-dfatab.o): New rule.
(insn-latencytab.o): New rule.
(simple_rtl_generated_c): Do not include insn-attrtab.c.
(s-attrtab): New rule.
2012-05-04 Steven Bosscher <steven@gcc.gnu.org>
* rtl.def (ATTR_FLAG): Remove probability indicating flags. * rtl.def (ATTR_FLAG): Remove probability indicating flags.
* genattr.c (main): Remove ATTR_FLAG_likely, ATTR_FLAG_unlikely, * genattr.c (main): Remove ATTR_FLAG_likely, ATTR_FLAG_unlikely,
ATTR_FLAG_very_likely, and ATTR_FLAG_very_unlikely. ATTR_FLAG_very_likely, and ATTR_FLAG_very_unlikely.
......
...@@ -1143,8 +1143,10 @@ C_OBJS = c-lang.o c-family/stub-objc.o $(C_AND_OBJC_OBJS) ...@@ -1143,8 +1143,10 @@ C_OBJS = c-lang.o c-family/stub-objc.o $(C_AND_OBJC_OBJS)
OBJS = \ OBJS = \
insn-attrtab.o \ insn-attrtab.o \
insn-automata.o \ insn-automata.o \
insn-dfatab.o \
insn-emit.o \ insn-emit.o \
insn-extract.o \ insn-extract.o \
insn-latencytab.o \
insn-modes.o \ insn-modes.o \
insn-opinit.o \ insn-opinit.o \
insn-output.o \ insn-output.o \
...@@ -1469,13 +1471,13 @@ ALL_HOST_BACKEND_OBJS = $(GCC_OBJS) $(OBJS) $(OBJS-libcommon) \ ...@@ -1469,13 +1471,13 @@ ALL_HOST_BACKEND_OBJS = $(GCC_OBJS) $(OBJS) $(OBJS-libcommon) \
# compilation or not. # compilation or not.
ALL_HOST_OBJS = $(ALL_HOST_FRONTEND_OBJS) $(ALL_HOST_BACKEND_OBJS) ALL_HOST_OBJS = $(ALL_HOST_FRONTEND_OBJS) $(ALL_HOST_BACKEND_OBJS)
BACKEND = main.o @TREEBROWSER@ libbackend.a libcommon-target.a libcommon.a \ BACKEND = libbackend.a main.o @TREEBROWSER@ libcommon-target.a libcommon.a \
$(CPPLIB) $(LIBDECNUMBER) $(CPPLIB) $(LIBDECNUMBER)
MOSTLYCLEANFILES = insn-flags.h insn-config.h insn-codes.h \ MOSTLYCLEANFILES = insn-flags.h insn-config.h insn-codes.h \
insn-output.c insn-recog.c insn-emit.c insn-extract.c insn-peep.c \ insn-output.c insn-recog.c insn-emit.c insn-extract.c insn-peep.c \
insn-attr.h insn-attr-common.h insn-attrtab.c insn-opinit.c \ insn-attr.h insn-attr-common.h insn-attrtab.c insn-dfatab.c \
insn-preds.c insn-constants.h \ insn-latencytab.c insn-opinit.c insn-preds.c insn-constants.h \
tm-preds.h tm-constrs.h checksum-options \ tm-preds.h tm-constrs.h checksum-options \
tree-check.h min-insn-modes.c insn-modes.c insn-modes.h \ tree-check.h min-insn-modes.c insn-modes.c insn-modes.h \
genrtl.h gt-*.h gtype-*.h gtype-desc.c gtyp-input.list \ genrtl.h gt-*.h gtype-*.h gtype-desc.c gtyp-input.list \
...@@ -3460,7 +3462,8 @@ $(common_out_object_file): $(common_out_file) $(CONFIG_H) $(SYSTEM_H) \ ...@@ -3460,7 +3462,8 @@ $(common_out_object_file): $(common_out_file) $(CONFIG_H) $(SYSTEM_H) \
.PRECIOUS: insn-config.h insn-flags.h insn-codes.h insn-constants.h \ .PRECIOUS: insn-config.h insn-flags.h insn-codes.h insn-constants.h \
insn-emit.c insn-recog.c insn-extract.c insn-output.c insn-peep.c \ insn-emit.c insn-recog.c insn-extract.c insn-output.c insn-peep.c \
insn-attr.h insn-attr-common.h insn-attrtab.c insn-preds.c insn-attr.h insn-attr-common.h insn-attrtab.c insn-dfatab.c \
insn-latencytab.c insn-preds.c
# Dependencies for the md file. The first time through, we just assume # Dependencies for the md file. The first time through, we just assume
# the md file itself and the generated dependency file (in order to get # the md file itself and the generated dependency file (in order to get
...@@ -3479,7 +3482,11 @@ insn-attrtab.o : insn-attrtab.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ ...@@ -3479,7 +3482,11 @@ insn-attrtab.o : insn-attrtab.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
insn-config.h $(DIAGNOSTIC_CORE_H) $(RECOG_H) $(TM_P_H) $(FLAGS_H) insn-config.h $(DIAGNOSTIC_CORE_H) $(RECOG_H) $(TM_P_H) $(FLAGS_H)
insn-automata.o : insn-automata.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ insn-automata.o : insn-automata.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(REGS_H) output.h $(INSN_ATTR_H) \ $(TM_H) $(RTL_H) $(REGS_H) output.h $(INSN_ATTR_H) \
insn-config.h toplev.h $(DIAGNOSTIC_CORE_H) $(RECOG_H) $(TM_P_H) $(FLAGS_H) $(EMIT_RTL_H) insn-config.h toplev.h $(DIAGNOSTIC_CORE_H) $(RECOG_H) \
$(TM_P_H) $(FLAGS_H) $(EMIT_RTL_H)
insn-dfatab.o : insn-dfatab.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(REGS_H) output.h $(INSN_ATTR_H) \
insn-config.h $(DIAGNOSTIC_CORE_H) $(RECOG_H) $(TM_P_H) $(FLAGS_H)
insn-emit.o : insn-emit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ insn-emit.o : insn-emit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(TM_P_H) $(FUNCTION_H) $(EXPR_H) $(OPTABS_H) \ $(RTL_H) $(TM_P_H) $(FUNCTION_H) $(EXPR_H) $(OPTABS_H) \
dfp.h $(FLAGS_H) output.h insn-config.h hard-reg-set.h $(RECOG_H) \ dfp.h $(FLAGS_H) output.h insn-config.h hard-reg-set.h $(RECOG_H) \
...@@ -3488,6 +3495,9 @@ insn-emit.o : insn-emit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ ...@@ -3488,6 +3495,9 @@ insn-emit.o : insn-emit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
insn-enums.o : insn-enums.c $(CONFIG_H) $(SYSTEM_H) insn-constants.h insn-enums.o : insn-enums.c $(CONFIG_H) $(SYSTEM_H) insn-constants.h
insn-extract.o : insn-extract.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ insn-extract.o : insn-extract.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(DIAGNOSTIC_CORE_H) insn-config.h $(RECOG_H) $(TM_H) $(RTL_H) $(DIAGNOSTIC_CORE_H) insn-config.h $(RECOG_H)
insn-latencytab.o : insn-latencytab.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(RTL_H) $(REGS_H) output.h $(INSN_ATTR_H) \
insn-config.h $(DIAGNOSTIC_CORE_H) $(RECOG_H) $(TM_P_H) $(FLAGS_H)
insn-modes.o : insn-modes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ insn-modes.o : insn-modes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(MACHMODE_H) $(MACHMODE_H)
insn-opinit.o : insn-opinit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ insn-opinit.o : insn-opinit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
...@@ -3520,7 +3530,7 @@ insn-recog.o : insn-recog.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ ...@@ -3520,7 +3530,7 @@ insn-recog.o : insn-recog.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
simple_rtl_generated_h = insn-attr.h insn-attr-common.h insn-codes.h \ simple_rtl_generated_h = insn-attr.h insn-attr-common.h insn-codes.h \
insn-config.h insn-flags.h insn-config.h insn-flags.h
simple_rtl_generated_c = insn-attrtab.c insn-automata.c insn-emit.c \ simple_rtl_generated_c = insn-automata.c insn-emit.c \
insn-extract.c insn-opinit.c insn-output.c \ insn-extract.c insn-opinit.c insn-output.c \
insn-peep.c insn-recog.c insn-peep.c insn-recog.c
...@@ -3557,6 +3567,17 @@ s-check : build/gencheck$(build_exeext) ...@@ -3557,6 +3567,17 @@ s-check : build/gencheck$(build_exeext)
$(SHELL) $(srcdir)/../move-if-change tmp-check.h tree-check.h $(SHELL) $(srcdir)/../move-if-change tmp-check.h tree-check.h
$(STAMP) s-check $(STAMP) s-check
# genattrtab produces three files: tmp-{attrtab.c,dfatab.c,latencytab.c}
insn-attrtab.c insn-dfatab.c insn-latencytab.c: s-attrtab ; @true
s-attrtab : $(MD_DEPS) build/genattrtab$(build_exeext) \
insn-conditions.md
$(RUN_GEN) build/genattrtab$(build_exeext) $(md_file) insn-conditions.md \
-Atmp-attrtab.c -Dtmp-dfatab.c -Ltmp-latencytab.c
$(SHELL) $(srcdir)/../move-if-change tmp-attrtab.c insn-attrtab.c
$(SHELL) $(srcdir)/../move-if-change tmp-dfatab.c insn-dfatab.c
$(SHELL) $(srcdir)/../move-if-change tmp-latencytab.c insn-latencytab.c
$(STAMP) s-attrtab
# gencondmd doesn't use the standard naming convention. # gencondmd doesn't use the standard naming convention.
build/gencondmd.c: s-conditions; @true build/gencondmd.c: s-conditions; @true
s-conditions: $(MD_DEPS) build/genconditions$(build_exeext) s-conditions: $(MD_DEPS) build/genconditions$(build_exeext)
......
...@@ -275,16 +275,17 @@ static rtx copy_rtx_unchanging (rtx); ...@@ -275,16 +275,17 @@ static rtx copy_rtx_unchanging (rtx);
static bool attr_alt_subset_p (rtx, rtx); static bool attr_alt_subset_p (rtx, rtx);
static bool attr_alt_subset_of_compl_p (rtx, rtx); static bool attr_alt_subset_of_compl_p (rtx, rtx);
static void clear_struct_flag (rtx); static void clear_struct_flag (rtx);
static void write_attr_valueq (struct attr_desc *, const char *); static void write_attr_valueq (FILE *, struct attr_desc *, const char *);
static struct attr_value *find_most_used (struct attr_desc *); static struct attr_value *find_most_used (struct attr_desc *);
static void write_attr_set (struct attr_desc *, int, rtx, static void write_attr_set (FILE *, struct attr_desc *, int, rtx,
const char *, const char *, rtx, const char *, const char *, rtx,
int, int, unsigned int); int, int, unsigned int);
static void write_attr_case (struct attr_desc *, struct attr_value *, static void write_attr_case (FILE *, struct attr_desc *,
struct attr_value *,
int, const char *, const char *, int, rtx); int, const char *, const char *, int, rtx);
static void write_attr_value (struct attr_desc *, rtx); static void write_attr_value (FILE *, struct attr_desc *, rtx);
static void write_upcase (const char *); static void write_upcase (FILE *, const char *);
static void write_indent (int); static void write_indent (FILE *, int);
static rtx identity_fn (rtx); static rtx identity_fn (rtx);
static rtx zero_fn (rtx); static rtx zero_fn (rtx);
static rtx one_fn (rtx); static rtx one_fn (rtx);
...@@ -294,6 +295,23 @@ static rtx min_fn (rtx); ...@@ -294,6 +295,23 @@ static rtx min_fn (rtx);
#define oballoc(T) XOBNEW (hash_obstack, T) #define oballoc(T) XOBNEW (hash_obstack, T)
#define oballocvec(T, N) XOBNEWVEC (hash_obstack, T, (N)) #define oballocvec(T, N) XOBNEWVEC (hash_obstack, T, (N))
/* This gen* file is unique, in that it writes out multiple files.
Before GCC 4.8, insn-attrtab.c was written out containing many large
functions and tables. This made insn-attrtab.c _the_ bottle-neck in
a parallel build, and even made it impossible to build GCC on machines
with relatively small RAM space (PR other/29442). Therefore, the
atrribute functions/tables are now written out to three separate
files: all "*insn_default_latency" functions go to LATENCY_FILE_NAME,
all "*internal_dfa_insn_code" functions go to DFA_FILE_NAME, and the
rest goes to ATTR_FILE_NAME. */
static const char *attr_file_name = NULL;
static const char *dfa_file_name = NULL;
static const char *latency_file_name = NULL;
static FILE *attr_file, *dfa_file, *latency_file;
/* Hash table for sharing RTL and strings. */ /* Hash table for sharing RTL and strings. */
/* Each hash table slot is a bucket containing a chain of these structures. /* Each hash table slot is a bucket containing a chain of these structures.
...@@ -1610,7 +1628,7 @@ min_fn (rtx exp) ...@@ -1610,7 +1628,7 @@ min_fn (rtx exp)
} }
static void static void
write_length_unit_log (void) write_length_unit_log (FILE *outf)
{ {
struct attr_desc *length_attr = find_attr (&length_str, 0); struct attr_desc *length_attr = find_attr (&length_str, 0);
struct attr_value *av; struct attr_value *av;
...@@ -1633,7 +1651,7 @@ write_length_unit_log (void) ...@@ -1633,7 +1651,7 @@ write_length_unit_log (void)
for (length_unit_log = 0; length_or & 1; length_or >>= 1) for (length_unit_log = 0; length_or & 1; length_or >>= 1)
length_unit_log++; length_unit_log++;
} }
printf ("EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log); fprintf (outf, "EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log);
} }
/* Take a COND expression and see if any of the conditions in it can be /* Take a COND expression and see if any of the conditions in it can be
...@@ -3247,7 +3265,7 @@ find_attrs_to_cache (rtx exp, bool create) ...@@ -3247,7 +3265,7 @@ find_attrs_to_cache (rtx exp, bool create)
} }
} }
/* Given a piece of RTX, print a C expression to test its truth value. /* Given a piece of RTX, print a C expression to test its truth value to OUTF.
We use AND and IOR both for logical and bit-wise operations, so We use AND and IOR both for logical and bit-wise operations, so
interpret them as logical unless they are inside a comparison expression. */ interpret them as logical unless they are inside a comparison expression. */
...@@ -3265,7 +3283,7 @@ find_attrs_to_cache (rtx exp, bool create) ...@@ -3265,7 +3283,7 @@ find_attrs_to_cache (rtx exp, bool create)
#define FLG_OUTSIDE_AND 8 #define FLG_OUTSIDE_AND 8
static unsigned int static unsigned int
write_test_expr (rtx exp, unsigned int attrs_cached, int flags) write_test_expr (FILE *outf, rtx exp, unsigned int attrs_cached, int flags)
{ {
int comparison_operator = 0; int comparison_operator = 0;
RTX_CODE code; RTX_CODE code;
...@@ -3274,14 +3292,14 @@ write_test_expr (rtx exp, unsigned int attrs_cached, int flags) ...@@ -3274,14 +3292,14 @@ write_test_expr (rtx exp, unsigned int attrs_cached, int flags)
/* In order not to worry about operator precedence, surround our part of /* In order not to worry about operator precedence, surround our part of
the expression with parentheses. */ the expression with parentheses. */
printf ("("); fprintf (outf, "(");
code = GET_CODE (exp); code = GET_CODE (exp);
switch (code) switch (code)
{ {
/* Binary operators. */ /* Binary operators. */
case GEU: case GTU: case GEU: case GTU:
case LEU: case LTU: case LEU: case LTU:
printf ("(unsigned) "); fprintf (outf, "(unsigned) ");
/* Fall through. */ /* Fall through. */
case EQ: case NE: case EQ: case NE:
...@@ -3295,7 +3313,7 @@ write_test_expr (rtx exp, unsigned int attrs_cached, int flags) ...@@ -3295,7 +3313,7 @@ write_test_expr (rtx exp, unsigned int attrs_cached, int flags)
if ((code != AND && code != IOR) || (flags & FLG_BITWISE)) if ((code != AND && code != IOR) || (flags & FLG_BITWISE))
{ {
flags &= ~(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND); flags &= ~(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND);
write_test_expr (XEXP (exp, 0), attrs_cached, write_test_expr (outf, XEXP (exp, 0), attrs_cached,
flags | comparison_operator); flags | comparison_operator);
} }
else else
...@@ -3307,78 +3325,78 @@ write_test_expr (rtx exp, unsigned int attrs_cached, int flags) ...@@ -3307,78 +3325,78 @@ write_test_expr (rtx exp, unsigned int attrs_cached, int flags)
|| (GET_CODE (XEXP (exp, 0)) == NOT || (GET_CODE (XEXP (exp, 0)) == NOT
&& GET_CODE (XEXP (XEXP (exp, 0), 0)) == EQ_ATTR)) && GET_CODE (XEXP (XEXP (exp, 0), 0)) == EQ_ATTR))
attrs_cached attrs_cached
= write_test_expr (XEXP (exp, 0), attrs_cached, flags); = write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
else else
write_test_expr (XEXP (exp, 0), attrs_cached, flags); write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
} }
switch (code) switch (code)
{ {
case EQ: case EQ:
printf (" == "); fprintf (outf, " == ");
break; break;
case NE: case NE:
printf (" != "); fprintf (outf, " != ");
break; break;
case GE: case GE:
printf (" >= "); fprintf (outf, " >= ");
break; break;
case GT: case GT:
printf (" > "); fprintf (outf, " > ");
break; break;
case GEU: case GEU:
printf (" >= (unsigned) "); fprintf (outf, " >= (unsigned) ");
break; break;
case GTU: case GTU:
printf (" > (unsigned) "); fprintf (outf, " > (unsigned) ");
break; break;
case LE: case LE:
printf (" <= "); fprintf (outf, " <= ");
break; break;
case LT: case LT:
printf (" < "); fprintf (outf, " < ");
break; break;
case LEU: case LEU:
printf (" <= (unsigned) "); fprintf (outf, " <= (unsigned) ");
break; break;
case LTU: case LTU:
printf (" < (unsigned) "); fprintf (outf, " < (unsigned) ");
break; break;
case PLUS: case PLUS:
printf (" + "); fprintf (outf, " + ");
break; break;
case MINUS: case MINUS:
printf (" - "); fprintf (outf, " - ");
break; break;
case MULT: case MULT:
printf (" * "); fprintf (outf, " * ");
break; break;
case DIV: case DIV:
printf (" / "); fprintf (outf, " / ");
break; break;
case MOD: case MOD:
printf (" %% "); fprintf (outf, " %% ");
break; break;
case AND: case AND:
if (flags & FLG_BITWISE) if (flags & FLG_BITWISE)
printf (" & "); fprintf (outf, " & ");
else else
printf (" && "); fprintf (outf, " && ");
break; break;
case IOR: case IOR:
if (flags & FLG_BITWISE) if (flags & FLG_BITWISE)
printf (" | "); fprintf (outf, " | ");
else else
printf (" || "); fprintf (outf, " || ");
break; break;
case XOR: case XOR:
printf (" ^ "); fprintf (outf, " ^ ");
break; break;
case ASHIFT: case ASHIFT:
printf (" << "); fprintf (outf, " << ");
break; break;
case LSHIFTRT: case LSHIFTRT:
case ASHIFTRT: case ASHIFTRT:
printf (" >> "); fprintf (outf, " >> ");
break; break;
default: default:
gcc_unreachable (); gcc_unreachable ();
...@@ -3409,9 +3427,9 @@ write_test_expr (rtx exp, unsigned int attrs_cached, int flags) ...@@ -3409,9 +3427,9 @@ write_test_expr (rtx exp, unsigned int attrs_cached, int flags)
|| (GET_CODE (XEXP (exp, 1)) == NOT || (GET_CODE (XEXP (exp, 1)) == NOT
&& GET_CODE (XEXP (XEXP (exp, 1), 0)) == EQ_ATTR))) && GET_CODE (XEXP (XEXP (exp, 1), 0)) == EQ_ATTR)))
attrs_cached attrs_cached
= write_test_expr (XEXP (exp, 1), attrs_cached, flags); = write_test_expr (outf, XEXP (exp, 1), attrs_cached, flags);
else else
write_test_expr (XEXP (exp, 1), attrs_cached, write_test_expr (outf, XEXP (exp, 1), attrs_cached,
flags | comparison_operator); flags | comparison_operator);
break; break;
...@@ -3421,12 +3439,14 @@ write_test_expr (rtx exp, unsigned int attrs_cached, int flags) ...@@ -3421,12 +3439,14 @@ write_test_expr (rtx exp, unsigned int attrs_cached, int flags)
{ {
if (XSTR (XEXP (exp, 0), 0) == alternative_name) if (XSTR (XEXP (exp, 0), 0) == alternative_name)
{ {
printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1)); fprintf (outf, "which_alternative != %s",
XSTR (XEXP (exp, 0), 1));
break; break;
} }
printf ("! "); fprintf (outf, "! ");
attrs_cached = write_test_expr (XEXP (exp, 0), attrs_cached, flags); attrs_cached =
write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
break; break;
} }
...@@ -3438,22 +3458,22 @@ write_test_expr (rtx exp, unsigned int attrs_cached, int flags) ...@@ -3438,22 +3458,22 @@ write_test_expr (rtx exp, unsigned int attrs_cached, int flags)
{ {
case NOT: case NOT:
if (flags & FLG_BITWISE) if (flags & FLG_BITWISE)
printf ("~ "); fprintf (outf, "~ ");
else else
printf ("! "); fprintf (outf, "! ");
break; break;
case ABS: case ABS:
printf ("abs "); fprintf (outf, "abs ");
break; break;
case NEG: case NEG:
printf ("-"); fprintf (outf, "-");
break; break;
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
flags &= ~(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND); flags &= ~(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND);
write_test_expr (XEXP (exp, 0), attrs_cached, flags); write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
break; break;
case EQ_ATTR_ALT: case EQ_ATTR_ALT:
...@@ -3491,13 +3511,13 @@ write_test_expr (rtx exp, unsigned int attrs_cached, int flags) ...@@ -3491,13 +3511,13 @@ write_test_expr (rtx exp, unsigned int attrs_cached, int flags)
if (!(set & 1)) if (!(set & 1))
bit++; bit++;
printf ("which_alternative %s= %d", fprintf (outf, "which_alternative %s= %d",
XINT (exp, 1) ? "!" : "=", bit); XINT (exp, 1) ? "!" : "=", bit);
} }
else else
{ {
printf ("%s((1 << which_alternative) & %#x)", fprintf (outf, "%s((1 << which_alternative) & %#x)",
XINT (exp, 1) ? "!" : "", set); XINT (exp, 1) ? "!" : "", set);
} }
} }
break; break;
...@@ -3511,7 +3531,7 @@ write_test_expr (rtx exp, unsigned int attrs_cached, int flags) ...@@ -3511,7 +3531,7 @@ write_test_expr (rtx exp, unsigned int attrs_cached, int flags)
if (XSTR (exp, 0) == alternative_name) if (XSTR (exp, 0) == alternative_name)
{ {
printf ("which_alternative == %s", XSTR (exp, 1)); fprintf (outf, "which_alternative == %s", XSTR (exp, 1));
break; break;
} }
...@@ -3521,8 +3541,10 @@ write_test_expr (rtx exp, unsigned int attrs_cached, int flags) ...@@ -3521,8 +3541,10 @@ write_test_expr (rtx exp, unsigned int attrs_cached, int flags)
/* Now is the time to expand the value of a constant attribute. */ /* Now is the time to expand the value of a constant attribute. */
if (attr->is_const) if (attr->is_const)
{ {
write_test_expr (evaluate_eq_attr (exp, attr, write_test_expr (outf,
attr->default_val->value, -2, -2), evaluate_eq_attr (exp, attr,
attr->default_val->value,
-2, -2),
attrs_cached, 0); attrs_cached, 0);
} }
else else
...@@ -3532,10 +3554,10 @@ write_test_expr (rtx exp, unsigned int attrs_cached, int flags) ...@@ -3532,10 +3554,10 @@ write_test_expr (rtx exp, unsigned int attrs_cached, int flags)
if (attr->name == cached_attrs[i]) if (attr->name == cached_attrs[i])
break; break;
if (i < cached_attr_count && (attrs_cached & (1U << i)) != 0) if (i < cached_attr_count && (attrs_cached & (1U << i)) != 0)
printf ("cached_%s", attr->name); fprintf (outf, "cached_%s", attr->name);
else if (i < cached_attr_count && (attrs_to_cache & (1U << i)) != 0) else if (i < cached_attr_count && (attrs_to_cache & (1U << i)) != 0)
{ {
printf ("(cached_%s = get_attr_%s (insn))", fprintf (outf, "(cached_%s = get_attr_%s (insn))",
attr->name, attr->name); attr->name, attr->name);
if (flags & FLG_AFTER) if (flags & FLG_AFTER)
attrs_cached_after |= (1U << i); attrs_cached_after |= (1U << i);
...@@ -3544,9 +3566,9 @@ write_test_expr (rtx exp, unsigned int attrs_cached, int flags) ...@@ -3544,9 +3566,9 @@ write_test_expr (rtx exp, unsigned int attrs_cached, int flags)
attrs_cached |= (1U << i); attrs_cached |= (1U << i);
} }
else else
printf ("get_attr_%s (insn)", attr->name); fprintf (outf, "get_attr_%s (insn)", attr->name);
printf (" == "); fprintf (outf, " == ");
write_attr_valueq (attr, XSTR (exp, 1)); write_attr_valueq (outf, attr, XSTR (exp, 1));
} }
break; break;
...@@ -3554,7 +3576,7 @@ write_test_expr (rtx exp, unsigned int attrs_cached, int flags) ...@@ -3554,7 +3576,7 @@ write_test_expr (rtx exp, unsigned int attrs_cached, int flags)
case ATTR_FLAG: case ATTR_FLAG:
if (flags & FLG_BITWISE) if (flags & FLG_BITWISE)
fatal ("ATTR_FLAG not valid inside comparison"); fatal ("ATTR_FLAG not valid inside comparison");
printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0)); fprintf (outf, "(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
break; break;
/* See if an operand matches a predicate. */ /* See if an operand matches a predicate. */
...@@ -3566,34 +3588,35 @@ write_test_expr (rtx exp, unsigned int attrs_cached, int flags) ...@@ -3566,34 +3588,35 @@ write_test_expr (rtx exp, unsigned int attrs_cached, int flags)
if (GET_MODE (exp) == VOIDmode) if (GET_MODE (exp) == VOIDmode)
fatal ("null MATCH_OPERAND specified as test"); fatal ("null MATCH_OPERAND specified as test");
else else
printf ("GET_MODE (operands[%d]) == %smode", fprintf (outf, "GET_MODE (operands[%d]) == %smode",
XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp))); XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
} }
else else
printf ("%s (operands[%d], %smode)", fprintf (outf, "%s (operands[%d], %smode)",
XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp))); XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
break; break;
/* Constant integer. */ /* Constant integer. */
case CONST_INT: case CONST_INT:
printf (HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0)); fprintf (outf, HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
break; break;
case MATCH_TEST: case MATCH_TEST:
print_c_condition (XSTR (exp, 0)); fprint_c_condition (outf, XSTR (exp, 0));
if (flags & FLG_BITWISE) if (flags & FLG_BITWISE)
printf (" != 0"); fprintf (outf, " != 0");
break; break;
/* A random C expression. */ /* A random C expression. */
case SYMBOL_REF: case SYMBOL_REF:
print_c_condition (XSTR (exp, 0)); fprint_c_condition (outf, XSTR (exp, 0));
break; break;
/* The address of the branch target. */ /* The address of the branch target. */
case MATCH_DUP: case MATCH_DUP:
printf ("INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0", fprintf (outf,
XINT (exp, 0), XINT (exp, 0), XINT (exp, 0)); "INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
break; break;
case PC: case PC:
...@@ -3602,19 +3625,19 @@ write_test_expr (rtx exp, unsigned int attrs_cached, int flags) ...@@ -3602,19 +3625,19 @@ write_test_expr (rtx exp, unsigned int attrs_cached, int flags)
address of the next insn for forward branches, and both with address of the next insn for forward branches, and both with
adjustments that account for the worst-case possible stretching of adjustments that account for the worst-case possible stretching of
intervening alignments between this insn and its destination. */ intervening alignments between this insn and its destination. */
printf ("insn_current_reference_address (insn)"); fprintf (outf, "insn_current_reference_address (insn)");
break; break;
case CONST_STRING: case CONST_STRING:
printf ("%s", XSTR (exp, 0)); fprintf (outf, "%s", XSTR (exp, 0));
break; break;
case IF_THEN_ELSE: case IF_THEN_ELSE:
write_test_expr (XEXP (exp, 0), attrs_cached, 0); write_test_expr (outf, XEXP (exp, 0), attrs_cached, 0);
printf (" ? "); fprintf (outf, " ? ");
write_test_expr (XEXP (exp, 1), attrs_cached, FLG_BITWISE); write_test_expr (outf, XEXP (exp, 1), attrs_cached, FLG_BITWISE);
printf (" : "); fprintf (outf, " : ");
write_test_expr (XEXP (exp, 2), attrs_cached, FLG_BITWISE); write_test_expr (outf, XEXP (exp, 2), attrs_cached, FLG_BITWISE);
break; break;
default: default:
...@@ -3622,7 +3645,7 @@ write_test_expr (rtx exp, unsigned int attrs_cached, int flags) ...@@ -3622,7 +3645,7 @@ write_test_expr (rtx exp, unsigned int attrs_cached, int flags)
GET_RTX_NAME (code)); GET_RTX_NAME (code));
} }
printf (")"); fprintf (outf, ")");
return attrs_cached; return attrs_cached;
} }
...@@ -3826,7 +3849,7 @@ walk_attr_value (rtx exp) ...@@ -3826,7 +3849,7 @@ walk_attr_value (rtx exp)
/* Write out a function to obtain the attribute for a given INSN. */ /* Write out a function to obtain the attribute for a given INSN. */
static void static void
write_attr_get (struct attr_desc *attr) write_attr_get (FILE *outf, struct attr_desc *attr)
{ {
struct attr_value *av, *common_av; struct attr_value *av, *common_av;
int i, j; int i, j;
...@@ -3838,37 +3861,37 @@ write_attr_get (struct attr_desc *attr) ...@@ -3838,37 +3861,37 @@ write_attr_get (struct attr_desc *attr)
/* Write out start of function, then all values with explicit `case' lines, /* Write out start of function, then all values with explicit `case' lines,
then a `default', then the value with the most uses. */ then a `default', then the value with the most uses. */
if (attr->enum_name) if (attr->enum_name)
printf ("enum %s\n", attr->enum_name); fprintf (outf, "enum %s\n", attr->enum_name);
else if (!attr->is_numeric) else if (!attr->is_numeric)
printf ("enum attr_%s\n", attr->name); fprintf (outf, "enum attr_%s\n", attr->name);
else else
printf ("int\n"); fprintf (outf, "int\n");
/* If the attribute name starts with a star, the remainder is the name of /* If the attribute name starts with a star, the remainder is the name of
the subroutine to use, instead of `get_attr_...'. */ the subroutine to use, instead of `get_attr_...'. */
if (attr->name[0] == '*') if (attr->name[0] == '*')
printf ("%s (rtx insn ATTRIBUTE_UNUSED)\n", &attr->name[1]); fprintf (outf, "%s (rtx insn ATTRIBUTE_UNUSED)\n", &attr->name[1]);
else if (attr->is_const == 0) else if (attr->is_const == 0)
printf ("get_attr_%s (rtx insn ATTRIBUTE_UNUSED)\n", attr->name); fprintf (outf, "get_attr_%s (rtx insn ATTRIBUTE_UNUSED)\n", attr->name);
else else
{ {
printf ("get_attr_%s (void)\n", attr->name); fprintf (outf, "get_attr_%s (void)\n", attr->name);
printf ("{\n"); fprintf (outf, "{\n");
for (av = attr->first_value; av; av = av->next) for (av = attr->first_value; av; av = av->next)
if (av->num_insns == 1) if (av->num_insns == 1)
write_attr_set (attr, 2, av->value, "return", ";", write_attr_set (outf, attr, 2, av->value, "return", ";",
true_rtx, av->first_insn->def->insn_code, true_rtx, av->first_insn->def->insn_code,
av->first_insn->def->insn_index, 0); av->first_insn->def->insn_index, 0);
else if (av->num_insns != 0) else if (av->num_insns != 0)
write_attr_set (attr, 2, av->value, "return", ";", write_attr_set (outf, attr, 2, av->value, "return", ";",
true_rtx, -2, 0, 0); true_rtx, -2, 0, 0);
printf ("}\n\n"); fprintf (outf, "}\n\n");
return; return;
} }
printf ("{\n"); fprintf (outf, "{\n");
/* Find attributes that are worth caching in the conditions. */ /* Find attributes that are worth caching in the conditions. */
cached_attr_count = 0; cached_attr_count = 0;
...@@ -3889,27 +3912,27 @@ write_attr_get (struct attr_desc *attr) ...@@ -3889,27 +3912,27 @@ write_attr_get (struct attr_desc *attr)
cached_attr = find_attr (&name, 0); cached_attr = find_attr (&name, 0);
gcc_assert (cached_attr && cached_attr->is_const == 0); gcc_assert (cached_attr && cached_attr->is_const == 0);
if (cached_attr->enum_name) if (cached_attr->enum_name)
printf (" enum %s", cached_attr->enum_name); fprintf (outf, " enum %s", cached_attr->enum_name);
else if (!cached_attr->is_numeric) else if (!cached_attr->is_numeric)
printf (" enum attr_%s", cached_attr->name); fprintf (outf, " enum attr_%s", cached_attr->name);
else else
printf (" int"); fprintf (outf, " int");
printf (" cached_%s ATTRIBUTE_UNUSED;\n", name); fprintf (outf, " cached_%s ATTRIBUTE_UNUSED;\n", name);
j++; j++;
} }
cached_attr_count = j; cached_attr_count = j;
if (cached_attr_count) if (cached_attr_count)
printf ("\n"); fprintf (outf, "\n");
printf (" switch (recog_memoized (insn))\n"); fprintf (outf, " switch (recog_memoized (insn))\n");
printf (" {\n"); fprintf (outf, " {\n");
for (av = attr->first_value; av; av = av->next) for (av = attr->first_value; av; av = av->next)
if (av != common_av) if (av != common_av)
write_attr_case (attr, av, 1, "return", ";", 4, true_rtx); write_attr_case (outf, attr, av, 1, "return", ";", 4, true_rtx);
write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx); write_attr_case (outf, attr, common_av, 0, "return", ";", 4, true_rtx);
printf (" }\n}\n\n"); fprintf (outf, " }\n}\n\n");
cached_attr_count = 0; cached_attr_count = 0;
} }
...@@ -3947,7 +3970,7 @@ eliminate_known_true (rtx known_true, rtx exp, int insn_code, int insn_index) ...@@ -3947,7 +3970,7 @@ eliminate_known_true (rtx known_true, rtx exp, int insn_code, int insn_index)
and ";"). */ and ";"). */
static void static void
write_attr_set (struct attr_desc *attr, int indent, rtx value, write_attr_set (FILE *outf, struct attr_desc *attr, int indent, rtx value,
const char *prefix, const char *suffix, rtx known_true, const char *prefix, const char *suffix, rtx known_true,
int insn_code, int insn_index, unsigned int attrs_cached) int insn_code, int insn_index, unsigned int attrs_cached)
{ {
...@@ -4002,49 +4025,49 @@ write_attr_set (struct attr_desc *attr, int indent, rtx value, ...@@ -4002,49 +4025,49 @@ write_attr_set (struct attr_desc *attr, int indent, rtx value,
attrs_cached_inside = attrs_cached; attrs_cached_inside = attrs_cached;
attrs_cached_after = attrs_cached; attrs_cached_after = attrs_cached;
write_indent (indent); write_indent (outf, indent);
printf ("%sif ", first_if ? "" : "else "); fprintf (outf, "%sif ", first_if ? "" : "else ");
first_if = 0; first_if = 0;
write_test_expr (testexp, attrs_cached, write_test_expr (outf, testexp, attrs_cached,
(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND)); (FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND));
attrs_cached = attrs_cached_after; attrs_cached = attrs_cached_after;
printf ("\n"); fprintf (outf, "\n");
write_indent (indent + 2); write_indent (outf, indent + 2);
printf ("{\n"); fprintf (outf, "{\n");
write_attr_set (attr, indent + 4, write_attr_set (outf, attr, indent + 4,
XVECEXP (value, 0, i + 1), prefix, suffix, XVECEXP (value, 0, i + 1), prefix, suffix,
inner_true, insn_code, insn_index, inner_true, insn_code, insn_index,
attrs_cached_inside); attrs_cached_inside);
write_indent (indent + 2); write_indent (outf, indent + 2);
printf ("}\n"); fprintf (outf, "}\n");
our_known_true = newexp; our_known_true = newexp;
} }
if (! first_if) if (! first_if)
{ {
write_indent (indent); write_indent (outf, indent);
printf ("else\n"); fprintf (outf, "else\n");
write_indent (indent + 2); write_indent (outf, indent + 2);
printf ("{\n"); fprintf (outf, "{\n");
} }
write_attr_set (attr, first_if ? indent : indent + 4, default_val, write_attr_set (outf, attr, first_if ? indent : indent + 4, default_val,
prefix, suffix, our_known_true, insn_code, insn_index, prefix, suffix, our_known_true, insn_code, insn_index,
attrs_cached); attrs_cached);
if (! first_if) if (! first_if)
{ {
write_indent (indent + 2); write_indent (outf, indent + 2);
printf ("}\n"); fprintf (outf, "}\n");
} }
} }
else else
{ {
write_indent (indent); write_indent (outf, indent);
printf ("%s ", prefix); fprintf (outf, "%s ", prefix);
write_attr_value (attr, value); write_attr_value (outf, attr, value);
printf ("%s\n", suffix); fprintf (outf, "%s\n", suffix);
} }
} }
...@@ -4052,25 +4075,25 @@ write_attr_set (struct attr_desc *attr, int indent, rtx value, ...@@ -4052,25 +4075,25 @@ write_attr_set (struct attr_desc *attr, int indent, rtx value,
INDENT is the amount of indentation to write before each case. */ INDENT is the amount of indentation to write before each case. */
static void static void
write_insn_cases (struct insn_ent *ie, int indent) write_insn_cases (FILE *outf, struct insn_ent *ie, int indent)
{ {
for (; ie != 0; ie = ie->next) for (; ie != 0; ie = ie->next)
if (ie->def->insn_code != -1) if (ie->def->insn_code != -1)
{ {
write_indent (indent); write_indent (outf, indent);
if (GET_CODE (ie->def->def) == DEFINE_PEEPHOLE) if (GET_CODE (ie->def->def) == DEFINE_PEEPHOLE)
printf ("case %d: /* define_peephole, line %d */\n", fprintf (outf, "case %d: /* define_peephole, line %d */\n",
ie->def->insn_code, ie->def->lineno); ie->def->insn_code, ie->def->lineno);
else else
printf ("case %d: /* %s */\n", fprintf (outf, "case %d: /* %s */\n",
ie->def->insn_code, XSTR (ie->def->def, 0)); ie->def->insn_code, XSTR (ie->def->def, 0));
} }
} }
/* Write out the computation for one attribute value. */ /* Write out the computation for one attribute value. */
static void static void
write_attr_case (struct attr_desc *attr, struct attr_value *av, write_attr_case (FILE *outf, struct attr_desc *attr, struct attr_value *av,
int write_case_lines, const char *prefix, const char *suffix, int write_case_lines, const char *prefix, const char *suffix,
int indent, rtx known_true) int indent, rtx known_true)
{ {
...@@ -4079,22 +4102,22 @@ write_attr_case (struct attr_desc *attr, struct attr_value *av, ...@@ -4079,22 +4102,22 @@ write_attr_case (struct attr_desc *attr, struct attr_value *av,
if (av->has_asm_insn) if (av->has_asm_insn)
{ {
write_indent (indent); write_indent (outf, indent);
printf ("case -1:\n"); fprintf (outf, "case -1:\n");
write_indent (indent + 2); write_indent (outf, indent + 2);
printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n"); fprintf (outf, "if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
write_indent (indent + 2); write_indent (outf, indent + 2);
printf (" && asm_noperands (PATTERN (insn)) < 0)\n"); fprintf (outf, " && asm_noperands (PATTERN (insn)) < 0)\n");
write_indent (indent + 2); write_indent (outf, indent + 2);
printf (" fatal_insn_not_found (insn);\n"); fprintf (outf, " fatal_insn_not_found (insn);\n");
} }
if (write_case_lines) if (write_case_lines)
write_insn_cases (av->first_insn, indent); write_insn_cases (outf, av->first_insn, indent);
else else
{ {
write_indent (indent); write_indent (outf, indent);
printf ("default:\n"); fprintf (outf, "default:\n");
} }
/* See what we have to do to output this value. */ /* See what we have to do to output this value. */
...@@ -4103,85 +4126,85 @@ write_attr_case (struct attr_desc *attr, struct attr_value *av, ...@@ -4103,85 +4126,85 @@ write_attr_case (struct attr_desc *attr, struct attr_value *av,
if (must_constrain) if (must_constrain)
{ {
write_indent (indent + 2); write_indent (outf, indent + 2);
printf ("extract_constrain_insn_cached (insn);\n"); fprintf (outf, "extract_constrain_insn_cached (insn);\n");
} }
else if (must_extract) else if (must_extract)
{ {
write_indent (indent + 2); write_indent (outf, indent + 2);
printf ("extract_insn_cached (insn);\n"); fprintf (outf, "extract_insn_cached (insn);\n");
} }
attrs_to_cache = 0; attrs_to_cache = 0;
if (av->num_insns == 1) if (av->num_insns == 1)
write_attr_set (attr, indent + 2, av->value, prefix, suffix, write_attr_set (outf, attr, indent + 2, av->value, prefix, suffix,
known_true, av->first_insn->def->insn_code, known_true, av->first_insn->def->insn_code,
av->first_insn->def->insn_index, 0); av->first_insn->def->insn_index, 0);
else else
write_attr_set (attr, indent + 2, av->value, prefix, suffix, write_attr_set (outf, attr, indent + 2, av->value, prefix, suffix,
known_true, -2, 0, 0); known_true, -2, 0, 0);
if (strncmp (prefix, "return", 6)) if (strncmp (prefix, "return", 6))
{ {
write_indent (indent + 2); write_indent (outf, indent + 2);
printf ("break;\n"); fprintf (outf, "break;\n");
} }
printf ("\n"); fprintf (outf, "\n");
} }
/* Utilities to write in various forms. */ /* Utilities to write in various forms. */
static void static void
write_attr_valueq (struct attr_desc *attr, const char *s) write_attr_valueq (FILE *outf, struct attr_desc *attr, const char *s)
{ {
if (attr->is_numeric) if (attr->is_numeric)
{ {
int num = atoi (s); int num = atoi (s);
printf ("%d", num); fprintf (outf, "%d", num);
if (num > 9 || num < 0) if (num > 9 || num < 0)
printf (" /* %#x */", num); fprintf (outf, " /* %#x */", num);
} }
else else
{ {
write_upcase (attr->enum_name ? attr->enum_name : attr->name); write_upcase (outf, attr->enum_name ? attr->enum_name : attr->name);
printf ("_"); fprintf (outf, "_");
write_upcase (s); write_upcase (outf, s);
} }
} }
static void static void
write_attr_value (struct attr_desc *attr, rtx value) write_attr_value (FILE *outf, struct attr_desc *attr, rtx value)
{ {
int op; int op;
switch (GET_CODE (value)) switch (GET_CODE (value))
{ {
case CONST_STRING: case CONST_STRING:
write_attr_valueq (attr, XSTR (value, 0)); write_attr_valueq (outf, attr, XSTR (value, 0));
break; break;
case CONST_INT: case CONST_INT:
printf (HOST_WIDE_INT_PRINT_DEC, INTVAL (value)); fprintf (outf, HOST_WIDE_INT_PRINT_DEC, INTVAL (value));
break; break;
case SYMBOL_REF: case SYMBOL_REF:
print_c_condition (XSTR (value, 0)); fprint_c_condition (outf, XSTR (value, 0));
break; break;
case ATTR: case ATTR:
{ {
struct attr_desc *attr2 = find_attr (&XSTR (value, 0), 0); struct attr_desc *attr2 = find_attr (&XSTR (value, 0), 0);
if (attr->enum_name) if (attr->enum_name)
printf ("(enum %s)", attr->enum_name); fprintf (outf, "(enum %s)", attr->enum_name);
else if (!attr->is_numeric) else if (!attr->is_numeric)
printf ("(enum attr_%s)", attr->name); fprintf (outf, "(enum attr_%s)", attr->name);
else if (!attr2->is_numeric) else if (!attr2->is_numeric)
printf ("(int)"); fprintf (outf, "(int)");
printf ("get_attr_%s (%s)", attr2->name, fprintf (outf, "get_attr_%s (%s)", attr2->name,
(attr2->is_const ? "" : "insn")); (attr2->is_const ? "" : "insn"));
} }
break; break;
...@@ -4202,11 +4225,11 @@ write_attr_value (struct attr_desc *attr, rtx value) ...@@ -4202,11 +4225,11 @@ write_attr_value (struct attr_desc *attr, rtx value)
goto do_operator; goto do_operator;
do_operator: do_operator:
write_attr_value (attr, XEXP (value, 0)); write_attr_value (outf, attr, XEXP (value, 0));
putchar (' '); fputc (' ', outf);
putchar (op); fputc (op, outf);
putchar (' '); fputc (' ', outf);
write_attr_value (attr, XEXP (value, 1)); write_attr_value (outf, attr, XEXP (value, 1));
break; break;
default: default:
...@@ -4215,24 +4238,24 @@ write_attr_value (struct attr_desc *attr, rtx value) ...@@ -4215,24 +4238,24 @@ write_attr_value (struct attr_desc *attr, rtx value)
} }
static void static void
write_upcase (const char *str) write_upcase (FILE *outf, const char *str)
{ {
while (*str) while (*str)
{ {
/* The argument of TOUPPER should not have side effects. */ /* The argument of TOUPPER should not have side effects. */
putchar (TOUPPER(*str)); fputc (TOUPPER(*str), outf);
str++; str++;
} }
} }
static void static void
write_indent (int indent) write_indent (FILE *outf, int indent)
{ {
for (; indent > 8; indent -= 8) for (; indent > 8; indent -= 8)
printf ("\t"); fprintf (outf, "\t");
for (; indent; indent--) for (; indent; indent--)
printf (" "); fprintf (outf, " ");
} }
/* Write a subroutine that is given an insn that requires a delay slot, a /* Write a subroutine that is given an insn that requires a delay slot, a
...@@ -4248,7 +4271,7 @@ write_indent (int indent) ...@@ -4248,7 +4271,7 @@ write_indent (int indent)
or "annul_false"). */ or "annul_false"). */
static void static void
write_eligible_delay (const char *kind) write_eligible_delay (FILE *outf, const char *kind)
{ {
struct delay_desc *delay; struct delay_desc *delay;
int max_slots; int max_slots;
...@@ -4268,19 +4291,20 @@ write_eligible_delay (const char *kind) ...@@ -4268,19 +4291,20 @@ write_eligible_delay (const char *kind)
/* Write function prelude. */ /* Write function prelude. */
printf ("int\n"); fprintf (outf, "int\n");
printf ("eligible_for_%s (rtx delay_insn ATTRIBUTE_UNUSED, int slot, rtx candidate_insn, int flags ATTRIBUTE_UNUSED)\n", fprintf (outf, "eligible_for_%s (rtx delay_insn ATTRIBUTE_UNUSED, int slot, \n"
kind); " rtx candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
printf ("{\n"); kind);
printf (" rtx insn;\n"); fprintf (outf, "{\n");
printf ("\n"); fprintf (outf, " rtx insn;\n");
printf (" gcc_assert (slot < %d);\n", max_slots); fprintf (outf, "\n");
printf ("\n"); fprintf (outf, " gcc_assert (slot < %d);\n", max_slots);
fprintf (outf, "\n");
/* Allow dbr_schedule to pass labels, etc. This can happen if try_split /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
converts a compound instruction into a loop. */ converts a compound instruction into a loop. */
printf (" if (!INSN_P (candidate_insn))\n"); fprintf (outf, " if (!INSN_P (candidate_insn))\n");
printf (" return 0;\n"); fprintf (outf, " return 0;\n");
printf ("\n"); fprintf (outf, "\n");
/* If more than one delay type, find out which type the delay insn is. */ /* If more than one delay type, find out which type the delay insn is. */
...@@ -4290,28 +4314,28 @@ write_eligible_delay (const char *kind) ...@@ -4290,28 +4314,28 @@ write_eligible_delay (const char *kind)
gcc_assert (attr); gcc_assert (attr);
common_av = find_most_used (attr); common_av = find_most_used (attr);
printf (" insn = delay_insn;\n"); fprintf (outf, " insn = delay_insn;\n");
printf (" switch (recog_memoized (insn))\n"); fprintf (outf, " switch (recog_memoized (insn))\n");
printf (" {\n"); fprintf (outf, " {\n");
sprintf (str, " * %d;\n break;", max_slots); sprintf (str, " * %d;\n break;", max_slots);
for (av = attr->first_value; av; av = av->next) for (av = attr->first_value; av; av = av->next)
if (av != common_av) if (av != common_av)
write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx); write_attr_case (outf, attr, av, 1, "slot +=", str, 4, true_rtx);
write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx); write_attr_case (outf, attr, common_av, 0, "slot +=", str, 4, true_rtx);
printf (" }\n\n"); fprintf (outf, " }\n\n");
/* Ensure matched. Otherwise, shouldn't have been called. */ /* Ensure matched. Otherwise, shouldn't have been called. */
printf (" gcc_assert (slot >= %d);\n\n", max_slots); fprintf (outf, " gcc_assert (slot >= %d);\n\n", max_slots);
} }
/* If just one type of delay slot, write simple switch. */ /* If just one type of delay slot, write simple switch. */
if (num_delays == 1 && max_slots == 1) if (num_delays == 1 && max_slots == 1)
{ {
printf (" insn = candidate_insn;\n"); fprintf (outf, " insn = candidate_insn;\n");
printf (" switch (recog_memoized (insn))\n"); fprintf (outf, " switch (recog_memoized (insn))\n");
printf (" {\n"); fprintf (outf, " {\n");
attr = find_attr (&delay_1_0_str, 0); attr = find_attr (&delay_1_0_str, 0);
gcc_assert (attr); gcc_assert (attr);
...@@ -4319,27 +4343,27 @@ write_eligible_delay (const char *kind) ...@@ -4319,27 +4343,27 @@ write_eligible_delay (const char *kind)
for (av = attr->first_value; av; av = av->next) for (av = attr->first_value; av; av = av->next)
if (av != common_av) if (av != common_av)
write_attr_case (attr, av, 1, "return", ";", 4, true_rtx); write_attr_case (outf, attr, av, 1, "return", ";", 4, true_rtx);
write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx); write_attr_case (outf, attr, common_av, 0, "return", ";", 4, true_rtx);
printf (" }\n"); fprintf (outf, " }\n");
} }
else else
{ {
/* Write a nested CASE. The first indicates which condition we need to /* Write a nested CASE. The first indicates which condition we need to
test, and the inner CASE tests the condition. */ test, and the inner CASE tests the condition. */
printf (" insn = candidate_insn;\n"); fprintf (outf, " insn = candidate_insn;\n");
printf (" switch (slot)\n"); fprintf (outf, " switch (slot)\n");
printf (" {\n"); fprintf (outf, " {\n");
for (delay = delays; delay; delay = delay->next) for (delay = delays; delay; delay = delay->next)
for (i = 0; i < XVECLEN (delay->def, 1); i += 3) for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
{ {
printf (" case %d:\n", fprintf (outf, " case %d:\n",
(i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots)); (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
printf (" switch (recog_memoized (insn))\n"); fprintf (outf, " switch (recog_memoized (insn))\n");
printf ("\t{\n"); fprintf (outf, "\t{\n");
sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3); sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
pstr = str; pstr = str;
...@@ -4349,18 +4373,18 @@ write_eligible_delay (const char *kind) ...@@ -4349,18 +4373,18 @@ write_eligible_delay (const char *kind)
for (av = attr->first_value; av; av = av->next) for (av = attr->first_value; av; av = av->next)
if (av != common_av) if (av != common_av)
write_attr_case (attr, av, 1, "return", ";", 8, true_rtx); write_attr_case (outf, attr, av, 1, "return", ";", 8, true_rtx);
write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx); write_attr_case (outf, attr, common_av, 0, "return", ";", 8, true_rtx);
printf (" }\n"); fprintf (outf, " }\n");
} }
printf (" default:\n"); fprintf (outf, " default:\n");
printf (" gcc_unreachable ();\n"); fprintf (outf, " gcc_unreachable ();\n");
printf (" }\n"); fprintf (outf, " }\n");
} }
printf ("}\n\n"); fprintf (outf, "}\n\n");
} }
/* This page contains miscellaneous utility routines. */ /* This page contains miscellaneous utility routines. */
...@@ -4499,29 +4523,29 @@ copy_rtx_unchanging (rtx orig) ...@@ -4499,29 +4523,29 @@ copy_rtx_unchanging (rtx orig)
number of delay slots is not a function of the length of the insn. */ number of delay slots is not a function of the length of the insn. */
static void static void
write_const_num_delay_slots (void) write_const_num_delay_slots (FILE *outf)
{ {
struct attr_desc *attr = find_attr (&num_delay_slots_str, 0); struct attr_desc *attr = find_attr (&num_delay_slots_str, 0);
struct attr_value *av; struct attr_value *av;
if (attr) if (attr)
{ {
printf ("int\nconst_num_delay_slots (rtx insn)\n"); fprintf (outf, "int\nconst_num_delay_slots (rtx insn)\n");
printf ("{\n"); fprintf (outf, "{\n");
printf (" switch (recog_memoized (insn))\n"); fprintf (outf, " switch (recog_memoized (insn))\n");
printf (" {\n"); fprintf (outf, " {\n");
for (av = attr->first_value; av; av = av->next) for (av = attr->first_value; av; av = av->next)
{ {
length_used = 0; length_used = 0;
walk_attr_value (av->value); walk_attr_value (av->value);
if (length_used) if (length_used)
write_insn_cases (av->first_insn, 4); write_insn_cases (outf, av->first_insn, 4);
} }
printf (" default:\n"); fprintf (outf, " default:\n");
printf (" return 1;\n"); fprintf (outf, " return 1;\n");
printf (" }\n}\n\n"); fprintf (outf, " }\n}\n\n");
} }
} }
...@@ -4697,7 +4721,10 @@ find_tune_attr (rtx exp) ...@@ -4697,7 +4721,10 @@ find_tune_attr (rtx exp)
} }
} }
/* Create all of the attributes that describe automaton properties. */ /* Create all of the attributes that describe automaton properties.
Write the DFA and latency function prototypes to the files that
need to have them, and write the init_sched_attrs(). */
static void static void
make_automaton_attrs (void) make_automaton_attrs (void)
{ {
...@@ -4719,23 +4746,49 @@ make_automaton_attrs (void) ...@@ -4719,23 +4746,49 @@ make_automaton_attrs (void)
gcc_assert (tune_attr->is_const gcc_assert (tune_attr->is_const
&& !tune_attr->is_special && !tune_attr->is_special
&& !tune_attr->is_numeric); && !tune_attr->is_numeric);
/* Write the prototypes for all DFA functions. */
for (val = tune_attr->first_value; val; val = val->next)
{
if (val == tune_attr->default_val)
continue;
gcc_assert (GET_CODE (val->value) == CONST_STRING);
fprintf (dfa_file,
"extern int internal_dfa_insn_code_%s (rtx);\n",
XSTR (val->value, 0));
}
fprintf (dfa_file, "\n");
/* Write the prototypes for all latency functions. */
for (val = tune_attr->first_value; val; val = val->next) for (val = tune_attr->first_value; val; val = val->next)
{ {
if (val == tune_attr->default_val) if (val == tune_attr->default_val)
continue; continue;
gcc_assert (GET_CODE (val->value) == CONST_STRING); gcc_assert (GET_CODE (val->value) == CONST_STRING);
printf ("static int internal_dfa_insn_code_%s (rtx);\n" fprintf (latency_file,
"static int insn_default_latency_%s (rtx);\n", "extern int insn_default_latency_%s (rtx);\n",
XSTR (val->value, 0), XSTR (val->value, 0)); XSTR (val->value, 0));
} }
fprintf (latency_file, "\n");
printf ("\n"); /* Write the prototypes for all automaton functions. */
printf ("int (*internal_dfa_insn_code) (rtx);\n"); for (val = tune_attr->first_value; val; val = val->next)
printf ("int (*insn_default_latency) (rtx);\n"); {
printf ("\n"); if (val == tune_attr->default_val)
printf ("void\n"); continue;
printf ("init_sched_attrs (void)\n"); gcc_assert (GET_CODE (val->value) == CONST_STRING);
printf ("{\n"); fprintf (attr_file,
"extern int internal_dfa_insn_code_%s (rtx);\n"
"extern int insn_default_latency_%s (rtx);\n",
XSTR (val->value, 0), XSTR (val->value, 0));
}
fprintf (attr_file, "\n");
fprintf (attr_file, "int (*internal_dfa_insn_code) (rtx);\n");
fprintf (attr_file, "int (*insn_default_latency) (rtx);\n");
fprintf (attr_file, "\n");
fprintf (attr_file, "void\n");
fprintf (attr_file, "init_sched_attrs (void)\n");
fprintf (attr_file, "{\n");
for (val = tune_attr->first_value; val; val = val->next) for (val = tune_attr->first_value; val; val = val->next)
{ {
...@@ -4804,27 +4857,27 @@ make_automaton_attrs (void) ...@@ -4804,27 +4857,27 @@ make_automaton_attrs (void)
if (first) if (first)
{ {
printf (" if ("); fprintf (attr_file, " if (");
first = false; first = false;
} }
else else
printf (" else if ("); fprintf (attr_file, " else if (");
write_test_expr (test, 0, 0); write_test_expr (attr_file, test, 0, 0);
printf (")\n"); fprintf (attr_file, ")\n");
printf (" {\n"); fprintf (attr_file, " {\n");
printf (" internal_dfa_insn_code\n"); fprintf (attr_file, " internal_dfa_insn_code\n");
printf (" = internal_dfa_insn_code_%s;\n", fprintf (attr_file, " = internal_dfa_insn_code_%s;\n",
XSTR (val->value, 0)); XSTR (val->value, 0));
printf (" insn_default_latency\n"); fprintf (attr_file, " insn_default_latency\n");
printf (" = insn_default_latency_%s;\n", fprintf (attr_file, " = insn_default_latency_%s;\n",
XSTR (val->value, 0)); XSTR (val->value, 0));
printf (" }\n"); fprintf (attr_file, " }\n");
} }
printf (" else\n"); fprintf (attr_file, " else\n");
printf (" gcc_unreachable ();\n"); fprintf (attr_file, " gcc_unreachable ();\n");
printf ("}\n"); fprintf (attr_file, "}\n");
printf ("\n"); fprintf (attr_file, "\n");
XDELETEVEC (condexps); XDELETEVEC (condexps);
} }
...@@ -4874,7 +4927,62 @@ make_automaton_attrs (void) ...@@ -4874,7 +4927,62 @@ make_automaton_attrs (void)
} }
} }
make_internal_attr ("*bypass_p", byps_exp, ATTR_NONE); make_internal_attr ("*bypass_p", byps_exp, ATTR_NONE);
}
static void
write_header (FILE *outf)
{
fprintf (outf, "/* Generated automatically by the program `genattrtab'\n"
" from the machine description file `md'. */\n\n");
fprintf (outf, "#include \"config.h\"\n");
fprintf (outf, "#include \"system.h\"\n");
fprintf (outf, "#include \"coretypes.h\"\n");
fprintf (outf, "#include \"tm.h\"\n");
fprintf (outf, "#include \"rtl.h\"\n");
fprintf (outf, "#include \"insn-attr.h\"\n");
fprintf (outf, "#include \"tm_p.h\"\n");
fprintf (outf, "#include \"insn-config.h\"\n");
fprintf (outf, "#include \"recog.h\"\n");
fprintf (outf, "#include \"regs.h\"\n");
fprintf (outf, "#include \"real.h\"\n");
fprintf (outf, "#include \"output.h\"\n");
fprintf (outf, "#include \"toplev.h\"\n");
fprintf (outf, "#include \"flags.h\"\n");
fprintf (outf, "#include \"function.h\"\n");
fprintf (outf, "\n");
fprintf (outf, "#define operands recog_data.operand\n\n");
}
static FILE *
open_outfile (const char *file_name)
{
FILE *outf;
outf = fopen (file_name, "w");
if (! outf)
fatal ("cannot open file %s: %s", file_name, xstrerror (errno));
write_header (outf);
return outf;
}
static bool
handle_arg (const char *arg)
{
switch (arg[1])
{
case 'A':
attr_file_name = &arg[2];
return true;
case 'D':
dfa_file_name = &arg[2];
return true;
case 'L':
latency_file_name = &arg[2];
return true;
default:
return false;
}
} }
int int
...@@ -4888,8 +4996,12 @@ main (int argc, char **argv) ...@@ -4888,8 +4996,12 @@ main (int argc, char **argv)
progname = "genattrtab"; progname = "genattrtab";
if (!init_rtx_reader_args (argc, argv)) if (!init_rtx_reader_args_cb (argc, argv, handle_arg))
return (FATAL_EXIT_CODE); return FATAL_EXIT_CODE;
attr_file = open_outfile (attr_file_name);
dfa_file = open_outfile (dfa_file_name);
latency_file = open_outfile (latency_file_name);
obstack_init (hash_obstack); obstack_init (hash_obstack);
obstack_init (temp_obstack); obstack_init (temp_obstack);
...@@ -4908,9 +5020,6 @@ main (int argc, char **argv) ...@@ -4908,9 +5020,6 @@ main (int argc, char **argv)
delay_1_0_str = DEF_ATTR_STRING ("*delay_1_0"); delay_1_0_str = DEF_ATTR_STRING ("*delay_1_0");
num_delay_slots_str = DEF_ATTR_STRING ("*num_delay_slots"); num_delay_slots_str = DEF_ATTR_STRING ("*num_delay_slots");
printf ("/* Generated automatically by the program `genattrtab'\n\
from the machine description file `md'. */\n\n");
/* Read the machine description. */ /* Read the machine description. */
while (1) while (1)
...@@ -4970,23 +5079,6 @@ from the machine description file `md'. */\n\n"); ...@@ -4970,23 +5079,6 @@ from the machine description file `md'. */\n\n");
if (num_delays) if (num_delays)
expand_delays (); expand_delays ();
printf ("#include \"config.h\"\n");
printf ("#include \"system.h\"\n");
printf ("#include \"coretypes.h\"\n");
printf ("#include \"tm.h\"\n");
printf ("#include \"rtl.h\"\n");
printf ("#include \"insn-attr.h\"\n");
printf ("#include \"tm_p.h\"\n");
printf ("#include \"insn-config.h\"\n");
printf ("#include \"recog.h\"\n");
printf ("#include \"regs.h\"\n");
printf ("#include \"output.h\"\n");
printf ("#include \"diagnostic-core.h\"\n");
printf ("#include \"flags.h\"\n");
printf ("#include \"function.h\"\n");
printf ("\n");
printf ("#define operands recog_data.operand\n\n");
/* Make `insn_alternatives'. */ /* Make `insn_alternatives'. */
insn_alternatives = oballocvec (int, insn_code_number); insn_alternatives = oballocvec (int, insn_code_number);
for (id = defs; id; id = id->next) for (id = defs; id; id = id->next)
...@@ -5031,8 +5123,19 @@ from the machine description file `md'. */\n\n"); ...@@ -5031,8 +5123,19 @@ from the machine description file `md'. */\n\n");
for (i = 0; i < MAX_ATTRS_INDEX; i++) for (i = 0; i < MAX_ATTRS_INDEX; i++)
for (attr = attrs[i]; attr; attr = attr->next) for (attr = attrs[i]; attr; attr = attr->next)
{ {
FILE *outf;
#define IS_ATTR_GROUP(X) (!strncmp(attr->name,X,strlen(X)))
if (IS_ATTR_GROUP ("*internal_dfa_insn_code"))
outf = dfa_file;
else if (IS_ATTR_GROUP ("*insn_default_latency"))
outf = latency_file;
else
outf = attr_file;
#undef IS_ATTR_GROUP
if (! attr->is_special && ! attr->is_const) if (! attr->is_special && ! attr->is_const)
write_attr_get (attr); write_attr_get (outf, attr);
} }
/* Write out delay eligibility information, if DEFINE_DELAY present. /* Write out delay eligibility information, if DEFINE_DELAY present.
...@@ -5040,18 +5143,25 @@ from the machine description file `md'. */\n\n"); ...@@ -5040,18 +5143,25 @@ from the machine description file `md'. */\n\n");
below.) */ below.) */
if (num_delays) if (num_delays)
{ {
write_eligible_delay ("delay"); write_eligible_delay (attr_file, "delay");
if (have_annul_true) if (have_annul_true)
write_eligible_delay ("annul_true"); write_eligible_delay (attr_file, "annul_true");
if (have_annul_false) if (have_annul_false)
write_eligible_delay ("annul_false"); write_eligible_delay (attr_file, "annul_false");
} }
/* Write out constant delay slot info. */ /* Write out constant delay slot info. */
write_const_num_delay_slots (); write_const_num_delay_slots (attr_file);
write_length_unit_log (); write_length_unit_log (attr_file);
fflush (stdout); if (fclose (attr_file) != 0)
return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); fatal ("cannot close file %s: %s", attr_file_name, xstrerror (errno));
if (fclose (dfa_file) != 0)
fatal ("cannot close file %s: %s", dfa_file_name, xstrerror (errno));
if (fclose (latency_file) != 0)
fatal ("cannot close file %s: %s", latency_file_name, xstrerror (errno));
return SUCCESS_EXIT_CODE;
} }
...@@ -167,14 +167,21 @@ copy_md_ptr_loc (const void *new_ptr, const void *old_ptr) ...@@ -167,14 +167,21 @@ copy_md_ptr_loc (const void *new_ptr, const void *old_ptr)
} }
/* If PTR is associated with a known file position, print a #line /* If PTR is associated with a known file position, print a #line
directive for it. */ directive for it to OUTF. */
void void
print_md_ptr_loc (const void *ptr) fprint_md_ptr_loc (FILE *outf, const void *ptr)
{ {
const struct ptr_loc *loc = get_md_ptr_loc (ptr); const struct ptr_loc *loc = get_md_ptr_loc (ptr);
if (loc != 0) if (loc != 0)
printf ("#line %d \"%s\"\n", loc->lineno, loc->filename); fprintf (outf, "#line %d \"%s\"\n", loc->lineno, loc->filename);
}
/* Special fprint_md_ptr_loc for writing to STDOUT. */
void
print_md_ptr_loc (const void *ptr)
{
fprint_md_ptr_loc (stdout, ptr);
} }
/* Return a condition that satisfies both COND1 and COND2. Either string /* Return a condition that satisfies both COND1 and COND2. Either string
...@@ -204,31 +211,39 @@ join_c_conditions (const char *cond1, const char *cond2) ...@@ -204,31 +211,39 @@ join_c_conditions (const char *cond1, const char *cond2)
return result; return result;
} }
/* Print condition COND, wrapped in brackets. If COND was created by /* Print condition COND to OUTF, wrapped in brackets. If COND was created
join_c_conditions, recursively invoke this function for the original by join_c_conditions, recursively invoke this function for the original
conditions and join the result with "&&". Otherwise print a #line conditions and join the result with "&&". Otherwise print a #line
directive for COND if its original file position is known. */ directive for COND if its original file position is known. */
void void
print_c_condition (const char *cond) fprint_c_condition (FILE *outf, const char *cond)
{ {
const char **halves = (const char **) htab_find (joined_conditions, &cond); const char **halves = (const char **) htab_find (joined_conditions, &cond);
if (halves != 0) if (halves != 0)
{ {
printf ("("); fprintf (outf, "(");
print_c_condition (halves[1]); fprint_c_condition (outf, halves[1]);
printf (" && "); fprintf (outf, " && ");
print_c_condition (halves[2]); fprint_c_condition (outf, halves[2]);
printf (")"); fprintf (outf, ")");
} }
else else
{ {
putc ('\n', stdout); fputc ('\n', outf);
print_md_ptr_loc (cond); fprint_md_ptr_loc (outf, cond);
printf ("(%s)", cond); fprintf (outf, "(%s)", cond);
} }
} }
/* Special fprint_c_condition for writing to STDOUT. */
void
print_c_condition (const char *cond)
{
fprint_c_condition (stdout, cond);
}
/* A vfprintf-like function for reporting an error against line LINENO /* A vfprintf-like function for reporting an error against line LINENO
of the current MD file. */ of the current MD file. */
......
...@@ -118,8 +118,10 @@ extern hashval_t leading_string_hash (const void *); ...@@ -118,8 +118,10 @@ extern hashval_t leading_string_hash (const void *);
extern int leading_string_eq_p (const void *, const void *); extern int leading_string_eq_p (const void *, const void *);
extern void copy_md_ptr_loc (const void *, const void *); extern void copy_md_ptr_loc (const void *, const void *);
extern void print_md_ptr_loc (const void *); extern void print_md_ptr_loc (const void *);
extern void fprint_md_ptr_loc (FILE *, const void *);
extern const char *join_c_conditions (const char *, const char *); extern const char *join_c_conditions (const char *, const char *);
extern void print_c_condition (const char *); extern void print_c_condition (const char *);
extern void fprint_c_condition (FILE *, const char *);
extern void message_with_line (int, 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 error_with_line (int, const char *, ...) ATTRIBUTE_PRINTF_2;
extern void fatal_with_file_and_line (const char *, ...) extern void fatal_with_file_and_line (const char *, ...)
......
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