Commit e543e219 by Zack Weinberg

genpreds.c: Add capability to generate predicate bodies as well as function prototypes.

	* genpreds.c: Add capability to generate predicate bodies as
	well as function prototypes.  Write function prototypes for
	the generic predicates too.
	(process_define_predicate, write_tm_preds_h, write_insn_preds_c)
	(write_predicate_subfunction, mark_mode_tests, add_mode_tests)
	(write_match_code, write_predicate_expr, write_one_predicate_function)
	(parse_option): New functions.
	(output_predicate_decls): Delete.
	(main): Read the machine description, process DEFINE_PREDICATE or
	DEFINE_SPECIAL_PREDICATE patterns, write tm-preds.h or insn-preds.c
	as appropriate.

	* genrecog.c (struct decision_test): Replace index with
	struct pred_data pointer.
	(next_index): Remove, unused.
	(pred_table, preds, special_mode_pred_table): Delete.
	(compute_predicate_codes, process_define_predicate): New functions.
	(validate_pattern, add_to_sequence, write_switch): Update for
	new data structures.
	(main): Handle DEFINE_PREDICATE and DEFINE_SPECIAL_PREDICATE.
	Check both error_count and have_error.

	* gensupport.c (in_fname, first_predicate): New globals.
	(define_pred_queue, define_pred_tail): New RTL-pattern queue.
	(predicate_table, last_predicate, old_pred_table)
	(old_special_pred_table): New statics.
	(hash_struct_pred_data, eq_struct_pred_data, lookup_predicate)
	(add_predicate, init_predicate_table): New functions.
	(process_rtx): Handle DEFINE_PREDICATE and DEFINE_SPECIAL_PREDICATE.
	(init_md_reader_args_cb): Use the global in_fname.  No need to zero
	it or max_include_len.  Call init_predicate_table.
	(read_rtx): Run the predicate queue after the attribute queue
	but before all the others.
	* gensupport.h (in_fname, struct pred_data, first_predicate)
	(lookup_predicate, add_predicate, FOR_ALL_PREDICATES): Declare.
	* rtl.def (MATCH_CODE, MATCH_TEST, DEFINE_PREDICATE)
	(DEFINE_SPECIAL_PREDICATE): New RTL codes.
	* dummy-conditions.c: Don't include bconfig.h, system.h,
	coretypes.h, tm.h, or system.h.  Do include stddef.h.
	Duplicate declaration of struct c_test from gensupport.h.

	* Makefile.in (OBJS-common): Add insn-preds.o.
	(STAGESTUFF, .PRECIOUS): Add insn-preds.c.
	(insn-preds.c, insn-preds.o): New rules.
	(s-preds): Also generate insn-preds.c.
	(dummy-conditions.o, genpreds$(build_exeext), genpreds.o):
	Update dependencies.
	(print-rtl.o, print-rtl1.o): Correct dependencies.

	* recog.h: Delete prototypes of predicate functions.

	* doc/md.texi (Predicates): New section with complete
	documentation of operand/operator predicates.  Remove some
	incomplete documentation of predicates from other places.
	* doc/tm.texi (Misc): Move SPECIAL_MODE_PREDICATES next to
	PREDICATE_CODES; indicate that both are deprecated in favor
	of define_predicate/define_special_predicate.

	* config/ia64/ia64.c: All predicate function definitions moved
	to ia64.md, except
	(small_addr_symbolic_operand, tls_symbolic_operand): Delete.
	(ia64_expand_load_address, ia64_expand_move):
	Check SYMBOL_REF_TLS_MODEL directly, don't use tls_symbolic_operand.

	* config/ia64/ia64.md: All predicates now defined here.
	(symbolic_operand): Is now a special predicate.

	* config/ia64/ia64.h: Declare ia64_section_threshold.
	(PREDICATE_CODES): Delete.

From-SVN: r85855
parent b4d49f49
2004-08-12 Zack Weinberg <zack@codesourcery.com>
* genpreds.c: Add capability to generate predicate bodies as
well as function prototypes. Write function prototypes for
the generic predicates too.
(process_define_predicate, write_tm_preds_h, write_insn_preds_c)
(write_predicate_subfunction, mark_mode_tests, add_mode_tests)
(write_match_code, write_predicate_expr, write_one_predicate_function)
(parse_option): New functions.
(output_predicate_decls): Delete.
(main): Read the machine description, process DEFINE_PREDICATE or
DEFINE_SPECIAL_PREDICATE patterns, write tm-preds.h or insn-preds.c
as appropriate.
* genrecog.c (struct decision_test): Replace index with
struct pred_data pointer.
(next_index): Remove, unused.
(pred_table, preds, special_mode_pred_table): Delete.
(compute_predicate_codes, process_define_predicate): New functions.
(validate_pattern, add_to_sequence, write_switch): Update for
new data structures.
(main): Handle DEFINE_PREDICATE and DEFINE_SPECIAL_PREDICATE.
Check both error_count and have_error.
* gensupport.c (in_fname, first_predicate): New globals.
(define_pred_queue, define_pred_tail): New RTL-pattern queue.
(predicate_table, last_predicate, old_pred_table)
(old_special_pred_table): New statics.
(hash_struct_pred_data, eq_struct_pred_data, lookup_predicate)
(add_predicate, init_predicate_table): New functions.
(process_rtx): Handle DEFINE_PREDICATE and DEFINE_SPECIAL_PREDICATE.
(init_md_reader_args_cb): Use the global in_fname. No need to zero
it or max_include_len. Call init_predicate_table.
(read_rtx): Run the predicate queue after the attribute queue
but before all the others.
* gensupport.h (in_fname, struct pred_data, first_predicate)
(lookup_predicate, add_predicate, FOR_ALL_PREDICATES): Declare.
* rtl.def (MATCH_CODE, MATCH_TEST, DEFINE_PREDICATE)
(DEFINE_SPECIAL_PREDICATE): New RTL codes.
* dummy-conditions.c: Don't include bconfig.h, system.h,
coretypes.h, tm.h, or system.h. Do include stddef.h.
Duplicate declaration of struct c_test from gensupport.h.
* Makefile.in (OBJS-common): Add insn-preds.o.
(STAGESTUFF, .PRECIOUS): Add insn-preds.c.
(insn-preds.c, insn-preds.o): New rules.
(s-preds): Also generate insn-preds.c.
(dummy-conditions.o, genpreds$(build_exeext), genpreds.o):
Update dependencies.
(print-rtl.o, print-rtl1.o): Correct dependencies.
* recog.h: Delete prototypes of predicate functions.
* doc/md.texi (Predicates): New section with complete
documentation of operand/operator predicates. Remove some
incomplete documentation of predicates from other places.
* doc/tm.texi (Misc): Move SPECIAL_MODE_PREDICATES next to
PREDICATE_CODES; indicate that both are deprecated in favor
of define_predicate/define_special_predicate.
* config/ia64/ia64.c: All predicate function definitions moved
to ia64.md, except
(small_addr_symbolic_operand, tls_symbolic_operand): Delete.
(ia64_expand_load_address, ia64_expand_move):
Check SYMBOL_REF_TLS_MODEL directly, don't use tls_symbolic_operand.
* config/ia64/ia64.md: All predicates now defined here.
(symbolic_operand): Is now a special predicate.
* config/ia64/ia64.h: Declare ia64_section_threshold.
(PREDICATE_CODES): Delete.
2004-08-12 Richard Henderson <rth@redhat.com>
* c-common.h (STATEMENT_LIST_HAS_LABEL): New.
......@@ -8,7 +80,7 @@
2004-08-12 Richard Henderson <rth@redhat.com>
* stor-layout.c (round_up, round_down): Move ...
* fold-const.c (round_up, round_down): ... here. Use
* fold-const.c (round_up, round_down): ... here. Use
multiple_of_p to avoid any arithmetic at all.
2004-08-12 Richard Henderson <rth@redhat.com>
......@@ -56,7 +128,7 @@
(LINK_SPEC): Same.
* doc/invoke.texi (Darwin Options): Document -dead_strip and
-no_dead_strip_inits_and_terms.
2004-08-11 Paul Brook <paul@codesourcery.com>
* config/arm/arm-protos.h (arm_finalize_pic) Rename ...
......@@ -102,15 +174,15 @@
get_vuse_ops,get_v_must_def_ops): Add operand structure reference.
(get_v_may_def_result_ptr, get_v_may_def_op_ptr): New access struct.
(start_ssa_stmt_operands): Delete.
* tree-flow.h (struct stmt_ann_d): Replace operand vectors with new
* tree-flow.h (struct stmt_ann_d): Replace operand vectors with new
struct stmt_operands_d.
(build_ssa_operands): New extern entry point.
* tree-ssa-dom.c (record_equivalences_from_stmt): Remove operand
* tree-ssa-dom.c (record_equivalences_from_stmt): Remove operand
building code, replace with create_ssa_artficial_load_stmt().
* tree-ssa-operands.c (struct voperands_d): Delete.
(allocate_v_may_def_optype): Allocate v_may_def_operand_type_t vector.
(allocate_v_must_def_optype): Use sizeof (tree), not sizeof (tree *).
(free_uses, free_defs, free_vuses, free_v_may_defs,
(free_uses, free_defs, free_vuses, free_v_may_defs,
free_v_must_defs): Remove dealloc parameter.
(remove_vuses, remove_v_may_def, remove_v_must_defs): Delete.
(finalize_ssa_defs, finalize_ssa_uses, finalize_ssa_v_may_defs,
......@@ -125,7 +197,7 @@
duplicates and simple accumulation.
(free_ssa_operands): Free vectors in a stmt_operand structure.
(build_ssa_operands): New. Create a new stmt_operand structure from
a stmt and an old set of stmt_operands.
a stmt and an old set of stmt_operands.
(get_stmt_operands): Simplify and call build_ssa_operands.
(get_expr_operands, get_asm_expr_operands, get_indirect_ref_operands,
get_call_expr_operands, add_stmt_operand, add_call_clobber_ops,
......
......@@ -910,8 +910,8 @@ OBJS-common = \
genrtl.o ggc-common.o global.o graph.o gtype-desc.o \
haifa-sched.o hooks.o ifcvt.o insn-attrtab.o insn-emit.o insn-modes.o \
insn-extract.o insn-opinit.o insn-output.o insn-peep.o insn-recog.o \
integrate.o intl.o jump.o langhooks.o lcm.o lists.o local-alloc.o \
loop.o modulo-sched.o \
insn-preds.o integrate.o intl.o jump.o langhooks.o lcm.o lists.o \
local-alloc.o loop.o modulo-sched.o \
optabs.o options.o opts.o params.o postreload.o predict.o \
print-rtl.o print-tree.o value-prof.o var-tracking.o \
profile.o ra.o ra-build.o ra-colorize.o ra-debug.o ra-rewrite.o \
......@@ -937,7 +937,8 @@ BACKEND = main.o @TREEBROWSER@ libbackend.a $(CPPLIB)
# Files to be copied away after each stage in building.
STAGESTUFF = *$(objext) 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-attr.h insn-attrtab.c insn-opinit.c insn-constants.h tm-preds.h \
insn-attr.h insn-attrtab.c insn-opinit.c insn-preds.c insn-constants.h \
tm-preds.h \
tree-check.h insn-conditions.c min-insn-modes.c insn-modes.c insn-modes.h \
s-flags s-config s-codes s-mlib s-genrtl s-modes s-gtype gtyp-gen.h \
s-gtyp-gen s-output s-recog s-emit s-extract s-peep s-check s-conditions \
......@@ -1796,7 +1797,7 @@ rtl.o : rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) $(RTL_H) real.h \
$(CC) -c $(ALL_CFLAGS) -DGENERATOR_FILE $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
print-rtl.o : print-rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(TREE_H) hard-reg-set.h $(BASIC_BLOCK_H) real.h
$(RTL_H) $(TREE_H) hard-reg-set.h $(BASIC_BLOCK_H) real.h $(FLAGS_H)
rtlanal.o : rtlanal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) toplev.h \
$(RTL_H) hard-reg-set.h $(TM_P_H) insn-config.h $(RECOG_H) real.h $(FLAGS_H) \
$(BASIC_BLOCK_H) $(REGS_H) output.h target.h function.h
......@@ -2166,7 +2167,7 @@ libbackend.o : $(OBJS-common:.o=.c) $(out_file) \
.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-attr.h insn-attrtab.c
insn-attr.h insn-attrtab.c insn-preds.c
# The following pair of rules has this effect:
# genconfig is run only if the md has changed since genconfig was last run;
......@@ -2205,8 +2206,7 @@ insn-conditions.o : insn-conditions.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
insn-constants.h
$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) insn-conditions.c
dummy-conditions.o : dummy-conditions.c $(BCONFIG_H) $(SYSTEM_H) \
coretypes.h $(GTM_H) gensupport.h
dummy-conditions.o : dummy-conditions.c
insn-flags.h: s-flags ; @true
s-flags : $(md_file) genflags$(build_exeext)
......@@ -2340,13 +2340,19 @@ s-modes: genmodes$(build_exeext)
$(SHELL) $(srcdir)/../move-if-change tmp-modes.c insn-modes.c
$(STAMP) s-modes
tm-preds.h: s-preds; @true
insn-preds.c tm-preds.h: s-preds; @true
s-preds: genpreds$(build_exeext)
$(RUN_GEN) ./genpreds$(build_exeext) > tmp-preds.h
s-preds: $(md_file) genpreds$(build_exeext)
$(RUN_GEN) ./genpreds$(build_exeext) -h $(md_file) > tmp-preds.h
$(SHELL) $(srcdir)/../move-if-change tmp-preds.h tm-preds.h
$(RUN_GEN) ./genpreds$(build_exeext) $(md_file) > tmp-preds.c
$(SHELL) $(srcdir)/../move-if-change tmp-preds.c insn-preds.c
$(STAMP) s-preds
insn-preds.o : insn-preds.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) insn-config.h $(RECOG_H) real.h output.h $(FLAGS_H) function.h \
hard-reg-set.h $(RESOURCE_H) $(TM_P_H) toplev.h reload.h
GTFILES = $(srcdir)/input.h $(srcdir)/coretypes.h \
$(CPP_ID_DATA_H) $(host_xm_file_list) \
$(tm_file_list) $(HASHTAB_H) $(SPLAY_TREE_H) $(srcdir)/bitmap.h \
......@@ -2539,11 +2545,14 @@ genmodes$(build_exeext) : genmodes.o $(BUILD_ERRORS) $(BUILD_LIBDEPS)
genmodes.o : genmodes.c $(BCONFIG_H) $(SYSTEM_H) errors.h $(HASHTAB_H) \
machmode.def $(extra_modes_file)
genpreds$(build_exeext) : genpreds.o $(BUILD_LIBDEPS)
genpreds$(build_exeext) : genpreds.o $(BUILD_RTL) $(BUILD_EARLY_SUPPORT) \
$(BUILD_PRINT) $(BUILD_ERRORS) $(BUILD_LIBDEPS)
$(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \
genpreds.o $(BUILD_LIBS)
genpreds.o $(BUILD_RTL) $(BUILD_EARLY_SUPPORT) $(BUILD_PRINT) \
$(BUILD_ERRORS) $(BUILD_LIBS)
genpreds.o : genpreds.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H)
genpreds.o : genpreds.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) coretypes.h \
$(GTM_H) errors.h gensupport.h $(OBSTACK_H)
gengtype$(build_exeext) : gengtype.o gengtype-lex.o gengtype-yacc.o \
$(BUILD_LIBDEPS)
......@@ -2593,7 +2602,7 @@ $(BUILD_PREFIX_1)rtl.o: $(srcdir)/rtl.c $(BCONFIG_H) coretypes.h $(GTM_H) $(SYST
$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(BUILD_PREFIX)rtl.c $(OUTPUT_OPTION)
print-rtl1.o: $(srcdir)/print-rtl.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h \
$(GTM_H) $(RTL_H) $(TREE_H) hard-reg-set.h $(BASIC_BLOCK_H)
$(GTM_H) $(RTL_BASE_H) $(TREE_H) $(FLAGS_H) hard-reg-set.h $(BASIC_BLOCK_H)
rm -f print-rtl1.c
sed -e 's/config[.]h/bconfig.h/' $(srcdir)/print-rtl.c > print-rtl1.c
$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) print-rtl1.c $(OUTPUT_OPTION)
......
......@@ -146,6 +146,10 @@ extern int target_flags;
#define TARGET_DWARF2_ASM (target_flags & MASK_DWARF2_ASM)
/* Variables which are this size or smaller are put in the sdata/sbss
sections. */
extern unsigned int ia64_section_threshold;
/* If the assembler supports thread-local storage, assume that the
system does as well. If a particular target system has an
assembler that supports TLS -- but the rest of the system does not
......@@ -2140,53 +2144,6 @@ do { \
#define SYMBOL_REF_SMALL_ADDR_P(X) \
((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_SMALL_ADDR) != 0)
/* Define this if you have defined special-purpose predicates in the file
`MACHINE.c'. For each predicate, list all rtl codes that can be in
expressions matched by the predicate. */
#define PREDICATE_CODES \
{ "call_operand", {SUBREG, REG, SYMBOL_REF}}, \
{ "got_symbolic_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \
{ "sdata_symbolic_operand", {SYMBOL_REF, CONST}}, \
{ "small_addr_symbolic_operand", {SYMBOL_REF}}, \
{ "symbolic_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \
{ "tls_symbolic_operand", {SYMBOL_REF}}, \
{ "function_operand", {SYMBOL_REF}}, \
{ "destination_operand", {SUBREG, REG, MEM}}, \
{ "not_postinc_memory_operand", {MEM}}, \
{ "move_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE, \
SYMBOL_REF, CONST, LABEL_REF}}, \
{ "gr_register_operand", {SUBREG, REG}}, \
{ "fr_register_operand", {SUBREG, REG}}, \
{ "grfr_register_operand", {SUBREG, REG}}, \
{ "gr_nonimmediate_operand", {SUBREG, REG, MEM}}, \
{ "fr_nonimmediate_operand", {SUBREG, REG, MEM}}, \
{ "grfr_nonimmediate_operand", {SUBREG, REG, MEM}}, \
{ "gr_reg_or_0_operand", {SUBREG, REG, CONST_INT}}, \
{ "gr_reg_or_5bit_operand", {SUBREG, REG, CONST_INT}}, \
{ "gr_reg_or_6bit_operand", {SUBREG, REG, CONST_INT}}, \
{ "gr_reg_or_8bit_operand", {SUBREG, REG, CONST_INT}}, \
{ "grfr_reg_or_8bit_operand", {SUBREG, REG, CONST_INT}}, \
{ "gr_reg_or_8bit_adjusted_operand", {SUBREG, REG, CONST_INT}}, \
{ "gr_reg_or_8bit_and_adjusted_operand", {SUBREG, REG, CONST_INT}}, \
{ "gr_reg_or_14bit_operand", {SUBREG, REG, CONST_INT}}, \
{ "gr_reg_or_22bit_operand", {SUBREG, REG, CONST_INT}}, \
{ "shift_count_operand", {SUBREG, REG, CONST_INT}}, \
{ "shift_32bit_count_operand", {SUBREG, REG, CONST_INT}}, \
{ "shladd_operand", {CONST_INT}}, \
{ "fetchadd_operand", {CONST_INT}}, \
{ "fr_reg_or_fp01_operand", {SUBREG, REG, CONST_DOUBLE}}, \
{ "normal_comparison_operator", {EQ, NE, GT, LE, GTU, LEU}}, \
{ "adjusted_comparison_operator", {LT, GE, LTU, GEU}}, \
{ "signed_inequality_operator", {GE, GT, LE, LT}}, \
{ "predicate_operator", {NE, EQ}}, \
{ "condop_operator", {PLUS, MINUS, IOR, XOR, AND}}, \
{ "ar_lc_reg_operand", {REG}}, \
{ "ar_ccv_reg_operand", {REG}}, \
{ "ar_pfs_reg_operand", {REG}}, \
{ "xfreg_or_fp01_operand", {REG, CONST_DOUBLE}}, \
{ "basereg_operand", {SUBREG, REG}},
/* An alias for a machine mode name. This is the machine mode that elements of
a jump-table should have. */
......
......@@ -8539,24 +8539,9 @@ patterns.
For each predicate function named in @code{PREDICATE_CODES}, a
declaration will be generated in @file{insn-codes.h}.
@end defmac
@defmac HAS_LONG_COND_BRANCH
Define this boolean macro to indicate whether or not your architecture
has conditional branches that can span all of memory. It is used in
conjunction with an optimization that partitions hot and cold basic
blocks into separate sections of the executable. If this macro is
set to false, gcc will convert any conditional branches that attempt
to cross between sections into unconditional branches or indirect jumps.
@end defmac
@defmac HAS_LONG_UNCOND_BRANCH
Define this boolean macro to indicate whether or not your architecture
has unconditional branches that can span all of memory. It is used in
conjunction with an optimization that partitions hot and cold basic
blocks into separate sections of the executable. If this macro is
set to false, gcc will convert any unconditional branches that attempt
to cross between sections into indirect jumps.
Use of this macro is deprecated; use @code{define_predicate} instead.
@xref{Defining Predicates}.
@end defmac
@defmac SPECIAL_MODE_PREDICATES
......@@ -8574,6 +8559,27 @@ for a byte extraction from @code{%ah} etc.).
#define SPECIAL_MODE_PREDICATES \
"ext_register_operand",
@end smallexample
Use of this macro is deprecated; use @code{define_special_predicate}
instead. @xref{Defining Predicates}.
@end defmac
@defmac HAS_LONG_COND_BRANCH
Define this boolean macro to indicate whether or not your architecture
has conditional branches that can span all of memory. It is used in
conjunction with an optimization that partitions hot and cold basic
blocks into separate sections of the executable. If this macro is
set to false, gcc will convert any conditional branches that attempt
to cross between sections into unconditional branches or indirect jumps.
@end defmac
@defmac HAS_LONG_UNCOND_BRANCH
Define this boolean macro to indicate whether or not your architecture
has unconditional branches that can span all of memory. It is used in
conjunction with an optimization that partitions hot and cold basic
blocks into separate sections of the executable. If this macro is
set to false, gcc will convert any unconditional branches that attempt
to cross between sections into indirect jumps.
@end defmac
@defmac CASE_VECTOR_MODE
......
/* Support for calculating constant conditions.
Copyright (C) 2002 Free Software Foundation, Inc.
Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GCC.
......@@ -18,16 +18,22 @@
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "bconfig.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "gensupport.h"
#include <stddef.h> /* for size_t */
/* MD generators that are run before insn-conditions.c exists should
link against this file instead. Currently that is genconditions
and genconstants. */
/* In order to avoid dragging in all the headers that are needed to
declare things that gensupport.h uses, we duplicate the declaration
of struct c_test here. (In particular we do not want to have to
include tm.h nor rtl.h in this file.) */
struct c_test
{
const char *expr;
int value;
};
/* Empty conditions table to prevent link errors. */
const struct c_test insn_conditions[1] = { { 0, 0 } };
const size_t n_insn_conditions = 0;
......
......@@ -35,6 +35,8 @@ int target_flags;
int insn_elision = 1;
const char *in_fname;
static struct obstack obstack;
struct obstack *rtl_obstack = &obstack;
......@@ -65,6 +67,8 @@ struct queue_elem
static struct queue_elem *define_attr_queue;
static struct queue_elem **define_attr_tail = &define_attr_queue;
static struct queue_elem *define_pred_queue;
static struct queue_elem **define_pred_tail = &define_pred_queue;
static struct queue_elem *define_insn_queue;
static struct queue_elem **define_insn_tail = &define_insn_queue;
static struct queue_elem *define_cond_exec_queue;
......@@ -109,6 +113,7 @@ static void process_one_cond_exec (struct queue_elem *);
static void process_define_cond_exec (void);
static void process_include (rtx, int);
static char *save_string (const char *, int);
static void init_predicate_table (void);
void
message_with_line (int lineno, const char *msg, ...)
......@@ -284,6 +289,11 @@ process_rtx (rtx desc, int lineno)
queue_pattern (desc, &define_attr_tail, read_rtx_filename, lineno);
break;
case DEFINE_PREDICATE:
case DEFINE_SPECIAL_PREDICATE:
queue_pattern (desc, &define_pred_tail, read_rtx_filename, lineno);
break;
case INCLUDE:
process_include (desc, lineno);
break;
......@@ -904,10 +914,7 @@ init_md_reader_args_cb (int argc, char **argv, bool (*parse_opt)(const char *))
int i;
size_t ix;
char *lastsl;
const char *in_fname;
max_include_len = 0;
in_fname = NULL;
for (i = 1; i < argc; i++)
{
if (argv[i][0] != '-')
......@@ -977,6 +984,8 @@ init_md_reader_args_cb (int argc, char **argv, bool (*parse_opt)(const char *))
*(htab_find_slot (condition_table, &insn_conditions[ix], INSERT))
= (void *) &insn_conditions[ix];
init_predicate_table ();
obstack_init (rtl_obstack);
errors = 0;
sequence_num = 0;
......@@ -1025,6 +1034,8 @@ read_md_rtx (int *lineno, int *seqnr)
/* Read all patterns from a given queue before moving on to the next. */
if (define_attr_queue != NULL)
queue = &define_attr_queue;
else if (define_pred_queue != NULL)
queue = &define_pred_queue;
else if (define_insn_queue != NULL)
queue = &define_insn_queue;
else if (other_queue != NULL)
......@@ -1181,3 +1192,154 @@ scan_comma_elt (const char **pstr)
*pstr = p;
return start;
}
/* Helper functions for define_predicate and define_special_predicate
processing. Shared between genrecog.c and genpreds.c. */
static htab_t predicate_table;
struct pred_data *first_predicate;
static struct pred_data **last_predicate = &first_predicate;
static hashval_t
hash_struct_pred_data (const void *ptr)
{
return htab_hash_string (((const struct pred_data *)ptr)->name);
}
static int
eq_struct_pred_data (const void *a, const void *b)
{
return !strcmp (((const struct pred_data *)a)->name,
((const struct pred_data *)b)->name);
}
struct pred_data *
lookup_predicate (const char *name)
{
struct pred_data key;
key.name = name;
return htab_find (predicate_table, &key);
}
void
add_predicate (struct pred_data *pred)
{
void **slot = htab_find_slot (predicate_table, pred, INSERT);
if (*slot)
{
error ("duplicate predicate definition for '%s'", pred->name);
return;
}
*slot = pred;
*last_predicate = pred;
last_predicate = &pred->next;
}
/* This array gives the initial content of the predicate table. It
has entries for all predicates defined in recog.c. The back end
can define PREDICATE_CODES to give additional entries for the
table; this is considered an obsolete mechanism (use
define_predicate instead). */
struct old_pred_table
{
const char *name;
RTX_CODE codes[NUM_RTX_CODE];
};
static const struct old_pred_table old_preds[] = {
{"general_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
LABEL_REF, SUBREG, REG, MEM }},
{"address_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
LABEL_REF, SUBREG, REG, MEM,
PLUS, MINUS, MULT}},
{"register_operand", {SUBREG, REG}},
{"pmode_register_operand", {SUBREG, REG}},
{"scratch_operand", {SCRATCH, REG}},
{"immediate_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
LABEL_REF}},
{"const_int_operand", {CONST_INT}},
{"const_double_operand", {CONST_INT, CONST_DOUBLE}},
{"nonimmediate_operand", {SUBREG, REG, MEM}},
{"nonmemory_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
LABEL_REF, SUBREG, REG}},
{"push_operand", {MEM}},
{"pop_operand", {MEM}},
{"memory_operand", {SUBREG, MEM}},
{"indirect_operand", {SUBREG, MEM}},
{"comparison_operator", {EQ, NE, LE, LT, GE, GT, LEU, LTU, GEU, GTU,
UNORDERED, ORDERED, UNEQ, UNGE, UNGT, UNLE,
UNLT, LTGT}},
#ifdef PREDICATE_CODES
PREDICATE_CODES
#endif
};
#define NUM_KNOWN_OLD_PREDS ARRAY_SIZE (old_preds)
/* This table gives the initial set of special predicates. It has
entries for all special predicates defined in recog.c. The back
end can define SPECIAL_MODE_PREDICATES to give additional entries
for the table; this is considered an obsolete mechanism (use
define_special_predicate instead). */
static const char *const old_special_pred_table[] = {
"address_operand",
"pmode_register_operand",
#ifdef SPECIAL_MODE_PREDICATES
SPECIAL_MODE_PREDICATES
#endif
};
#define NUM_OLD_SPECIAL_MODE_PREDS ARRAY_SIZE (old_special_pred_table)
/* Initialize the table of predicate definitions, starting with
the information we have on generic predicates, and the old-style
PREDICATE_CODES definitions. */
static void
init_predicate_table (void)
{
size_t i, j;
struct pred_data *pred;
predicate_table = htab_create_alloc (37, hash_struct_pred_data,
eq_struct_pred_data, 0,
xcalloc, free);
for (i = 0; i < NUM_KNOWN_OLD_PREDS; i++)
{
pred = xcalloc (sizeof (struct pred_data), 1);
pred->name = old_preds[i].name;
for (j = 0; old_preds[i].codes[j] != 0; j++)
{
enum rtx_code code = old_preds[i].codes[j];
pred->codes[code] = true;
if (GET_RTX_CLASS (code) != RTX_CONST_OBJ)
pred->allows_non_const = true;
if (code != REG
&& code != SUBREG
&& code != MEM
&& code != CONCAT
&& code != PARALLEL
&& code != STRICT_LOW_PART)
pred->allows_non_lvalue = true;
}
if (j == 1)
pred->singleton = old_preds[i].codes[0];
add_predicate (pred);
}
for (i = 0; i < NUM_OLD_SPECIAL_MODE_PREDS; i++)
{
pred = lookup_predicate (old_special_pred_table[i]);
if (!pred)
{
error ("old-style special predicate list refers "
"to unknown predicate '%s'", old_special_pred_table[i]);
continue;
}
pred->special = true;
}
}
......@@ -23,6 +23,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
struct obstack;
extern struct obstack *rtl_obstack;
extern const char *in_fname;
extern int init_md_reader_args_cb (int, char **, bool (*)(const char *));
extern int init_md_reader_args (int, char **);
......@@ -66,4 +67,29 @@ extern int cmp_c_test (const void *, const void *);
extern int n_comma_elts (const char *);
extern const char *scan_comma_elt (const char **);
/* Predicate handling: helper functions and data structures. */
struct pred_data
{
struct pred_data *next; /* for iterating over the set of all preds */
const char *name; /* predicate name */
bool special; /* special handling of modes? */
/* data used primarily by genpreds.c */
const char *c_block; /* C test block */
rtx exp; /* RTL test expression */
/* data used primarily by genrecog.c */
enum rtx_code singleton; /* if pred takes only one code, that code */
bool allows_non_lvalue; /* if pred allows non-lvalue expressions */
bool allows_non_const; /* if pred allows non-const expressions */
bool codes[NUM_RTX_CODE]; /* set of codes accepted */
};
extern struct pred_data *first_predicate;
extern struct pred_data *lookup_predicate (const char *);
extern void add_predicate (struct pred_data *);
#define FOR_ALL_PREDICATES(p) for (p = first_predicate; p; p = p->next)
#endif /* GCC_GENSUPPORT_H */
......@@ -96,22 +96,6 @@ extern int next_insn_tests_no_inequality (rtx);
extern int reg_fits_class_p (rtx, enum reg_class, int, enum machine_mode);
extern rtx *find_single_use (rtx, rtx, rtx *);
extern int general_operand (rtx, enum machine_mode);
extern int address_operand (rtx, enum machine_mode);
extern int register_operand (rtx, enum machine_mode);
extern int pmode_register_operand (rtx, enum machine_mode);
extern int scratch_operand (rtx, enum machine_mode);
extern int immediate_operand (rtx, enum machine_mode);
extern int const_int_operand (rtx, enum machine_mode);
extern int const_double_operand (rtx, enum machine_mode);
extern int nonimmediate_operand (rtx, enum machine_mode);
extern int nonmemory_operand (rtx, enum machine_mode);
extern int push_operand (rtx, enum machine_mode);
extern int pop_operand (rtx, enum machine_mode);
extern int memory_operand (rtx, enum machine_mode);
extern int indirect_operand (rtx, enum machine_mode);
extern int comparison_operator (rtx, enum machine_mode);
extern int offsettable_memref_p (rtx);
extern int offsettable_nonstrict_memref_p (rtx);
extern int offsettable_address_p (int, enum machine_mode, rtx);
......
......@@ -182,6 +182,17 @@ DEF_RTL_EXPR(MATCH_OP_DUP, "match_op_dup", "iE", RTX_MATCH)
at the index specified by the argument. For MATCH_PARALLEL. */
DEF_RTL_EXPR(MATCH_PAR_DUP, "match_par_dup", "iE", RTX_MATCH)
/* Appears only in define_predicate/define_special predicate
expressions in a machine description. Evaluates true only if the
operand has an RTX code from the set given by the argument (a
comma-separated list). */
DEF_RTL_EXPR(MATCH_CODE, "match_code", "s", RTX_MATCH)
/* Appears only in define_predicate/define_special_predicate expressions
in a machine description. The argument is a C expression to be injected
at this point in the predicate formula. */
DEF_RTL_EXPR(MATCH_TEST, "match_test", "s", RTX_MATCH)
/* Appears only in machine descriptions.
Defines the pattern for one kind of instruction.
Operand:
......@@ -297,6 +308,23 @@ DEF_RTL_EXPR(DEFINE_ASM_ATTRIBUTES, "define_asm_attributes", "V", RTX_EXTRA)
2: A template or C code to produce assembler output. */
DEF_RTL_EXPR(DEFINE_COND_EXEC, "define_cond_exec", "Ess", RTX_EXTRA)
/* Definition of an operand predicate. The difference between
DEFINE_PREDICATE and DEFINE_SPECIAL_PREDICATE is that genrecog will
not warn about a match_operand with no mode if it has a predicate
defined with DEFINE_SPECIAL_PREDICATE.
Operand:
0: The name of the predicate.
1: A boolean expression which computes whether or not the predicate
matches. This expression can use IOR, AND, NOT, MATCH_OPERAND,
MATCH_CODE, and MATCH_TEST. It must be specific enough that genrecog
can calculate the set of RTX codes that can possibly match.
2: A C function body which must return true for the predicate to match.
Optional. Use this when the test is too complicated to fit into a
match_test expression. */
DEF_RTL_EXPR(DEFINE_PREDICATE, "define_predicate", "ses", RTX_EXTRA)
DEF_RTL_EXPR(DEFINE_SPECIAL_PREDICATE, "define_special_predicate", "ses", RTX_EXTRA)
/* SEQUENCE appears in the result of a `gen_...' function
for a DEFINE_EXPAND that wants to make several insns.
Its elements are the bodies of the insns that should be made.
......
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