summaryrefslogtreecommitdiff
path: root/gcc/gensupport.c
diff options
context:
space:
mode:
authorzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>2004-08-12 07:49:00 +0000
committerzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>2004-08-12 07:49:00 +0000
commitcbf464bd936b926a34bbc04e8ccd39afd4c5815a (patch)
tree35550b19b3978c830f6043f43687018fe8198d2d /gcc/gensupport.c
parent307719b97143646f73530f046493efc507351385 (diff)
downloadgcc-cbf464bd936b926a34bbc04e8ccd39afd4c5815a.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@85855 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/gensupport.c')
-rw-r--r--gcc/gensupport.c168
1 files changed, 165 insertions, 3 deletions
diff --git a/gcc/gensupport.c b/gcc/gensupport.c
index 2acfc8a3efd..618e1a271a5 100644
--- a/gcc/gensupport.c
+++ b/gcc/gensupport.c
@@ -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;
+ }
+}