1 /* Support routines for the various generation passes.
2 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006
3 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 2, 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 COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
24 #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 *);
124 message_with_line (int lineno, const char *msg, ...)
130 fprintf (stderr, "%s:%d: ", read_rtx_filename, lineno);
131 vfprintf (stderr, msg, ap);
132 fputc ('\n', stderr);
137 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
138 the gensupport programs. */
141 gen_rtx_CONST_INT (enum machine_mode ARG_UNUSED (mode),
144 rtx rt = rtx_alloc (CONST_INT);
150 /* Queue PATTERN on LIST_TAIL. Return the address of the new queue
153 static struct queue_elem *
154 queue_pattern (rtx pattern, struct queue_elem ***list_tail,
155 const char *filename, int lineno)
157 struct queue_elem *e = XNEW(struct queue_elem);
159 e->filename = filename;
164 *list_tail = &e->next;
168 /* Recursively remove constraints from an rtx. */
171 remove_constraints (rtx part)
174 const char *format_ptr;
179 if (GET_CODE (part) == MATCH_OPERAND)
181 else if (GET_CODE (part) == MATCH_SCRATCH)
184 format_ptr = GET_RTX_FORMAT (GET_CODE (part));
186 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
187 switch (*format_ptr++)
191 remove_constraints (XEXP (part, i));
194 if (XVEC (part, i) != NULL)
195 for (j = 0; j < XVECLEN (part, i); j++)
196 remove_constraints (XVECEXP (part, i, j));
201 /* Process an include file assuming that it lives in gcc/config/{target}/
202 if the include looks like (include "file"). */
205 process_include (rtx desc, int lineno)
207 const char *filename = XSTR (desc, 0);
208 const char *old_filename;
213 /* If specified file name is absolute, skip the include stack. */
214 if (! IS_ABSOLUTE_PATH (filename))
216 struct file_name_list *stackp;
218 /* Search directory path, trying to open the file. */
219 for (stackp = first_dir_md_include; stackp; stackp = stackp->next)
221 static const char sep[2] = { DIR_SEPARATOR, '\0' };
223 pathname = concat (stackp->fname, sep, filename, NULL);
224 input_file = fopen (pathname, "r");
225 if (input_file != NULL)
232 pathname = concat (base_dir, filename, NULL);
234 pathname = xstrdup (filename);
235 input_file = fopen (pathname, "r");
236 if (input_file == NULL)
239 message_with_line (lineno, "include file `%s' not found", filename);
245 /* Save old cursor; setup new for the new file. Note that "lineno" the
246 argument to this function is the beginning of the include statement,
247 while read_rtx_lineno has already been advanced. */
248 old_filename = read_rtx_filename;
249 old_lineno = read_rtx_lineno;
250 read_rtx_filename = pathname;
253 if (include_callback)
254 include_callback (pathname);
256 /* Read the entire file. */
257 while (read_rtx (input_file, &desc, &lineno))
258 process_rtx (desc, lineno);
260 /* Do not free pathname. It is attached to the various rtx queue
263 read_rtx_filename = old_filename;
264 read_rtx_lineno = old_lineno;
269 /* Process a top level rtx in some way, queuing as appropriate. */
272 process_rtx (rtx desc, int lineno)
274 switch (GET_CODE (desc))
277 queue_pattern (desc, &define_insn_tail, read_rtx_filename, lineno);
280 case DEFINE_COND_EXEC:
281 queue_pattern (desc, &define_cond_exec_tail, read_rtx_filename, lineno);
285 queue_pattern (desc, &define_attr_tail, read_rtx_filename, lineno);
288 case DEFINE_PREDICATE:
289 case DEFINE_SPECIAL_PREDICATE:
290 case DEFINE_CONSTRAINT:
291 case DEFINE_REGISTER_CONSTRAINT:
292 case DEFINE_MEMORY_CONSTRAINT:
293 case DEFINE_ADDRESS_CONSTRAINT:
294 queue_pattern (desc, &define_pred_tail, read_rtx_filename, lineno);
298 process_include (desc, lineno);
301 case DEFINE_INSN_AND_SPLIT:
303 const char *split_cond;
307 struct queue_elem *insn_elem;
308 struct queue_elem *split_elem;
310 /* Create a split with values from the insn_and_split. */
311 split = rtx_alloc (DEFINE_SPLIT);
313 i = XVECLEN (desc, 1);
314 XVEC (split, 0) = rtvec_alloc (i);
317 XVECEXP (split, 0, i) = copy_rtx (XVECEXP (desc, 1, i));
318 remove_constraints (XVECEXP (split, 0, i));
321 /* If the split condition starts with "&&", append it to the
322 insn condition to create the new split condition. */
323 split_cond = XSTR (desc, 4);
324 if (split_cond[0] == '&' && split_cond[1] == '&')
326 copy_rtx_ptr_loc (split_cond + 2, split_cond);
327 split_cond = join_c_conditions (XSTR (desc, 2), split_cond + 2);
329 XSTR (split, 1) = split_cond;
330 XVEC (split, 2) = XVEC (desc, 5);
331 XSTR (split, 3) = XSTR (desc, 6);
333 /* Fix up the DEFINE_INSN. */
334 attr = XVEC (desc, 7);
335 PUT_CODE (desc, DEFINE_INSN);
336 XVEC (desc, 4) = attr;
340 = queue_pattern (desc, &define_insn_tail, read_rtx_filename,
343 = queue_pattern (split, &other_tail, read_rtx_filename, lineno);
344 insn_elem->split = split_elem;
349 queue_pattern (desc, &other_tail, read_rtx_filename, lineno);
354 /* Return true if attribute PREDICABLE is true for ELEM, which holds
358 is_predicable (struct queue_elem *elem)
360 rtvec vec = XVEC (elem->data, 4);
365 return predicable_default;
367 for (i = GET_NUM_ELEM (vec) - 1; i >= 0; --i)
369 rtx sub = RTVEC_ELT (vec, i);
370 switch (GET_CODE (sub))
373 if (strcmp (XSTR (sub, 0), "predicable") == 0)
375 value = XSTR (sub, 1);
380 case SET_ATTR_ALTERNATIVE:
381 if (strcmp (XSTR (sub, 0), "predicable") == 0)
383 message_with_line (elem->lineno,
384 "multiple alternatives for `predicable'");
391 if (GET_CODE (SET_DEST (sub)) != ATTR
392 || strcmp (XSTR (SET_DEST (sub), 0), "predicable") != 0)
395 if (GET_CODE (sub) == CONST_STRING)
397 value = XSTR (sub, 0);
401 /* ??? It would be possible to handle this if we really tried.
402 It's not easy though, and I'm not going to bother until it
403 really proves necessary. */
404 message_with_line (elem->lineno,
405 "non-constant value for `predicable'");
414 return predicable_default;
417 /* Verify that predicability does not vary on the alternative. */
418 /* ??? It should be possible to handle this by simply eliminating
419 the non-predicable alternatives from the insn. FRV would like
420 to do this. Delay this until we've got the basics solid. */
421 if (strchr (value, ',') != NULL)
423 message_with_line (elem->lineno,
424 "multiple alternatives for `predicable'");
429 /* Find out which value we're looking at. */
430 if (strcmp (value, predicable_true) == 0)
432 if (strcmp (value, predicable_false) == 0)
435 message_with_line (elem->lineno,
436 "unknown value `%s' for `predicable' attribute",
442 /* Examine the attribute "predicable"; discover its boolean values
446 identify_predicable_attribute (void)
448 struct queue_elem *elem;
449 char *p_true, *p_false;
452 /* Look for the DEFINE_ATTR for `predicable', which must exist. */
453 for (elem = define_attr_queue; elem ; elem = elem->next)
454 if (strcmp (XSTR (elem->data, 0), "predicable") == 0)
457 message_with_line (define_cond_exec_queue->lineno,
458 "attribute `predicable' not defined");
463 value = XSTR (elem->data, 1);
464 p_false = xstrdup (value);
465 p_true = strchr (p_false, ',');
466 if (p_true == NULL || strchr (++p_true, ',') != NULL)
468 message_with_line (elem->lineno,
469 "attribute `predicable' is not a boolean");
477 predicable_true = p_true;
478 predicable_false = p_false;
480 switch (GET_CODE (XEXP (elem->data, 2)))
483 value = XSTR (XEXP (elem->data, 2), 0);
487 message_with_line (elem->lineno,
488 "attribute `predicable' cannot be const");
495 message_with_line (elem->lineno,
496 "attribute `predicable' must have a constant default");
503 if (strcmp (value, p_true) == 0)
504 predicable_default = 1;
505 else if (strcmp (value, p_false) == 0)
506 predicable_default = 0;
509 message_with_line (elem->lineno,
510 "unknown value `%s' for `predicable' attribute",
519 /* Return the number of alternatives in constraint S. */
522 n_alternatives (const char *s)
533 /* Determine how many alternatives there are in INSN, and how many
537 collect_insn_data (rtx pattern, int *palt, int *pmax)
543 code = GET_CODE (pattern);
547 i = n_alternatives (XSTR (pattern, 2));
548 *palt = (i > *palt ? i : *palt);
554 i = XINT (pattern, 0);
563 fmt = GET_RTX_FORMAT (code);
564 len = GET_RTX_LENGTH (code);
565 for (i = 0; i < len; i++)
570 collect_insn_data (XEXP (pattern, i), palt, pmax);
574 if (XVEC (pattern, i) == NULL)
578 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
579 collect_insn_data (XVECEXP (pattern, i, j), palt, pmax);
582 case 'i': case 'w': case '0': case 's': case 'S': case 'T':
592 alter_predicate_for_insn (rtx pattern, int alt, int max_op, int lineno)
598 code = GET_CODE (pattern);
603 const char *c = XSTR (pattern, 2);
605 if (n_alternatives (c) != 1)
607 message_with_line (lineno,
608 "too many alternatives for operand %d",
614 /* Replicate C as needed to fill out ALT alternatives. */
615 if (c && *c && alt > 1)
617 size_t c_len = strlen (c);
618 size_t len = alt * (c_len + 1);
619 char *new_c = XNEWVEC(char, len);
621 memcpy (new_c, c, c_len);
622 for (i = 1; i < alt; ++i)
624 new_c[i * (c_len + 1) - 1] = ',';
625 memcpy (&new_c[i * (c_len + 1)], c, c_len);
627 new_c[len - 1] = '\0';
628 XSTR (pattern, 2) = new_c;
636 XINT (pattern, 0) += max_op;
643 fmt = GET_RTX_FORMAT (code);
644 len = GET_RTX_LENGTH (code);
645 for (i = 0; i < len; i++)
652 r = alter_predicate_for_insn (XEXP (pattern, i), alt,
659 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
661 r = alter_predicate_for_insn (XVECEXP (pattern, i, j),
662 alt, max_op, lineno);
668 case 'i': case 'w': case '0': case 's':
680 alter_test_for_insn (struct queue_elem *ce_elem,
681 struct queue_elem *insn_elem)
683 return join_c_conditions (XSTR (ce_elem->data, 1),
684 XSTR (insn_elem->data, 2));
687 /* Adjust all of the operand numbers in SRC to match the shift they'll
688 get from an operand displacement of DISP. Return a pointer after the
692 shift_output_template (char *dest, const char *src, int disp)
701 if (ISDIGIT ((unsigned char) c))
703 else if (ISALPHA (c))
716 alter_output_for_insn (struct queue_elem *ce_elem,
717 struct queue_elem *insn_elem,
720 const char *ce_out, *insn_out;
722 size_t len, ce_len, insn_len;
724 /* ??? Could coordinate with genoutput to not duplicate code here. */
726 ce_out = XSTR (ce_elem->data, 2);
727 insn_out = XTMPL (insn_elem->data, 3);
728 if (!ce_out || *ce_out == '\0')
731 ce_len = strlen (ce_out);
732 insn_len = strlen (insn_out);
734 if (*insn_out == '*')
735 /* You must take care of the predicate yourself. */
738 if (*insn_out == '@')
740 len = (ce_len + 1) * alt + insn_len + 1;
741 p = result = XNEWVEC(char, len);
747 while (ISSPACE ((unsigned char) *insn_out));
749 if (*insn_out != '#')
751 p = shift_output_template (p, ce_out, max_op);
757 while (*insn_out && *insn_out != '\n');
764 len = ce_len + 1 + insn_len + 1;
765 result = XNEWVEC (char, len);
767 p = shift_output_template (result, ce_out, max_op);
769 memcpy (p, insn_out, insn_len + 1);
775 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */
778 process_one_cond_exec (struct queue_elem *ce_elem)
780 struct queue_elem *insn_elem;
781 for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
783 int alternatives, max_operand;
784 rtx pred, insn, pattern, split;
787 if (! is_predicable (insn_elem))
792 collect_insn_data (insn_elem->data, &alternatives, &max_operand);
795 if (XVECLEN (ce_elem->data, 0) != 1)
797 message_with_line (ce_elem->lineno,
798 "too many patterns in predicate");
803 pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0));
804 pred = alter_predicate_for_insn (pred, alternatives, max_operand,
809 /* Construct a new pattern for the new insn. */
810 insn = copy_rtx (insn_elem->data);
812 pattern = rtx_alloc (COND_EXEC);
813 XEXP (pattern, 0) = pred;
814 if (XVECLEN (insn, 1) == 1)
816 XEXP (pattern, 1) = XVECEXP (insn, 1, 0);
817 XVECEXP (insn, 1, 0) = pattern;
818 PUT_NUM_ELEM (XVEC (insn, 1), 1);
822 XEXP (pattern, 1) = rtx_alloc (PARALLEL);
823 XVEC (XEXP (pattern, 1), 0) = XVEC (insn, 1);
824 XVEC (insn, 1) = rtvec_alloc (1);
825 XVECEXP (insn, 1, 0) = pattern;
828 XSTR (insn, 2) = alter_test_for_insn (ce_elem, insn_elem);
829 XTMPL (insn, 3) = alter_output_for_insn (ce_elem, insn_elem,
830 alternatives, max_operand);
832 /* ??? Set `predicable' to false. Not crucial since it's really
833 only used here, and we won't reprocess this new pattern. */
835 /* Put the new pattern on the `other' list so that it
836 (a) is not reprocessed by other define_cond_exec patterns
837 (b) appears after all normal define_insn patterns.
839 ??? B is debatable. If one has normal insns that match
840 cond_exec patterns, they will be preferred over these
841 generated patterns. Whether this matters in practice, or if
842 it's a good thing, or whether we should thread these new
843 patterns into the define_insn chain just after their generator
844 is something we'll have to experiment with. */
846 queue_pattern (insn, &other_tail, insn_elem->filename,
849 if (!insn_elem->split)
852 /* If the original insn came from a define_insn_and_split,
853 generate a new split to handle the predicated insn. */
854 split = copy_rtx (insn_elem->split->data);
855 /* Predicate the pattern matched by the split. */
856 pattern = rtx_alloc (COND_EXEC);
857 XEXP (pattern, 0) = pred;
858 if (XVECLEN (split, 0) == 1)
860 XEXP (pattern, 1) = XVECEXP (split, 0, 0);
861 XVECEXP (split, 0, 0) = pattern;
862 PUT_NUM_ELEM (XVEC (split, 0), 1);
866 XEXP (pattern, 1) = rtx_alloc (PARALLEL);
867 XVEC (XEXP (pattern, 1), 0) = XVEC (split, 0);
868 XVEC (split, 0) = rtvec_alloc (1);
869 XVECEXP (split, 0, 0) = pattern;
871 /* Predicate all of the insns generated by the split. */
872 for (i = 0; i < XVECLEN (split, 2); i++)
874 pattern = rtx_alloc (COND_EXEC);
875 XEXP (pattern, 0) = pred;
876 XEXP (pattern, 1) = XVECEXP (split, 2, i);
877 XVECEXP (split, 2, i) = pattern;
879 /* Add the new split to the queue. */
880 queue_pattern (split, &other_tail, read_rtx_filename,
881 insn_elem->split->lineno);
885 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
886 patterns appropriately. */
889 process_define_cond_exec (void)
891 struct queue_elem *elem;
893 identify_predicable_attribute ();
897 for (elem = define_cond_exec_queue; elem ; elem = elem->next)
898 process_one_cond_exec (elem);
902 save_string (const char *s, int len)
904 char *result = XNEWVEC (char, len + 1);
906 memcpy (result, s, len);
912 /* The entry point for initializing the reader. */
915 init_md_reader_args_cb (int argc, char **argv, bool (*parse_opt)(const char *))
921 bool no_more_options;
922 bool already_read_stdin;
924 /* Unlock the stdio streams. */
925 unlock_std_streams ();
927 /* First we loop over all the options. */
928 for (i = 1; i < argc; i++)
930 if (argv[i][0] != '-')
936 case 'I': /* Add directory to path for includes. */
938 struct file_name_list *dirtmp;
940 dirtmp = XNEW (struct file_name_list);
941 dirtmp->next = 0; /* New one goes on the end */
942 if (first_dir_md_include == 0)
943 first_dir_md_include = dirtmp;
945 last_dir_md_include->next = dirtmp;
946 last_dir_md_include = dirtmp; /* Tail follows the last one */
947 if (argv[i][1] == 'I' && argv[i][2] != 0)
948 dirtmp->fname = argv[i] + 2;
949 else if (i + 1 == argc)
950 fatal ("directory name missing after -I option");
952 dirtmp->fname = argv[++i];
953 if (strlen (dirtmp->fname) > max_include_len)
954 max_include_len = strlen (dirtmp->fname);
959 /* An argument consisting of exactly one dash is a request to
960 read stdin. This will be handled in the second loop. */
964 /* An argument consisting of just two dashes causes option
966 if (argv[i][2] == '\0')
967 goto stop_parsing_options;
970 /* The program may have provided a callback so it can
971 accept its own options. */
972 if (parse_opt && parse_opt (argv[i]))
975 fatal ("invalid option `%s'", argv[i]);
979 stop_parsing_options:
981 /* Prepare to read input. */
982 condition_table = htab_create (500, hash_c_test, cmp_c_test, NULL);
983 init_predicate_table ();
984 obstack_init (rtl_obstack);
987 no_more_options = false;
988 already_read_stdin = false;
991 /* Now loop over all input files. */
992 for (i = 1; i < argc; i++)
994 if (argv[i][0] == '-')
996 if (argv[i][1] == '\0')
999 if (already_read_stdin)
1000 fatal ("cannot read standard input twice");
1003 read_rtx_filename = in_fname = "<stdin>";
1004 read_rtx_lineno = 1;
1006 already_read_stdin = true;
1008 while (read_rtx (input_file, &desc, &lineno))
1009 process_rtx (desc, lineno);
1010 fclose (input_file);
1013 else if (argv[i][1] == '-' && argv[i][2] == '\0')
1015 /* No further arguments are to be treated as options. */
1016 no_more_options = true;
1019 else if (!no_more_options)
1023 /* If we get here we are looking at a non-option argument, i.e.
1024 a file to be processed. */
1027 lastsl = strrchr (in_fname, '/');
1029 base_dir = save_string (in_fname, lastsl - in_fname + 1 );
1033 read_rtx_filename = in_fname;
1034 read_rtx_lineno = 1;
1035 input_file = fopen (in_fname, "r");
1036 if (input_file == 0)
1039 return FATAL_EXIT_CODE;
1042 while (read_rtx (input_file, &desc, &lineno))
1043 process_rtx (desc, lineno);
1044 fclose (input_file);
1047 /* If we get to this point without having seen any files to process,
1048 read standard input now. */
1052 read_rtx_filename = in_fname = "<stdin>";
1053 read_rtx_lineno = 1;
1056 while (read_rtx (input_file, &desc, &lineno))
1057 process_rtx (desc, lineno);
1058 fclose (input_file);
1061 /* Process define_cond_exec patterns. */
1062 if (define_cond_exec_queue != NULL)
1063 process_define_cond_exec ();
1065 return errors ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
1068 /* Programs that don't have their own options can use this entry point
1071 init_md_reader_args (int argc, char **argv)
1073 return init_md_reader_args_cb (argc, argv, 0);
1076 /* The entry point for reading a single rtx from an md file. */
1079 read_md_rtx (int *lineno, int *seqnr)
1081 struct queue_elem **queue, *elem;
1086 /* Read all patterns from a given queue before moving on to the next. */
1087 if (define_attr_queue != NULL)
1088 queue = &define_attr_queue;
1089 else if (define_pred_queue != NULL)
1090 queue = &define_pred_queue;
1091 else if (define_insn_queue != NULL)
1092 queue = &define_insn_queue;
1093 else if (other_queue != NULL)
1094 queue = &other_queue;
1099 *queue = elem->next;
1101 read_rtx_filename = elem->filename;
1102 *lineno = elem->lineno;
1103 *seqnr = sequence_num;
1107 /* Discard insn patterns which we know can never match (because
1108 their C test is provably always false). If insn_elision is
1109 false, our caller needs to see all the patterns. Note that the
1110 elided patterns are never counted by the sequence numbering; it
1111 it is the caller's responsibility, when insn_elision is false, not
1112 to use elided pattern numbers for anything. */
1113 switch (GET_CODE (desc))
1117 if (maybe_eval_c_test (XSTR (desc, 2)) != 0)
1119 else if (insn_elision)
1122 /* *seqnr is used here so the name table will match caller's
1123 idea of insn numbering, whether or not elision is active. */
1124 record_insn_name (*seqnr, XSTR (desc, 0));
1128 case DEFINE_PEEPHOLE:
1129 case DEFINE_PEEPHOLE2:
1130 if (maybe_eval_c_test (XSTR (desc, 1)) != 0)
1132 else if (insn_elision)
1143 /* Helper functions for insn elision. */
1145 /* Compute a hash function of a c_test structure, which is keyed
1146 by its ->expr field. */
1148 hash_c_test (const void *x)
1150 const struct c_test *a = (const struct c_test *) x;
1151 const unsigned char *base, *s = (const unsigned char *) a->expr;
1159 while ((c = *s++) != '\0')
1161 hash += c + (c << 17);
1166 hash += len + (len << 17);
1172 /* Compare two c_test expression structures. */
1174 cmp_c_test (const void *x, const void *y)
1176 const struct c_test *a = (const struct c_test *) x;
1177 const struct c_test *b = (const struct c_test *) y;
1179 return !strcmp (a->expr, b->expr);
1182 /* Given a string representing a C test expression, look it up in the
1183 condition_table and report whether or not its value is known
1184 at compile time. Returns a tristate: 1 for known true, 0 for
1185 known false, -1 for unknown. */
1187 maybe_eval_c_test (const char *expr)
1189 const struct c_test *test;
1190 struct c_test dummy;
1196 test = (const struct c_test *)htab_find (condition_table, &dummy);
1202 /* Record the C test expression EXPR in the condition_table, with
1203 value VAL. Duplicates clobber previous entries. */
1206 add_c_test (const char *expr, int value)
1208 struct c_test *test;
1213 test = XNEW (struct c_test);
1215 test->value = value;
1217 *(htab_find_slot (condition_table, test, INSERT)) = test;
1220 /* For every C test, call CALLBACK with two arguments: a pointer to
1221 the condition structure and INFO. Stops when CALLBACK returns zero. */
1223 traverse_c_tests (htab_trav callback, void *info)
1225 if (condition_table)
1226 htab_traverse (condition_table, callback, info);
1230 /* Given a string, return the number of comma-separated elements in it.
1231 Return 0 for the null string. */
1233 n_comma_elts (const char *s)
1240 for (n = 1; *s; s++)
1247 /* Given a pointer to a (char *), return a pointer to the beginning of the
1248 next comma-separated element in the string. Advance the pointer given
1249 to the end of that element. Return NULL if at end of string. Caller
1250 is responsible for copying the string if necessary. White space between
1251 a comma and an element is ignored. */
1254 scan_comma_elt (const char **pstr)
1257 const char *p = *pstr;
1269 while (*p != ',' && *p != '\0')
1276 /* Helper functions for define_predicate and define_special_predicate
1277 processing. Shared between genrecog.c and genpreds.c. */
1279 static htab_t predicate_table;
1280 struct pred_data *first_predicate;
1281 static struct pred_data **last_predicate = &first_predicate;
1284 hash_struct_pred_data (const void *ptr)
1286 return htab_hash_string (((const struct pred_data *)ptr)->name);
1290 eq_struct_pred_data (const void *a, const void *b)
1292 return !strcmp (((const struct pred_data *)a)->name,
1293 ((const struct pred_data *)b)->name);
1297 lookup_predicate (const char *name)
1299 struct pred_data key;
1301 return (struct pred_data *) htab_find (predicate_table, &key);
1305 add_predicate (struct pred_data *pred)
1307 void **slot = htab_find_slot (predicate_table, pred, INSERT);
1310 error ("duplicate predicate definition for '%s'", pred->name);
1314 *last_predicate = pred;
1315 last_predicate = &pred->next;
1318 /* This array gives the initial content of the predicate table. It
1319 has entries for all predicates defined in recog.c. */
1321 struct std_pred_table
1325 RTX_CODE codes[NUM_RTX_CODE];
1328 static const struct std_pred_table std_preds[] = {
1329 {"general_operand", false, {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
1330 LABEL_REF, SUBREG, REG, MEM }},
1331 {"address_operand", true, {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
1332 LABEL_REF, SUBREG, REG, MEM,
1333 PLUS, MINUS, MULT}},
1334 {"register_operand", false, {SUBREG, REG}},
1335 {"pmode_register_operand", true, {SUBREG, REG}},
1336 {"scratch_operand", false, {SCRATCH, REG}},
1337 {"immediate_operand", false, {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
1339 {"const_int_operand", false, {CONST_INT}},
1340 {"const_double_operand", false, {CONST_INT, CONST_DOUBLE}},
1341 {"nonimmediate_operand", false, {SUBREG, REG, MEM}},
1342 {"nonmemory_operand", false, {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
1343 LABEL_REF, SUBREG, REG}},
1344 {"push_operand", false, {MEM}},
1345 {"pop_operand", false, {MEM}},
1346 {"memory_operand", false, {SUBREG, MEM}},
1347 {"indirect_operand", false, {SUBREG, MEM}},
1348 {"comparison_operator", false, {EQ, NE, LE, LT, GE, GT, LEU, LTU, GEU, GTU,
1349 UNORDERED, ORDERED, UNEQ, UNGE, UNGT, UNLE,
1352 #define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)
1354 /* Initialize the table of predicate definitions, starting with
1355 the information we have on generic predicates. */
1358 init_predicate_table (void)
1361 struct pred_data *pred;
1363 predicate_table = htab_create_alloc (37, hash_struct_pred_data,
1364 eq_struct_pred_data, 0,
1367 for (i = 0; i < NUM_KNOWN_STD_PREDS; i++)
1369 pred = XCNEW (struct pred_data);
1370 pred->name = std_preds[i].name;
1371 pred->special = std_preds[i].special;
1373 for (j = 0; std_preds[i].codes[j] != 0; j++)
1375 enum rtx_code code = std_preds[i].codes[j];
1377 pred->codes[code] = true;
1378 if (GET_RTX_CLASS (code) != RTX_CONST_OBJ)
1379 pred->allows_non_const = true;
1385 && code != STRICT_LOW_PART)
1386 pred->allows_non_lvalue = true;
1389 pred->singleton = std_preds[i].codes[0];
1391 add_predicate (pred);
1395 /* These functions allow linkage with print-rtl.c. Also, some generators
1396 like to annotate their output with insn names. */
1398 /* Holds an array of names indexed by insn_code_number. */
1399 static char **insn_name_ptr = 0;
1400 static int insn_name_ptr_size = 0;
1403 get_insn_name (int code)
1405 if (code < insn_name_ptr_size)
1406 return insn_name_ptr[code];
1412 record_insn_name (int code, const char *name)
1414 static const char *last_real_name = "insn";
1415 static int last_real_code = 0;
1418 if (insn_name_ptr_size <= code)
1421 new_size = (insn_name_ptr_size ? insn_name_ptr_size * 2 : 512);
1422 insn_name_ptr = xrealloc (insn_name_ptr, sizeof(char *) * new_size);
1423 memset (insn_name_ptr + insn_name_ptr_size, 0,
1424 sizeof(char *) * (new_size - insn_name_ptr_size));
1425 insn_name_ptr_size = new_size;
1428 if (!name || name[0] == '\0')
1430 new = xmalloc (strlen (last_real_name) + 10);
1431 sprintf (new, "%s+%d", last_real_name, code - last_real_code);
1435 last_real_name = new = xstrdup (name);
1436 last_real_code = code;
1439 insn_name_ptr[code] = new;