1 /* Support routines for the various generation passes.
2 Copyright (C) 2000, 2001, 2002, 2003, 2004
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, 59 Temple Place - Suite 330, 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 static struct obstack obstack
;
41 struct obstack
*rtl_obstack
= &obstack
;
43 static int sequence_num
;
46 static int predicable_default
;
47 static const char *predicable_true
;
48 static const char *predicable_false
;
50 static htab_t condition_table
;
52 static char *base_dir
= NULL
;
54 /* We initially queue all patterns, process the define_insn and
55 define_cond_exec patterns, then return them one at a time. */
62 struct queue_elem
*next
;
63 /* In a DEFINE_INSN that came from a DEFINE_INSN_AND_SPLIT, SPLIT
64 points to the generated DEFINE_SPLIT. */
65 struct queue_elem
*split
;
68 static struct queue_elem
*define_attr_queue
;
69 static struct queue_elem
**define_attr_tail
= &define_attr_queue
;
70 static struct queue_elem
*define_pred_queue
;
71 static struct queue_elem
**define_pred_tail
= &define_pred_queue
;
72 static struct queue_elem
*define_insn_queue
;
73 static struct queue_elem
**define_insn_tail
= &define_insn_queue
;
74 static struct queue_elem
*define_cond_exec_queue
;
75 static struct queue_elem
**define_cond_exec_tail
= &define_cond_exec_queue
;
76 static struct queue_elem
*other_queue
;
77 static struct queue_elem
**other_tail
= &other_queue
;
79 static struct queue_elem
*queue_pattern (rtx
, struct queue_elem
***,
82 /* Current maximum length of directory names in the search path
83 for include files. (Altered as we get more of them.) */
85 size_t max_include_len
;
89 struct file_name_list
*next
;
93 struct file_name_list
*first_dir_md_include
= 0; /* First dir to search */
94 /* First dir to search for <file> */
95 struct file_name_list
*first_bracket_include
= 0;
96 struct file_name_list
*last_dir_md_include
= 0; /* Last in chain */
98 static void remove_constraints (rtx
);
99 static void process_rtx (rtx
, int);
101 static int is_predicable (struct queue_elem
*);
102 static void identify_predicable_attribute (void);
103 static int n_alternatives (const char *);
104 static void collect_insn_data (rtx
, int *, int *);
105 static rtx
alter_predicate_for_insn (rtx
, int, int, int);
106 static const char *alter_test_for_insn (struct queue_elem
*,
107 struct queue_elem
*);
108 static char *shift_output_template (char *, const char *, int);
109 static const char *alter_output_for_insn (struct queue_elem
*,
112 static void process_one_cond_exec (struct queue_elem
*);
113 static void process_define_cond_exec (void);
114 static void process_include (rtx
, int);
115 static char *save_string (const char *, int);
116 static void init_predicate_table (void);
119 message_with_line (int lineno
, const char *msg
, ...)
125 fprintf (stderr
, "%s:%d: ", read_rtx_filename
, lineno
);
126 vfprintf (stderr
, msg
, ap
);
127 fputc ('\n', stderr
);
132 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
133 the gensupport programs. */
136 gen_rtx_CONST_INT (enum machine_mode
ARG_UNUSED (mode
),
139 rtx rt
= rtx_alloc (CONST_INT
);
145 /* Queue PATTERN on LIST_TAIL. Return the address of the new queue
148 static struct queue_elem
*
149 queue_pattern (rtx pattern
, struct queue_elem
***list_tail
,
150 const char *filename
, int lineno
)
152 struct queue_elem
*e
= XNEW(struct queue_elem
);
154 e
->filename
= filename
;
159 *list_tail
= &e
->next
;
163 /* Recursively remove constraints from an rtx. */
166 remove_constraints (rtx part
)
169 const char *format_ptr
;
174 if (GET_CODE (part
) == MATCH_OPERAND
)
176 else if (GET_CODE (part
) == MATCH_SCRATCH
)
179 format_ptr
= GET_RTX_FORMAT (GET_CODE (part
));
181 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (part
)); i
++)
182 switch (*format_ptr
++)
186 remove_constraints (XEXP (part
, i
));
189 if (XVEC (part
, i
) != NULL
)
190 for (j
= 0; j
< XVECLEN (part
, i
); j
++)
191 remove_constraints (XVECEXP (part
, i
, j
));
196 /* Process an include file assuming that it lives in gcc/config/{target}/
197 if the include looks like (include "file"). */
200 process_include (rtx desc
, int lineno
)
202 const char *filename
= XSTR (desc
, 0);
203 const char *old_filename
;
208 /* If specified file name is absolute, skip the include stack. */
209 if (! IS_ABSOLUTE_PATH (filename
))
211 struct file_name_list
*stackp
;
213 /* Search directory path, trying to open the file. */
214 for (stackp
= first_dir_md_include
; stackp
; stackp
= stackp
->next
)
216 static const char sep
[2] = { DIR_SEPARATOR
, '\0' };
218 pathname
= concat (stackp
->fname
, sep
, filename
, NULL
);
219 input_file
= fopen (pathname
, "r");
220 if (input_file
!= NULL
)
227 pathname
= concat (base_dir
, filename
, NULL
);
229 pathname
= xstrdup (filename
);
230 input_file
= fopen (pathname
, "r");
231 if (input_file
== NULL
)
234 message_with_line (lineno
, "include file `%s' not found", filename
);
240 /* Save old cursor; setup new for the new file. Note that "lineno" the
241 argument to this function is the beginning of the include statement,
242 while read_rtx_lineno has already been advanced. */
243 old_filename
= read_rtx_filename
;
244 old_lineno
= read_rtx_lineno
;
245 read_rtx_filename
= pathname
;
248 /* Read the entire file. */
249 while (read_rtx (input_file
, &desc
, &lineno
))
250 process_rtx (desc
, lineno
);
252 /* Do not free pathname. It is attached to the various rtx queue
255 read_rtx_filename
= old_filename
;
256 read_rtx_lineno
= old_lineno
;
261 /* Process a top level rtx in some way, queuing as appropriate. */
264 process_rtx (rtx desc
, int lineno
)
266 switch (GET_CODE (desc
))
269 queue_pattern (desc
, &define_insn_tail
, read_rtx_filename
, lineno
);
272 case DEFINE_COND_EXEC
:
273 queue_pattern (desc
, &define_cond_exec_tail
, read_rtx_filename
, lineno
);
277 queue_pattern (desc
, &define_attr_tail
, read_rtx_filename
, lineno
);
280 case DEFINE_PREDICATE
:
281 case DEFINE_SPECIAL_PREDICATE
:
282 queue_pattern (desc
, &define_pred_tail
, read_rtx_filename
, lineno
);
286 process_include (desc
, lineno
);
289 case DEFINE_INSN_AND_SPLIT
:
291 const char *split_cond
;
295 struct queue_elem
*insn_elem
;
296 struct queue_elem
*split_elem
;
298 /* Create a split with values from the insn_and_split. */
299 split
= rtx_alloc (DEFINE_SPLIT
);
301 i
= XVECLEN (desc
, 1);
302 XVEC (split
, 0) = rtvec_alloc (i
);
305 XVECEXP (split
, 0, i
) = copy_rtx (XVECEXP (desc
, 1, i
));
306 remove_constraints (XVECEXP (split
, 0, i
));
309 /* If the split condition starts with "&&", append it to the
310 insn condition to create the new split condition. */
311 split_cond
= XSTR (desc
, 4);
312 if (split_cond
[0] == '&' && split_cond
[1] == '&')
313 split_cond
= concat (XSTR (desc
, 2), split_cond
, NULL
);
314 XSTR (split
, 1) = split_cond
;
315 XVEC (split
, 2) = XVEC (desc
, 5);
316 XSTR (split
, 3) = XSTR (desc
, 6);
318 /* Fix up the DEFINE_INSN. */
319 attr
= XVEC (desc
, 7);
320 PUT_CODE (desc
, DEFINE_INSN
);
321 XVEC (desc
, 4) = attr
;
325 = queue_pattern (desc
, &define_insn_tail
, read_rtx_filename
,
328 = queue_pattern (split
, &other_tail
, read_rtx_filename
, lineno
);
329 insn_elem
->split
= split_elem
;
334 queue_pattern (desc
, &other_tail
, read_rtx_filename
, lineno
);
339 /* Return true if attribute PREDICABLE is true for ELEM, which holds
343 is_predicable (struct queue_elem
*elem
)
345 rtvec vec
= XVEC (elem
->data
, 4);
350 return predicable_default
;
352 for (i
= GET_NUM_ELEM (vec
) - 1; i
>= 0; --i
)
354 rtx sub
= RTVEC_ELT (vec
, i
);
355 switch (GET_CODE (sub
))
358 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
360 value
= XSTR (sub
, 1);
365 case SET_ATTR_ALTERNATIVE
:
366 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
368 message_with_line (elem
->lineno
,
369 "multiple alternatives for `predicable'");
376 if (GET_CODE (SET_DEST (sub
)) != ATTR
377 || strcmp (XSTR (SET_DEST (sub
), 0), "predicable") != 0)
380 if (GET_CODE (sub
) == CONST_STRING
)
382 value
= XSTR (sub
, 0);
386 /* ??? It would be possible to handle this if we really tried.
387 It's not easy though, and I'm not going to bother until it
388 really proves necessary. */
389 message_with_line (elem
->lineno
,
390 "non-constant value for `predicable'");
399 return predicable_default
;
402 /* Verify that predicability does not vary on the alternative. */
403 /* ??? It should be possible to handle this by simply eliminating
404 the non-predicable alternatives from the insn. FRV would like
405 to do this. Delay this until we've got the basics solid. */
406 if (strchr (value
, ',') != NULL
)
408 message_with_line (elem
->lineno
,
409 "multiple alternatives for `predicable'");
414 /* Find out which value we're looking at. */
415 if (strcmp (value
, predicable_true
) == 0)
417 if (strcmp (value
, predicable_false
) == 0)
420 message_with_line (elem
->lineno
,
421 "unknown value `%s' for `predicable' attribute",
427 /* Examine the attribute "predicable"; discover its boolean values
431 identify_predicable_attribute (void)
433 struct queue_elem
*elem
;
434 char *p_true
, *p_false
;
437 /* Look for the DEFINE_ATTR for `predicable', which must exist. */
438 for (elem
= define_attr_queue
; elem
; elem
= elem
->next
)
439 if (strcmp (XSTR (elem
->data
, 0), "predicable") == 0)
442 message_with_line (define_cond_exec_queue
->lineno
,
443 "attribute `predicable' not defined");
448 value
= XSTR (elem
->data
, 1);
449 p_false
= xstrdup (value
);
450 p_true
= strchr (p_false
, ',');
451 if (p_true
== NULL
|| strchr (++p_true
, ',') != NULL
)
453 message_with_line (elem
->lineno
,
454 "attribute `predicable' is not a boolean");
460 predicable_true
= p_true
;
461 predicable_false
= p_false
;
463 switch (GET_CODE (XEXP (elem
->data
, 2)))
466 value
= XSTR (XEXP (elem
->data
, 2), 0);
470 message_with_line (elem
->lineno
,
471 "attribute `predicable' cannot be const");
476 message_with_line (elem
->lineno
,
477 "attribute `predicable' must have a constant default");
482 if (strcmp (value
, p_true
) == 0)
483 predicable_default
= 1;
484 else if (strcmp (value
, p_false
) == 0)
485 predicable_default
= 0;
488 message_with_line (elem
->lineno
,
489 "unknown value `%s' for `predicable' attribute",
495 /* Return the number of alternatives in constraint S. */
498 n_alternatives (const char *s
)
509 /* Determine how many alternatives there are in INSN, and how many
513 collect_insn_data (rtx pattern
, int *palt
, int *pmax
)
519 code
= GET_CODE (pattern
);
523 i
= n_alternatives (XSTR (pattern
, 2));
524 *palt
= (i
> *palt
? i
: *palt
);
530 i
= XINT (pattern
, 0);
539 fmt
= GET_RTX_FORMAT (code
);
540 len
= GET_RTX_LENGTH (code
);
541 for (i
= 0; i
< len
; i
++)
546 collect_insn_data (XEXP (pattern
, i
), palt
, pmax
);
550 if (XVEC (pattern
, i
) == NULL
)
554 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
555 collect_insn_data (XVECEXP (pattern
, i
, j
), palt
, pmax
);
558 case 'i': case 'w': case '0': case 's': case 'S': case 'T':
568 alter_predicate_for_insn (rtx pattern
, int alt
, int max_op
, int lineno
)
574 code
= GET_CODE (pattern
);
579 const char *c
= XSTR (pattern
, 2);
581 if (n_alternatives (c
) != 1)
583 message_with_line (lineno
,
584 "too many alternatives for operand %d",
590 /* Replicate C as needed to fill out ALT alternatives. */
591 if (c
&& *c
&& alt
> 1)
593 size_t c_len
= strlen (c
);
594 size_t len
= alt
* (c_len
+ 1);
595 char *new_c
= XNEWVEC(char, len
);
597 memcpy (new_c
, c
, c_len
);
598 for (i
= 1; i
< alt
; ++i
)
600 new_c
[i
* (c_len
+ 1) - 1] = ',';
601 memcpy (&new_c
[i
* (c_len
+ 1)], c
, c_len
);
603 new_c
[len
- 1] = '\0';
604 XSTR (pattern
, 2) = new_c
;
612 XINT (pattern
, 0) += max_op
;
619 fmt
= GET_RTX_FORMAT (code
);
620 len
= GET_RTX_LENGTH (code
);
621 for (i
= 0; i
< len
; i
++)
628 r
= alter_predicate_for_insn (XEXP (pattern
, i
), alt
,
635 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
637 r
= alter_predicate_for_insn (XVECEXP (pattern
, i
, j
),
638 alt
, max_op
, lineno
);
644 case 'i': case 'w': case '0': case 's':
656 alter_test_for_insn (struct queue_elem
*ce_elem
,
657 struct queue_elem
*insn_elem
)
659 const char *ce_test
, *insn_test
;
661 ce_test
= XSTR (ce_elem
->data
, 1);
662 insn_test
= XSTR (insn_elem
->data
, 2);
663 if (!ce_test
|| *ce_test
== '\0')
665 if (!insn_test
|| *insn_test
== '\0')
668 return concat ("(", ce_test
, ") && (", insn_test
, ")", NULL
);
671 /* Adjust all of the operand numbers in SRC to match the shift they'll
672 get from an operand displacement of DISP. Return a pointer after the
676 shift_output_template (char *dest
, const char *src
, int disp
)
685 if (ISDIGIT ((unsigned char) c
))
687 else if (ISALPHA (c
))
700 alter_output_for_insn (struct queue_elem
*ce_elem
,
701 struct queue_elem
*insn_elem
,
704 const char *ce_out
, *insn_out
;
706 size_t len
, ce_len
, insn_len
;
708 /* ??? Could coordinate with genoutput to not duplicate code here. */
710 ce_out
= XSTR (ce_elem
->data
, 2);
711 insn_out
= XTMPL (insn_elem
->data
, 3);
712 if (!ce_out
|| *ce_out
== '\0')
715 ce_len
= strlen (ce_out
);
716 insn_len
= strlen (insn_out
);
718 if (*insn_out
== '*')
719 /* You must take care of the predicate yourself. */
722 if (*insn_out
== '@')
724 len
= (ce_len
+ 1) * alt
+ insn_len
+ 1;
725 p
= result
= XNEWVEC(char, len
);
731 while (ISSPACE ((unsigned char) *insn_out
));
733 if (*insn_out
!= '#')
735 p
= shift_output_template (p
, ce_out
, max_op
);
741 while (*insn_out
&& *insn_out
!= '\n');
748 len
= ce_len
+ 1 + insn_len
+ 1;
749 result
= XNEWVEC (char, len
);
751 p
= shift_output_template (result
, ce_out
, max_op
);
753 memcpy (p
, insn_out
, insn_len
+ 1);
759 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */
762 process_one_cond_exec (struct queue_elem
*ce_elem
)
764 struct queue_elem
*insn_elem
;
765 for (insn_elem
= define_insn_queue
; insn_elem
; insn_elem
= insn_elem
->next
)
767 int alternatives
, max_operand
;
768 rtx pred
, insn
, pattern
, split
;
771 if (! is_predicable (insn_elem
))
776 collect_insn_data (insn_elem
->data
, &alternatives
, &max_operand
);
779 if (XVECLEN (ce_elem
->data
, 0) != 1)
781 message_with_line (ce_elem
->lineno
,
782 "too many patterns in predicate");
787 pred
= copy_rtx (XVECEXP (ce_elem
->data
, 0, 0));
788 pred
= alter_predicate_for_insn (pred
, alternatives
, max_operand
,
793 /* Construct a new pattern for the new insn. */
794 insn
= copy_rtx (insn_elem
->data
);
796 pattern
= rtx_alloc (COND_EXEC
);
797 XEXP (pattern
, 0) = pred
;
798 if (XVECLEN (insn
, 1) == 1)
800 XEXP (pattern
, 1) = XVECEXP (insn
, 1, 0);
801 XVECEXP (insn
, 1, 0) = pattern
;
802 PUT_NUM_ELEM (XVEC (insn
, 1), 1);
806 XEXP (pattern
, 1) = rtx_alloc (PARALLEL
);
807 XVEC (XEXP (pattern
, 1), 0) = XVEC (insn
, 1);
808 XVEC (insn
, 1) = rtvec_alloc (1);
809 XVECEXP (insn
, 1, 0) = pattern
;
812 XSTR (insn
, 2) = alter_test_for_insn (ce_elem
, insn_elem
);
813 XTMPL (insn
, 3) = alter_output_for_insn (ce_elem
, insn_elem
,
814 alternatives
, max_operand
);
816 /* ??? Set `predicable' to false. Not crucial since it's really
817 only used here, and we won't reprocess this new pattern. */
819 /* Put the new pattern on the `other' list so that it
820 (a) is not reprocessed by other define_cond_exec patterns
821 (b) appears after all normal define_insn patterns.
823 ??? B is debatable. If one has normal insns that match
824 cond_exec patterns, they will be preferred over these
825 generated patterns. Whether this matters in practice, or if
826 it's a good thing, or whether we should thread these new
827 patterns into the define_insn chain just after their generator
828 is something we'll have to experiment with. */
830 queue_pattern (insn
, &other_tail
, insn_elem
->filename
,
833 if (!insn_elem
->split
)
836 /* If the original insn came from a define_insn_and_split,
837 generate a new split to handle the predicated insn. */
838 split
= copy_rtx (insn_elem
->split
->data
);
839 /* Predicate the pattern matched by the split. */
840 pattern
= rtx_alloc (COND_EXEC
);
841 XEXP (pattern
, 0) = pred
;
842 if (XVECLEN (split
, 0) == 1)
844 XEXP (pattern
, 1) = XVECEXP (split
, 0, 0);
845 XVECEXP (split
, 0, 0) = pattern
;
846 PUT_NUM_ELEM (XVEC (split
, 0), 1);
850 XEXP (pattern
, 1) = rtx_alloc (PARALLEL
);
851 XVEC (XEXP (pattern
, 1), 0) = XVEC (split
, 0);
852 XVEC (split
, 0) = rtvec_alloc (1);
853 XVECEXP (split
, 0, 0) = pattern
;
855 /* Predicate all of the insns generated by the split. */
856 for (i
= 0; i
< XVECLEN (split
, 2); i
++)
858 pattern
= rtx_alloc (COND_EXEC
);
859 XEXP (pattern
, 0) = pred
;
860 XEXP (pattern
, 1) = XVECEXP (split
, 2, i
);
861 XVECEXP (split
, 2, i
) = pattern
;
863 /* Add the new split to the queue. */
864 queue_pattern (split
, &other_tail
, read_rtx_filename
,
865 insn_elem
->split
->lineno
);
869 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
870 patterns appropriately. */
873 process_define_cond_exec (void)
875 struct queue_elem
*elem
;
877 identify_predicable_attribute ();
881 for (elem
= define_cond_exec_queue
; elem
; elem
= elem
->next
)
882 process_one_cond_exec (elem
);
886 save_string (const char *s
, int len
)
888 char *result
= XNEWVEC (char, len
+ 1);
890 memcpy (result
, s
, len
);
896 /* The entry point for initializing the reader. */
899 init_md_reader_args_cb (int argc
, char **argv
, bool (*parse_opt
)(const char *))
907 for (i
= 1; i
< argc
; i
++)
909 if (argv
[i
][0] != '-')
912 fatal ("too many input files");
921 case 'I': /* Add directory to path for includes. */
923 struct file_name_list
*dirtmp
;
925 dirtmp
= XNEW (struct file_name_list
);
926 dirtmp
->next
= 0; /* New one goes on the end */
927 if (first_dir_md_include
== 0)
928 first_dir_md_include
= dirtmp
;
930 last_dir_md_include
->next
= dirtmp
;
931 last_dir_md_include
= dirtmp
; /* Tail follows the last one */
932 if (argv
[i
][1] == 'I' && argv
[i
][2] != 0)
933 dirtmp
->fname
= argv
[i
] + 2;
934 else if (i
+ 1 == argc
)
935 fatal ("directory name missing after -I option");
937 dirtmp
->fname
= argv
[++i
];
938 if (strlen (dirtmp
->fname
) > max_include_len
)
939 max_include_len
= strlen (dirtmp
->fname
);
943 /* The program may have provided a callback so it can
944 accept its own options. */
945 if (parse_opt
&& parse_opt (argv
[i
]))
948 fatal ("invalid option `%s'", argv
[i
]);
954 fatal ("no input file name");
956 lastsl
= strrchr (in_fname
, '/');
958 base_dir
= save_string (in_fname
, lastsl
- in_fname
+ 1 );
960 read_rtx_filename
= in_fname
;
961 input_file
= fopen (in_fname
, "r");
965 return FATAL_EXIT_CODE
;
968 /* Initialize the table of insn conditions. */
969 condition_table
= htab_create (n_insn_conditions
,
970 hash_c_test
, cmp_c_test
, NULL
);
972 for (ix
= 0; ix
< n_insn_conditions
; ix
++)
973 *(htab_find_slot (condition_table
, &insn_conditions
[ix
], INSERT
))
974 = (void *) &insn_conditions
[ix
];
976 init_predicate_table ();
978 obstack_init (rtl_obstack
);
982 /* Read the entire file. */
983 while (read_rtx (input_file
, &desc
, &lineno
))
984 process_rtx (desc
, lineno
);
987 /* Process define_cond_exec patterns. */
988 if (define_cond_exec_queue
!= NULL
)
989 process_define_cond_exec ();
991 return errors
? FATAL_EXIT_CODE
: SUCCESS_EXIT_CODE
;
994 /* Programs that don't have their own options can use this entry point
997 init_md_reader_args (int argc
, char **argv
)
999 return init_md_reader_args_cb (argc
, argv
, 0);
1002 /* The entry point for reading a single rtx from an md file. */
1005 read_md_rtx (int *lineno
, int *seqnr
)
1007 struct queue_elem
**queue
, *elem
;
1012 /* Read all patterns from a given queue before moving on to the next. */
1013 if (define_attr_queue
!= NULL
)
1014 queue
= &define_attr_queue
;
1015 else if (define_pred_queue
!= NULL
)
1016 queue
= &define_pred_queue
;
1017 else if (define_insn_queue
!= NULL
)
1018 queue
= &define_insn_queue
;
1019 else if (other_queue
!= NULL
)
1020 queue
= &other_queue
;
1025 *queue
= elem
->next
;
1027 read_rtx_filename
= elem
->filename
;
1028 *lineno
= elem
->lineno
;
1029 *seqnr
= sequence_num
;
1033 /* Discard insn patterns which we know can never match (because
1034 their C test is provably always false). If insn_elision is
1035 false, our caller needs to see all the patterns. Note that the
1036 elided patterns are never counted by the sequence numbering; it
1037 it is the caller's responsibility, when insn_elision is false, not
1038 to use elided pattern numbers for anything. */
1039 switch (GET_CODE (desc
))
1043 if (maybe_eval_c_test (XSTR (desc
, 2)) != 0)
1045 else if (insn_elision
)
1050 case DEFINE_PEEPHOLE
:
1051 case DEFINE_PEEPHOLE2
:
1052 if (maybe_eval_c_test (XSTR (desc
, 1)) != 0)
1054 else if (insn_elision
)
1065 /* Helper functions for insn elision. */
1067 /* Compute a hash function of a c_test structure, which is keyed
1068 by its ->expr field. */
1070 hash_c_test (const void *x
)
1072 const struct c_test
*a
= (const struct c_test
*) x
;
1073 const unsigned char *base
, *s
= (const unsigned char *) a
->expr
;
1081 while ((c
= *s
++) != '\0')
1083 hash
+= c
+ (c
<< 17);
1088 hash
+= len
+ (len
<< 17);
1094 /* Compare two c_test expression structures. */
1096 cmp_c_test (const void *x
, const void *y
)
1098 const struct c_test
*a
= (const struct c_test
*) x
;
1099 const struct c_test
*b
= (const struct c_test
*) y
;
1101 return !strcmp (a
->expr
, b
->expr
);
1104 /* Given a string representing a C test expression, look it up in the
1105 condition_table and report whether or not its value is known
1106 at compile time. Returns a tristate: 1 for known true, 0 for
1107 known false, -1 for unknown. */
1109 maybe_eval_c_test (const char *expr
)
1111 const struct c_test
*test
;
1112 struct c_test dummy
;
1117 if (insn_elision_unavailable
)
1121 test
= (const struct c_test
*)htab_find (condition_table
, &dummy
);
1127 /* Given a string, return the number of comma-separated elements in it.
1128 Return 0 for the null string. */
1130 n_comma_elts (const char *s
)
1137 for (n
= 1; *s
; s
++)
1144 /* Given a pointer to a (char *), return a pointer to the beginning of the
1145 next comma-separated element in the string. Advance the pointer given
1146 to the end of that element. Return NULL if at end of string. Caller
1147 is responsible for copying the string if necessary. White space between
1148 a comma and an element is ignored. */
1151 scan_comma_elt (const char **pstr
)
1154 const char *p
= *pstr
;
1166 while (*p
!= ',' && *p
!= '\0')
1173 /* Helper functions for define_predicate and define_special_predicate
1174 processing. Shared between genrecog.c and genpreds.c. */
1176 static htab_t predicate_table
;
1177 struct pred_data
*first_predicate
;
1178 static struct pred_data
**last_predicate
= &first_predicate
;
1181 hash_struct_pred_data (const void *ptr
)
1183 return htab_hash_string (((const struct pred_data
*)ptr
)->name
);
1187 eq_struct_pred_data (const void *a
, const void *b
)
1189 return !strcmp (((const struct pred_data
*)a
)->name
,
1190 ((const struct pred_data
*)b
)->name
);
1194 lookup_predicate (const char *name
)
1196 struct pred_data key
;
1198 return htab_find (predicate_table
, &key
);
1202 add_predicate (struct pred_data
*pred
)
1204 void **slot
= htab_find_slot (predicate_table
, pred
, INSERT
);
1207 error ("duplicate predicate definition for '%s'", pred
->name
);
1211 *last_predicate
= pred
;
1212 last_predicate
= &pred
->next
;
1215 /* This array gives the initial content of the predicate table. It
1216 has entries for all predicates defined in recog.c. The back end
1217 can define PREDICATE_CODES to give additional entries for the
1218 table; this is considered an obsolete mechanism (use
1219 define_predicate instead). */
1221 struct old_pred_table
1224 RTX_CODE codes
[NUM_RTX_CODE
];
1227 static const struct old_pred_table old_preds
[] = {
1228 {"general_operand", {CONST_INT
, CONST_DOUBLE
, CONST
, SYMBOL_REF
,
1229 LABEL_REF
, SUBREG
, REG
, MEM
}},
1230 {"address_operand", {CONST_INT
, CONST_DOUBLE
, CONST
, SYMBOL_REF
,
1231 LABEL_REF
, SUBREG
, REG
, MEM
,
1232 PLUS
, MINUS
, MULT
}},
1233 {"register_operand", {SUBREG
, REG
}},
1234 {"pmode_register_operand", {SUBREG
, REG
}},
1235 {"scratch_operand", {SCRATCH
, REG
}},
1236 {"immediate_operand", {CONST_INT
, CONST_DOUBLE
, CONST
, SYMBOL_REF
,
1238 {"const_int_operand", {CONST_INT
}},
1239 {"const_double_operand", {CONST_INT
, CONST_DOUBLE
}},
1240 {"nonimmediate_operand", {SUBREG
, REG
, MEM
}},
1241 {"nonmemory_operand", {CONST_INT
, CONST_DOUBLE
, CONST
, SYMBOL_REF
,
1242 LABEL_REF
, SUBREG
, REG
}},
1243 {"push_operand", {MEM
}},
1244 {"pop_operand", {MEM
}},
1245 {"memory_operand", {SUBREG
, MEM
}},
1246 {"indirect_operand", {SUBREG
, MEM
}},
1247 {"comparison_operator", {EQ
, NE
, LE
, LT
, GE
, GT
, LEU
, LTU
, GEU
, GTU
,
1248 UNORDERED
, ORDERED
, UNEQ
, UNGE
, UNGT
, UNLE
,
1250 #ifdef PREDICATE_CODES
1254 #define NUM_KNOWN_OLD_PREDS ARRAY_SIZE (old_preds)
1256 /* This table gives the initial set of special predicates. It has
1257 entries for all special predicates defined in recog.c. The back
1258 end can define SPECIAL_MODE_PREDICATES to give additional entries
1259 for the table; this is considered an obsolete mechanism (use
1260 define_special_predicate instead). */
1261 static const char *const old_special_pred_table
[] = {
1263 "pmode_register_operand",
1264 #ifdef SPECIAL_MODE_PREDICATES
1265 SPECIAL_MODE_PREDICATES
1269 #define NUM_OLD_SPECIAL_MODE_PREDS ARRAY_SIZE (old_special_pred_table)
1271 /* Initialize the table of predicate definitions, starting with
1272 the information we have on generic predicates, and the old-style
1273 PREDICATE_CODES definitions. */
1276 init_predicate_table (void)
1279 struct pred_data
*pred
;
1281 predicate_table
= htab_create_alloc (37, hash_struct_pred_data
,
1282 eq_struct_pred_data
, 0,
1285 for (i
= 0; i
< NUM_KNOWN_OLD_PREDS
; i
++)
1287 pred
= xcalloc (sizeof (struct pred_data
), 1);
1288 pred
->name
= old_preds
[i
].name
;
1290 for (j
= 0; old_preds
[i
].codes
[j
] != 0; j
++)
1292 enum rtx_code code
= old_preds
[i
].codes
[j
];
1294 pred
->codes
[code
] = true;
1295 if (GET_RTX_CLASS (code
) != RTX_CONST_OBJ
)
1296 pred
->allows_non_const
= true;
1302 && code
!= STRICT_LOW_PART
)
1303 pred
->allows_non_lvalue
= true;
1306 pred
->singleton
= old_preds
[i
].codes
[0];
1308 add_predicate (pred
);
1311 for (i
= 0; i
< NUM_OLD_SPECIAL_MODE_PREDS
; i
++)
1313 pred
= lookup_predicate (old_special_pred_table
[i
]);
1316 error ("old-style special predicate list refers "
1317 "to unknown predicate '%s'", old_special_pred_table
[i
]);
1320 pred
->special
= true;