expr.c (emit_move_insn): Use SCALAR_FLOAT_MODE_P
[official-gcc.git] / gcc / gensupport.c
blob53172dd55b46e2fd579b407f921d9b2499449ee8
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)
9 any later version.
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
19 02111-1307, USA. */
21 #include "hconfig.h"
22 #include "system.h"
23 #include "rtl.h"
24 #include "obstack.h"
25 #include "errors.h"
26 #include "hashtab.h"
27 #include "gensupport.h"
30 /* In case some macros used by files we include need it, define this here. */
31 int target_flags;
33 int insn_elision = 1;
35 static struct obstack obstack;
36 struct obstack *rtl_obstack = &obstack;
38 static int sequence_num;
39 static int errors;
41 static int predicable_default;
42 static const char *predicable_true;
43 static const char *predicable_false;
45 static htab_t condition_table;
47 static char *base_dir = NULL;
49 /* We initially queue all patterns, process the define_insn and
50 define_cond_exec patterns, then return them one at a time. */
52 struct queue_elem
54 rtx data;
55 const char *filename;
56 int lineno;
57 struct queue_elem *next;
60 static struct queue_elem *define_attr_queue;
61 static struct queue_elem **define_attr_tail = &define_attr_queue;
62 static struct queue_elem *define_insn_queue;
63 static struct queue_elem **define_insn_tail = &define_insn_queue;
64 static struct queue_elem *define_cond_exec_queue;
65 static struct queue_elem **define_cond_exec_tail = &define_cond_exec_queue;
66 static struct queue_elem *other_queue;
67 static struct queue_elem **other_tail = &other_queue;
69 static void queue_pattern PARAMS ((rtx, struct queue_elem ***,
70 const char *, int));
72 /* Current maximum length of directory names in the search path
73 for include files. (Altered as we get more of them.) */
75 size_t max_include_len;
77 struct file_name_list
79 struct file_name_list *next;
80 const char *fname;
83 struct file_name_list *first_dir_md_include = 0; /* First dir to search */
84 /* First dir to search for <file> */
85 struct file_name_list *first_bracket_include = 0;
86 struct file_name_list *last_dir_md_include = 0; /* Last in chain */
88 static void remove_constraints PARAMS ((rtx));
89 static void process_rtx PARAMS ((rtx, int));
91 static int is_predicable PARAMS ((struct queue_elem *));
92 static void identify_predicable_attribute PARAMS ((void));
93 static int n_alternatives PARAMS ((const char *));
94 static void collect_insn_data PARAMS ((rtx, int *, int *));
95 static rtx alter_predicate_for_insn PARAMS ((rtx, int, int, int));
96 static const char *alter_test_for_insn PARAMS ((struct queue_elem *,
97 struct queue_elem *));
98 static char *shift_output_template PARAMS ((char *, const char *, int));
99 static const char *alter_output_for_insn PARAMS ((struct queue_elem *,
100 struct queue_elem *,
101 int, int));
102 static void process_one_cond_exec PARAMS ((struct queue_elem *));
103 static void process_define_cond_exec PARAMS ((void));
104 static void process_include PARAMS ((rtx, int));
105 static char *save_string PARAMS ((const char *, int));
107 void
108 message_with_line VPARAMS ((int lineno, const char *msg, ...))
110 VA_OPEN (ap, msg);
111 VA_FIXEDARG (ap, int, lineno);
112 VA_FIXEDARG (ap, const char *, msg);
114 fprintf (stderr, "%s:%d: ", read_rtx_filename, lineno);
115 vfprintf (stderr, msg, ap);
116 fputc ('\n', stderr);
118 VA_CLOSE (ap);
121 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
122 the gensupport programs. */
125 gen_rtx_CONST_INT (mode, arg)
126 enum machine_mode mode ATTRIBUTE_UNUSED;
127 HOST_WIDE_INT arg;
129 rtx rt = rtx_alloc (CONST_INT);
131 XWINT (rt, 0) = arg;
132 return rt;
135 /* Queue PATTERN on LIST_TAIL. */
137 static void
138 queue_pattern (pattern, list_tail, filename, lineno)
139 rtx pattern;
140 struct queue_elem ***list_tail;
141 const char *filename;
142 int lineno;
144 struct queue_elem *e = (struct queue_elem *) xmalloc (sizeof (*e));
145 e->data = pattern;
146 e->filename = filename;
147 e->lineno = lineno;
148 e->next = NULL;
149 **list_tail = e;
150 *list_tail = &e->next;
153 /* Recursively remove constraints from an rtx. */
155 static void
156 remove_constraints (part)
157 rtx part;
159 int i, j;
160 const char *format_ptr;
162 if (part == 0)
163 return;
165 if (GET_CODE (part) == MATCH_OPERAND)
166 XSTR (part, 2) = "";
167 else if (GET_CODE (part) == MATCH_SCRATCH)
168 XSTR (part, 1) = "";
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++)
175 case 'e':
176 case 'u':
177 remove_constraints (XEXP (part, i));
178 break;
179 case 'E':
180 if (XVEC (part, i) != NULL)
181 for (j = 0; j < XVECLEN (part, i); j++)
182 remove_constraints (XVECEXP (part, i, j));
183 break;
187 /* Process an include file assuming that it lives in gcc/config/{target}/
188 if the include looks like (include "file"). */
190 static void
191 process_include (desc, lineno)
192 rtx desc;
193 int lineno;
195 const char *filename = XSTR (desc, 0);
196 const char *old_filename;
197 int old_lineno;
198 char *pathname;
199 FILE *input_file;
201 /* If specified file name is absolute, skip the include stack. */
202 if (! IS_ABSOLUTE_PATHNAME (filename))
204 struct file_name_list *stackp;
206 /* Search directory path, trying to open the file. */
207 for (stackp = first_dir_md_include; stackp; stackp = stackp->next)
209 static const char sep[2] = { DIR_SEPARATOR, '\0' };
211 pathname = concat (stackp->fname, sep, filename, NULL);
212 input_file = fopen (pathname, "r");
213 if (input_file != NULL)
214 goto success;
215 free (pathname);
219 if (base_dir)
220 pathname = concat (base_dir, filename, NULL);
221 else
222 pathname = xstrdup (filename);
223 input_file = fopen (pathname, "r");
224 if (input_file == NULL)
226 free (pathname);
227 message_with_line (lineno, "include file `%s' not found", filename);
228 errors = 1;
229 return;
231 success:
233 /* Save old cursor; setup new for the new file. Note that "lineno" the
234 argument to this function is the beginning of the include statement,
235 while read_rtx_lineno has already been advanced. */
236 old_filename = read_rtx_filename;
237 old_lineno = read_rtx_lineno;
238 read_rtx_filename = pathname;
239 read_rtx_lineno = 1;
241 /* Read the entire file. */
242 while (1)
244 rtx desc;
245 int c;
247 c = read_skip_spaces (input_file);
248 if (c == EOF)
249 break;
251 ungetc (c, input_file);
252 lineno = read_rtx_lineno;
253 desc = read_rtx (input_file);
254 process_rtx (desc, lineno);
257 /* Do not free pathname. It is attached to the various rtx queue
258 elements. */
260 read_rtx_filename = old_filename;
261 read_rtx_lineno = old_lineno;
263 fclose (input_file);
266 /* Process a top level rtx in some way, queueing as appropriate. */
268 static void
269 process_rtx (desc, lineno)
270 rtx desc;
271 int lineno;
273 switch (GET_CODE (desc))
275 case DEFINE_INSN:
276 queue_pattern (desc, &define_insn_tail, read_rtx_filename, lineno);
277 break;
279 case DEFINE_COND_EXEC:
280 queue_pattern (desc, &define_cond_exec_tail, read_rtx_filename, lineno);
281 break;
283 case DEFINE_ATTR:
284 queue_pattern (desc, &define_attr_tail, read_rtx_filename, lineno);
285 break;
287 case INCLUDE:
288 process_include (desc, lineno);
289 break;
291 case DEFINE_INSN_AND_SPLIT:
293 const char *split_cond;
294 rtx split;
295 rtvec attr;
296 int i;
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 queue_pattern (desc, &define_insn_tail, read_rtx_filename, lineno);
325 queue_pattern (split, &other_tail, read_rtx_filename, lineno);
326 break;
329 default:
330 queue_pattern (desc, &other_tail, read_rtx_filename, lineno);
331 break;
335 /* Return true if attribute PREDICABLE is true for ELEM, which holds
336 a DEFINE_INSN. */
338 static int
339 is_predicable (elem)
340 struct queue_elem *elem;
342 rtvec vec = XVEC (elem->data, 4);
343 const char *value;
344 int i;
346 if (! vec)
347 return predicable_default;
349 for (i = GET_NUM_ELEM (vec) - 1; i >= 0; --i)
351 rtx sub = RTVEC_ELT (vec, i);
352 switch (GET_CODE (sub))
354 case SET_ATTR:
355 if (strcmp (XSTR (sub, 0), "predicable") == 0)
357 value = XSTR (sub, 1);
358 goto found;
360 break;
362 case SET_ATTR_ALTERNATIVE:
363 if (strcmp (XSTR (sub, 0), "predicable") == 0)
365 message_with_line (elem->lineno,
366 "multiple alternatives for `predicable'");
367 errors = 1;
368 return 0;
370 break;
372 case SET:
373 if (GET_CODE (SET_DEST (sub)) != ATTR
374 || strcmp (XSTR (SET_DEST (sub), 0), "predicable") != 0)
375 break;
376 sub = SET_SRC (sub);
377 if (GET_CODE (sub) == CONST_STRING)
379 value = XSTR (sub, 0);
380 goto found;
383 /* ??? It would be possible to handle this if we really tried.
384 It's not easy though, and I'm not going to bother until it
385 really proves necessary. */
386 message_with_line (elem->lineno,
387 "non-constant value for `predicable'");
388 errors = 1;
389 return 0;
391 default:
392 abort ();
396 return predicable_default;
398 found:
399 /* Verify that predicability does not vary on the alternative. */
400 /* ??? It should be possible to handle this by simply eliminating
401 the non-predicable alternatives from the insn. FRV would like
402 to do this. Delay this until we've got the basics solid. */
403 if (strchr (value, ',') != NULL)
405 message_with_line (elem->lineno,
406 "multiple alternatives for `predicable'");
407 errors = 1;
408 return 0;
411 /* Find out which value we're looking at. */
412 if (strcmp (value, predicable_true) == 0)
413 return 1;
414 if (strcmp (value, predicable_false) == 0)
415 return 0;
417 message_with_line (elem->lineno,
418 "unknown value `%s' for `predicable' attribute",
419 value);
420 errors = 1;
421 return 0;
424 /* Examine the attribute "predicable"; discover its boolean values
425 and its default. */
427 static void
428 identify_predicable_attribute ()
430 struct queue_elem *elem;
431 char *p_true, *p_false;
432 const char *value;
434 /* Look for the DEFINE_ATTR for `predicable', which must exist. */
435 for (elem = define_attr_queue; elem ; elem = elem->next)
436 if (strcmp (XSTR (elem->data, 0), "predicable") == 0)
437 goto found;
439 message_with_line (define_cond_exec_queue->lineno,
440 "attribute `predicable' not defined");
441 errors = 1;
442 return;
444 found:
445 value = XSTR (elem->data, 1);
446 p_false = xstrdup (value);
447 p_true = strchr (p_false, ',');
448 if (p_true == NULL || strchr (++p_true, ',') != NULL)
450 message_with_line (elem->lineno,
451 "attribute `predicable' is not a boolean");
452 errors = 1;
453 return;
455 p_true[-1] = '\0';
457 predicable_true = p_true;
458 predicable_false = p_false;
460 switch (GET_CODE (XEXP (elem->data, 2)))
462 case CONST_STRING:
463 value = XSTR (XEXP (elem->data, 2), 0);
464 break;
466 case CONST:
467 message_with_line (elem->lineno,
468 "attribute `predicable' cannot be const");
469 errors = 1;
470 return;
472 default:
473 message_with_line (elem->lineno,
474 "attribute `predicable' must have a constant default");
475 errors = 1;
476 return;
479 if (strcmp (value, p_true) == 0)
480 predicable_default = 1;
481 else if (strcmp (value, p_false) == 0)
482 predicable_default = 0;
483 else
485 message_with_line (elem->lineno,
486 "unknown value `%s' for `predicable' attribute",
487 value);
488 errors = 1;
492 /* Return the number of alternatives in constraint S. */
494 static int
495 n_alternatives (s)
496 const char *s;
498 int n = 1;
500 if (s)
501 while (*s)
502 n += (*s++ == ',');
504 return n;
507 /* Determine how many alternatives there are in INSN, and how many
508 operands. */
510 static void
511 collect_insn_data (pattern, palt, pmax)
512 rtx pattern;
513 int *palt, *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 /* FALLTHRU */
527 case MATCH_OPERATOR:
528 case MATCH_SCRATCH:
529 case MATCH_PARALLEL:
530 case MATCH_INSN:
531 i = XINT (pattern, 0);
532 if (i > *pmax)
533 *pmax = i;
534 break;
536 default:
537 break;
540 fmt = GET_RTX_FORMAT (code);
541 len = GET_RTX_LENGTH (code);
542 for (i = 0; i < len; i++)
544 switch (fmt[i])
546 case 'e': case 'u':
547 collect_insn_data (XEXP (pattern, i), palt, pmax);
548 break;
550 case 'V':
551 if (XVEC (pattern, i) == NULL)
552 break;
553 /* FALLTHRU */
554 case 'E':
555 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
556 collect_insn_data (XVECEXP (pattern, i, j), palt, pmax);
557 break;
559 case 'i': case 'w': case '0': case 's': case 'S': case 'T':
560 break;
562 default:
563 abort ();
568 static rtx
569 alter_predicate_for_insn (pattern, alt, max_op, lineno)
570 rtx pattern;
571 int alt, max_op, lineno;
573 const char *fmt;
574 enum rtx_code code;
575 int i, j, len;
577 code = GET_CODE (pattern);
578 switch (code)
580 case MATCH_OPERAND:
582 const char *c = XSTR (pattern, 2);
584 if (n_alternatives (c) != 1)
586 message_with_line (lineno,
587 "too many alternatives for operand %d",
588 XINT (pattern, 0));
589 errors = 1;
590 return NULL;
593 /* Replicate C as needed to fill out ALT alternatives. */
594 if (c && *c && alt > 1)
596 size_t c_len = strlen (c);
597 size_t len = alt * (c_len + 1);
598 char *new_c = (char *) xmalloc (len);
600 memcpy (new_c, c, c_len);
601 for (i = 1; i < alt; ++i)
603 new_c[i * (c_len + 1) - 1] = ',';
604 memcpy (&new_c[i * (c_len + 1)], c, c_len);
606 new_c[len - 1] = '\0';
607 XSTR (pattern, 2) = new_c;
610 /* FALLTHRU */
612 case MATCH_OPERATOR:
613 case MATCH_SCRATCH:
614 case MATCH_PARALLEL:
615 case MATCH_INSN:
616 XINT (pattern, 0) += max_op;
617 break;
619 default:
620 break;
623 fmt = GET_RTX_FORMAT (code);
624 len = GET_RTX_LENGTH (code);
625 for (i = 0; i < len; i++)
627 rtx r;
629 switch (fmt[i])
631 case 'e': case 'u':
632 r = alter_predicate_for_insn (XEXP (pattern, i), alt,
633 max_op, lineno);
634 if (r == NULL)
635 return r;
636 break;
638 case 'E':
639 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
641 r = alter_predicate_for_insn (XVECEXP (pattern, i, j),
642 alt, max_op, lineno);
643 if (r == NULL)
644 return r;
646 break;
648 case 'i': case 'w': case '0': case 's':
649 break;
651 default:
652 abort ();
656 return pattern;
659 static const char *
660 alter_test_for_insn (ce_elem, insn_elem)
661 struct queue_elem *ce_elem, *insn_elem;
663 const char *ce_test, *insn_test;
665 ce_test = XSTR (ce_elem->data, 1);
666 insn_test = XSTR (insn_elem->data, 2);
667 if (!ce_test || *ce_test == '\0')
668 return insn_test;
669 if (!insn_test || *insn_test == '\0')
670 return ce_test;
672 return concat ("(", ce_test, ") && (", insn_test, ")", NULL);
675 /* Adjust all of the operand numbers in OLD to match the shift they'll
676 get from an operand displacement of DISP. Return a pointer after the
677 adjusted string. */
679 static char *
680 shift_output_template (new, old, disp)
681 char *new;
682 const char *old;
683 int disp;
685 while (*old)
687 char c = *old++;
688 *new++ = c;
689 if (c == '%')
691 c = *old++;
692 if (ISDIGIT ((unsigned char) c))
693 c += disp;
694 else if (ISALPHA (c))
696 *new++ = c;
697 c = *old++ + disp;
699 *new++ = c;
703 return new;
706 static const char *
707 alter_output_for_insn (ce_elem, insn_elem, alt, max_op)
708 struct queue_elem *ce_elem, *insn_elem;
709 int alt, max_op;
711 const char *ce_out, *insn_out;
712 char *new, *p;
713 size_t len, ce_len, insn_len;
715 /* ??? Could coordinate with genoutput to not duplicate code here. */
717 ce_out = XSTR (ce_elem->data, 2);
718 insn_out = XTMPL (insn_elem->data, 3);
719 if (!ce_out || *ce_out == '\0')
720 return insn_out;
722 ce_len = strlen (ce_out);
723 insn_len = strlen (insn_out);
725 if (*insn_out == '*')
726 /* You must take care of the predicate yourself. */
727 return insn_out;
729 if (*insn_out == '@')
731 len = (ce_len + 1) * alt + insn_len + 1;
732 p = new = xmalloc (len);
737 *p++ = *insn_out++;
738 while (ISSPACE ((unsigned char) *insn_out));
740 if (*insn_out != '#')
742 p = shift_output_template (p, ce_out, max_op);
743 *p++ = ' ';
747 *p++ = *insn_out++;
748 while (*insn_out && *insn_out != '\n');
750 while (*insn_out);
751 *p = '\0';
753 else
755 len = ce_len + 1 + insn_len + 1;
756 new = xmalloc (len);
758 p = shift_output_template (new, ce_out, max_op);
759 *p++ = ' ';
760 memcpy (p, insn_out, insn_len + 1);
763 return new;
766 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */
768 static void
769 process_one_cond_exec (ce_elem)
770 struct queue_elem *ce_elem;
772 struct queue_elem *insn_elem;
773 for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
775 int alternatives, max_operand;
776 rtx pred, insn, pattern;
778 if (! is_predicable (insn_elem))
779 continue;
781 alternatives = 1;
782 max_operand = -1;
783 collect_insn_data (insn_elem->data, &alternatives, &max_operand);
784 max_operand += 1;
786 if (XVECLEN (ce_elem->data, 0) != 1)
788 message_with_line (ce_elem->lineno,
789 "too many patterns in predicate");
790 errors = 1;
791 return;
794 pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0));
795 pred = alter_predicate_for_insn (pred, alternatives, max_operand,
796 ce_elem->lineno);
797 if (pred == NULL)
798 return;
800 /* Construct a new pattern for the new insn. */
801 insn = copy_rtx (insn_elem->data);
802 XSTR (insn, 0) = "";
803 pattern = rtx_alloc (COND_EXEC);
804 XEXP (pattern, 0) = pred;
805 if (XVECLEN (insn, 1) == 1)
807 XEXP (pattern, 1) = XVECEXP (insn, 1, 0);
808 XVECEXP (insn, 1, 0) = pattern;
809 PUT_NUM_ELEM (XVEC (insn, 1), 1);
811 else
813 XEXP (pattern, 1) = rtx_alloc (PARALLEL);
814 XVEC (XEXP (pattern, 1), 0) = XVEC (insn, 1);
815 XVEC (insn, 1) = rtvec_alloc (1);
816 XVECEXP (insn, 1, 0) = pattern;
819 XSTR (insn, 2) = alter_test_for_insn (ce_elem, insn_elem);
820 XTMPL (insn, 3) = alter_output_for_insn (ce_elem, insn_elem,
821 alternatives, max_operand);
823 /* ??? Set `predicable' to false. Not crucial since it's really
824 only used here, and we won't reprocess this new pattern. */
826 /* Put the new pattern on the `other' list so that it
827 (a) is not reprocessed by other define_cond_exec patterns
828 (b) appears after all normal define_insn patterns.
830 ??? B is debatable. If one has normal insns that match
831 cond_exec patterns, they will be preferred over these
832 generated patterns. Whether this matters in practice, or if
833 it's a good thing, or whether we should thread these new
834 patterns into the define_insn chain just after their generator
835 is something we'll have to experiment with. */
837 queue_pattern (insn, &other_tail, insn_elem->filename,
838 insn_elem->lineno);
842 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
843 patterns appropriately. */
845 static void
846 process_define_cond_exec ()
848 struct queue_elem *elem;
850 identify_predicable_attribute ();
851 if (errors)
852 return;
854 for (elem = define_cond_exec_queue; elem ; elem = elem->next)
855 process_one_cond_exec (elem);
858 static char *
859 save_string (s, len)
860 const char *s;
861 int len;
863 register char *result = xmalloc (len + 1);
865 memcpy (result, s, len);
866 result[len] = 0;
867 return result;
871 /* The entry point for initializing the reader. */
874 init_md_reader_args (argc, argv)
875 int argc;
876 char **argv;
878 int i;
879 const char *in_fname;
881 max_include_len = 0;
882 in_fname = NULL;
883 for (i = 1; i < argc; i++)
885 if (argv[i][0] != '-')
887 if (in_fname == NULL)
888 in_fname = argv[i];
890 else
892 int c = argv[i][1];
893 switch (c)
895 case 'I': /* Add directory to path for includes. */
897 struct file_name_list *dirtmp;
899 dirtmp = (struct file_name_list *)
900 xmalloc (sizeof (struct file_name_list));
901 dirtmp->next = 0; /* New one goes on the end */
902 if (first_dir_md_include == 0)
903 first_dir_md_include = dirtmp;
904 else
905 last_dir_md_include->next = dirtmp;
906 last_dir_md_include = dirtmp; /* Tail follows the last one */
907 if (argv[i][1] == 'I' && argv[i][2] != 0)
908 dirtmp->fname = argv[i] + 2;
909 else if (i + 1 == argc)
910 fatal ("directory name missing after -I option");
911 else
912 dirtmp->fname = argv[++i];
913 if (strlen (dirtmp->fname) > max_include_len)
914 max_include_len = strlen (dirtmp->fname);
916 break;
917 default:
918 fatal ("invalid option `%s'", argv[i]);
923 return init_md_reader (in_fname);
926 /* The entry point for initializing the reader. */
929 init_md_reader (filename)
930 const char *filename;
932 FILE *input_file;
933 int c;
934 size_t i;
935 char *lastsl;
937 lastsl = strrchr (filename, '/');
938 if (lastsl != NULL)
939 base_dir = save_string (filename, lastsl - filename + 1 );
941 read_rtx_filename = filename;
942 input_file = fopen (filename, "r");
943 if (input_file == 0)
945 perror (filename);
946 return FATAL_EXIT_CODE;
949 /* Initialize the table of insn conditions. */
950 condition_table = htab_create (n_insn_conditions,
951 hash_c_test, cmp_c_test, NULL);
953 for (i = 0; i < n_insn_conditions; i++)
954 *(htab_find_slot (condition_table, (PTR) &insn_conditions[i], INSERT))
955 = (PTR) &insn_conditions[i];
957 obstack_init (rtl_obstack);
958 errors = 0;
959 sequence_num = 0;
961 /* Read the entire file. */
962 while (1)
964 rtx desc;
965 int lineno;
967 c = read_skip_spaces (input_file);
968 if (c == EOF)
969 break;
971 ungetc (c, input_file);
972 lineno = read_rtx_lineno;
973 desc = read_rtx (input_file);
974 process_rtx (desc, lineno);
976 fclose (input_file);
978 /* Process define_cond_exec patterns. */
979 if (define_cond_exec_queue != NULL)
980 process_define_cond_exec ();
982 return errors ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
985 /* The entry point for reading a single rtx from an md file. */
988 read_md_rtx (lineno, seqnr)
989 int *lineno;
990 int *seqnr;
992 struct queue_elem **queue, *elem;
993 rtx desc;
995 discard:
997 /* Read all patterns from a given queue before moving on to the next. */
998 if (define_attr_queue != NULL)
999 queue = &define_attr_queue;
1000 else if (define_insn_queue != NULL)
1001 queue = &define_insn_queue;
1002 else if (other_queue != NULL)
1003 queue = &other_queue;
1004 else
1005 return NULL_RTX;
1007 elem = *queue;
1008 *queue = elem->next;
1009 desc = elem->data;
1010 read_rtx_filename = elem->filename;
1011 *lineno = elem->lineno;
1012 *seqnr = sequence_num;
1014 free (elem);
1016 /* Discard insn patterns which we know can never match (because
1017 their C test is provably always false). If insn_elision is
1018 false, our caller needs to see all the patterns. Note that the
1019 elided patterns are never counted by the sequence numbering; it
1020 it is the caller's responsibility, when insn_elision is false, not
1021 to use elided pattern numbers for anything. */
1022 switch (GET_CODE (desc))
1024 case DEFINE_INSN:
1025 case DEFINE_EXPAND:
1026 if (maybe_eval_c_test (XSTR (desc, 2)) != 0)
1027 sequence_num++;
1028 else if (insn_elision)
1029 goto discard;
1030 break;
1032 case DEFINE_SPLIT:
1033 case DEFINE_PEEPHOLE:
1034 case DEFINE_PEEPHOLE2:
1035 if (maybe_eval_c_test (XSTR (desc, 1)) != 0)
1036 sequence_num++;
1037 else if (insn_elision)
1038 goto discard;
1039 break;
1041 default:
1042 break;
1045 return desc;
1048 /* Helper functions for insn elision. */
1050 /* Compute a hash function of a c_test structure, which is keyed
1051 by its ->expr field. */
1052 hashval_t
1053 hash_c_test (x)
1054 const PTR x;
1056 const struct c_test *a = (const struct c_test *) x;
1057 const unsigned char *base, *s = (const unsigned char *) a->expr;
1058 hashval_t hash;
1059 unsigned char c;
1060 unsigned int len;
1062 base = s;
1063 hash = 0;
1065 while ((c = *s++) != '\0')
1067 hash += c + (c << 17);
1068 hash ^= hash >> 2;
1071 len = s - base;
1072 hash += len + (len << 17);
1073 hash ^= hash >> 2;
1075 return hash;
1078 /* Compare two c_test expression structures. */
1080 cmp_c_test (x, y)
1081 const PTR x;
1082 const PTR y;
1084 const struct c_test *a = (const struct c_test *) x;
1085 const struct c_test *b = (const struct c_test *) y;
1087 return !strcmp (a->expr, b->expr);
1090 /* Given a string representing a C test expression, look it up in the
1091 condition_table and report whether or not its value is known
1092 at compile time. Returns a tristate: 1 for known true, 0 for
1093 known false, -1 for unknown. */
1095 maybe_eval_c_test (expr)
1096 const char *expr;
1098 const struct c_test *test;
1099 struct c_test dummy;
1101 if (expr[0] == 0)
1102 return 1;
1104 if (insn_elision_unavailable)
1105 return -1;
1107 dummy.expr = expr;
1108 test = (const struct c_test *) htab_find (condition_table, &dummy);
1109 if (!test)
1110 abort ();
1112 return test->value;
1115 /* Given a string, return the number of comma-separated elements in it.
1116 Return 0 for the null string. */
1118 n_comma_elts (s)
1119 const char *s;
1121 int n;
1123 if (*s == '\0')
1124 return 0;
1126 for (n = 1; *s; s++)
1127 if (*s == ',')
1128 n++;
1130 return n;
1133 /* Given a pointer to a (char *), return a pointer to the beginning of the
1134 next comma-separated element in the string. Advance the pointer given
1135 to the end of that element. Return NULL if at end of string. Caller
1136 is responsible for copying the string if necessary. White space between
1137 a comma and an element is ignored. */
1139 const char *
1140 scan_comma_elt (pstr)
1141 const char **pstr;
1143 const char *start;
1144 const char *p = *pstr;
1146 if (*p == ',')
1147 p++;
1148 while (ISSPACE(*p))
1149 p++;
1151 if (*p == '\0')
1152 return NULL;
1154 start = p;
1156 while (*p != ',' && *p != '\0')
1157 p++;
1159 *pstr = p;
1160 return start;