1 /* Support routines for the various generation passes.
2 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
3 2010, Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
30 #include "gensupport.h"
33 /* In case some macros used by files we include need it, define this here. */
40 /* This callback will be invoked whenever an rtl include directive is
41 processed. To be used for creation of the dependency file. */
42 void (*include_callback) (const char *);
44 static struct obstack obstack;
45 struct obstack *rtl_obstack = &obstack;
47 static int sequence_num;
50 static int predicable_default;
51 static const char *predicable_true;
52 static const char *predicable_false;
54 static htab_t condition_table;
56 static char *base_dir = NULL;
58 /* We initially queue all patterns, process the define_insn and
59 define_cond_exec patterns, then return them one at a time. */
66 struct queue_elem *next;
67 /* In a DEFINE_INSN that came from a DEFINE_INSN_AND_SPLIT, SPLIT
68 points to the generated DEFINE_SPLIT. */
69 struct queue_elem *split;
72 static struct queue_elem *define_attr_queue;
73 static struct queue_elem **define_attr_tail = &define_attr_queue;
74 static struct queue_elem *define_pred_queue;
75 static struct queue_elem **define_pred_tail = &define_pred_queue;
76 static struct queue_elem *define_insn_queue;
77 static struct queue_elem **define_insn_tail = &define_insn_queue;
78 static struct queue_elem *define_cond_exec_queue;
79 static struct queue_elem **define_cond_exec_tail = &define_cond_exec_queue;
80 static struct queue_elem *other_queue;
81 static struct queue_elem **other_tail = &other_queue;
83 static struct queue_elem *queue_pattern (rtx, struct queue_elem ***,
86 /* Current maximum length of directory names in the search path
87 for include files. (Altered as we get more of them.) */
89 size_t max_include_len;
93 struct file_name_list *next;
97 struct file_name_list *first_dir_md_include = 0; /* First dir to search */
98 /* First dir to search for <file> */
99 struct file_name_list *first_bracket_include = 0;
100 struct file_name_list *last_dir_md_include = 0; /* Last in chain */
102 static void remove_constraints (rtx);
103 static void process_rtx (rtx, int);
105 static int is_predicable (struct queue_elem *);
106 static void identify_predicable_attribute (void);
107 static int n_alternatives (const char *);
108 static void collect_insn_data (rtx, int *, int *);
109 static rtx alter_predicate_for_insn (rtx, int, int, int);
110 static const char *alter_test_for_insn (struct queue_elem *,
111 struct queue_elem *);
112 static char *shift_output_template (char *, const char *, int);
113 static const char *alter_output_for_insn (struct queue_elem *,
116 static void process_one_cond_exec (struct queue_elem *);
117 static void process_define_cond_exec (void);
118 static void process_include (rtx, int);
119 static char *save_string (const char *, int);
120 static void init_predicate_table (void);
121 static void record_insn_name (int, const char *);
123 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
124 the gensupport programs. */
127 gen_rtx_CONST_INT (enum machine_mode ARG_UNUSED (mode),
130 rtx rt = rtx_alloc (CONST_INT);
136 /* Queue PATTERN on LIST_TAIL. Return the address of the new queue
139 static struct queue_elem *
140 queue_pattern (rtx pattern, struct queue_elem ***list_tail,
141 const char *filename, int lineno)
143 struct queue_elem *e = XNEW(struct queue_elem);
145 e->filename = filename;
150 *list_tail = &e->next;
154 /* Recursively remove constraints from an rtx. */
157 remove_constraints (rtx part)
160 const char *format_ptr;
165 if (GET_CODE (part) == MATCH_OPERAND)
167 else if (GET_CODE (part) == MATCH_SCRATCH)
170 format_ptr = GET_RTX_FORMAT (GET_CODE (part));
172 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
173 switch (*format_ptr++)
177 remove_constraints (XEXP (part, i));
180 if (XVEC (part, i) != NULL)
181 for (j = 0; j < XVECLEN (part, i); j++)
182 remove_constraints (XVECEXP (part, i, j));
187 /* Process an include file assuming that it lives in gcc/config/{target}/
188 if the include looks like (include "file"). */
191 process_include (rtx desc, int lineno)
193 const char *filename = XSTR (desc, 0);
194 const char *old_filename;
197 FILE *input_file, *old_file;
199 /* If specified file name is absolute, skip the include stack. */
200 if (! IS_ABSOLUTE_PATH (filename))
202 struct file_name_list *stackp;
204 /* Search directory path, trying to open the file. */
205 for (stackp = first_dir_md_include; stackp; stackp = stackp->next)
207 static const char sep[2] = { DIR_SEPARATOR, '\0' };
209 pathname = concat (stackp->fname, sep, filename, NULL);
210 input_file = fopen (pathname, "r");
211 if (input_file != NULL)
218 pathname = concat (base_dir, filename, NULL);
220 pathname = xstrdup (filename);
221 input_file = fopen (pathname, "r");
222 if (input_file == NULL)
225 message_with_line (lineno, "include file `%s' not found", filename);
231 /* Save old cursor; setup new for the new file. Note that "lineno" the
232 argument to this function is the beginning of the include statement,
233 while read_md_lineno has already been advanced. */
234 old_file = read_md_file;
235 old_filename = read_md_filename;
236 old_lineno = read_md_lineno;
237 read_md_file = input_file;
238 read_md_filename = pathname;
241 if (include_callback)
242 include_callback (pathname);
244 /* Read the entire file. */
245 while (read_rtx (&desc, &lineno))
246 process_rtx (desc, lineno);
248 /* Do not free pathname. It is attached to the various rtx queue
251 read_md_file = old_file;
252 read_md_filename = old_filename;
253 read_md_lineno = old_lineno;
258 /* Process a top level rtx in some way, queuing as appropriate. */
261 process_rtx (rtx desc, int lineno)
263 switch (GET_CODE (desc))
266 queue_pattern (desc, &define_insn_tail, read_md_filename, lineno);
269 case DEFINE_COND_EXEC:
270 queue_pattern (desc, &define_cond_exec_tail, read_md_filename, lineno);
274 queue_pattern (desc, &define_attr_tail, read_md_filename, lineno);
277 case DEFINE_PREDICATE:
278 case DEFINE_SPECIAL_PREDICATE:
279 case DEFINE_CONSTRAINT:
280 case DEFINE_REGISTER_CONSTRAINT:
281 case DEFINE_MEMORY_CONSTRAINT:
282 case DEFINE_ADDRESS_CONSTRAINT:
283 queue_pattern (desc, &define_pred_tail, read_md_filename, lineno);
287 process_include (desc, lineno);
290 case DEFINE_INSN_AND_SPLIT:
292 const char *split_cond;
296 struct queue_elem *insn_elem;
297 struct queue_elem *split_elem;
299 /* Create a split with values from the insn_and_split. */
300 split = rtx_alloc (DEFINE_SPLIT);
302 i = XVECLEN (desc, 1);
303 XVEC (split, 0) = rtvec_alloc (i);
306 XVECEXP (split, 0, i) = copy_rtx (XVECEXP (desc, 1, i));
307 remove_constraints (XVECEXP (split, 0, i));
310 /* If the split condition starts with "&&", append it to the
311 insn condition to create the new split condition. */
312 split_cond = XSTR (desc, 4);
313 if (split_cond[0] == '&' && split_cond[1] == '&')
315 copy_md_ptr_loc (split_cond + 2, split_cond);
316 split_cond = join_c_conditions (XSTR (desc, 2), split_cond + 2);
318 XSTR (split, 1) = split_cond;
319 XVEC (split, 2) = XVEC (desc, 5);
320 XSTR (split, 3) = XSTR (desc, 6);
322 /* Fix up the DEFINE_INSN. */
323 attr = XVEC (desc, 7);
324 PUT_CODE (desc, DEFINE_INSN);
325 XVEC (desc, 4) = attr;
329 = queue_pattern (desc, &define_insn_tail, read_md_filename,
332 = queue_pattern (split, &other_tail, read_md_filename, lineno);
333 insn_elem->split = split_elem;
338 queue_pattern (desc, &other_tail, read_md_filename, lineno);
343 /* Return true if attribute PREDICABLE is true for ELEM, which holds
347 is_predicable (struct queue_elem *elem)
349 rtvec vec = XVEC (elem->data, 4);
354 return predicable_default;
356 for (i = GET_NUM_ELEM (vec) - 1; i >= 0; --i)
358 rtx sub = RTVEC_ELT (vec, i);
359 switch (GET_CODE (sub))
362 if (strcmp (XSTR (sub, 0), "predicable") == 0)
364 value = XSTR (sub, 1);
369 case SET_ATTR_ALTERNATIVE:
370 if (strcmp (XSTR (sub, 0), "predicable") == 0)
372 message_with_line (elem->lineno,
373 "multiple alternatives for `predicable'");
380 if (GET_CODE (SET_DEST (sub)) != ATTR
381 || strcmp (XSTR (SET_DEST (sub), 0), "predicable") != 0)
384 if (GET_CODE (sub) == CONST_STRING)
386 value = XSTR (sub, 0);
390 /* ??? It would be possible to handle this if we really tried.
391 It's not easy though, and I'm not going to bother until it
392 really proves necessary. */
393 message_with_line (elem->lineno,
394 "non-constant value for `predicable'");
403 return predicable_default;
406 /* Verify that predicability does not vary on the alternative. */
407 /* ??? It should be possible to handle this by simply eliminating
408 the non-predicable alternatives from the insn. FRV would like
409 to do this. Delay this until we've got the basics solid. */
410 if (strchr (value, ',') != NULL)
412 message_with_line (elem->lineno,
413 "multiple alternatives for `predicable'");
418 /* Find out which value we're looking at. */
419 if (strcmp (value, predicable_true) == 0)
421 if (strcmp (value, predicable_false) == 0)
424 message_with_line (elem->lineno,
425 "unknown value `%s' for `predicable' attribute",
431 /* Examine the attribute "predicable"; discover its boolean values
435 identify_predicable_attribute (void)
437 struct queue_elem *elem;
438 char *p_true, *p_false;
441 /* Look for the DEFINE_ATTR for `predicable', which must exist. */
442 for (elem = define_attr_queue; elem ; elem = elem->next)
443 if (strcmp (XSTR (elem->data, 0), "predicable") == 0)
446 message_with_line (define_cond_exec_queue->lineno,
447 "attribute `predicable' not defined");
452 value = XSTR (elem->data, 1);
453 p_false = xstrdup (value);
454 p_true = strchr (p_false, ',');
455 if (p_true == NULL || strchr (++p_true, ',') != NULL)
457 message_with_line (elem->lineno,
458 "attribute `predicable' is not a boolean");
466 predicable_true = p_true;
467 predicable_false = p_false;
469 switch (GET_CODE (XEXP (elem->data, 2)))
472 value = XSTR (XEXP (elem->data, 2), 0);
476 message_with_line (elem->lineno,
477 "attribute `predicable' cannot be const");
484 message_with_line (elem->lineno,
485 "attribute `predicable' must have a constant default");
492 if (strcmp (value, p_true) == 0)
493 predicable_default = 1;
494 else if (strcmp (value, p_false) == 0)
495 predicable_default = 0;
498 message_with_line (elem->lineno,
499 "unknown value `%s' for `predicable' attribute",
507 /* Return the number of alternatives in constraint S. */
510 n_alternatives (const char *s)
521 /* Determine how many alternatives there are in INSN, and how many
525 collect_insn_data (rtx pattern, int *palt, int *pmax)
531 code = GET_CODE (pattern);
535 i = n_alternatives (XSTR (pattern, 2));
536 *palt = (i > *palt ? i : *palt);
542 i = XINT (pattern, 0);
551 fmt = GET_RTX_FORMAT (code);
552 len = GET_RTX_LENGTH (code);
553 for (i = 0; i < len; i++)
558 collect_insn_data (XEXP (pattern, i), palt, pmax);
562 if (XVEC (pattern, i) == NULL)
566 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
567 collect_insn_data (XVECEXP (pattern, i, j), palt, pmax);
570 case 'i': case 'w': case '0': case 's': case 'S': case 'T':
580 alter_predicate_for_insn (rtx pattern, int alt, int max_op, int lineno)
586 code = GET_CODE (pattern);
591 const char *c = XSTR (pattern, 2);
593 if (n_alternatives (c) != 1)
595 message_with_line (lineno,
596 "too many alternatives for operand %d",
602 /* Replicate C as needed to fill out ALT alternatives. */
603 if (c && *c && alt > 1)
605 size_t c_len = strlen (c);
606 size_t len = alt * (c_len + 1);
607 char *new_c = XNEWVEC(char, len);
609 memcpy (new_c, c, c_len);
610 for (i = 1; i < alt; ++i)
612 new_c[i * (c_len + 1) - 1] = ',';
613 memcpy (&new_c[i * (c_len + 1)], c, c_len);
615 new_c[len - 1] = '\0';
616 XSTR (pattern, 2) = new_c;
624 XINT (pattern, 0) += max_op;
631 fmt = GET_RTX_FORMAT (code);
632 len = GET_RTX_LENGTH (code);
633 for (i = 0; i < len; i++)
640 r = alter_predicate_for_insn (XEXP (pattern, i), alt,
647 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
649 r = alter_predicate_for_insn (XVECEXP (pattern, i, j),
650 alt, max_op, lineno);
656 case 'i': case 'w': case '0': case 's':
668 alter_test_for_insn (struct queue_elem *ce_elem,
669 struct queue_elem *insn_elem)
671 return join_c_conditions (XSTR (ce_elem->data, 1),
672 XSTR (insn_elem->data, 2));
675 /* Adjust all of the operand numbers in SRC to match the shift they'll
676 get from an operand displacement of DISP. Return a pointer after the
680 shift_output_template (char *dest, const char *src, int disp)
689 if (ISDIGIT ((unsigned char) c))
691 else if (ISALPHA (c))
704 alter_output_for_insn (struct queue_elem *ce_elem,
705 struct queue_elem *insn_elem,
708 const char *ce_out, *insn_out;
710 size_t len, ce_len, insn_len;
712 /* ??? Could coordinate with genoutput to not duplicate code here. */
714 ce_out = XSTR (ce_elem->data, 2);
715 insn_out = XTMPL (insn_elem->data, 3);
716 if (!ce_out || *ce_out == '\0')
719 ce_len = strlen (ce_out);
720 insn_len = strlen (insn_out);
722 if (*insn_out == '*')
723 /* You must take care of the predicate yourself. */
726 if (*insn_out == '@')
728 len = (ce_len + 1) * alt + insn_len + 1;
729 p = result = XNEWVEC(char, len);
735 while (ISSPACE ((unsigned char) *insn_out));
737 if (*insn_out != '#')
739 p = shift_output_template (p, ce_out, max_op);
745 while (*insn_out && *insn_out != '\n');
752 len = ce_len + 1 + insn_len + 1;
753 result = XNEWVEC (char, len);
755 p = shift_output_template (result, ce_out, max_op);
757 memcpy (p, insn_out, insn_len + 1);
763 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */
766 process_one_cond_exec (struct queue_elem *ce_elem)
768 struct queue_elem *insn_elem;
769 for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
771 int alternatives, max_operand;
772 rtx pred, insn, pattern, split;
776 if (! is_predicable (insn_elem))
781 collect_insn_data (insn_elem->data, &alternatives, &max_operand);
784 if (XVECLEN (ce_elem->data, 0) != 1)
786 message_with_line (ce_elem->lineno,
787 "too many patterns in predicate");
792 pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0));
793 pred = alter_predicate_for_insn (pred, alternatives, max_operand,
798 /* Construct a new pattern for the new insn. */
799 insn = copy_rtx (insn_elem->data);
800 new_name = XNEWVAR (char, strlen XSTR (insn_elem->data, 0) + 4);
801 sprintf (new_name, "*p %s", XSTR (insn_elem->data, 0));
802 XSTR (insn, 0) = new_name;
803 pattern = rtx_alloc (COND_EXEC);
804 XEXP (pattern, 0) = pred;
805 if (XVECLEN (insn, 1) == 1)
807 XEXP (pattern, 1) = XVECEXP (insn, 1, 0);
808 XVECEXP (insn, 1, 0) = pattern;
809 PUT_NUM_ELEM (XVEC (insn, 1), 1);
813 XEXP (pattern, 1) = rtx_alloc (PARALLEL);
814 XVEC (XEXP (pattern, 1), 0) = XVEC (insn, 1);
815 XVEC (insn, 1) = rtvec_alloc (1);
816 XVECEXP (insn, 1, 0) = pattern;
819 XSTR (insn, 2) = alter_test_for_insn (ce_elem, insn_elem);
820 XTMPL (insn, 3) = alter_output_for_insn (ce_elem, insn_elem,
821 alternatives, max_operand);
823 /* ??? Set `predicable' to false. Not crucial since it's really
824 only used here, and we won't reprocess this new pattern. */
826 /* Put the new pattern on the `other' list so that it
827 (a) is not reprocessed by other define_cond_exec patterns
828 (b) appears after all normal define_insn patterns.
830 ??? B is debatable. If one has normal insns that match
831 cond_exec patterns, they will be preferred over these
832 generated patterns. Whether this matters in practice, or if
833 it's a good thing, or whether we should thread these new
834 patterns into the define_insn chain just after their generator
835 is something we'll have to experiment with. */
837 queue_pattern (insn, &other_tail, insn_elem->filename,
840 if (!insn_elem->split)
843 /* If the original insn came from a define_insn_and_split,
844 generate a new split to handle the predicated insn. */
845 split = copy_rtx (insn_elem->split->data);
846 /* Predicate the pattern matched by the split. */
847 pattern = rtx_alloc (COND_EXEC);
848 XEXP (pattern, 0) = pred;
849 if (XVECLEN (split, 0) == 1)
851 XEXP (pattern, 1) = XVECEXP (split, 0, 0);
852 XVECEXP (split, 0, 0) = pattern;
853 PUT_NUM_ELEM (XVEC (split, 0), 1);
857 XEXP (pattern, 1) = rtx_alloc (PARALLEL);
858 XVEC (XEXP (pattern, 1), 0) = XVEC (split, 0);
859 XVEC (split, 0) = rtvec_alloc (1);
860 XVECEXP (split, 0, 0) = pattern;
862 /* Predicate all of the insns generated by the split. */
863 for (i = 0; i < XVECLEN (split, 2); i++)
865 pattern = rtx_alloc (COND_EXEC);
866 XEXP (pattern, 0) = pred;
867 XEXP (pattern, 1) = XVECEXP (split, 2, i);
868 XVECEXP (split, 2, i) = pattern;
870 /* Add the new split to the queue. */
871 queue_pattern (split, &other_tail, read_md_filename,
872 insn_elem->split->lineno);
876 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
877 patterns appropriately. */
880 process_define_cond_exec (void)
882 struct queue_elem *elem;
884 identify_predicable_attribute ();
888 for (elem = define_cond_exec_queue; elem ; elem = elem->next)
889 process_one_cond_exec (elem);
893 save_string (const char *s, int len)
895 char *result = XNEWVEC (char, len + 1);
897 memcpy (result, s, len);
903 /* The entry point for initializing the reader. */
906 init_md_reader_args_cb (int argc, char **argv, bool (*parse_opt)(const char *))
911 bool no_more_options;
912 bool already_read_stdin;
914 /* Unlock the stdio streams. */
915 unlock_std_streams ();
917 /* First we loop over all the options. */
918 for (i = 1; i < argc; i++)
920 if (argv[i][0] != '-')
926 case 'I': /* Add directory to path for includes. */
928 struct file_name_list *dirtmp;
930 dirtmp = XNEW (struct file_name_list);
931 dirtmp->next = 0; /* New one goes on the end */
932 if (first_dir_md_include == 0)
933 first_dir_md_include = dirtmp;
935 last_dir_md_include->next = dirtmp;
936 last_dir_md_include = dirtmp; /* Tail follows the last one */
937 if (argv[i][1] == 'I' && argv[i][2] != 0)
938 dirtmp->fname = argv[i] + 2;
939 else if (i + 1 == argc)
940 fatal ("directory name missing after -I option");
942 dirtmp->fname = argv[++i];
943 if (strlen (dirtmp->fname) > max_include_len)
944 max_include_len = strlen (dirtmp->fname);
949 /* An argument consisting of exactly one dash is a request to
950 read stdin. This will be handled in the second loop. */
954 /* An argument consisting of just two dashes causes option
956 if (argv[i][2] == '\0')
957 goto stop_parsing_options;
960 /* The program may have provided a callback so it can
961 accept its own options. */
962 if (parse_opt && parse_opt (argv[i]))
965 fatal ("invalid option `%s'", argv[i]);
969 stop_parsing_options:
971 /* Prepare to read input. */
972 condition_table = htab_create (500, hash_c_test, cmp_c_test, NULL);
973 init_predicate_table ();
974 obstack_init (rtl_obstack);
977 no_more_options = false;
978 already_read_stdin = false;
981 /* Now loop over all input files. */
982 for (i = 1; i < argc; i++)
984 if (argv[i][0] == '-')
986 if (argv[i][1] == '\0')
989 if (already_read_stdin)
990 fatal ("cannot read standard input twice");
993 read_md_file = stdin;
994 read_md_filename = in_fname = "<stdin>";
996 already_read_stdin = true;
998 while (read_rtx (&desc, &lineno))
999 process_rtx (desc, lineno);
1000 fclose (read_md_file);
1003 else if (argv[i][1] == '-' && argv[i][2] == '\0')
1005 /* No further arguments are to be treated as options. */
1006 no_more_options = true;
1009 else if (!no_more_options)
1013 /* If we get here we are looking at a non-option argument, i.e.
1014 a file to be processed. */
1017 lastsl = strrchr (in_fname, '/');
1019 base_dir = save_string (in_fname, lastsl - in_fname + 1 );
1023 read_md_file = fopen (in_fname, "r");
1024 if (read_md_file == 0)
1027 return FATAL_EXIT_CODE;
1029 read_md_filename = in_fname;
1032 while (read_rtx (&desc, &lineno))
1033 process_rtx (desc, lineno);
1034 fclose (read_md_file);
1037 /* If we get to this point without having seen any files to process,
1038 read standard input now. */
1042 read_md_file = stdin;
1043 read_md_filename = in_fname = "<stdin>";
1046 while (read_rtx (&desc, &lineno))
1047 process_rtx (desc, lineno);
1048 fclose (read_md_file);
1051 /* Process define_cond_exec patterns. */
1052 if (define_cond_exec_queue != NULL)
1053 process_define_cond_exec ();
1055 return errors ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
1058 /* Programs that don't have their own options can use this entry point
1061 init_md_reader_args (int argc, char **argv)
1063 return init_md_reader_args_cb (argc, argv, 0);
1066 /* The entry point for reading a single rtx from an md file. */
1069 read_md_rtx (int *lineno, int *seqnr)
1071 struct queue_elem **queue, *elem;
1076 /* Read all patterns from a given queue before moving on to the next. */
1077 if (define_attr_queue != NULL)
1078 queue = &define_attr_queue;
1079 else if (define_pred_queue != NULL)
1080 queue = &define_pred_queue;
1081 else if (define_insn_queue != NULL)
1082 queue = &define_insn_queue;
1083 else if (other_queue != NULL)
1084 queue = &other_queue;
1089 *queue = elem->next;
1091 read_md_filename = elem->filename;
1092 *lineno = elem->lineno;
1093 *seqnr = sequence_num;
1097 /* Discard insn patterns which we know can never match (because
1098 their C test is provably always false). If insn_elision is
1099 false, our caller needs to see all the patterns. Note that the
1100 elided patterns are never counted by the sequence numbering; it
1101 it is the caller's responsibility, when insn_elision is false, not
1102 to use elided pattern numbers for anything. */
1103 switch (GET_CODE (desc))
1107 if (maybe_eval_c_test (XSTR (desc, 2)) != 0)
1109 else if (insn_elision)
1112 /* *seqnr is used here so the name table will match caller's
1113 idea of insn numbering, whether or not elision is active. */
1114 record_insn_name (*seqnr, XSTR (desc, 0));
1118 case DEFINE_PEEPHOLE:
1119 case DEFINE_PEEPHOLE2:
1120 if (maybe_eval_c_test (XSTR (desc, 1)) != 0)
1122 else if (insn_elision)
1133 /* Helper functions for insn elision. */
1135 /* Compute a hash function of a c_test structure, which is keyed
1136 by its ->expr field. */
1138 hash_c_test (const void *x)
1140 const struct c_test *a = (const struct c_test *) x;
1141 const unsigned char *base, *s = (const unsigned char *) a->expr;
1149 while ((c = *s++) != '\0')
1151 hash += c + (c << 17);
1156 hash += len + (len << 17);
1162 /* Compare two c_test expression structures. */
1164 cmp_c_test (const void *x, const void *y)
1166 const struct c_test *a = (const struct c_test *) x;
1167 const struct c_test *b = (const struct c_test *) y;
1169 return !strcmp (a->expr, b->expr);
1172 /* Given a string representing a C test expression, look it up in the
1173 condition_table and report whether or not its value is known
1174 at compile time. Returns a tristate: 1 for known true, 0 for
1175 known false, -1 for unknown. */
1177 maybe_eval_c_test (const char *expr)
1179 const struct c_test *test;
1180 struct c_test dummy;
1186 test = (const struct c_test *)htab_find (condition_table, &dummy);
1192 /* Record the C test expression EXPR in the condition_table, with
1193 value VAL. Duplicates clobber previous entries. */
1196 add_c_test (const char *expr, int value)
1198 struct c_test *test;
1203 test = XNEW (struct c_test);
1205 test->value = value;
1207 *(htab_find_slot (condition_table, test, INSERT)) = test;
1210 /* For every C test, call CALLBACK with two arguments: a pointer to
1211 the condition structure and INFO. Stops when CALLBACK returns zero. */
1213 traverse_c_tests (htab_trav callback, void *info)
1215 if (condition_table)
1216 htab_traverse (condition_table, callback, info);
1219 /* Helper functions for define_predicate and define_special_predicate
1220 processing. Shared between genrecog.c and genpreds.c. */
1222 static htab_t predicate_table;
1223 struct pred_data *first_predicate;
1224 static struct pred_data **last_predicate = &first_predicate;
1227 hash_struct_pred_data (const void *ptr)
1229 return htab_hash_string (((const struct pred_data *)ptr)->name);
1233 eq_struct_pred_data (const void *a, const void *b)
1235 return !strcmp (((const struct pred_data *)a)->name,
1236 ((const struct pred_data *)b)->name);
1240 lookup_predicate (const char *name)
1242 struct pred_data key;
1244 return (struct pred_data *) htab_find (predicate_table, &key);
1247 /* Record that predicate PRED can accept CODE. */
1250 add_predicate_code (struct pred_data *pred, enum rtx_code code)
1252 if (!pred->codes[code])
1255 pred->codes[code] = true;
1257 if (GET_RTX_CLASS (code) != RTX_CONST_OBJ)
1258 pred->allows_non_const = true;
1265 && code != STRICT_LOW_PART)
1266 pred->allows_non_lvalue = true;
1268 if (pred->num_codes == 1)
1269 pred->singleton = code;
1270 else if (pred->num_codes == 2)
1271 pred->singleton = UNKNOWN;
1276 add_predicate (struct pred_data *pred)
1278 void **slot = htab_find_slot (predicate_table, pred, INSERT);
1281 error ("duplicate predicate definition for '%s'", pred->name);
1285 *last_predicate = pred;
1286 last_predicate = &pred->next;
1289 /* This array gives the initial content of the predicate table. It
1290 has entries for all predicates defined in recog.c. */
1292 struct std_pred_table
1296 bool allows_const_p;
1297 RTX_CODE codes[NUM_RTX_CODE];
1300 static const struct std_pred_table std_preds[] = {
1301 {"general_operand", false, true, {SUBREG, REG, MEM}},
1302 {"address_operand", true, true, {SUBREG, REG, MEM, PLUS, MINUS, MULT}},
1303 {"register_operand", false, false, {SUBREG, REG}},
1304 {"pmode_register_operand", true, false, {SUBREG, REG}},
1305 {"scratch_operand", false, false, {SCRATCH, REG}},
1306 {"immediate_operand", false, true, {UNKNOWN}},
1307 {"const_int_operand", false, false, {CONST_INT}},
1308 {"const_double_operand", false, false, {CONST_INT, CONST_DOUBLE}},
1309 {"nonimmediate_operand", false, false, {SUBREG, REG, MEM}},
1310 {"nonmemory_operand", false, true, {SUBREG, REG}},
1311 {"push_operand", false, false, {MEM}},
1312 {"pop_operand", false, false, {MEM}},
1313 {"memory_operand", false, false, {SUBREG, MEM}},
1314 {"indirect_operand", false, false, {SUBREG, MEM}},
1315 {"ordered_comparison_operator", false, false, {EQ, NE,
1317 LEU, LTU, GEU, GTU}},
1318 {"comparison_operator", false, false, {EQ, NE,
1325 #define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)
1327 /* Initialize the table of predicate definitions, starting with
1328 the information we have on generic predicates. */
1331 init_predicate_table (void)
1334 struct pred_data *pred;
1336 predicate_table = htab_create_alloc (37, hash_struct_pred_data,
1337 eq_struct_pred_data, 0,
1340 for (i = 0; i < NUM_KNOWN_STD_PREDS; i++)
1342 pred = XCNEW (struct pred_data);
1343 pred->name = std_preds[i].name;
1344 pred->special = std_preds[i].special;
1346 for (j = 0; std_preds[i].codes[j] != 0; j++)
1347 add_predicate_code (pred, std_preds[i].codes[j]);
1349 if (std_preds[i].allows_const_p)
1350 for (j = 0; j < NUM_RTX_CODE; j++)
1351 if (GET_RTX_CLASS (j) == RTX_CONST_OBJ)
1352 add_predicate_code (pred, (enum rtx_code) j);
1354 add_predicate (pred);
1358 /* These functions allow linkage with print-rtl.c. Also, some generators
1359 like to annotate their output with insn names. */
1361 /* Holds an array of names indexed by insn_code_number. */
1362 static char **insn_name_ptr = 0;
1363 static int insn_name_ptr_size = 0;
1366 get_insn_name (int code)
1368 if (code < insn_name_ptr_size)
1369 return insn_name_ptr[code];
1375 record_insn_name (int code, const char *name)
1377 static const char *last_real_name = "insn";
1378 static int last_real_code = 0;
1381 if (insn_name_ptr_size <= code)
1384 new_size = (insn_name_ptr_size ? insn_name_ptr_size * 2 : 512);
1385 insn_name_ptr = XRESIZEVEC (char *, insn_name_ptr, new_size);
1386 memset (insn_name_ptr + insn_name_ptr_size, 0,
1387 sizeof(char *) * (new_size - insn_name_ptr_size));
1388 insn_name_ptr_size = new_size;
1391 if (!name || name[0] == '\0')
1393 new_name = XNEWVAR (char, strlen (last_real_name) + 10);
1394 sprintf (new_name, "%s+%d", last_real_name, code - last_real_code);
1398 last_real_name = new_name = xstrdup (name);
1399 last_real_code = code;
1402 insn_name_ptr[code] = new_name;