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
;
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_filename
= read_md_filename
;
235 old_lineno
= read_md_lineno
;
236 read_md_filename
= pathname
;
239 if (include_callback
)
240 include_callback (pathname
);
242 /* Read the entire file. */
243 while (read_rtx (input_file
, &desc
, &lineno
))
244 process_rtx (desc
, lineno
);
246 /* Do not free pathname. It is attached to the various rtx queue
249 read_md_filename
= old_filename
;
250 read_md_lineno
= old_lineno
;
255 /* Process a top level rtx in some way, queuing as appropriate. */
258 process_rtx (rtx desc
, int lineno
)
260 switch (GET_CODE (desc
))
263 queue_pattern (desc
, &define_insn_tail
, read_md_filename
, lineno
);
266 case DEFINE_COND_EXEC
:
267 queue_pattern (desc
, &define_cond_exec_tail
, read_md_filename
, lineno
);
271 queue_pattern (desc
, &define_attr_tail
, read_md_filename
, lineno
);
274 case DEFINE_PREDICATE
:
275 case DEFINE_SPECIAL_PREDICATE
:
276 case DEFINE_CONSTRAINT
:
277 case DEFINE_REGISTER_CONSTRAINT
:
278 case DEFINE_MEMORY_CONSTRAINT
:
279 case DEFINE_ADDRESS_CONSTRAINT
:
280 queue_pattern (desc
, &define_pred_tail
, read_md_filename
, lineno
);
284 process_include (desc
, lineno
);
287 case DEFINE_INSN_AND_SPLIT
:
289 const char *split_cond
;
293 struct queue_elem
*insn_elem
;
294 struct queue_elem
*split_elem
;
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 copy_md_ptr_loc (split_cond
+ 2, split_cond
);
313 split_cond
= join_c_conditions (XSTR (desc
, 2), split_cond
+ 2);
315 XSTR (split
, 1) = split_cond
;
316 XVEC (split
, 2) = XVEC (desc
, 5);
317 XSTR (split
, 3) = XSTR (desc
, 6);
319 /* Fix up the DEFINE_INSN. */
320 attr
= XVEC (desc
, 7);
321 PUT_CODE (desc
, DEFINE_INSN
);
322 XVEC (desc
, 4) = attr
;
326 = queue_pattern (desc
, &define_insn_tail
, read_md_filename
,
329 = queue_pattern (split
, &other_tail
, read_md_filename
, lineno
);
330 insn_elem
->split
= split_elem
;
335 queue_pattern (desc
, &other_tail
, read_md_filename
, lineno
);
340 /* Return true if attribute PREDICABLE is true for ELEM, which holds
344 is_predicable (struct queue_elem
*elem
)
346 rtvec vec
= XVEC (elem
->data
, 4);
351 return predicable_default
;
353 for (i
= GET_NUM_ELEM (vec
) - 1; i
>= 0; --i
)
355 rtx sub
= RTVEC_ELT (vec
, i
);
356 switch (GET_CODE (sub
))
359 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
361 value
= XSTR (sub
, 1);
366 case SET_ATTR_ALTERNATIVE
:
367 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
369 message_with_line (elem
->lineno
,
370 "multiple alternatives for `predicable'");
377 if (GET_CODE (SET_DEST (sub
)) != ATTR
378 || strcmp (XSTR (SET_DEST (sub
), 0), "predicable") != 0)
381 if (GET_CODE (sub
) == CONST_STRING
)
383 value
= XSTR (sub
, 0);
387 /* ??? It would be possible to handle this if we really tried.
388 It's not easy though, and I'm not going to bother until it
389 really proves necessary. */
390 message_with_line (elem
->lineno
,
391 "non-constant value for `predicable'");
400 return predicable_default
;
403 /* Verify that predicability does not vary on the alternative. */
404 /* ??? It should be possible to handle this by simply eliminating
405 the non-predicable alternatives from the insn. FRV would like
406 to do this. Delay this until we've got the basics solid. */
407 if (strchr (value
, ',') != NULL
)
409 message_with_line (elem
->lineno
,
410 "multiple alternatives for `predicable'");
415 /* Find out which value we're looking at. */
416 if (strcmp (value
, predicable_true
) == 0)
418 if (strcmp (value
, predicable_false
) == 0)
421 message_with_line (elem
->lineno
,
422 "unknown value `%s' for `predicable' attribute",
428 /* Examine the attribute "predicable"; discover its boolean values
432 identify_predicable_attribute (void)
434 struct queue_elem
*elem
;
435 char *p_true
, *p_false
;
438 /* Look for the DEFINE_ATTR for `predicable', which must exist. */
439 for (elem
= define_attr_queue
; elem
; elem
= elem
->next
)
440 if (strcmp (XSTR (elem
->data
, 0), "predicable") == 0)
443 message_with_line (define_cond_exec_queue
->lineno
,
444 "attribute `predicable' not defined");
449 value
= XSTR (elem
->data
, 1);
450 p_false
= xstrdup (value
);
451 p_true
= strchr (p_false
, ',');
452 if (p_true
== NULL
|| strchr (++p_true
, ',') != NULL
)
454 message_with_line (elem
->lineno
,
455 "attribute `predicable' is not a boolean");
463 predicable_true
= p_true
;
464 predicable_false
= p_false
;
466 switch (GET_CODE (XEXP (elem
->data
, 2)))
469 value
= XSTR (XEXP (elem
->data
, 2), 0);
473 message_with_line (elem
->lineno
,
474 "attribute `predicable' cannot be const");
481 message_with_line (elem
->lineno
,
482 "attribute `predicable' must have a constant default");
489 if (strcmp (value
, p_true
) == 0)
490 predicable_default
= 1;
491 else if (strcmp (value
, p_false
) == 0)
492 predicable_default
= 0;
495 message_with_line (elem
->lineno
,
496 "unknown value `%s' for `predicable' attribute",
504 /* Return the number of alternatives in constraint S. */
507 n_alternatives (const char *s
)
518 /* Determine how many alternatives there are in INSN, and how many
522 collect_insn_data (rtx pattern
, int *palt
, int *pmax
)
528 code
= GET_CODE (pattern
);
532 i
= n_alternatives (XSTR (pattern
, 2));
533 *palt
= (i
> *palt
? i
: *palt
);
539 i
= XINT (pattern
, 0);
548 fmt
= GET_RTX_FORMAT (code
);
549 len
= GET_RTX_LENGTH (code
);
550 for (i
= 0; i
< len
; i
++)
555 collect_insn_data (XEXP (pattern
, i
), palt
, pmax
);
559 if (XVEC (pattern
, i
) == NULL
)
563 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
564 collect_insn_data (XVECEXP (pattern
, i
, j
), palt
, pmax
);
567 case 'i': case 'w': case '0': case 's': case 'S': case 'T':
577 alter_predicate_for_insn (rtx pattern
, int alt
, int max_op
, int lineno
)
583 code
= GET_CODE (pattern
);
588 const char *c
= XSTR (pattern
, 2);
590 if (n_alternatives (c
) != 1)
592 message_with_line (lineno
,
593 "too many alternatives for operand %d",
599 /* Replicate C as needed to fill out ALT alternatives. */
600 if (c
&& *c
&& alt
> 1)
602 size_t c_len
= strlen (c
);
603 size_t len
= alt
* (c_len
+ 1);
604 char *new_c
= XNEWVEC(char, len
);
606 memcpy (new_c
, c
, c_len
);
607 for (i
= 1; i
< alt
; ++i
)
609 new_c
[i
* (c_len
+ 1) - 1] = ',';
610 memcpy (&new_c
[i
* (c_len
+ 1)], c
, c_len
);
612 new_c
[len
- 1] = '\0';
613 XSTR (pattern
, 2) = new_c
;
621 XINT (pattern
, 0) += max_op
;
628 fmt
= GET_RTX_FORMAT (code
);
629 len
= GET_RTX_LENGTH (code
);
630 for (i
= 0; i
< len
; i
++)
637 r
= alter_predicate_for_insn (XEXP (pattern
, i
), alt
,
644 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
646 r
= alter_predicate_for_insn (XVECEXP (pattern
, i
, j
),
647 alt
, max_op
, lineno
);
653 case 'i': case 'w': case '0': case 's':
665 alter_test_for_insn (struct queue_elem
*ce_elem
,
666 struct queue_elem
*insn_elem
)
668 return join_c_conditions (XSTR (ce_elem
->data
, 1),
669 XSTR (insn_elem
->data
, 2));
672 /* Adjust all of the operand numbers in SRC to match the shift they'll
673 get from an operand displacement of DISP. Return a pointer after the
677 shift_output_template (char *dest
, const char *src
, int disp
)
686 if (ISDIGIT ((unsigned char) c
))
688 else if (ISALPHA (c
))
701 alter_output_for_insn (struct queue_elem
*ce_elem
,
702 struct queue_elem
*insn_elem
,
705 const char *ce_out
, *insn_out
;
707 size_t len
, ce_len
, insn_len
;
709 /* ??? Could coordinate with genoutput to not duplicate code here. */
711 ce_out
= XSTR (ce_elem
->data
, 2);
712 insn_out
= XTMPL (insn_elem
->data
, 3);
713 if (!ce_out
|| *ce_out
== '\0')
716 ce_len
= strlen (ce_out
);
717 insn_len
= strlen (insn_out
);
719 if (*insn_out
== '*')
720 /* You must take care of the predicate yourself. */
723 if (*insn_out
== '@')
725 len
= (ce_len
+ 1) * alt
+ insn_len
+ 1;
726 p
= result
= XNEWVEC(char, len
);
732 while (ISSPACE ((unsigned char) *insn_out
));
734 if (*insn_out
!= '#')
736 p
= shift_output_template (p
, ce_out
, max_op
);
742 while (*insn_out
&& *insn_out
!= '\n');
749 len
= ce_len
+ 1 + insn_len
+ 1;
750 result
= XNEWVEC (char, len
);
752 p
= shift_output_template (result
, ce_out
, max_op
);
754 memcpy (p
, insn_out
, insn_len
+ 1);
760 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */
763 process_one_cond_exec (struct queue_elem
*ce_elem
)
765 struct queue_elem
*insn_elem
;
766 for (insn_elem
= define_insn_queue
; insn_elem
; insn_elem
= insn_elem
->next
)
768 int alternatives
, max_operand
;
769 rtx pred
, insn
, pattern
, split
;
773 if (! is_predicable (insn_elem
))
778 collect_insn_data (insn_elem
->data
, &alternatives
, &max_operand
);
781 if (XVECLEN (ce_elem
->data
, 0) != 1)
783 message_with_line (ce_elem
->lineno
,
784 "too many patterns in predicate");
789 pred
= copy_rtx (XVECEXP (ce_elem
->data
, 0, 0));
790 pred
= alter_predicate_for_insn (pred
, alternatives
, max_operand
,
795 /* Construct a new pattern for the new insn. */
796 insn
= copy_rtx (insn_elem
->data
);
797 new_name
= XNEWVAR (char, strlen
XSTR (insn_elem
->data
, 0) + 4);
798 sprintf (new_name
, "*p %s", XSTR (insn_elem
->data
, 0));
799 XSTR (insn
, 0) = new_name
;
800 pattern
= rtx_alloc (COND_EXEC
);
801 XEXP (pattern
, 0) = pred
;
802 if (XVECLEN (insn
, 1) == 1)
804 XEXP (pattern
, 1) = XVECEXP (insn
, 1, 0);
805 XVECEXP (insn
, 1, 0) = pattern
;
806 PUT_NUM_ELEM (XVEC (insn
, 1), 1);
810 XEXP (pattern
, 1) = rtx_alloc (PARALLEL
);
811 XVEC (XEXP (pattern
, 1), 0) = XVEC (insn
, 1);
812 XVEC (insn
, 1) = rtvec_alloc (1);
813 XVECEXP (insn
, 1, 0) = pattern
;
816 XSTR (insn
, 2) = alter_test_for_insn (ce_elem
, insn_elem
);
817 XTMPL (insn
, 3) = alter_output_for_insn (ce_elem
, insn_elem
,
818 alternatives
, max_operand
);
820 /* ??? Set `predicable' to false. Not crucial since it's really
821 only used here, and we won't reprocess this new pattern. */
823 /* Put the new pattern on the `other' list so that it
824 (a) is not reprocessed by other define_cond_exec patterns
825 (b) appears after all normal define_insn patterns.
827 ??? B is debatable. If one has normal insns that match
828 cond_exec patterns, they will be preferred over these
829 generated patterns. Whether this matters in practice, or if
830 it's a good thing, or whether we should thread these new
831 patterns into the define_insn chain just after their generator
832 is something we'll have to experiment with. */
834 queue_pattern (insn
, &other_tail
, insn_elem
->filename
,
837 if (!insn_elem
->split
)
840 /* If the original insn came from a define_insn_and_split,
841 generate a new split to handle the predicated insn. */
842 split
= copy_rtx (insn_elem
->split
->data
);
843 /* Predicate the pattern matched by the split. */
844 pattern
= rtx_alloc (COND_EXEC
);
845 XEXP (pattern
, 0) = pred
;
846 if (XVECLEN (split
, 0) == 1)
848 XEXP (pattern
, 1) = XVECEXP (split
, 0, 0);
849 XVECEXP (split
, 0, 0) = pattern
;
850 PUT_NUM_ELEM (XVEC (split
, 0), 1);
854 XEXP (pattern
, 1) = rtx_alloc (PARALLEL
);
855 XVEC (XEXP (pattern
, 1), 0) = XVEC (split
, 0);
856 XVEC (split
, 0) = rtvec_alloc (1);
857 XVECEXP (split
, 0, 0) = pattern
;
859 /* Predicate all of the insns generated by the split. */
860 for (i
= 0; i
< XVECLEN (split
, 2); i
++)
862 pattern
= rtx_alloc (COND_EXEC
);
863 XEXP (pattern
, 0) = pred
;
864 XEXP (pattern
, 1) = XVECEXP (split
, 2, i
);
865 XVECEXP (split
, 2, i
) = pattern
;
867 /* Add the new split to the queue. */
868 queue_pattern (split
, &other_tail
, read_md_filename
,
869 insn_elem
->split
->lineno
);
873 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
874 patterns appropriately. */
877 process_define_cond_exec (void)
879 struct queue_elem
*elem
;
881 identify_predicable_attribute ();
885 for (elem
= define_cond_exec_queue
; elem
; elem
= elem
->next
)
886 process_one_cond_exec (elem
);
890 save_string (const char *s
, int len
)
892 char *result
= XNEWVEC (char, len
+ 1);
894 memcpy (result
, s
, len
);
900 /* The entry point for initializing the reader. */
903 init_md_reader_args_cb (int argc
, char **argv
, bool (*parse_opt
)(const char *))
909 bool no_more_options
;
910 bool already_read_stdin
;
912 /* Unlock the stdio streams. */
913 unlock_std_streams ();
915 /* First we loop over all the options. */
916 for (i
= 1; i
< argc
; i
++)
918 if (argv
[i
][0] != '-')
924 case 'I': /* Add directory to path for includes. */
926 struct file_name_list
*dirtmp
;
928 dirtmp
= XNEW (struct file_name_list
);
929 dirtmp
->next
= 0; /* New one goes on the end */
930 if (first_dir_md_include
== 0)
931 first_dir_md_include
= dirtmp
;
933 last_dir_md_include
->next
= dirtmp
;
934 last_dir_md_include
= dirtmp
; /* Tail follows the last one */
935 if (argv
[i
][1] == 'I' && argv
[i
][2] != 0)
936 dirtmp
->fname
= argv
[i
] + 2;
937 else if (i
+ 1 == argc
)
938 fatal ("directory name missing after -I option");
940 dirtmp
->fname
= argv
[++i
];
941 if (strlen (dirtmp
->fname
) > max_include_len
)
942 max_include_len
= strlen (dirtmp
->fname
);
947 /* An argument consisting of exactly one dash is a request to
948 read stdin. This will be handled in the second loop. */
952 /* An argument consisting of just two dashes causes option
954 if (argv
[i
][2] == '\0')
955 goto stop_parsing_options
;
958 /* The program may have provided a callback so it can
959 accept its own options. */
960 if (parse_opt
&& parse_opt (argv
[i
]))
963 fatal ("invalid option `%s'", argv
[i
]);
967 stop_parsing_options
:
969 /* Prepare to read input. */
970 condition_table
= htab_create (500, hash_c_test
, cmp_c_test
, NULL
);
971 init_predicate_table ();
972 obstack_init (rtl_obstack
);
975 no_more_options
= false;
976 already_read_stdin
= false;
979 /* Now loop over all input files. */
980 for (i
= 1; i
< argc
; i
++)
982 if (argv
[i
][0] == '-')
984 if (argv
[i
][1] == '\0')
987 if (already_read_stdin
)
988 fatal ("cannot read standard input twice");
991 read_md_filename
= in_fname
= "<stdin>";
994 already_read_stdin
= true;
996 while (read_rtx (input_file
, &desc
, &lineno
))
997 process_rtx (desc
, lineno
);
1001 else if (argv
[i
][1] == '-' && argv
[i
][2] == '\0')
1003 /* No further arguments are to be treated as options. */
1004 no_more_options
= true;
1007 else if (!no_more_options
)
1011 /* If we get here we are looking at a non-option argument, i.e.
1012 a file to be processed. */
1015 lastsl
= strrchr (in_fname
, '/');
1017 base_dir
= save_string (in_fname
, lastsl
- in_fname
+ 1 );
1021 read_md_filename
= in_fname
;
1023 input_file
= fopen (in_fname
, "r");
1024 if (input_file
== 0)
1027 return FATAL_EXIT_CODE
;
1030 while (read_rtx (input_file
, &desc
, &lineno
))
1031 process_rtx (desc
, lineno
);
1032 fclose (input_file
);
1035 /* If we get to this point without having seen any files to process,
1036 read standard input now. */
1040 read_md_filename
= in_fname
= "<stdin>";
1044 while (read_rtx (input_file
, &desc
, &lineno
))
1045 process_rtx (desc
, lineno
);
1046 fclose (input_file
);
1049 /* Process define_cond_exec patterns. */
1050 if (define_cond_exec_queue
!= NULL
)
1051 process_define_cond_exec ();
1053 return errors
? FATAL_EXIT_CODE
: SUCCESS_EXIT_CODE
;
1056 /* Programs that don't have their own options can use this entry point
1059 init_md_reader_args (int argc
, char **argv
)
1061 return init_md_reader_args_cb (argc
, argv
, 0);
1064 /* The entry point for reading a single rtx from an md file. */
1067 read_md_rtx (int *lineno
, int *seqnr
)
1069 struct queue_elem
**queue
, *elem
;
1074 /* Read all patterns from a given queue before moving on to the next. */
1075 if (define_attr_queue
!= NULL
)
1076 queue
= &define_attr_queue
;
1077 else if (define_pred_queue
!= NULL
)
1078 queue
= &define_pred_queue
;
1079 else if (define_insn_queue
!= NULL
)
1080 queue
= &define_insn_queue
;
1081 else if (other_queue
!= NULL
)
1082 queue
= &other_queue
;
1087 *queue
= elem
->next
;
1089 read_md_filename
= elem
->filename
;
1090 *lineno
= elem
->lineno
;
1091 *seqnr
= sequence_num
;
1095 /* Discard insn patterns which we know can never match (because
1096 their C test is provably always false). If insn_elision is
1097 false, our caller needs to see all the patterns. Note that the
1098 elided patterns are never counted by the sequence numbering; it
1099 it is the caller's responsibility, when insn_elision is false, not
1100 to use elided pattern numbers for anything. */
1101 switch (GET_CODE (desc
))
1105 if (maybe_eval_c_test (XSTR (desc
, 2)) != 0)
1107 else if (insn_elision
)
1110 /* *seqnr is used here so the name table will match caller's
1111 idea of insn numbering, whether or not elision is active. */
1112 record_insn_name (*seqnr
, XSTR (desc
, 0));
1116 case DEFINE_PEEPHOLE
:
1117 case DEFINE_PEEPHOLE2
:
1118 if (maybe_eval_c_test (XSTR (desc
, 1)) != 0)
1120 else if (insn_elision
)
1131 /* Helper functions for insn elision. */
1133 /* Compute a hash function of a c_test structure, which is keyed
1134 by its ->expr field. */
1136 hash_c_test (const void *x
)
1138 const struct c_test
*a
= (const struct c_test
*) x
;
1139 const unsigned char *base
, *s
= (const unsigned char *) a
->expr
;
1147 while ((c
= *s
++) != '\0')
1149 hash
+= c
+ (c
<< 17);
1154 hash
+= len
+ (len
<< 17);
1160 /* Compare two c_test expression structures. */
1162 cmp_c_test (const void *x
, const void *y
)
1164 const struct c_test
*a
= (const struct c_test
*) x
;
1165 const struct c_test
*b
= (const struct c_test
*) y
;
1167 return !strcmp (a
->expr
, b
->expr
);
1170 /* Given a string representing a C test expression, look it up in the
1171 condition_table and report whether or not its value is known
1172 at compile time. Returns a tristate: 1 for known true, 0 for
1173 known false, -1 for unknown. */
1175 maybe_eval_c_test (const char *expr
)
1177 const struct c_test
*test
;
1178 struct c_test dummy
;
1184 test
= (const struct c_test
*)htab_find (condition_table
, &dummy
);
1190 /* Record the C test expression EXPR in the condition_table, with
1191 value VAL. Duplicates clobber previous entries. */
1194 add_c_test (const char *expr
, int value
)
1196 struct c_test
*test
;
1201 test
= XNEW (struct c_test
);
1203 test
->value
= value
;
1205 *(htab_find_slot (condition_table
, test
, INSERT
)) = test
;
1208 /* For every C test, call CALLBACK with two arguments: a pointer to
1209 the condition structure and INFO. Stops when CALLBACK returns zero. */
1211 traverse_c_tests (htab_trav callback
, void *info
)
1213 if (condition_table
)
1214 htab_traverse (condition_table
, callback
, info
);
1217 /* Helper functions for define_predicate and define_special_predicate
1218 processing. Shared between genrecog.c and genpreds.c. */
1220 static htab_t predicate_table
;
1221 struct pred_data
*first_predicate
;
1222 static struct pred_data
**last_predicate
= &first_predicate
;
1225 hash_struct_pred_data (const void *ptr
)
1227 return htab_hash_string (((const struct pred_data
*)ptr
)->name
);
1231 eq_struct_pred_data (const void *a
, const void *b
)
1233 return !strcmp (((const struct pred_data
*)a
)->name
,
1234 ((const struct pred_data
*)b
)->name
);
1238 lookup_predicate (const char *name
)
1240 struct pred_data key
;
1242 return (struct pred_data
*) htab_find (predicate_table
, &key
);
1245 /* Record that predicate PRED can accept CODE. */
1248 add_predicate_code (struct pred_data
*pred
, enum rtx_code code
)
1250 if (!pred
->codes
[code
])
1253 pred
->codes
[code
] = true;
1255 if (GET_RTX_CLASS (code
) != RTX_CONST_OBJ
)
1256 pred
->allows_non_const
= true;
1263 && code
!= STRICT_LOW_PART
)
1264 pred
->allows_non_lvalue
= true;
1266 if (pred
->num_codes
== 1)
1267 pred
->singleton
= code
;
1268 else if (pred
->num_codes
== 2)
1269 pred
->singleton
= UNKNOWN
;
1274 add_predicate (struct pred_data
*pred
)
1276 void **slot
= htab_find_slot (predicate_table
, pred
, INSERT
);
1279 error ("duplicate predicate definition for '%s'", pred
->name
);
1283 *last_predicate
= pred
;
1284 last_predicate
= &pred
->next
;
1287 /* This array gives the initial content of the predicate table. It
1288 has entries for all predicates defined in recog.c. */
1290 struct std_pred_table
1294 bool allows_const_p
;
1295 RTX_CODE codes
[NUM_RTX_CODE
];
1298 static const struct std_pred_table std_preds
[] = {
1299 {"general_operand", false, true, {SUBREG
, REG
, MEM
}},
1300 {"address_operand", true, true, {SUBREG
, REG
, MEM
, PLUS
, MINUS
, MULT
}},
1301 {"register_operand", false, false, {SUBREG
, REG
}},
1302 {"pmode_register_operand", true, false, {SUBREG
, REG
}},
1303 {"scratch_operand", false, false, {SCRATCH
, REG
}},
1304 {"immediate_operand", false, true, {UNKNOWN
}},
1305 {"const_int_operand", false, false, {CONST_INT
}},
1306 {"const_double_operand", false, false, {CONST_INT
, CONST_DOUBLE
}},
1307 {"nonimmediate_operand", false, false, {SUBREG
, REG
, MEM
}},
1308 {"nonmemory_operand", false, true, {SUBREG
, REG
}},
1309 {"push_operand", false, false, {MEM
}},
1310 {"pop_operand", false, false, {MEM
}},
1311 {"memory_operand", false, false, {SUBREG
, MEM
}},
1312 {"indirect_operand", false, false, {SUBREG
, MEM
}},
1313 {"ordered_comparison_operator", false, false, {EQ
, NE
,
1315 LEU
, LTU
, GEU
, GTU
}},
1316 {"comparison_operator", false, false, {EQ
, NE
,
1323 #define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)
1325 /* Initialize the table of predicate definitions, starting with
1326 the information we have on generic predicates. */
1329 init_predicate_table (void)
1332 struct pred_data
*pred
;
1334 predicate_table
= htab_create_alloc (37, hash_struct_pred_data
,
1335 eq_struct_pred_data
, 0,
1338 for (i
= 0; i
< NUM_KNOWN_STD_PREDS
; i
++)
1340 pred
= XCNEW (struct pred_data
);
1341 pred
->name
= std_preds
[i
].name
;
1342 pred
->special
= std_preds
[i
].special
;
1344 for (j
= 0; std_preds
[i
].codes
[j
] != 0; j
++)
1345 add_predicate_code (pred
, std_preds
[i
].codes
[j
]);
1347 if (std_preds
[i
].allows_const_p
)
1348 for (j
= 0; j
< NUM_RTX_CODE
; j
++)
1349 if (GET_RTX_CLASS (j
) == RTX_CONST_OBJ
)
1350 add_predicate_code (pred
, (enum rtx_code
) j
);
1352 add_predicate (pred
);
1356 /* These functions allow linkage with print-rtl.c. Also, some generators
1357 like to annotate their output with insn names. */
1359 /* Holds an array of names indexed by insn_code_number. */
1360 static char **insn_name_ptr
= 0;
1361 static int insn_name_ptr_size
= 0;
1364 get_insn_name (int code
)
1366 if (code
< insn_name_ptr_size
)
1367 return insn_name_ptr
[code
];
1373 record_insn_name (int code
, const char *name
)
1375 static const char *last_real_name
= "insn";
1376 static int last_real_code
= 0;
1379 if (insn_name_ptr_size
<= code
)
1382 new_size
= (insn_name_ptr_size
? insn_name_ptr_size
* 2 : 512);
1383 insn_name_ptr
= XRESIZEVEC (char *, insn_name_ptr
, new_size
);
1384 memset (insn_name_ptr
+ insn_name_ptr_size
, 0,
1385 sizeof(char *) * (new_size
- insn_name_ptr_size
));
1386 insn_name_ptr_size
= new_size
;
1389 if (!name
|| name
[0] == '\0')
1391 new_name
= XNEWVAR (char, strlen (last_real_name
) + 10);
1392 sprintf (new_name
, "%s+%d", last_real_name
, code
- last_real_code
);
1396 last_real_name
= new_name
= xstrdup (name
);
1397 last_real_code
= code
;
1400 insn_name_ptr
[code
] = new_name
;