OSDN Git Service

bc07c90317cc632a228eb77ef11869469591a12d
[pf3gnuchains/gcc-fork.git] / gcc / gensupport.c
1 /* Support routines for the various generation passes.
2    Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
3
4    This file is part of GCC.
5
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.
10
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.
15
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.  */
20
21 #include "bconfig.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "rtl.h"
26 #include "obstack.h"
27 #include "errors.h"
28 #include "hashtab.h"
29 #include "gensupport.h"
30
31
32 /* In case some macros used by files we include need it, define this here.  */
33 int target_flags;
34
35 int insn_elision = 1;
36
37 static struct obstack obstack;
38 struct obstack *rtl_obstack = &obstack;
39
40 static int sequence_num;
41 static int errors;
42
43 static int predicable_default;
44 static const char *predicable_true;
45 static const char *predicable_false;
46
47 static htab_t condition_table;
48
49 static char *base_dir = NULL;
50
51 /* We initially queue all patterns, process the define_insn and
52    define_cond_exec patterns, then return them one at a time.  */
53
54 struct queue_elem
55 {
56   rtx data;
57   const char *filename;
58   int lineno;
59   struct queue_elem *next;
60 };
61
62 static struct queue_elem *define_attr_queue;
63 static struct queue_elem **define_attr_tail = &define_attr_queue;
64 static struct queue_elem *define_insn_queue;
65 static struct queue_elem **define_insn_tail = &define_insn_queue;
66 static struct queue_elem *define_cond_exec_queue;
67 static struct queue_elem **define_cond_exec_tail = &define_cond_exec_queue;
68 static struct queue_elem *other_queue;
69 static struct queue_elem **other_tail = &other_queue;
70
71 static void queue_pattern PARAMS ((rtx, struct queue_elem ***,
72                                    const char *, int));
73
74 /* Current maximum length of directory names in the search path
75    for include files.  (Altered as we get more of them.)  */
76
77 size_t max_include_len;
78
79 struct file_name_list
80   {
81     struct file_name_list *next;
82     const char *fname;
83   };
84
85 struct file_name_list *first_dir_md_include = 0;  /* First dir to search */
86         /* First dir to search for <file> */
87 struct file_name_list *first_bracket_include = 0;
88 struct file_name_list *last_dir_md_include = 0;        /* Last in chain */
89
90 static void remove_constraints PARAMS ((rtx));
91 static void process_rtx PARAMS ((rtx, int));
92
93 static int is_predicable PARAMS ((struct queue_elem *));
94 static void identify_predicable_attribute PARAMS ((void));
95 static int n_alternatives PARAMS ((const char *));
96 static void collect_insn_data PARAMS ((rtx, int *, int *));
97 static rtx alter_predicate_for_insn PARAMS ((rtx, int, int, int));
98 static const char *alter_test_for_insn PARAMS ((struct queue_elem *,
99                                                 struct queue_elem *));
100 static char *shift_output_template PARAMS ((char *, const char *, int));
101 static const char *alter_output_for_insn PARAMS ((struct queue_elem *,
102                                                   struct queue_elem *,
103                                                   int, int));
104 static void process_one_cond_exec PARAMS ((struct queue_elem *));
105 static void process_define_cond_exec PARAMS ((void));
106 static void process_include PARAMS ((rtx, int));
107 static char *save_string PARAMS ((const char *, int));
108 \f
109 void
110 message_with_line VPARAMS ((int lineno, const char *msg, ...))
111 {
112   VA_OPEN (ap, msg);
113   VA_FIXEDARG (ap, int, lineno);
114   VA_FIXEDARG (ap, const char *, msg);
115
116   fprintf (stderr, "%s:%d: ", read_rtx_filename, lineno);
117   vfprintf (stderr, msg, ap);
118   fputc ('\n', stderr);
119
120   VA_CLOSE (ap);
121 }
122
123 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
124    the gensupport programs.  */
125
126 rtx
127 gen_rtx_CONST_INT (mode, arg)
128      enum machine_mode mode ATTRIBUTE_UNUSED;
129      HOST_WIDE_INT arg;
130 {
131   rtx rt = rtx_alloc (CONST_INT);
132
133   XWINT (rt, 0) = arg;
134   return rt;
135 }
136 \f
137 /* Queue PATTERN on LIST_TAIL.  */
138
139 static void
140 queue_pattern (pattern, list_tail, filename, lineno)
141      rtx pattern;
142      struct queue_elem ***list_tail;
143      const char *filename;
144      int lineno;
145 {
146   struct queue_elem *e = (struct queue_elem *) xmalloc (sizeof (*e));
147   e->data = pattern;
148   e->filename = filename;
149   e->lineno = lineno;
150   e->next = NULL;
151   **list_tail = e;
152   *list_tail = &e->next;
153 }
154
155 /* Recursively remove constraints from an rtx.  */
156
157 static void
158 remove_constraints (part)
159      rtx part;
160 {
161   int i, j;
162   const char *format_ptr;
163
164   if (part == 0)
165     return;
166
167   if (GET_CODE (part) == MATCH_OPERAND)
168     XSTR (part, 2) = "";
169   else if (GET_CODE (part) == MATCH_SCRATCH)
170     XSTR (part, 1) = "";
171
172   format_ptr = GET_RTX_FORMAT (GET_CODE (part));
173
174   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
175     switch (*format_ptr++)
176       {
177       case 'e':
178       case 'u':
179         remove_constraints (XEXP (part, i));
180         break;
181       case 'E':
182         if (XVEC (part, i) != NULL)
183           for (j = 0; j < XVECLEN (part, i); j++)
184             remove_constraints (XVECEXP (part, i, j));
185         break;
186       }
187 }
188
189 /* Process an include file assuming that it lives in gcc/config/{target}/ 
190    if the include looks like (include "file").  */
191
192 static void
193 process_include (desc, lineno)
194      rtx desc;
195      int lineno;
196 {
197   const char *filename = XSTR (desc, 0);
198   const char *old_filename;
199   int old_lineno;
200   char *pathname;
201   FILE *input_file;
202
203   /* If specified file name is absolute, skip the include stack.  */
204   if (! IS_ABSOLUTE_PATHNAME (filename))
205     {
206       struct file_name_list *stackp;
207
208       /* Search directory path, trying to open the file.  */
209       for (stackp = first_dir_md_include; stackp; stackp = stackp->next)
210         {
211           static const char sep[2] = { DIR_SEPARATOR, '\0' };
212
213           pathname = concat (stackp->fname, sep, filename, NULL);
214           input_file = fopen (pathname, "r");
215           if (input_file != NULL) 
216             goto success;
217           free (pathname);
218         }
219     }
220
221   if (base_dir)
222     pathname = concat (base_dir, filename, NULL);
223   else
224     pathname = xstrdup (filename);
225   input_file = fopen (pathname, "r");
226   if (input_file == NULL)
227     {
228       free (pathname);
229       message_with_line (lineno, "include file `%s' not found", filename);
230       errors = 1;
231       return;
232     }
233  success:
234
235   /* Save old cursor; setup new for the new file.  Note that "lineno" the
236      argument to this function is the beginning of the include statement,
237      while read_rtx_lineno has already been advanced.  */
238   old_filename = read_rtx_filename;
239   old_lineno = read_rtx_lineno;
240   read_rtx_filename = pathname;
241   read_rtx_lineno = 1;
242
243   /* Read the entire file.  */
244   while (1)
245     {
246       rtx desc;
247       int c;
248
249       c = read_skip_spaces (input_file);
250       if (c == EOF)
251         break;
252
253       ungetc (c, input_file);
254       lineno = read_rtx_lineno;
255       desc = read_rtx (input_file);
256       process_rtx (desc, lineno);
257     }
258
259   /* Do not free pathname.  It is attached to the various rtx queue
260      elements.  */
261
262   read_rtx_filename = old_filename;
263   read_rtx_lineno = old_lineno;
264
265   fclose (input_file);
266 }
267
268 /* Process a top level rtx in some way, queueing as appropriate.  */
269
270 static void
271 process_rtx (desc, lineno)
272      rtx desc;
273      int lineno;
274 {
275   switch (GET_CODE (desc))
276     {
277     case DEFINE_INSN:
278       queue_pattern (desc, &define_insn_tail, read_rtx_filename, lineno);
279       break;
280
281     case DEFINE_COND_EXEC:
282       queue_pattern (desc, &define_cond_exec_tail, read_rtx_filename, lineno);
283       break;
284
285     case DEFINE_ATTR:
286       queue_pattern (desc, &define_attr_tail, read_rtx_filename, lineno);
287       break;
288
289     case INCLUDE:
290       process_include (desc, lineno);
291       break;
292
293     case DEFINE_INSN_AND_SPLIT:
294       {
295         const char *split_cond;
296         rtx split;
297         rtvec attr;
298         int i;
299
300         /* Create a split with values from the insn_and_split.  */
301         split = rtx_alloc (DEFINE_SPLIT);
302
303         i = XVECLEN (desc, 1);
304         XVEC (split, 0) = rtvec_alloc (i);
305         while (--i >= 0)
306           {
307             XVECEXP (split, 0, i) = copy_rtx (XVECEXP (desc, 1, i));
308             remove_constraints (XVECEXP (split, 0, i));
309           }
310
311         /* If the split condition starts with "&&", append it to the
312            insn condition to create the new split condition.  */
313         split_cond = XSTR (desc, 4);
314         if (split_cond[0] == '&' && split_cond[1] == '&')
315           split_cond = concat (XSTR (desc, 2), split_cond, NULL);
316         XSTR (split, 1) = split_cond;
317         XVEC (split, 2) = XVEC (desc, 5);
318         XSTR (split, 3) = XSTR (desc, 6);
319
320         /* Fix up the DEFINE_INSN.  */
321         attr = XVEC (desc, 7);
322         PUT_CODE (desc, DEFINE_INSN);
323         XVEC (desc, 4) = attr;
324
325         /* Queue them.  */
326         queue_pattern (desc, &define_insn_tail, read_rtx_filename, lineno);
327         queue_pattern (split, &other_tail, read_rtx_filename, lineno);
328         break;
329       }
330
331     default:
332       queue_pattern (desc, &other_tail, read_rtx_filename, lineno);
333       break;
334     }
335 }
336 \f
337 /* Return true if attribute PREDICABLE is true for ELEM, which holds
338    a DEFINE_INSN.  */
339
340 static int
341 is_predicable (elem)
342      struct queue_elem *elem;
343 {
344   rtvec vec = XVEC (elem->data, 4);
345   const char *value;
346   int i;
347
348   if (! vec)
349     return predicable_default;
350
351   for (i = GET_NUM_ELEM (vec) - 1; i >= 0; --i)
352     {
353       rtx sub = RTVEC_ELT (vec, i);
354       switch (GET_CODE (sub))
355         {
356         case SET_ATTR:
357           if (strcmp (XSTR (sub, 0), "predicable") == 0)
358             {
359               value = XSTR (sub, 1);
360               goto found;
361             }
362           break;
363
364         case SET_ATTR_ALTERNATIVE:
365           if (strcmp (XSTR (sub, 0), "predicable") == 0)
366             {
367               message_with_line (elem->lineno,
368                                  "multiple alternatives for `predicable'");
369               errors = 1;
370               return 0;
371             }
372           break;
373
374         case SET:
375           if (GET_CODE (SET_DEST (sub)) != ATTR
376               || strcmp (XSTR (SET_DEST (sub), 0), "predicable") != 0)
377             break;
378           sub = SET_SRC (sub);
379           if (GET_CODE (sub) == CONST_STRING)
380             {
381               value = XSTR (sub, 0);
382               goto found;
383             }
384
385           /* ??? It would be possible to handle this if we really tried.
386              It's not easy though, and I'm not going to bother until it
387              really proves necessary.  */
388           message_with_line (elem->lineno,
389                              "non-constant value for `predicable'");
390           errors = 1;
391           return 0;
392
393         default:
394           abort ();
395         }
396     }
397
398   return predicable_default;
399
400  found:
401   /* Verify that predicability does not vary on the alternative.  */
402   /* ??? It should be possible to handle this by simply eliminating
403      the non-predicable alternatives from the insn.  FRV would like
404      to do this.  Delay this until we've got the basics solid.  */
405   if (strchr (value, ',') != NULL)
406     {
407       message_with_line (elem->lineno,
408                          "multiple alternatives for `predicable'");
409       errors = 1;
410       return 0;
411     }
412
413   /* Find out which value we're looking at.  */
414   if (strcmp (value, predicable_true) == 0)
415     return 1;
416   if (strcmp (value, predicable_false) == 0)
417     return 0;
418
419   message_with_line (elem->lineno,
420                      "unknown value `%s' for `predicable' attribute",
421                      value);
422   errors = 1;
423   return 0;
424 }
425
426 /* Examine the attribute "predicable"; discover its boolean values
427    and its default.  */
428
429 static void
430 identify_predicable_attribute ()
431 {
432   struct queue_elem *elem;
433   char *p_true, *p_false;
434   const char *value;
435
436   /* Look for the DEFINE_ATTR for `predicable', which must exist.  */
437   for (elem = define_attr_queue; elem ; elem = elem->next)
438     if (strcmp (XSTR (elem->data, 0), "predicable") == 0)
439       goto found;
440
441   message_with_line (define_cond_exec_queue->lineno,
442                      "attribute `predicable' not defined");
443   errors = 1;
444   return;
445
446  found:
447   value = XSTR (elem->data, 1);
448   p_false = xstrdup (value);
449   p_true = strchr (p_false, ',');
450   if (p_true == NULL || strchr (++p_true, ',') != NULL)
451     {
452       message_with_line (elem->lineno,
453                          "attribute `predicable' is not a boolean");
454       errors = 1;
455       return;
456     }
457   p_true[-1] = '\0';
458
459   predicable_true = p_true;
460   predicable_false = p_false;
461
462   switch (GET_CODE (XEXP (elem->data, 2)))
463     {
464     case CONST_STRING:
465       value = XSTR (XEXP (elem->data, 2), 0);
466       break;
467
468     case CONST:
469       message_with_line (elem->lineno,
470                          "attribute `predicable' cannot be const");
471       errors = 1;
472       return;
473
474     default:
475       message_with_line (elem->lineno,
476                          "attribute `predicable' must have a constant default");
477       errors = 1;
478       return;
479     }
480
481   if (strcmp (value, p_true) == 0)
482     predicable_default = 1;
483   else if (strcmp (value, p_false) == 0)
484     predicable_default = 0;
485   else
486     {
487       message_with_line (elem->lineno,
488                          "unknown value `%s' for `predicable' attribute",
489                          value);
490       errors = 1;
491     }
492 }
493
494 /* Return the number of alternatives in constraint S.  */
495
496 static int
497 n_alternatives (s)
498      const char *s;
499 {
500   int n = 1;
501
502   if (s)
503     while (*s)
504       n += (*s++ == ',');
505
506   return n;
507 }
508
509 /* Determine how many alternatives there are in INSN, and how many
510    operands.  */
511
512 static void
513 collect_insn_data (pattern, palt, pmax)
514      rtx pattern;
515      int *palt, *pmax;
516 {
517   const char *fmt;
518   enum rtx_code code;
519   int i, j, len;
520
521   code = GET_CODE (pattern);
522   switch (code)
523     {
524     case MATCH_OPERAND:
525       i = n_alternatives (XSTR (pattern, 2));
526       *palt = (i > *palt ? i : *palt);
527       /* FALLTHRU */
528
529     case MATCH_OPERATOR:
530     case MATCH_SCRATCH:
531     case MATCH_PARALLEL:
532     case MATCH_INSN:
533       i = XINT (pattern, 0);
534       if (i > *pmax)
535         *pmax = i;
536       break;
537
538     default:
539       break;
540     }
541
542   fmt = GET_RTX_FORMAT (code);
543   len = GET_RTX_LENGTH (code);
544   for (i = 0; i < len; i++)
545     {
546       switch (fmt[i])
547         {
548         case 'e': case 'u':
549           collect_insn_data (XEXP (pattern, i), palt, pmax);
550           break;
551
552         case 'V':
553           if (XVEC (pattern, i) == NULL)
554             break;
555           /* FALLTHRU */
556         case 'E':
557           for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
558             collect_insn_data (XVECEXP (pattern, i, j), palt, pmax);
559           break;
560
561         case 'i': case 'w': case '0': case 's': case 'S': case 'T':
562           break;
563
564         default:
565           abort ();
566         }
567     }
568 }
569
570 static rtx
571 alter_predicate_for_insn (pattern, alt, max_op, lineno)
572      rtx pattern;
573      int alt, max_op, lineno;
574 {
575   const char *fmt;
576   enum rtx_code code;
577   int i, j, len;
578
579   code = GET_CODE (pattern);
580   switch (code)
581     {
582     case MATCH_OPERAND:
583       {
584         const char *c = XSTR (pattern, 2);
585
586         if (n_alternatives (c) != 1)
587           {
588             message_with_line (lineno,
589                                "too many alternatives for operand %d",
590                                XINT (pattern, 0));
591             errors = 1;
592             return NULL;
593           }
594
595         /* Replicate C as needed to fill out ALT alternatives.  */
596         if (c && *c && alt > 1)
597           {
598             size_t c_len = strlen (c);
599             size_t len = alt * (c_len + 1);
600             char *new_c = (char *) xmalloc (len);
601
602             memcpy (new_c, c, c_len);
603             for (i = 1; i < alt; ++i)
604               {
605                 new_c[i * (c_len + 1) - 1] = ',';
606                 memcpy (&new_c[i * (c_len + 1)], c, c_len);
607               }
608             new_c[len - 1] = '\0';
609             XSTR (pattern, 2) = new_c;
610           }
611       }
612       /* FALLTHRU */
613
614     case MATCH_OPERATOR:
615     case MATCH_SCRATCH:
616     case MATCH_PARALLEL:
617     case MATCH_INSN:
618       XINT (pattern, 0) += max_op;
619       break;
620
621     default:
622       break;
623     }
624
625   fmt = GET_RTX_FORMAT (code);
626   len = GET_RTX_LENGTH (code);
627   for (i = 0; i < len; i++)
628     {
629       rtx r;
630
631       switch (fmt[i])
632         {
633         case 'e': case 'u':
634           r = alter_predicate_for_insn (XEXP (pattern, i), alt,
635                                         max_op, lineno);
636           if (r == NULL)
637             return r;
638           break;
639
640         case 'E':
641           for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
642             {
643               r = alter_predicate_for_insn (XVECEXP (pattern, i, j),
644                                             alt, max_op, lineno);
645               if (r == NULL)
646                 return r;
647             }
648           break;
649
650         case 'i': case 'w': case '0': case 's':
651           break;
652
653         default:
654           abort ();
655         }
656     }
657
658   return pattern;
659 }
660
661 static const char *
662 alter_test_for_insn (ce_elem, insn_elem)
663      struct queue_elem *ce_elem, *insn_elem;
664 {
665   const char *ce_test, *insn_test;
666
667   ce_test = XSTR (ce_elem->data, 1);
668   insn_test = XSTR (insn_elem->data, 2);
669   if (!ce_test || *ce_test == '\0')
670     return insn_test;
671   if (!insn_test || *insn_test == '\0')
672     return ce_test;
673
674   return concat ("(", ce_test, ") && (", insn_test, ")", NULL);
675 }
676
677 /* Adjust all of the operand numbers in OLD to match the shift they'll
678    get from an operand displacement of DISP.  Return a pointer after the
679    adjusted string.  */
680
681 static char *
682 shift_output_template (new, old, disp)
683      char *new;
684      const char *old;
685      int disp;
686 {
687   while (*old)
688     {
689       char c = *old++;
690       *new++ = c;
691       if (c == '%')
692         {
693           c = *old++;
694           if (ISDIGIT ((unsigned char) c))
695             c += disp;
696           else if (ISALPHA (c))
697             {
698               *new++ = c;
699               c = *old++ + disp;
700             }
701           *new++ = c;
702         }
703     }
704
705   return new;
706 }
707
708 static const char *
709 alter_output_for_insn (ce_elem, insn_elem, alt, max_op)
710      struct queue_elem *ce_elem, *insn_elem;
711      int alt, max_op;
712 {
713   const char *ce_out, *insn_out;
714   char *new, *p;
715   size_t len, ce_len, insn_len;
716
717   /* ??? Could coordinate with genoutput to not duplicate code here.  */
718
719   ce_out = XSTR (ce_elem->data, 2);
720   insn_out = XTMPL (insn_elem->data, 3);
721   if (!ce_out || *ce_out == '\0')
722     return insn_out;
723
724   ce_len = strlen (ce_out);
725   insn_len = strlen (insn_out);
726
727   if (*insn_out == '*')
728     /* You must take care of the predicate yourself.  */
729     return insn_out;
730
731   if (*insn_out == '@')
732     {
733       len = (ce_len + 1) * alt + insn_len + 1;
734       p = new = xmalloc (len);
735
736       do
737         {
738           do
739             *p++ = *insn_out++;
740           while (ISSPACE ((unsigned char) *insn_out));
741
742           if (*insn_out != '#')
743             {
744               p = shift_output_template (p, ce_out, max_op);
745               *p++ = ' ';
746             }
747
748           do
749             *p++ = *insn_out++;
750           while (*insn_out && *insn_out != '\n');
751         }
752       while (*insn_out);
753       *p = '\0';
754     }
755   else
756     {
757       len = ce_len + 1 + insn_len + 1;
758       new = xmalloc (len);
759
760       p = shift_output_template (new, ce_out, max_op);
761       *p++ = ' ';
762       memcpy (p, insn_out, insn_len + 1);
763     }
764
765   return new;
766 }
767
768 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC.  */
769
770 static void
771 process_one_cond_exec (ce_elem)
772      struct queue_elem *ce_elem;
773 {
774   struct queue_elem *insn_elem;
775   for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
776     {
777       int alternatives, max_operand;
778       rtx pred, insn, pattern;
779
780       if (! is_predicable (insn_elem))
781         continue;
782
783       alternatives = 1;
784       max_operand = -1;
785       collect_insn_data (insn_elem->data, &alternatives, &max_operand);
786       max_operand += 1;
787
788       if (XVECLEN (ce_elem->data, 0) != 1)
789         {
790           message_with_line (ce_elem->lineno,
791                              "too many patterns in predicate");
792           errors = 1;
793           return;
794         }
795
796       pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0));
797       pred = alter_predicate_for_insn (pred, alternatives, max_operand,
798                                        ce_elem->lineno);
799       if (pred == NULL)
800         return;
801
802       /* Construct a new pattern for the new insn.  */
803       insn = copy_rtx (insn_elem->data);
804       XSTR (insn, 0) = "";
805       pattern = rtx_alloc (COND_EXEC);
806       XEXP (pattern, 0) = pred;
807       if (XVECLEN (insn, 1) == 1)
808         {
809           XEXP (pattern, 1) = XVECEXP (insn, 1, 0);
810           XVECEXP (insn, 1, 0) = pattern;
811           PUT_NUM_ELEM (XVEC (insn, 1), 1);
812         }
813       else
814         {
815           XEXP (pattern, 1) = rtx_alloc (PARALLEL);
816           XVEC (XEXP (pattern, 1), 0) = XVEC (insn, 1);
817           XVEC (insn, 1) = rtvec_alloc (1);
818           XVECEXP (insn, 1, 0) = pattern;
819         }
820
821       XSTR (insn, 2) = alter_test_for_insn (ce_elem, insn_elem);
822       XTMPL (insn, 3) = alter_output_for_insn (ce_elem, insn_elem,
823                                               alternatives, max_operand);
824
825       /* ??? Set `predicable' to false.  Not crucial since it's really
826          only used here, and we won't reprocess this new pattern.  */
827
828       /* Put the new pattern on the `other' list so that it
829          (a) is not reprocessed by other define_cond_exec patterns
830          (b) appears after all normal define_insn patterns.
831
832          ??? B is debatable.  If one has normal insns that match
833          cond_exec patterns, they will be preferred over these
834          generated patterns.  Whether this matters in practice, or if
835          it's a good thing, or whether we should thread these new
836          patterns into the define_insn chain just after their generator
837          is something we'll have to experiment with.  */
838
839       queue_pattern (insn, &other_tail, insn_elem->filename,
840                      insn_elem->lineno);
841     }
842 }
843
844 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
845    patterns appropriately.  */
846
847 static void
848 process_define_cond_exec ()
849 {
850   struct queue_elem *elem;
851
852   identify_predicable_attribute ();
853   if (errors)
854     return;
855
856   for (elem = define_cond_exec_queue; elem ; elem = elem->next)
857     process_one_cond_exec (elem);
858 }
859
860 static char *
861 save_string (s, len)
862      const char *s;
863      int len;
864 {
865   register char *result = xmalloc (len + 1);
866
867   memcpy (result, s, len);
868   result[len] = 0;
869   return result;
870 }
871
872 \f
873 /* The entry point for initializing the reader.  */
874
875 int
876 init_md_reader_args (argc, argv)
877      int argc;
878      char **argv;
879 {
880   int i;
881   const char *in_fname;
882
883   max_include_len = 0;
884   in_fname = NULL;
885   for (i = 1; i < argc; i++)
886     {
887       if (argv[i][0] != '-')
888         {
889           if (in_fname == NULL)
890             in_fname = argv[i];
891         }
892       else
893         {
894           int c = argv[i][1];
895           switch (c)
896             {
897             case 'I':           /* Add directory to path for includes.  */
898               {
899                 struct file_name_list *dirtmp;
900
901                 dirtmp = (struct file_name_list *)
902                   xmalloc (sizeof (struct file_name_list));
903                 dirtmp->next = 0;       /* New one goes on the end */
904                 if (first_dir_md_include == 0)
905                   first_dir_md_include = dirtmp;
906                 else
907                   last_dir_md_include->next = dirtmp;
908                 last_dir_md_include = dirtmp;   /* Tail follows the last one */
909                 if (argv[i][1] == 'I' && argv[i][2] != 0)
910                   dirtmp->fname = argv[i] + 2;
911                 else if (i + 1 == argc)
912                   fatal ("directory name missing after -I option");
913                 else
914                   dirtmp->fname = argv[++i];
915                 if (strlen (dirtmp->fname) > max_include_len)
916                   max_include_len = strlen (dirtmp->fname);
917               }
918               break;
919             default:
920               fatal ("invalid option `%s'", argv[i]);
921
922             }
923         }
924     }
925     return init_md_reader (in_fname);
926 }
927 \f
928 /* The entry point for initializing the reader.  */
929
930 int
931 init_md_reader (filename)
932      const char *filename;
933 {
934   FILE *input_file;
935   int c;
936   size_t i;
937   char *lastsl;
938
939   lastsl = strrchr (filename, '/');
940   if (lastsl != NULL) 
941     base_dir = save_string (filename, lastsl - filename + 1 );
942
943   read_rtx_filename = filename;
944   input_file = fopen (filename, "r");
945   if (input_file == 0)
946     {
947       perror (filename);
948       return FATAL_EXIT_CODE;
949     }
950
951   /* Initialize the table of insn conditions.  */
952   condition_table = htab_create (n_insn_conditions,
953                                  hash_c_test, cmp_c_test, NULL);
954
955   for (i = 0; i < n_insn_conditions; i++)
956     *(htab_find_slot (condition_table, (PTR) &insn_conditions[i], INSERT))
957       = (PTR) &insn_conditions[i];
958
959   obstack_init (rtl_obstack);
960   errors = 0;
961   sequence_num = 0;
962
963   /* Read the entire file.  */
964   while (1)
965     {
966       rtx desc;
967       int lineno;
968
969       c = read_skip_spaces (input_file);
970       if (c == EOF)
971         break;
972
973       ungetc (c, input_file);
974       lineno = read_rtx_lineno;
975       desc = read_rtx (input_file);
976       process_rtx (desc, lineno);
977     }
978   fclose (input_file);
979
980   /* Process define_cond_exec patterns.  */
981   if (define_cond_exec_queue != NULL)
982     process_define_cond_exec ();
983
984   return errors ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
985 }
986
987 /* The entry point for reading a single rtx from an md file.  */
988
989 rtx
990 read_md_rtx (lineno, seqnr)
991      int *lineno;
992      int *seqnr;
993 {
994   struct queue_elem **queue, *elem;
995   rtx desc;
996
997  discard:
998
999   /* Read all patterns from a given queue before moving on to the next.  */
1000   if (define_attr_queue != NULL)
1001     queue = &define_attr_queue;
1002   else if (define_insn_queue != NULL)
1003     queue = &define_insn_queue;
1004   else if (other_queue != NULL)
1005     queue = &other_queue;
1006   else
1007     return NULL_RTX;
1008
1009   elem = *queue;
1010   *queue = elem->next;
1011   desc = elem->data;
1012   read_rtx_filename = elem->filename;
1013   *lineno = elem->lineno;
1014   *seqnr = sequence_num;
1015
1016   free (elem);
1017
1018   /* Discard insn patterns which we know can never match (because
1019      their C test is provably always false).  If insn_elision is
1020      false, our caller needs to see all the patterns.  Note that the
1021      elided patterns are never counted by the sequence numbering; it
1022      it is the caller's responsibility, when insn_elision is false, not
1023      to use elided pattern numbers for anything.  */
1024   switch (GET_CODE (desc))
1025     {
1026     case DEFINE_INSN:
1027     case DEFINE_EXPAND:
1028       if (maybe_eval_c_test (XSTR (desc, 2)) != 0)
1029         sequence_num++;
1030       else if (insn_elision)
1031         goto discard;
1032       break;
1033
1034     case DEFINE_SPLIT:
1035     case DEFINE_PEEPHOLE:
1036     case DEFINE_PEEPHOLE2:
1037       if (maybe_eval_c_test (XSTR (desc, 1)) != 0)
1038         sequence_num++;
1039       else if (insn_elision)
1040             goto discard;
1041       break;
1042
1043     default:
1044       break;
1045     }
1046
1047   return desc;
1048 }
1049
1050 /* Helper functions for insn elision.  */
1051
1052 /* Compute a hash function of a c_test structure, which is keyed
1053    by its ->expr field.  */
1054 hashval_t
1055 hash_c_test (x)
1056      const PTR x;
1057 {
1058   const struct c_test *a = (const struct c_test *) x;
1059   const unsigned char *base, *s = (const unsigned char *) a->expr;
1060   hashval_t hash;
1061   unsigned char c;
1062   unsigned int len;
1063
1064   base = s;
1065   hash = 0;
1066
1067   while ((c = *s++) != '\0')
1068     {
1069       hash += c + (c << 17);
1070       hash ^= hash >> 2;
1071     }
1072
1073   len = s - base;
1074   hash += len + (len << 17);
1075   hash ^= hash >> 2;
1076
1077   return hash;
1078 }
1079
1080 /* Compare two c_test expression structures.  */
1081 int
1082 cmp_c_test (x, y)
1083      const PTR x;
1084      const PTR y;
1085 {
1086   const struct c_test *a = (const struct c_test *) x;
1087   const struct c_test *b = (const struct c_test *) y;
1088
1089   return !strcmp (a->expr, b->expr);
1090 }
1091
1092 /* Given a string representing a C test expression, look it up in the
1093    condition_table and report whether or not its value is known
1094    at compile time.  Returns a tristate: 1 for known true, 0 for
1095    known false, -1 for unknown.  */
1096 int
1097 maybe_eval_c_test (expr)
1098      const char *expr;
1099 {
1100   const struct c_test *test;
1101   struct c_test dummy;
1102
1103   if (expr[0] == 0)
1104     return 1;
1105
1106   if (insn_elision_unavailable)
1107     return -1;
1108
1109   dummy.expr = expr;
1110   test = (const struct c_test *) htab_find (condition_table, &dummy);
1111   if (!test)
1112     abort ();
1113
1114   return test->value;
1115 }
1116
1117 /* Given a string, return the number of comma-separated elements in it.
1118    Return 0 for the null string.  */
1119 int
1120 n_comma_elts (s)
1121      const char *s;
1122 {
1123   int n;
1124
1125   if (*s == '\0')
1126     return 0;
1127
1128   for (n = 1; *s; s++)
1129     if (*s == ',')
1130       n++;
1131
1132   return n;
1133 }
1134
1135 /* Given a pointer to a (char *), return a pointer to the beginning of the
1136    next comma-separated element in the string.  Advance the pointer given
1137    to the end of that element.  Return NULL if at end of string.  Caller
1138    is responsible for copying the string if necessary.  White space between
1139    a comma and an element is ignored.  */
1140
1141 const char *
1142 scan_comma_elt (pstr)
1143      const char **pstr;
1144 {
1145   const char *start;
1146   const char *p = *pstr;
1147
1148   if (*p == ',')
1149     p++;
1150   while (ISSPACE(*p))
1151     p++;
1152
1153   if (*p == '\0')
1154     return NULL;
1155
1156   start = p;
1157
1158   while (*p != ',' && *p != '\0')
1159     p++;
1160
1161   *pstr = p;
1162   return start;
1163 }