1 /* Support routines for the various generation passes.
2 Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING. If not, write to the Free
18 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
26 #include "gensupport.h"
29 /* In case some macros used by files we include need it, define this here. */
32 static struct obstack obstack;
33 struct obstack *rtl_obstack = &obstack;
35 #define obstack_chunk_alloc xmalloc
36 #define obstack_chunk_free free
38 static int sequence_num;
41 static int predicable_default;
42 static const char *predicable_true;
43 static const char *predicable_false;
45 static char *base_dir = NULL;
47 /* We initially queue all patterns, process the define_insn and
48 define_cond_exec patterns, then return them one at a time. */
54 struct queue_elem *next;
57 static struct queue_elem *define_attr_queue;
58 static struct queue_elem **define_attr_tail = &define_attr_queue;
59 static struct queue_elem *define_insn_queue;
60 static struct queue_elem **define_insn_tail = &define_insn_queue;
61 static struct queue_elem *define_cond_exec_queue;
62 static struct queue_elem **define_cond_exec_tail = &define_cond_exec_queue;
63 static struct queue_elem *other_queue;
64 static struct queue_elem **other_tail = &other_queue;
66 static void queue_pattern PARAMS ((rtx, struct queue_elem ***, int));
68 /* Current maximum length of directory names in the search path
69 for include files. (Altered as we get more of them.) */
71 size_t max_include_len;
75 struct file_name_list *next;
79 struct file_name_list *first_dir_md_include = 0; /* First dir to search */
80 /* First dir to search for <file> */
81 struct file_name_list *first_bracket_include = 0;
82 struct file_name_list *last_dir_md_include = 0; /* Last in chain */
84 static void remove_constraints PARAMS ((rtx));
85 static void process_rtx PARAMS ((rtx, int));
87 static int is_predicable PARAMS ((struct queue_elem *));
88 static void identify_predicable_attribute PARAMS ((void));
89 static int n_alternatives PARAMS ((const char *));
90 static void collect_insn_data PARAMS ((rtx, int *, int *));
91 static rtx alter_predicate_for_insn PARAMS ((rtx, int, int, int));
92 static const char *alter_test_for_insn PARAMS ((struct queue_elem *,
93 struct queue_elem *));
94 static char *shift_output_template PARAMS ((char *, const char *, int));
95 static const char *alter_output_for_insn PARAMS ((struct queue_elem *,
98 static void process_one_cond_exec PARAMS ((struct queue_elem *));
99 static void process_define_cond_exec PARAMS ((void));
100 static int process_include PARAMS ((rtx, int));
101 static char *save_string PARAMS ((const char *, int));
102 static int init_include_reader PARAMS ((FILE *));
105 message_with_line VPARAMS ((int lineno, const char *msg, ...))
108 VA_FIXEDARG (ap, int, lineno);
109 VA_FIXEDARG (ap, const char *, msg);
111 fprintf (stderr, "%s:%d: ", read_rtx_filename, lineno);
112 vfprintf (stderr, msg, ap);
113 fputc ('\n', stderr);
118 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
119 the gensupport programs. */
122 gen_rtx_CONST_INT (mode, arg)
123 enum machine_mode mode ATTRIBUTE_UNUSED;
126 rtx rt = rtx_alloc (CONST_INT);
132 /* Queue PATTERN on LIST_TAIL. */
135 queue_pattern (pattern, list_tail, lineno)
137 struct queue_elem ***list_tail;
140 struct queue_elem *e = (struct queue_elem *) xmalloc (sizeof (*e));
145 *list_tail = &e->next;
148 /* Recursively remove constraints from an rtx. */
151 remove_constraints (part)
155 const char *format_ptr;
160 if (GET_CODE (part) == MATCH_OPERAND)
162 else if (GET_CODE (part) == MATCH_SCRATCH)
165 format_ptr = GET_RTX_FORMAT (GET_CODE (part));
167 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
168 switch (*format_ptr++)
172 remove_constraints (XEXP (part, i));
175 if (XVEC (part, i) != NULL)
176 for (j = 0; j < XVECLEN (part, i); j++)
177 remove_constraints (XVECEXP (part, i, j));
182 /* The entry point for initializing the reader. */
185 init_include_reader (inf)
192 /* Read the entire file. */
198 c = read_skip_spaces (inf);
203 lineno = read_rtx_lineno;
204 desc = read_rtx (inf);
205 process_rtx (desc, lineno);
209 /* Process define_cond_exec patterns. */
210 if (define_cond_exec_queue != NULL)
211 process_define_cond_exec ();
213 return errors ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
216 /* Process an include file assuming that it lives in gcc/config/{target}/
217 if the include looks line (include "file" ) */
219 process_include (desc, lineno)
223 const char *filename = XSTR (desc, 0);
224 char *pathname = NULL;
227 struct file_name_list *stackp;
230 stackp = first_dir_md_include;
232 /* If specified file name is absolute, just open it. */
233 if (IS_ABSOLUTE_PATHNAME (filename) || !stackp)
237 pathname = xmalloc (strlen (base_dir) + strlen (filename) + 1);
238 pathname = strcpy (pathname, base_dir);
239 strcat (pathname, filename);
240 strcat (pathname, "\0");
244 pathname = xstrdup (filename);
246 read_rtx_filename = pathname;
247 input_file = fopen (pathname, "r");
252 return FATAL_EXIT_CODE;
258 flen = strlen (filename);
260 fname = (char *) xmalloc (max_include_len + flen + 2);
262 /* + 2 above for slash and terminating null. */
264 /* Search directory path, trying to open the file.
265 Copy each filename tried into FNAME. */
267 for (; stackp; stackp = stackp->next)
271 strcpy (fname, stackp->fname);
273 fname[strlen (fname) + flen] = 0;
279 strncat (fname, (const char *) filename, flen);
280 read_rtx_filename = fname;
281 input_file = fopen (fname, "r");
282 if (input_file != NULL)
287 if (strchr (fname, '/') == NULL || strchr (fname, '\\' ) || base_dir)
292 xmalloc (strlen (base_dir) + strlen (filename) + 1);
293 pathname = strcpy (pathname, base_dir);
294 strcat (pathname, filename);
295 strcat (pathname, "\0");
298 pathname = xstrdup (filename);
300 read_rtx_filename = pathname;
301 input_file = fopen (pathname, "r");
306 return FATAL_EXIT_CODE;
312 if (init_include_reader (input_file) == FATAL_EXIT_CODE)
313 message_with_line (lineno, "read errors found in include file %s\n", pathname);
317 return SUCCESS_EXIT_CODE;
320 /* Process a top level rtx in some way, queueing as appropriate. */
323 process_rtx (desc, lineno)
327 switch (GET_CODE (desc))
330 queue_pattern (desc, &define_insn_tail, lineno);
333 case DEFINE_COND_EXEC:
334 queue_pattern (desc, &define_cond_exec_tail, lineno);
338 queue_pattern (desc, &define_attr_tail, lineno);
342 if (process_include (desc, lineno) == FATAL_EXIT_CODE)
344 const char *filename = XSTR (desc, 0);
345 message_with_line (lineno, "include file at %s not found\n",
350 case DEFINE_INSN_AND_SPLIT:
352 const char *split_cond;
357 /* Create a split with values from the insn_and_split. */
358 split = rtx_alloc (DEFINE_SPLIT);
360 i = XVECLEN (desc, 1);
361 XVEC (split, 0) = rtvec_alloc (i);
364 XVECEXP (split, 0, i) = copy_rtx (XVECEXP (desc, 1, i));
365 remove_constraints (XVECEXP (split, 0, i));
368 /* If the split condition starts with "&&", append it to the
369 insn condition to create the new split condition. */
370 split_cond = XSTR (desc, 4);
371 if (split_cond[0] == '&' && split_cond[1] == '&')
373 const char *insn_cond = XSTR (desc, 2);
374 size_t insn_cond_len = strlen (insn_cond);
375 size_t split_cond_len = strlen (split_cond);
378 combined = (char *) xmalloc (insn_cond_len + split_cond_len + 1);
379 memcpy (combined, insn_cond, insn_cond_len);
380 memcpy (combined + insn_cond_len, split_cond, split_cond_len + 1);
382 split_cond = combined;
384 XSTR (split, 1) = split_cond;
385 XVEC (split, 2) = XVEC (desc, 5);
386 XSTR (split, 3) = XSTR (desc, 6);
388 /* Fix up the DEFINE_INSN. */
389 attr = XVEC (desc, 7);
390 PUT_CODE (desc, DEFINE_INSN);
391 XVEC (desc, 4) = attr;
394 queue_pattern (desc, &define_insn_tail, lineno);
395 queue_pattern (split, &other_tail, lineno);
400 queue_pattern (desc, &other_tail, lineno);
405 /* Return true if attribute PREDICABLE is true for ELEM, which holds
410 struct queue_elem *elem;
412 rtvec vec = XVEC (elem->data, 4);
417 return predicable_default;
419 for (i = GET_NUM_ELEM (vec) - 1; i >= 0; --i)
421 rtx sub = RTVEC_ELT (vec, i);
422 switch (GET_CODE (sub))
425 if (strcmp (XSTR (sub, 0), "predicable") == 0)
427 value = XSTR (sub, 1);
432 case SET_ATTR_ALTERNATIVE:
433 if (strcmp (XSTR (sub, 0), "predicable") == 0)
435 message_with_line (elem->lineno,
436 "multiple alternatives for `predicable'");
443 if (GET_CODE (SET_DEST (sub)) != ATTR
444 || strcmp (XSTR (SET_DEST (sub), 0), "predicable") != 0)
447 if (GET_CODE (sub) == CONST_STRING)
449 value = XSTR (sub, 0);
453 /* ??? It would be possible to handle this if we really tried.
454 It's not easy though, and I'm not going to bother until it
455 really proves necessary. */
456 message_with_line (elem->lineno,
457 "non-constant value for `predicable'");
466 return predicable_default;
469 /* Verify that predicability does not vary on the alternative. */
470 /* ??? It should be possible to handle this by simply eliminating
471 the non-predicable alternatives from the insn. FRV would like
472 to do this. Delay this until we've got the basics solid. */
473 if (strchr (value, ',') != NULL)
475 message_with_line (elem->lineno,
476 "multiple alternatives for `predicable'");
481 /* Find out which value we're looking at. */
482 if (strcmp (value, predicable_true) == 0)
484 if (strcmp (value, predicable_false) == 0)
487 message_with_line (elem->lineno,
488 "unknown value `%s' for `predicable' attribute",
494 /* Examine the attribute "predicable"; discover its boolean values
498 identify_predicable_attribute ()
500 struct queue_elem *elem;
501 char *p_true, *p_false;
505 /* Look for the DEFINE_ATTR for `predicable', which must exist. */
506 for (elem = define_attr_queue; elem ; elem = elem->next)
507 if (strcmp (XSTR (elem->data, 0), "predicable") == 0)
510 message_with_line (define_cond_exec_queue->lineno,
511 "attribute `predicable' not defined");
516 value = XSTR (elem->data, 1);
517 len = strlen (value);
518 p_false = (char *) xmalloc (len + 1);
519 memcpy (p_false, value, len + 1);
521 p_true = strchr (p_false, ',');
522 if (p_true == NULL || strchr (++p_true, ',') != NULL)
524 message_with_line (elem->lineno,
525 "attribute `predicable' is not a boolean");
531 predicable_true = p_true;
532 predicable_false = p_false;
534 switch (GET_CODE (XEXP (elem->data, 2)))
537 value = XSTR (XEXP (elem->data, 2), 0);
541 message_with_line (elem->lineno,
542 "attribute `predicable' cannot be const");
547 message_with_line (elem->lineno,
548 "attribute `predicable' must have a constant default");
553 if (strcmp (value, p_true) == 0)
554 predicable_default = 1;
555 else if (strcmp (value, p_false) == 0)
556 predicable_default = 0;
559 message_with_line (elem->lineno,
560 "unknown value `%s' for `predicable' attribute",
566 /* Return the number of alternatives in constraint S. */
581 /* Determine how many alternatives there are in INSN, and how many
585 collect_insn_data (pattern, palt, pmax)
593 code = GET_CODE (pattern);
597 i = n_alternatives (XSTR (pattern, 2));
598 *palt = (i > *palt ? i : *palt);
605 i = XINT (pattern, 0);
614 fmt = GET_RTX_FORMAT (code);
615 len = GET_RTX_LENGTH (code);
616 for (i = 0; i < len; i++)
621 collect_insn_data (XEXP (pattern, i), palt, pmax);
625 if (XVEC (pattern, i) == NULL)
629 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
630 collect_insn_data (XVECEXP (pattern, i, j), palt, pmax);
633 case 'i': case 'w': case '0': case 's': case 'S': case 'T':
643 alter_predicate_for_insn (pattern, alt, max_op, lineno)
645 int alt, max_op, lineno;
651 code = GET_CODE (pattern);
656 const char *c = XSTR (pattern, 2);
658 if (n_alternatives (c) != 1)
660 message_with_line (lineno,
661 "too many alternatives for operand %d",
667 /* Replicate C as needed to fill out ALT alternatives. */
668 if (c && *c && alt > 1)
670 size_t c_len = strlen (c);
671 size_t len = alt * (c_len + 1);
672 char *new_c = (char *) xmalloc (len);
674 memcpy (new_c, c, c_len);
675 for (i = 1; i < alt; ++i)
677 new_c[i * (c_len + 1) - 1] = ',';
678 memcpy (&new_c[i * (c_len + 1)], c, c_len);
680 new_c[len - 1] = '\0';
681 XSTR (pattern, 2) = new_c;
690 XINT (pattern, 0) += max_op;
697 fmt = GET_RTX_FORMAT (code);
698 len = GET_RTX_LENGTH (code);
699 for (i = 0; i < len; i++)
706 r = alter_predicate_for_insn (XEXP (pattern, i), alt,
713 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
715 r = alter_predicate_for_insn (XVECEXP (pattern, i, j),
716 alt, max_op, lineno);
722 case 'i': case 'w': case '0': case 's':
734 alter_test_for_insn (ce_elem, insn_elem)
735 struct queue_elem *ce_elem, *insn_elem;
737 const char *ce_test, *insn_test;
739 size_t len, ce_len, insn_len;
741 ce_test = XSTR (ce_elem->data, 1);
742 insn_test = XSTR (insn_elem->data, 2);
743 if (!ce_test || *ce_test == '\0')
745 if (!insn_test || *insn_test == '\0')
748 ce_len = strlen (ce_test);
749 insn_len = strlen (insn_test);
750 len = 1 + ce_len + 1 + 4 + 1 + insn_len + 1 + 1;
751 new_test = (char *) xmalloc (len);
753 sprintf (new_test, "(%s) && (%s)", ce_test, insn_test);
758 /* Adjust all of the operand numbers in OLD to match the shift they'll
759 get from an operand displacement of DISP. Return a pointer after the
763 shift_output_template (new, old, disp)
775 if (ISDIGIT ((unsigned char) c))
777 else if (ISALPHA (c))
790 alter_output_for_insn (ce_elem, insn_elem, alt, max_op)
791 struct queue_elem *ce_elem, *insn_elem;
794 const char *ce_out, *insn_out;
796 size_t len, ce_len, insn_len;
798 /* ??? Could coordinate with genoutput to not duplicate code here. */
800 ce_out = XSTR (ce_elem->data, 2);
801 insn_out = XTMPL (insn_elem->data, 3);
802 if (!ce_out || *ce_out == '\0')
805 ce_len = strlen (ce_out);
806 insn_len = strlen (insn_out);
808 if (*insn_out == '*')
809 /* You must take care of the predicate yourself. */
812 if (*insn_out == '@')
814 len = (ce_len + 1) * alt + insn_len + 1;
815 p = new = xmalloc (len);
821 while (ISSPACE ((unsigned char) *insn_out));
823 if (*insn_out != '#')
825 p = shift_output_template (p, ce_out, max_op);
831 while (*insn_out && *insn_out != '\n');
838 len = ce_len + 1 + insn_len + 1;
841 p = shift_output_template (new, ce_out, max_op);
843 memcpy (p, insn_out, insn_len + 1);
849 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */
852 process_one_cond_exec (ce_elem)
853 struct queue_elem *ce_elem;
855 struct queue_elem *insn_elem;
856 for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
858 int alternatives, max_operand;
859 rtx pred, insn, pattern;
861 if (! is_predicable (insn_elem))
866 collect_insn_data (insn_elem->data, &alternatives, &max_operand);
869 if (XVECLEN (ce_elem->data, 0) != 1)
871 message_with_line (ce_elem->lineno,
872 "too many patterns in predicate");
877 pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0));
878 pred = alter_predicate_for_insn (pred, alternatives, max_operand,
883 /* Construct a new pattern for the new insn. */
884 insn = copy_rtx (insn_elem->data);
886 pattern = rtx_alloc (COND_EXEC);
887 XEXP (pattern, 0) = pred;
888 if (XVECLEN (insn, 1) == 1)
890 XEXP (pattern, 1) = XVECEXP (insn, 1, 0);
891 XVECEXP (insn, 1, 0) = pattern;
892 PUT_NUM_ELEM (XVEC (insn, 1), 1);
896 XEXP (pattern, 1) = rtx_alloc (PARALLEL);
897 XVEC (XEXP (pattern, 1), 0) = XVEC (insn, 1);
898 XVEC (insn, 1) = rtvec_alloc (1);
899 XVECEXP (insn, 1, 0) = pattern;
902 XSTR (insn, 2) = alter_test_for_insn (ce_elem, insn_elem);
903 XTMPL (insn, 3) = alter_output_for_insn (ce_elem, insn_elem,
904 alternatives, max_operand);
906 /* ??? Set `predicable' to false. Not crucial since it's really
907 only used here, and we won't reprocess this new pattern. */
909 /* Put the new pattern on the `other' list so that it
910 (a) is not reprocessed by other define_cond_exec patterns
911 (b) appears after all normal define_insn patterns.
913 ??? B is debatable. If one has normal insns that match
914 cond_exec patterns, they will be preferred over these
915 generated patterns. Whether this matters in practice, or if
916 it's a good thing, or whether we should thread these new
917 patterns into the define_insn chain just after their generator
918 is something we'll have to experiment with. */
920 queue_pattern (insn, &other_tail, insn_elem->lineno);
924 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
925 patterns appropriately. */
928 process_define_cond_exec ()
930 struct queue_elem *elem;
932 identify_predicable_attribute ();
936 for (elem = define_cond_exec_queue; elem ; elem = elem->next)
937 process_one_cond_exec (elem);
945 register char *result = xmalloc (len + 1);
947 memcpy (result, s, len);
953 /* The entry point for initializing the reader. */
956 init_md_reader_args (argc, argv)
961 const char *in_fname;
965 for (i = 1; i < argc; i++)
967 if (argv[i][0] != '-')
969 if (in_fname == NULL)
977 case 'I': /* Add directory to path for includes. */
979 struct file_name_list *dirtmp;
981 dirtmp = (struct file_name_list *)
982 xmalloc (sizeof (struct file_name_list));
983 dirtmp->next = 0; /* New one goes on the end */
984 if (first_dir_md_include == 0)
985 first_dir_md_include = dirtmp;
987 last_dir_md_include->next = dirtmp;
988 last_dir_md_include = dirtmp; /* Tail follows the last one */
989 if (argv[i][1] == 'I' && argv[i][2] != 0)
990 dirtmp->fname = argv[i] + 2;
991 else if (i + 1 == argc)
992 fatal ("directory name missing after -I option");
994 dirtmp->fname = argv[++i];
995 if (strlen (dirtmp->fname) > max_include_len)
996 max_include_len = strlen (dirtmp->fname);
1000 fatal ("invalid option `%s'", argv[i]);
1005 return init_md_reader (in_fname);
1008 /* The entry point for initializing the reader. */
1011 init_md_reader (filename)
1012 const char *filename;
1018 lastsl = strrchr (filename, '/');
1020 base_dir = save_string (filename, lastsl - filename + 1 );
1022 read_rtx_filename = filename;
1023 input_file = fopen (filename, "r");
1024 if (input_file == 0)
1027 return FATAL_EXIT_CODE;
1030 obstack_init (rtl_obstack);
1034 /* Read the entire file. */
1040 c = read_skip_spaces (input_file);
1044 ungetc (c, input_file);
1045 lineno = read_rtx_lineno;
1046 desc = read_rtx (input_file);
1047 process_rtx (desc, lineno);
1049 fclose (input_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 /* The entry point for reading a single rtx from an md file. */
1061 read_md_rtx (lineno, seqnr)
1065 struct queue_elem **queue, *elem;
1068 /* Read all patterns from a given queue before moving on to the next. */
1069 if (define_attr_queue != NULL)
1070 queue = &define_attr_queue;
1071 else if (define_insn_queue != NULL)
1072 queue = &define_insn_queue;
1073 else if (other_queue != NULL)
1074 queue = &other_queue;
1079 *queue = elem->next;
1081 *lineno = elem->lineno;
1082 *seqnr = sequence_num;
1086 switch (GET_CODE (desc))
1091 case DEFINE_PEEPHOLE:
1092 case DEFINE_PEEPHOLE2:
1103 /* Given a string, return the number of comma-separated elements in it.
1104 Return 0 for the null string. */
1114 for (n = 1; *s; s++)
1121 /* Given a pointer to a (char *), return a pointer to the beginning of the
1122 next comma-separated element in the string. Advance the pointer given
1123 to the end of that element. Return NULL if at end of string. Caller
1124 is responsible for copying the string if necessary. White space between
1125 a comma and an element is ignored. */
1128 scan_comma_elt (pstr)
1132 const char *p = *pstr;
1144 while (*p != ',' && *p != '\0')