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. */
55 struct queue_elem
*next
;
58 static struct queue_elem
*define_attr_queue
;
59 static struct queue_elem
**define_attr_tail
= &define_attr_queue
;
60 static struct queue_elem
*define_insn_queue
;
61 static struct queue_elem
**define_insn_tail
= &define_insn_queue
;
62 static struct queue_elem
*define_cond_exec_queue
;
63 static struct queue_elem
**define_cond_exec_tail
= &define_cond_exec_queue
;
64 static struct queue_elem
*other_queue
;
65 static struct queue_elem
**other_tail
= &other_queue
;
67 static void queue_pattern
PARAMS ((rtx
, struct queue_elem
***,
70 /* Current maximum length of directory names in the search path
71 for include files. (Altered as we get more of them.) */
73 size_t max_include_len
;
77 struct file_name_list
*next
;
81 struct file_name_list
*first_dir_md_include
= 0; /* First dir to search */
82 /* First dir to search for <file> */
83 struct file_name_list
*first_bracket_include
= 0;
84 struct file_name_list
*last_dir_md_include
= 0; /* Last in chain */
86 static void remove_constraints
PARAMS ((rtx
));
87 static void process_rtx
PARAMS ((rtx
, int));
89 static int is_predicable
PARAMS ((struct queue_elem
*));
90 static void identify_predicable_attribute
PARAMS ((void));
91 static int n_alternatives
PARAMS ((const char *));
92 static void collect_insn_data
PARAMS ((rtx
, int *, int *));
93 static rtx alter_predicate_for_insn
PARAMS ((rtx
, int, int, int));
94 static const char *alter_test_for_insn
PARAMS ((struct queue_elem
*,
95 struct queue_elem
*));
96 static char *shift_output_template
PARAMS ((char *, const char *, int));
97 static const char *alter_output_for_insn
PARAMS ((struct queue_elem
*,
100 static void process_one_cond_exec
PARAMS ((struct queue_elem
*));
101 static void process_define_cond_exec
PARAMS ((void));
102 static void process_include
PARAMS ((rtx
, int));
103 static char *save_string
PARAMS ((const char *, int));
106 message_with_line
VPARAMS ((int lineno
, const char *msg
, ...))
109 VA_FIXEDARG (ap
, int, lineno
);
110 VA_FIXEDARG (ap
, const char *, msg
);
112 fprintf (stderr
, "%s:%d: ", read_rtx_filename
, lineno
);
113 vfprintf (stderr
, msg
, ap
);
114 fputc ('\n', stderr
);
119 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
120 the gensupport programs. */
123 gen_rtx_CONST_INT (mode
, arg
)
124 enum machine_mode mode ATTRIBUTE_UNUSED
;
127 rtx rt
= rtx_alloc (CONST_INT
);
133 /* Queue PATTERN on LIST_TAIL. */
136 queue_pattern (pattern
, list_tail
, filename
, lineno
)
138 struct queue_elem
***list_tail
;
139 const char *filename
;
142 struct queue_elem
*e
= (struct queue_elem
*) xmalloc (sizeof (*e
));
144 e
->filename
= filename
;
148 *list_tail
= &e
->next
;
151 /* Recursively remove constraints from an rtx. */
154 remove_constraints (part
)
158 const char *format_ptr
;
163 if (GET_CODE (part
) == MATCH_OPERAND
)
165 else if (GET_CODE (part
) == MATCH_SCRATCH
)
168 format_ptr
= GET_RTX_FORMAT (GET_CODE (part
));
170 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (part
)); i
++)
171 switch (*format_ptr
++)
175 remove_constraints (XEXP (part
, i
));
178 if (XVEC (part
, i
) != NULL
)
179 for (j
= 0; j
< XVECLEN (part
, i
); j
++)
180 remove_constraints (XVECEXP (part
, i
, j
));
185 /* Process an include file assuming that it lives in gcc/config/{target}/
186 if the include looks line (include "file"). */
189 process_include (desc
, lineno
)
193 const char *filename
= XSTR (desc
, 0);
194 const char *old_filename
;
199 /* If specified file name is absolute, skip the include stack. */
200 if (! IS_ABSOLUTE_PATHNAME (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_rtx_lineno has already been advanced. */
234 old_filename
= read_rtx_filename
;
235 old_lineno
= read_rtx_lineno
;
236 read_rtx_filename
= pathname
;
239 /* Read the entire file. */
245 c
= read_skip_spaces (input_file
);
249 ungetc (c
, input_file
);
250 lineno
= read_rtx_lineno
;
251 desc
= read_rtx (input_file
);
252 process_rtx (desc
, lineno
);
255 /* Do not free pathname. It is attached to the various rtx queue
258 read_rtx_filename
= old_filename
;
259 read_rtx_lineno
= old_lineno
;
264 /* Process a top level rtx in some way, queueing as appropriate. */
267 process_rtx (desc
, lineno
)
271 switch (GET_CODE (desc
))
274 queue_pattern (desc
, &define_insn_tail
, read_rtx_filename
, lineno
);
277 case DEFINE_COND_EXEC
:
278 queue_pattern (desc
, &define_cond_exec_tail
, read_rtx_filename
, lineno
);
282 queue_pattern (desc
, &define_attr_tail
, read_rtx_filename
, lineno
);
286 process_include (desc
, lineno
);
289 case DEFINE_INSN_AND_SPLIT
:
291 const char *split_cond
;
296 /* Create a split with values from the insn_and_split. */
297 split
= rtx_alloc (DEFINE_SPLIT
);
299 i
= XVECLEN (desc
, 1);
300 XVEC (split
, 0) = rtvec_alloc (i
);
303 XVECEXP (split
, 0, i
) = copy_rtx (XVECEXP (desc
, 1, i
));
304 remove_constraints (XVECEXP (split
, 0, i
));
307 /* If the split condition starts with "&&", append it to the
308 insn condition to create the new split condition. */
309 split_cond
= XSTR (desc
, 4);
310 if (split_cond
[0] == '&' && split_cond
[1] == '&')
312 const char *insn_cond
= XSTR (desc
, 2);
313 size_t insn_cond_len
= strlen (insn_cond
);
314 size_t split_cond_len
= strlen (split_cond
);
317 combined
= (char *) xmalloc (insn_cond_len
+ split_cond_len
+ 1);
318 memcpy (combined
, insn_cond
, insn_cond_len
);
319 memcpy (combined
+ insn_cond_len
, split_cond
, split_cond_len
+ 1);
321 split_cond
= combined
;
323 XSTR (split
, 1) = split_cond
;
324 XVEC (split
, 2) = XVEC (desc
, 5);
325 XSTR (split
, 3) = XSTR (desc
, 6);
327 /* Fix up the DEFINE_INSN. */
328 attr
= XVEC (desc
, 7);
329 PUT_CODE (desc
, DEFINE_INSN
);
330 XVEC (desc
, 4) = attr
;
333 queue_pattern (desc
, &define_insn_tail
, read_rtx_filename
, lineno
);
334 queue_pattern (split
, &other_tail
, read_rtx_filename
, lineno
);
339 queue_pattern (desc
, &other_tail
, read_rtx_filename
, lineno
);
344 /* Return true if attribute PREDICABLE is true for ELEM, which holds
349 struct queue_elem
*elem
;
351 rtvec vec
= XVEC (elem
->data
, 4);
356 return predicable_default
;
358 for (i
= GET_NUM_ELEM (vec
) - 1; i
>= 0; --i
)
360 rtx sub
= RTVEC_ELT (vec
, i
);
361 switch (GET_CODE (sub
))
364 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
366 value
= XSTR (sub
, 1);
371 case SET_ATTR_ALTERNATIVE
:
372 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
374 message_with_line (elem
->lineno
,
375 "multiple alternatives for `predicable'");
382 if (GET_CODE (SET_DEST (sub
)) != ATTR
383 || strcmp (XSTR (SET_DEST (sub
), 0), "predicable") != 0)
386 if (GET_CODE (sub
) == CONST_STRING
)
388 value
= XSTR (sub
, 0);
392 /* ??? It would be possible to handle this if we really tried.
393 It's not easy though, and I'm not going to bother until it
394 really proves necessary. */
395 message_with_line (elem
->lineno
,
396 "non-constant value for `predicable'");
405 return predicable_default
;
408 /* Verify that predicability does not vary on the alternative. */
409 /* ??? It should be possible to handle this by simply eliminating
410 the non-predicable alternatives from the insn. FRV would like
411 to do this. Delay this until we've got the basics solid. */
412 if (strchr (value
, ',') != NULL
)
414 message_with_line (elem
->lineno
,
415 "multiple alternatives for `predicable'");
420 /* Find out which value we're looking at. */
421 if (strcmp (value
, predicable_true
) == 0)
423 if (strcmp (value
, predicable_false
) == 0)
426 message_with_line (elem
->lineno
,
427 "unknown value `%s' for `predicable' attribute",
433 /* Examine the attribute "predicable"; discover its boolean values
437 identify_predicable_attribute ()
439 struct queue_elem
*elem
;
440 char *p_true
, *p_false
;
444 /* Look for the DEFINE_ATTR for `predicable', which must exist. */
445 for (elem
= define_attr_queue
; elem
; elem
= elem
->next
)
446 if (strcmp (XSTR (elem
->data
, 0), "predicable") == 0)
449 message_with_line (define_cond_exec_queue
->lineno
,
450 "attribute `predicable' not defined");
455 value
= XSTR (elem
->data
, 1);
456 len
= strlen (value
);
457 p_false
= (char *) xmalloc (len
+ 1);
458 memcpy (p_false
, value
, len
+ 1);
460 p_true
= strchr (p_false
, ',');
461 if (p_true
== NULL
|| strchr (++p_true
, ',') != NULL
)
463 message_with_line (elem
->lineno
,
464 "attribute `predicable' is not a boolean");
470 predicable_true
= p_true
;
471 predicable_false
= p_false
;
473 switch (GET_CODE (XEXP (elem
->data
, 2)))
476 value
= XSTR (XEXP (elem
->data
, 2), 0);
480 message_with_line (elem
->lineno
,
481 "attribute `predicable' cannot be const");
486 message_with_line (elem
->lineno
,
487 "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",
505 /* Return the number of alternatives in constraint S. */
520 /* Determine how many alternatives there are in INSN, and how many
524 collect_insn_data (pattern
, palt
, pmax
)
532 code
= GET_CODE (pattern
);
536 i
= n_alternatives (XSTR (pattern
, 2));
537 *palt
= (i
> *palt
? i
: *palt
);
544 i
= XINT (pattern
, 0);
553 fmt
= GET_RTX_FORMAT (code
);
554 len
= GET_RTX_LENGTH (code
);
555 for (i
= 0; i
< len
; i
++)
560 collect_insn_data (XEXP (pattern
, i
), palt
, pmax
);
564 if (XVEC (pattern
, i
) == NULL
)
568 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
569 collect_insn_data (XVECEXP (pattern
, i
, j
), palt
, pmax
);
572 case 'i': case 'w': case '0': case 's': case 'S': case 'T':
582 alter_predicate_for_insn (pattern
, alt
, max_op
, lineno
)
584 int alt
, max_op
, lineno
;
590 code
= GET_CODE (pattern
);
595 const char *c
= XSTR (pattern
, 2);
597 if (n_alternatives (c
) != 1)
599 message_with_line (lineno
,
600 "too many alternatives for operand %d",
606 /* Replicate C as needed to fill out ALT alternatives. */
607 if (c
&& *c
&& alt
> 1)
609 size_t c_len
= strlen (c
);
610 size_t len
= alt
* (c_len
+ 1);
611 char *new_c
= (char *) xmalloc (len
);
613 memcpy (new_c
, c
, c_len
);
614 for (i
= 1; i
< alt
; ++i
)
616 new_c
[i
* (c_len
+ 1) - 1] = ',';
617 memcpy (&new_c
[i
* (c_len
+ 1)], c
, c_len
);
619 new_c
[len
- 1] = '\0';
620 XSTR (pattern
, 2) = new_c
;
629 XINT (pattern
, 0) += max_op
;
636 fmt
= GET_RTX_FORMAT (code
);
637 len
= GET_RTX_LENGTH (code
);
638 for (i
= 0; i
< len
; i
++)
645 r
= alter_predicate_for_insn (XEXP (pattern
, i
), alt
,
652 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
654 r
= alter_predicate_for_insn (XVECEXP (pattern
, i
, j
),
655 alt
, max_op
, lineno
);
661 case 'i': case 'w': case '0': case 's':
673 alter_test_for_insn (ce_elem
, insn_elem
)
674 struct queue_elem
*ce_elem
, *insn_elem
;
676 const char *ce_test
, *insn_test
;
678 size_t len
, ce_len
, insn_len
;
680 ce_test
= XSTR (ce_elem
->data
, 1);
681 insn_test
= XSTR (insn_elem
->data
, 2);
682 if (!ce_test
|| *ce_test
== '\0')
684 if (!insn_test
|| *insn_test
== '\0')
687 ce_len
= strlen (ce_test
);
688 insn_len
= strlen (insn_test
);
689 len
= 1 + ce_len
+ 1 + 4 + 1 + insn_len
+ 1 + 1;
690 new_test
= (char *) xmalloc (len
);
692 sprintf (new_test
, "(%s) && (%s)", ce_test
, insn_test
);
697 /* Adjust all of the operand numbers in OLD to match the shift they'll
698 get from an operand displacement of DISP. Return a pointer after the
702 shift_output_template (new, old
, disp
)
714 if (ISDIGIT ((unsigned char) c
))
716 else if (ISALPHA (c
))
729 alter_output_for_insn (ce_elem
, insn_elem
, alt
, max_op
)
730 struct queue_elem
*ce_elem
, *insn_elem
;
733 const char *ce_out
, *insn_out
;
735 size_t len
, ce_len
, insn_len
;
737 /* ??? Could coordinate with genoutput to not duplicate code here. */
739 ce_out
= XSTR (ce_elem
->data
, 2);
740 insn_out
= XTMPL (insn_elem
->data
, 3);
741 if (!ce_out
|| *ce_out
== '\0')
744 ce_len
= strlen (ce_out
);
745 insn_len
= strlen (insn_out
);
747 if (*insn_out
== '*')
748 /* You must take care of the predicate yourself. */
751 if (*insn_out
== '@')
753 len
= (ce_len
+ 1) * alt
+ insn_len
+ 1;
754 p
= new = xmalloc (len
);
760 while (ISSPACE ((unsigned char) *insn_out
));
762 if (*insn_out
!= '#')
764 p
= shift_output_template (p
, ce_out
, max_op
);
770 while (*insn_out
&& *insn_out
!= '\n');
777 len
= ce_len
+ 1 + insn_len
+ 1;
780 p
= shift_output_template (new, ce_out
, max_op
);
782 memcpy (p
, insn_out
, insn_len
+ 1);
788 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */
791 process_one_cond_exec (ce_elem
)
792 struct queue_elem
*ce_elem
;
794 struct queue_elem
*insn_elem
;
795 for (insn_elem
= define_insn_queue
; insn_elem
; insn_elem
= insn_elem
->next
)
797 int alternatives
, max_operand
;
798 rtx pred
, insn
, pattern
;
800 if (! is_predicable (insn_elem
))
805 collect_insn_data (insn_elem
->data
, &alternatives
, &max_operand
);
808 if (XVECLEN (ce_elem
->data
, 0) != 1)
810 message_with_line (ce_elem
->lineno
,
811 "too many patterns in predicate");
816 pred
= copy_rtx (XVECEXP (ce_elem
->data
, 0, 0));
817 pred
= alter_predicate_for_insn (pred
, alternatives
, max_operand
,
822 /* Construct a new pattern for the new insn. */
823 insn
= copy_rtx (insn_elem
->data
);
825 pattern
= rtx_alloc (COND_EXEC
);
826 XEXP (pattern
, 0) = pred
;
827 if (XVECLEN (insn
, 1) == 1)
829 XEXP (pattern
, 1) = XVECEXP (insn
, 1, 0);
830 XVECEXP (insn
, 1, 0) = pattern
;
831 PUT_NUM_ELEM (XVEC (insn
, 1), 1);
835 XEXP (pattern
, 1) = rtx_alloc (PARALLEL
);
836 XVEC (XEXP (pattern
, 1), 0) = XVEC (insn
, 1);
837 XVEC (insn
, 1) = rtvec_alloc (1);
838 XVECEXP (insn
, 1, 0) = pattern
;
841 XSTR (insn
, 2) = alter_test_for_insn (ce_elem
, insn_elem
);
842 XTMPL (insn
, 3) = alter_output_for_insn (ce_elem
, insn_elem
,
843 alternatives
, max_operand
);
845 /* ??? Set `predicable' to false. Not crucial since it's really
846 only used here, and we won't reprocess this new pattern. */
848 /* Put the new pattern on the `other' list so that it
849 (a) is not reprocessed by other define_cond_exec patterns
850 (b) appears after all normal define_insn patterns.
852 ??? B is debatable. If one has normal insns that match
853 cond_exec patterns, they will be preferred over these
854 generated patterns. Whether this matters in practice, or if
855 it's a good thing, or whether we should thread these new
856 patterns into the define_insn chain just after their generator
857 is something we'll have to experiment with. */
859 queue_pattern (insn
, &other_tail
, insn_elem
->filename
,
864 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
865 patterns appropriately. */
868 process_define_cond_exec ()
870 struct queue_elem
*elem
;
872 identify_predicable_attribute ();
876 for (elem
= define_cond_exec_queue
; elem
; elem
= elem
->next
)
877 process_one_cond_exec (elem
);
885 register char *result
= xmalloc (len
+ 1);
887 memcpy (result
, s
, len
);
893 /* The entry point for initializing the reader. */
896 init_md_reader_args (argc
, argv
)
901 const char *in_fname
;
905 for (i
= 1; i
< argc
; i
++)
907 if (argv
[i
][0] != '-')
909 if (in_fname
== NULL
)
917 case 'I': /* Add directory to path for includes. */
919 struct file_name_list
*dirtmp
;
921 dirtmp
= (struct file_name_list
*)
922 xmalloc (sizeof (struct file_name_list
));
923 dirtmp
->next
= 0; /* New one goes on the end */
924 if (first_dir_md_include
== 0)
925 first_dir_md_include
= dirtmp
;
927 last_dir_md_include
->next
= dirtmp
;
928 last_dir_md_include
= dirtmp
; /* Tail follows the last one */
929 if (argv
[i
][1] == 'I' && argv
[i
][2] != 0)
930 dirtmp
->fname
= argv
[i
] + 2;
931 else if (i
+ 1 == argc
)
932 fatal ("directory name missing after -I option");
934 dirtmp
->fname
= argv
[++i
];
935 if (strlen (dirtmp
->fname
) > max_include_len
)
936 max_include_len
= strlen (dirtmp
->fname
);
940 fatal ("invalid option `%s'", argv
[i
]);
945 return init_md_reader (in_fname
);
948 /* The entry point for initializing the reader. */
951 init_md_reader (filename
)
952 const char *filename
;
958 lastsl
= strrchr (filename
, '/');
960 base_dir
= save_string (filename
, lastsl
- filename
+ 1 );
962 read_rtx_filename
= filename
;
963 input_file
= fopen (filename
, "r");
967 return FATAL_EXIT_CODE
;
970 obstack_init (rtl_obstack
);
974 /* Read the entire file. */
980 c
= read_skip_spaces (input_file
);
984 ungetc (c
, input_file
);
985 lineno
= read_rtx_lineno
;
986 desc
= read_rtx (input_file
);
987 process_rtx (desc
, lineno
);
991 /* Process define_cond_exec patterns. */
992 if (define_cond_exec_queue
!= NULL
)
993 process_define_cond_exec ();
995 return errors
? FATAL_EXIT_CODE
: SUCCESS_EXIT_CODE
;
998 /* The entry point for reading a single rtx from an md file. */
1001 read_md_rtx (lineno
, seqnr
)
1005 struct queue_elem
**queue
, *elem
;
1008 /* Read all patterns from a given queue before moving on to the next. */
1009 if (define_attr_queue
!= NULL
)
1010 queue
= &define_attr_queue
;
1011 else if (define_insn_queue
!= NULL
)
1012 queue
= &define_insn_queue
;
1013 else if (other_queue
!= NULL
)
1014 queue
= &other_queue
;
1019 *queue
= elem
->next
;
1021 read_rtx_filename
= elem
->filename
;
1022 *lineno
= elem
->lineno
;
1023 *seqnr
= sequence_num
;
1027 switch (GET_CODE (desc
))
1032 case DEFINE_PEEPHOLE
:
1033 case DEFINE_PEEPHOLE2
:
1044 /* Given a string, return the number of comma-separated elements in it.
1045 Return 0 for the null string. */
1055 for (n
= 1; *s
; s
++)
1062 /* Given a pointer to a (char *), return a pointer to the beginning of the
1063 next comma-separated element in the string. Advance the pointer given
1064 to the end of that element. Return NULL if at end of string. Caller
1065 is responsible for copying the string if necessary. White space between
1066 a comma and an element is ignored. */
1069 scan_comma_elt (pstr
)
1073 const char *p
= *pstr
;
1085 while (*p
!= ',' && *p
!= '\0')