PR target/16286
[official-gcc.git] / gcc / gensupport.c
blob1fb45c0835f165439cebe4618cae1702ca169cb0
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)
10 any later version.
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
20 02111-1307, USA. */
22 #include "bconfig.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "rtl.h"
27 #include "obstack.h"
28 #include "errors.h"
29 #include "hashtab.h"
30 #include "gensupport.h"
33 /* In case some macros used by files we include need it, define this here. */
34 int target_flags;
36 int insn_elision = 1;
38 const char *in_fname;
40 static struct obstack obstack;
41 struct obstack *rtl_obstack = &obstack;
43 static int sequence_num;
44 static int errors;
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. */
57 struct queue_elem
59 rtx data;
60 const char *filename;
61 int lineno;
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 ***,
80 const char *, int);
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;
87 struct file_name_list
89 struct file_name_list *next;
90 const char *fname;
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 *,
110 struct queue_elem *,
111 int, int);
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);
118 void
119 message_with_line (int lineno, const char *msg, ...)
121 va_list ap;
123 va_start (ap, msg);
125 fprintf (stderr, "%s:%d: ", read_rtx_filename, lineno);
126 vfprintf (stderr, msg, ap);
127 fputc ('\n', stderr);
129 va_end (ap);
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),
137 HOST_WIDE_INT arg)
139 rtx rt = rtx_alloc (CONST_INT);
141 XWINT (rt, 0) = arg;
142 return rt;
145 /* Queue PATTERN on LIST_TAIL. Return the address of the new queue
146 element. */
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);
153 e->data = pattern;
154 e->filename = filename;
155 e->lineno = lineno;
156 e->next = NULL;
157 e->split = NULL;
158 **list_tail = e;
159 *list_tail = &e->next;
160 return e;
163 /* Recursively remove constraints from an rtx. */
165 static void
166 remove_constraints (rtx part)
168 int i, j;
169 const char *format_ptr;
171 if (part == 0)
172 return;
174 if (GET_CODE (part) == MATCH_OPERAND)
175 XSTR (part, 2) = "";
176 else if (GET_CODE (part) == MATCH_SCRATCH)
177 XSTR (part, 1) = "";
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++)
184 case 'e':
185 case 'u':
186 remove_constraints (XEXP (part, i));
187 break;
188 case 'E':
189 if (XVEC (part, i) != NULL)
190 for (j = 0; j < XVECLEN (part, i); j++)
191 remove_constraints (XVECEXP (part, i, j));
192 break;
196 /* Process an include file assuming that it lives in gcc/config/{target}/
197 if the include looks like (include "file"). */
199 static void
200 process_include (rtx desc, int lineno)
202 const char *filename = XSTR (desc, 0);
203 const char *old_filename;
204 int old_lineno;
205 char *pathname;
206 FILE *input_file;
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)
221 goto success;
222 free (pathname);
226 if (base_dir)
227 pathname = concat (base_dir, filename, NULL);
228 else
229 pathname = xstrdup (filename);
230 input_file = fopen (pathname, "r");
231 if (input_file == NULL)
233 free (pathname);
234 message_with_line (lineno, "include file `%s' not found", filename);
235 errors = 1;
236 return;
238 success:
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;
246 read_rtx_lineno = 1;
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
253 elements. */
255 read_rtx_filename = old_filename;
256 read_rtx_lineno = old_lineno;
258 fclose (input_file);
261 /* Process a top level rtx in some way, queuing as appropriate. */
263 static void
264 process_rtx (rtx desc, int lineno)
266 switch (GET_CODE (desc))
268 case DEFINE_INSN:
269 queue_pattern (desc, &define_insn_tail, read_rtx_filename, lineno);
270 break;
272 case DEFINE_COND_EXEC:
273 queue_pattern (desc, &define_cond_exec_tail, read_rtx_filename, lineno);
274 break;
276 case DEFINE_ATTR:
277 queue_pattern (desc, &define_attr_tail, read_rtx_filename, lineno);
278 break;
280 case DEFINE_PREDICATE:
281 case DEFINE_SPECIAL_PREDICATE:
282 queue_pattern (desc, &define_pred_tail, read_rtx_filename, lineno);
283 break;
285 case INCLUDE:
286 process_include (desc, lineno);
287 break;
289 case DEFINE_INSN_AND_SPLIT:
291 const char *split_cond;
292 rtx split;
293 rtvec attr;
294 int i;
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);
303 while (--i >= 0)
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;
323 /* Queue them. */
324 insn_elem
325 = queue_pattern (desc, &define_insn_tail, read_rtx_filename,
326 lineno);
327 split_elem
328 = queue_pattern (split, &other_tail, read_rtx_filename, lineno);
329 insn_elem->split = split_elem;
330 break;
333 default:
334 queue_pattern (desc, &other_tail, read_rtx_filename, lineno);
335 break;
339 /* Return true if attribute PREDICABLE is true for ELEM, which holds
340 a DEFINE_INSN. */
342 static int
343 is_predicable (struct queue_elem *elem)
345 rtvec vec = XVEC (elem->data, 4);
346 const char *value;
347 int i;
349 if (! vec)
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))
357 case SET_ATTR:
358 if (strcmp (XSTR (sub, 0), "predicable") == 0)
360 value = XSTR (sub, 1);
361 goto found;
363 break;
365 case SET_ATTR_ALTERNATIVE:
366 if (strcmp (XSTR (sub, 0), "predicable") == 0)
368 message_with_line (elem->lineno,
369 "multiple alternatives for `predicable'");
370 errors = 1;
371 return 0;
373 break;
375 case SET:
376 if (GET_CODE (SET_DEST (sub)) != ATTR
377 || strcmp (XSTR (SET_DEST (sub), 0), "predicable") != 0)
378 break;
379 sub = SET_SRC (sub);
380 if (GET_CODE (sub) == CONST_STRING)
382 value = XSTR (sub, 0);
383 goto found;
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'");
391 errors = 1;
392 return 0;
394 default:
395 gcc_unreachable ();
399 return predicable_default;
401 found:
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'");
410 errors = 1;
411 return 0;
414 /* Find out which value we're looking at. */
415 if (strcmp (value, predicable_true) == 0)
416 return 1;
417 if (strcmp (value, predicable_false) == 0)
418 return 0;
420 message_with_line (elem->lineno,
421 "unknown value `%s' for `predicable' attribute",
422 value);
423 errors = 1;
424 return 0;
427 /* Examine the attribute "predicable"; discover its boolean values
428 and its default. */
430 static void
431 identify_predicable_attribute (void)
433 struct queue_elem *elem;
434 char *p_true, *p_false;
435 const char *value;
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)
440 goto found;
442 message_with_line (define_cond_exec_queue->lineno,
443 "attribute `predicable' not defined");
444 errors = 1;
445 return;
447 found:
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");
455 errors = 1;
456 return;
458 p_true[-1] = '\0';
460 predicable_true = p_true;
461 predicable_false = p_false;
463 switch (GET_CODE (XEXP (elem->data, 2)))
465 case CONST_STRING:
466 value = XSTR (XEXP (elem->data, 2), 0);
467 break;
469 case CONST:
470 message_with_line (elem->lineno,
471 "attribute `predicable' cannot be const");
472 errors = 1;
473 return;
475 default:
476 message_with_line (elem->lineno,
477 "attribute `predicable' must have a constant default");
478 errors = 1;
479 return;
482 if (strcmp (value, p_true) == 0)
483 predicable_default = 1;
484 else if (strcmp (value, p_false) == 0)
485 predicable_default = 0;
486 else
488 message_with_line (elem->lineno,
489 "unknown value `%s' for `predicable' attribute",
490 value);
491 errors = 1;
495 /* Return the number of alternatives in constraint S. */
497 static int
498 n_alternatives (const char *s)
500 int n = 1;
502 if (s)
503 while (*s)
504 n += (*s++ == ',');
506 return n;
509 /* Determine how many alternatives there are in INSN, and how many
510 operands. */
512 static void
513 collect_insn_data (rtx pattern, int *palt, int *pmax)
515 const char *fmt;
516 enum rtx_code code;
517 int i, j, len;
519 code = GET_CODE (pattern);
520 switch (code)
522 case MATCH_OPERAND:
523 i = n_alternatives (XSTR (pattern, 2));
524 *palt = (i > *palt ? i : *palt);
525 /* Fall through. */
527 case MATCH_OPERATOR:
528 case MATCH_SCRATCH:
529 case MATCH_PARALLEL:
530 i = XINT (pattern, 0);
531 if (i > *pmax)
532 *pmax = i;
533 break;
535 default:
536 break;
539 fmt = GET_RTX_FORMAT (code);
540 len = GET_RTX_LENGTH (code);
541 for (i = 0; i < len; i++)
543 switch (fmt[i])
545 case 'e': case 'u':
546 collect_insn_data (XEXP (pattern, i), palt, pmax);
547 break;
549 case 'V':
550 if (XVEC (pattern, i) == NULL)
551 break;
552 /* Fall through. */
553 case 'E':
554 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
555 collect_insn_data (XVECEXP (pattern, i, j), palt, pmax);
556 break;
558 case 'i': case 'w': case '0': case 's': case 'S': case 'T':
559 break;
561 default:
562 gcc_unreachable ();
567 static rtx
568 alter_predicate_for_insn (rtx pattern, int alt, int max_op, int lineno)
570 const char *fmt;
571 enum rtx_code code;
572 int i, j, len;
574 code = GET_CODE (pattern);
575 switch (code)
577 case MATCH_OPERAND:
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",
585 XINT (pattern, 0));
586 errors = 1;
587 return NULL;
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;
607 /* Fall through. */
609 case MATCH_OPERATOR:
610 case MATCH_SCRATCH:
611 case MATCH_PARALLEL:
612 XINT (pattern, 0) += max_op;
613 break;
615 default:
616 break;
619 fmt = GET_RTX_FORMAT (code);
620 len = GET_RTX_LENGTH (code);
621 for (i = 0; i < len; i++)
623 rtx r;
625 switch (fmt[i])
627 case 'e': case 'u':
628 r = alter_predicate_for_insn (XEXP (pattern, i), alt,
629 max_op, lineno);
630 if (r == NULL)
631 return r;
632 break;
634 case 'E':
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);
639 if (r == NULL)
640 return r;
642 break;
644 case 'i': case 'w': case '0': case 's':
645 break;
647 default:
648 gcc_unreachable ();
652 return pattern;
655 static const char *
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')
664 return insn_test;
665 if (!insn_test || *insn_test == '\0')
666 return ce_test;
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
673 adjusted string. */
675 static char *
676 shift_output_template (char *dest, const char *src, int disp)
678 while (*src)
680 char c = *src++;
681 *dest++ = c;
682 if (c == '%')
684 c = *src++;
685 if (ISDIGIT ((unsigned char) c))
686 c += disp;
687 else if (ISALPHA (c))
689 *dest++ = c;
690 c = *src++ + disp;
692 *dest++ = c;
696 return dest;
699 static const char *
700 alter_output_for_insn (struct queue_elem *ce_elem,
701 struct queue_elem *insn_elem,
702 int alt, int max_op)
704 const char *ce_out, *insn_out;
705 char *result, *p;
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')
713 return insn_out;
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. */
720 return insn_out;
722 if (*insn_out == '@')
724 len = (ce_len + 1) * alt + insn_len + 1;
725 p = result = XNEWVEC(char, len);
730 *p++ = *insn_out++;
731 while (ISSPACE ((unsigned char) *insn_out));
733 if (*insn_out != '#')
735 p = shift_output_template (p, ce_out, max_op);
736 *p++ = ' ';
740 *p++ = *insn_out++;
741 while (*insn_out && *insn_out != '\n');
743 while (*insn_out);
744 *p = '\0';
746 else
748 len = ce_len + 1 + insn_len + 1;
749 result = XNEWVEC (char, len);
751 p = shift_output_template (result, ce_out, max_op);
752 *p++ = ' ';
753 memcpy (p, insn_out, insn_len + 1);
756 return result;
759 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */
761 static void
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;
769 int i;
771 if (! is_predicable (insn_elem))
772 continue;
774 alternatives = 1;
775 max_operand = -1;
776 collect_insn_data (insn_elem->data, &alternatives, &max_operand);
777 max_operand += 1;
779 if (XVECLEN (ce_elem->data, 0) != 1)
781 message_with_line (ce_elem->lineno,
782 "too many patterns in predicate");
783 errors = 1;
784 return;
787 pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0));
788 pred = alter_predicate_for_insn (pred, alternatives, max_operand,
789 ce_elem->lineno);
790 if (pred == NULL)
791 return;
793 /* Construct a new pattern for the new insn. */
794 insn = copy_rtx (insn_elem->data);
795 XSTR (insn, 0) = "";
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);
804 else
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,
831 insn_elem->lineno);
833 if (!insn_elem->split)
834 continue;
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);
848 else
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. */
872 static void
873 process_define_cond_exec (void)
875 struct queue_elem *elem;
877 identify_predicable_attribute ();
878 if (errors)
879 return;
881 for (elem = define_cond_exec_queue; elem ; elem = elem->next)
882 process_one_cond_exec (elem);
885 static char *
886 save_string (const char *s, int len)
888 char *result = XNEWVEC (char, len + 1);
890 memcpy (result, s, len);
891 result[len] = 0;
892 return result;
896 /* The entry point for initializing the reader. */
899 init_md_reader_args_cb (int argc, char **argv, bool (*parse_opt)(const char *))
901 FILE *input_file;
902 int i, lineno;
903 size_t ix;
904 char *lastsl;
905 rtx desc;
907 for (i = 1; i < argc; i++)
909 if (argv[i][0] != '-')
911 if (in_fname)
912 fatal ("too many input files");
914 in_fname = argv[i];
916 else
918 int c = argv[i][1];
919 switch (c)
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;
929 else
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");
936 else
937 dirtmp->fname = argv[++i];
938 if (strlen (dirtmp->fname) > max_include_len)
939 max_include_len = strlen (dirtmp->fname);
941 break;
942 default:
943 /* The program may have provided a callback so it can
944 accept its own options. */
945 if (parse_opt && parse_opt (argv[i]))
946 break;
948 fatal ("invalid option `%s'", argv[i]);
953 if (!in_fname)
954 fatal ("no input file name");
956 lastsl = strrchr (in_fname, '/');
957 if (lastsl != NULL)
958 base_dir = save_string (in_fname, lastsl - in_fname + 1 );
960 read_rtx_filename = in_fname;
961 input_file = fopen (in_fname, "r");
962 if (input_file == 0)
964 perror (in_fname);
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);
979 errors = 0;
980 sequence_num = 0;
982 /* Read the entire file. */
983 while (read_rtx (input_file, &desc, &lineno))
984 process_rtx (desc, lineno);
985 fclose (input_file);
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
995 instead. */
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;
1008 rtx desc;
1010 discard:
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;
1021 else
1022 return NULL_RTX;
1024 elem = *queue;
1025 *queue = elem->next;
1026 desc = elem->data;
1027 read_rtx_filename = elem->filename;
1028 *lineno = elem->lineno;
1029 *seqnr = sequence_num;
1031 free (elem);
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))
1041 case DEFINE_INSN:
1042 case DEFINE_EXPAND:
1043 if (maybe_eval_c_test (XSTR (desc, 2)) != 0)
1044 sequence_num++;
1045 else if (insn_elision)
1046 goto discard;
1047 break;
1049 case DEFINE_SPLIT:
1050 case DEFINE_PEEPHOLE:
1051 case DEFINE_PEEPHOLE2:
1052 if (maybe_eval_c_test (XSTR (desc, 1)) != 0)
1053 sequence_num++;
1054 else if (insn_elision)
1055 goto discard;
1056 break;
1058 default:
1059 break;
1062 return desc;
1065 /* Helper functions for insn elision. */
1067 /* Compute a hash function of a c_test structure, which is keyed
1068 by its ->expr field. */
1069 hashval_t
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;
1074 hashval_t hash;
1075 unsigned char c;
1076 unsigned int len;
1078 base = s;
1079 hash = 0;
1081 while ((c = *s++) != '\0')
1083 hash += c + (c << 17);
1084 hash ^= hash >> 2;
1087 len = s - base;
1088 hash += len + (len << 17);
1089 hash ^= hash >> 2;
1091 return hash;
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;
1114 if (expr[0] == 0)
1115 return 1;
1117 if (insn_elision_unavailable)
1118 return -1;
1120 dummy.expr = expr;
1121 test = (const struct c_test *)htab_find (condition_table, &dummy);
1122 gcc_assert (test);
1124 return test->value;
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)
1132 int n;
1134 if (*s == '\0')
1135 return 0;
1137 for (n = 1; *s; s++)
1138 if (*s == ',')
1139 n++;
1141 return n;
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. */
1150 const char *
1151 scan_comma_elt (const char **pstr)
1153 const char *start;
1154 const char *p = *pstr;
1156 if (*p == ',')
1157 p++;
1158 while (ISSPACE(*p))
1159 p++;
1161 if (*p == '\0')
1162 return NULL;
1164 start = p;
1166 while (*p != ',' && *p != '\0')
1167 p++;
1169 *pstr = p;
1170 return start;
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;
1180 static hashval_t
1181 hash_struct_pred_data (const void *ptr)
1183 return htab_hash_string (((const struct pred_data *)ptr)->name);
1186 static int
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);
1193 struct pred_data *
1194 lookup_predicate (const char *name)
1196 struct pred_data key;
1197 key.name = name;
1198 return htab_find (predicate_table, &key);
1201 void
1202 add_predicate (struct pred_data *pred)
1204 void **slot = htab_find_slot (predicate_table, pred, INSERT);
1205 if (*slot)
1207 error ("duplicate predicate definition for '%s'", pred->name);
1208 return;
1210 *slot = pred;
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
1223 const char *name;
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,
1237 LABEL_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,
1249 UNLT, LTGT}},
1250 #ifdef PREDICATE_CODES
1251 PREDICATE_CODES
1252 #endif
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[] = {
1262 "address_operand",
1263 "pmode_register_operand",
1264 #ifdef SPECIAL_MODE_PREDICATES
1265 SPECIAL_MODE_PREDICATES
1266 #endif
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. */
1275 static void
1276 init_predicate_table (void)
1278 size_t i, j;
1279 struct pred_data *pred;
1281 predicate_table = htab_create_alloc (37, hash_struct_pred_data,
1282 eq_struct_pred_data, 0,
1283 xcalloc, free);
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;
1297 if (code != REG
1298 && code != SUBREG
1299 && code != MEM
1300 && code != CONCAT
1301 && code != PARALLEL
1302 && code != STRICT_LOW_PART)
1303 pred->allows_non_lvalue = true;
1305 if (j == 1)
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]);
1314 if (!pred)
1316 error ("old-style special predicate list refers "
1317 "to unknown predicate '%s'", old_special_pred_table[i]);
1318 continue;
1320 pred->special = true;