OSDN Git Service

* ifcvt.c (noce_get_alt_condition): Use reg_overlap_mentioned_p.
[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 "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"
28
29
30 /* In case some macros used by files we include need it, define this here.  */
31 int target_flags;
32
33 int insn_elision = 1;
34
35 static struct obstack obstack;
36 struct obstack *rtl_obstack = &obstack;
37
38 static int sequence_num;
39 static int errors;
40
41 static int predicable_default;
42 static const char *predicable_true;
43 static const char *predicable_false;
44
45 static htab_t condition_table;
46
47 static char *base_dir = NULL;
48
49 /* We initially queue all patterns, process the define_insn and
50    define_cond_exec patterns, then return them one at a time.  */
51
52 struct queue_elem
53 {
54   rtx data;
55   const char *filename;
56   int lineno;
57   struct queue_elem *next;
58 };
59
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;
68
69 static void queue_pattern PARAMS ((rtx, struct queue_elem ***,
70                                    const char *, int));
71
72 /* Current maximum length of directory names in the search path
73    for include files.  (Altered as we get more of them.)  */
74
75 size_t max_include_len;
76
77 struct file_name_list
78   {
79     struct file_name_list *next;
80     const char *fname;
81   };
82
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 */
87
88 static void remove_constraints PARAMS ((rtx));
89 static void process_rtx PARAMS ((rtx, int));
90
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));
106 \f
107 void
108 message_with_line VPARAMS ((int lineno, const char *msg, ...))
109 {
110   VA_OPEN (ap, msg);
111   VA_FIXEDARG (ap, int, lineno);
112   VA_FIXEDARG (ap, const char *, msg);
113
114   fprintf (stderr, "%s:%d: ", read_rtx_filename, lineno);
115   vfprintf (stderr, msg, ap);
116   fputc ('\n', stderr);
117
118   VA_CLOSE (ap);
119 }
120
121 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
122    the gensupport programs.  */
123
124 rtx
125 gen_rtx_CONST_INT (mode, arg)
126      enum machine_mode mode ATTRIBUTE_UNUSED;
127      HOST_WIDE_INT arg;
128 {
129   rtx rt = rtx_alloc (CONST_INT);
130
131   XWINT (rt, 0) = arg;
132   return rt;
133 }
134 \f
135 /* Queue PATTERN on LIST_TAIL.  */
136
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;
143 {
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;
151 }
152
153 /* Recursively remove constraints from an rtx.  */
154
155 static void
156 remove_constraints (part)
157      rtx part;
158 {
159   int i, j;
160   const char *format_ptr;
161
162   if (part == 0)
163     return;
164
165   if (GET_CODE (part) == MATCH_OPERAND)
166     XSTR (part, 2) = "";
167   else if (GET_CODE (part) == MATCH_SCRATCH)
168     XSTR (part, 1) = "";
169
170   format_ptr = GET_RTX_FORMAT (GET_CODE (part));
171
172   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
173     switch (*format_ptr++)
174       {
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;
184       }
185 }
186
187 /* Process an include file assuming that it lives in gcc/config/{target}/ 
188    if the include looks like (include "file").  */
189
190 static void
191 process_include (desc, lineno)
192      rtx desc;
193      int lineno;
194 {
195   const char *filename = XSTR (desc, 0);
196   const char *old_filename;
197   int old_lineno;
198   char *pathname;
199   FILE *input_file;
200
201   /* If specified file name is absolute, skip the include stack.  */
202   if (! IS_ABSOLUTE_PATHNAME (filename))
203     {
204       struct file_name_list *stackp;
205
206       /* Search directory path, trying to open the file.  */
207       for (stackp = first_dir_md_include; stackp; stackp = stackp->next)
208         {
209           static const char sep[2] = { DIR_SEPARATOR, '\0' };
210
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);
216         }
217     }
218
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)
225     {
226       free (pathname);
227       message_with_line (lineno, "include file `%s' not found", filename);
228       errors = 1;
229       return;
230     }
231  success:
232
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;
240
241   /* Read the entire file.  */
242   while (1)
243     {
244       rtx desc;
245       int c;
246
247       c = read_skip_spaces (input_file);
248       if (c == EOF)
249         break;
250
251       ungetc (c, input_file);
252       lineno = read_rtx_lineno;
253       desc = read_rtx (input_file);
254       process_rtx (desc, lineno);
255     }
256
257   /* Do not free pathname.  It is attached to the various rtx queue
258      elements.  */
259
260   read_rtx_filename = old_filename;
261   read_rtx_lineno = old_lineno;
262
263   fclose (input_file);
264 }
265
266 /* Process a top level rtx in some way, queueing as appropriate.  */
267
268 static void
269 process_rtx (desc, lineno)
270      rtx desc;
271      int lineno;
272 {
273   switch (GET_CODE (desc))
274     {
275     case DEFINE_INSN:
276       queue_pattern (desc, &define_insn_tail, read_rtx_filename, lineno);
277       break;
278
279     case DEFINE_COND_EXEC:
280       queue_pattern (desc, &define_cond_exec_tail, read_rtx_filename, lineno);
281       break;
282
283     case DEFINE_ATTR:
284       queue_pattern (desc, &define_attr_tail, read_rtx_filename, lineno);
285       break;
286
287     case INCLUDE:
288       process_include (desc, lineno);
289       break;
290
291     case DEFINE_INSN_AND_SPLIT:
292       {
293         const char *split_cond;
294         rtx split;
295         rtvec attr;
296         int i;
297
298         /* Create a split with values from the insn_and_split.  */
299         split = rtx_alloc (DEFINE_SPLIT);
300
301         i = XVECLEN (desc, 1);
302         XVEC (split, 0) = rtvec_alloc (i);
303         while (--i >= 0)
304           {
305             XVECEXP (split, 0, i) = copy_rtx (XVECEXP (desc, 1, i));
306             remove_constraints (XVECEXP (split, 0, i));
307           }
308
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);
317
318         /* Fix up the DEFINE_INSN.  */
319         attr = XVEC (desc, 7);
320         PUT_CODE (desc, DEFINE_INSN);
321         XVEC (desc, 4) = attr;
322
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;
327       }
328
329     default:
330       queue_pattern (desc, &other_tail, read_rtx_filename, lineno);
331       break;
332     }
333 }
334 \f
335 /* Return true if attribute PREDICABLE is true for ELEM, which holds
336    a DEFINE_INSN.  */
337
338 static int
339 is_predicable (elem)
340      struct queue_elem *elem;
341 {
342   rtvec vec = XVEC (elem->data, 4);
343   const char *value;
344   int i;
345
346   if (! vec)
347     return predicable_default;
348
349   for (i = GET_NUM_ELEM (vec) - 1; i >= 0; --i)
350     {
351       rtx sub = RTVEC_ELT (vec, i);
352       switch (GET_CODE (sub))
353         {
354         case SET_ATTR:
355           if (strcmp (XSTR (sub, 0), "predicable") == 0)
356             {
357               value = XSTR (sub, 1);
358               goto found;
359             }
360           break;
361
362         case SET_ATTR_ALTERNATIVE:
363           if (strcmp (XSTR (sub, 0), "predicable") == 0)
364             {
365               message_with_line (elem->lineno,
366                                  "multiple alternatives for `predicable'");
367               errors = 1;
368               return 0;
369             }
370           break;
371
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)
378             {
379               value = XSTR (sub, 0);
380               goto found;
381             }
382
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;
390
391         default:
392           abort ();
393         }
394     }
395
396   return predicable_default;
397
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)
404     {
405       message_with_line (elem->lineno,
406                          "multiple alternatives for `predicable'");
407       errors = 1;
408       return 0;
409     }
410
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;
416
417   message_with_line (elem->lineno,
418                      "unknown value `%s' for `predicable' attribute",
419                      value);
420   errors = 1;
421   return 0;
422 }
423
424 /* Examine the attribute "predicable"; discover its boolean values
425    and its default.  */
426
427 static void
428 identify_predicable_attribute ()
429 {
430   struct queue_elem *elem;
431   char *p_true, *p_false;
432   const char *value;
433
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;
438
439   message_with_line (define_cond_exec_queue->lineno,
440                      "attribute `predicable' not defined");
441   errors = 1;
442   return;
443
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)
449     {
450       message_with_line (elem->lineno,
451                          "attribute `predicable' is not a boolean");
452       errors = 1;
453       return;
454     }
455   p_true[-1] = '\0';
456
457   predicable_true = p_true;
458   predicable_false = p_false;
459
460   switch (GET_CODE (XEXP (elem->data, 2)))
461     {
462     case CONST_STRING:
463       value = XSTR (XEXP (elem->data, 2), 0);
464       break;
465
466     case CONST:
467       message_with_line (elem->lineno,
468                          "attribute `predicable' cannot be const");
469       errors = 1;
470       return;
471
472     default:
473       message_with_line (elem->lineno,
474                          "attribute `predicable' must have a constant default");
475       errors = 1;
476       return;
477     }
478
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
484     {
485       message_with_line (elem->lineno,
486                          "unknown value `%s' for `predicable' attribute",
487                          value);
488       errors = 1;
489     }
490 }
491
492 /* Return the number of alternatives in constraint S.  */
493
494 static int
495 n_alternatives (s)
496      const char *s;
497 {
498   int n = 1;
499
500   if (s)
501     while (*s)
502       n += (*s++ == ',');
503
504   return n;
505 }
506
507 /* Determine how many alternatives there are in INSN, and how many
508    operands.  */
509
510 static void
511 collect_insn_data (pattern, palt, pmax)
512      rtx pattern;
513      int *palt, *pmax;
514 {
515   const char *fmt;
516   enum rtx_code code;
517   int i, j, len;
518
519   code = GET_CODE (pattern);
520   switch (code)
521     {
522     case MATCH_OPERAND:
523       i = n_alternatives (XSTR (pattern, 2));
524       *palt = (i > *palt ? i : *palt);
525       /* FALLTHRU */
526
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;
535
536     default:
537       break;
538     }
539
540   fmt = GET_RTX_FORMAT (code);
541   len = GET_RTX_LENGTH (code);
542   for (i = 0; i < len; i++)
543     {
544       switch (fmt[i])
545         {
546         case 'e': case 'u':
547           collect_insn_data (XEXP (pattern, i), palt, pmax);
548           break;
549
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;
558
559         case 'i': case 'w': case '0': case 's': case 'S': case 'T':
560           break;
561
562         default:
563           abort ();
564         }
565     }
566 }
567
568 static rtx
569 alter_predicate_for_insn (pattern, alt, max_op, lineno)
570      rtx pattern;
571      int alt, max_op, lineno;
572 {
573   const char *fmt;
574   enum rtx_code code;
575   int i, j, len;
576
577   code = GET_CODE (pattern);
578   switch (code)
579     {
580     case MATCH_OPERAND:
581       {
582         const char *c = XSTR (pattern, 2);
583
584         if (n_alternatives (c) != 1)
585           {
586             message_with_line (lineno,
587                                "too many alternatives for operand %d",
588                                XINT (pattern, 0));
589             errors = 1;
590             return NULL;
591           }
592
593         /* Replicate C as needed to fill out ALT alternatives.  */
594         if (c && *c && alt > 1)
595           {
596             size_t c_len = strlen (c);
597             size_t len = alt * (c_len + 1);
598             char *new_c = (char *) xmalloc (len);
599
600             memcpy (new_c, c, c_len);
601             for (i = 1; i < alt; ++i)
602               {
603                 new_c[i * (c_len + 1) - 1] = ',';
604                 memcpy (&new_c[i * (c_len + 1)], c, c_len);
605               }
606             new_c[len - 1] = '\0';
607             XSTR (pattern, 2) = new_c;
608           }
609       }
610       /* FALLTHRU */
611
612     case MATCH_OPERATOR:
613     case MATCH_SCRATCH:
614     case MATCH_PARALLEL:
615     case MATCH_INSN:
616       XINT (pattern, 0) += max_op;
617       break;
618
619     default:
620       break;
621     }
622
623   fmt = GET_RTX_FORMAT (code);
624   len = GET_RTX_LENGTH (code);
625   for (i = 0; i < len; i++)
626     {
627       rtx r;
628
629       switch (fmt[i])
630         {
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;
637
638         case 'E':
639           for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
640             {
641               r = alter_predicate_for_insn (XVECEXP (pattern, i, j),
642                                             alt, max_op, lineno);
643               if (r == NULL)
644                 return r;
645             }
646           break;
647
648         case 'i': case 'w': case '0': case 's':
649           break;
650
651         default:
652           abort ();
653         }
654     }
655
656   return pattern;
657 }
658
659 static const char *
660 alter_test_for_insn (ce_elem, insn_elem)
661      struct queue_elem *ce_elem, *insn_elem;
662 {
663   const char *ce_test, *insn_test;
664
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;
671
672   return concat ("(", ce_test, ") && (", insn_test, ")", NULL);
673 }
674
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.  */
678
679 static char *
680 shift_output_template (new, old, disp)
681      char *new;
682      const char *old;
683      int disp;
684 {
685   while (*old)
686     {
687       char c = *old++;
688       *new++ = c;
689       if (c == '%')
690         {
691           c = *old++;
692           if (ISDIGIT ((unsigned char) c))
693             c += disp;
694           else if (ISALPHA (c))
695             {
696               *new++ = c;
697               c = *old++ + disp;
698             }
699           *new++ = c;
700         }
701     }
702
703   return new;
704 }
705
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;
710 {
711   const char *ce_out, *insn_out;
712   char *new, *p;
713   size_t len, ce_len, insn_len;
714
715   /* ??? Could coordinate with genoutput to not duplicate code here.  */
716
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;
721
722   ce_len = strlen (ce_out);
723   insn_len = strlen (insn_out);
724
725   if (*insn_out == '*')
726     /* You must take care of the predicate yourself.  */
727     return insn_out;
728
729   if (*insn_out == '@')
730     {
731       len = (ce_len + 1) * alt + insn_len + 1;
732       p = new = xmalloc (len);
733
734       do
735         {
736           do
737             *p++ = *insn_out++;
738           while (ISSPACE ((unsigned char) *insn_out));
739
740           if (*insn_out != '#')
741             {
742               p = shift_output_template (p, ce_out, max_op);
743               *p++ = ' ';
744             }
745
746           do
747             *p++ = *insn_out++;
748           while (*insn_out && *insn_out != '\n');
749         }
750       while (*insn_out);
751       *p = '\0';
752     }
753   else
754     {
755       len = ce_len + 1 + insn_len + 1;
756       new = xmalloc (len);
757
758       p = shift_output_template (new, ce_out, max_op);
759       *p++ = ' ';
760       memcpy (p, insn_out, insn_len + 1);
761     }
762
763   return new;
764 }
765
766 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC.  */
767
768 static void
769 process_one_cond_exec (ce_elem)
770      struct queue_elem *ce_elem;
771 {
772   struct queue_elem *insn_elem;
773   for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
774     {
775       int alternatives, max_operand;
776       rtx pred, insn, pattern;
777
778       if (! is_predicable (insn_elem))
779         continue;
780
781       alternatives = 1;
782       max_operand = -1;
783       collect_insn_data (insn_elem->data, &alternatives, &max_operand);
784       max_operand += 1;
785
786       if (XVECLEN (ce_elem->data, 0) != 1)
787         {
788           message_with_line (ce_elem->lineno,
789                              "too many patterns in predicate");
790           errors = 1;
791           return;
792         }
793
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;
799
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)
806         {
807           XEXP (pattern, 1) = XVECEXP (insn, 1, 0);
808           XVECEXP (insn, 1, 0) = pattern;
809           PUT_NUM_ELEM (XVEC (insn, 1), 1);
810         }
811       else
812         {
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;
817         }
818
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);
822
823       /* ??? Set `predicable' to false.  Not crucial since it's really
824          only used here, and we won't reprocess this new pattern.  */
825
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.
829
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.  */
836
837       queue_pattern (insn, &other_tail, insn_elem->filename,
838                      insn_elem->lineno);
839     }
840 }
841
842 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
843    patterns appropriately.  */
844
845 static void
846 process_define_cond_exec ()
847 {
848   struct queue_elem *elem;
849
850   identify_predicable_attribute ();
851   if (errors)
852     return;
853
854   for (elem = define_cond_exec_queue; elem ; elem = elem->next)
855     process_one_cond_exec (elem);
856 }
857
858 static char *
859 save_string (s, len)
860      const char *s;
861      int len;
862 {
863   register char *result = xmalloc (len + 1);
864
865   memcpy (result, s, len);
866   result[len] = 0;
867   return result;
868 }
869
870 \f
871 /* The entry point for initializing the reader.  */
872
873 int
874 init_md_reader_args (argc, argv)
875      int argc;
876      char **argv;
877 {
878   int i;
879   const char *in_fname;
880
881   max_include_len = 0;
882   in_fname = NULL;
883   for (i = 1; i < argc; i++)
884     {
885       if (argv[i][0] != '-')
886         {
887           if (in_fname == NULL)
888             in_fname = argv[i];
889         }
890       else
891         {
892           int c = argv[i][1];
893           switch (c)
894             {
895             case 'I':           /* Add directory to path for includes.  */
896               {
897                 struct file_name_list *dirtmp;
898
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);
915               }
916               break;
917             default:
918               fatal ("invalid option `%s'", argv[i]);
919
920             }
921         }
922     }
923     return init_md_reader (in_fname);
924 }
925 \f
926 /* The entry point for initializing the reader.  */
927
928 int
929 init_md_reader (filename)
930      const char *filename;
931 {
932   FILE *input_file;
933   int c;
934   size_t i;
935   char *lastsl;
936
937   lastsl = strrchr (filename, '/');
938   if (lastsl != NULL) 
939     base_dir = save_string (filename, lastsl - filename + 1 );
940
941   read_rtx_filename = filename;
942   input_file = fopen (filename, "r");
943   if (input_file == 0)
944     {
945       perror (filename);
946       return FATAL_EXIT_CODE;
947     }
948
949   /* Initialize the table of insn conditions.  */
950   condition_table = htab_create (n_insn_conditions,
951                                  hash_c_test, cmp_c_test, NULL);
952
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];
956
957   obstack_init (rtl_obstack);
958   errors = 0;
959   sequence_num = 0;
960
961   /* Read the entire file.  */
962   while (1)
963     {
964       rtx desc;
965       int lineno;
966
967       c = read_skip_spaces (input_file);
968       if (c == EOF)
969         break;
970
971       ungetc (c, input_file);
972       lineno = read_rtx_lineno;
973       desc = read_rtx (input_file);
974       process_rtx (desc, lineno);
975     }
976   fclose (input_file);
977
978   /* Process define_cond_exec patterns.  */
979   if (define_cond_exec_queue != NULL)
980     process_define_cond_exec ();
981
982   return errors ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
983 }
984
985 /* The entry point for reading a single rtx from an md file.  */
986
987 rtx
988 read_md_rtx (lineno, seqnr)
989      int *lineno;
990      int *seqnr;
991 {
992   struct queue_elem **queue, *elem;
993   rtx desc;
994
995  discard:
996
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;
1006
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;
1013
1014   free (elem);
1015
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))
1023     {
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;
1031
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;
1040
1041     default:
1042       break;
1043     }
1044
1045   return desc;
1046 }
1047
1048 /* Helper functions for insn elision.  */
1049
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;
1055 {
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;
1061
1062   base = s;
1063   hash = 0;
1064
1065   while ((c = *s++) != '\0')
1066     {
1067       hash += c + (c << 17);
1068       hash ^= hash >> 2;
1069     }
1070
1071   len = s - base;
1072   hash += len + (len << 17);
1073   hash ^= hash >> 2;
1074
1075   return hash;
1076 }
1077
1078 /* Compare two c_test expression structures.  */
1079 int
1080 cmp_c_test (x, y)
1081      const PTR x;
1082      const PTR y;
1083 {
1084   const struct c_test *a = (const struct c_test *) x;
1085   const struct c_test *b = (const struct c_test *) y;
1086
1087   return !strcmp (a->expr, b->expr);
1088 }
1089
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.  */
1094 int
1095 maybe_eval_c_test (expr)
1096      const char *expr;
1097 {
1098   const struct c_test *test;
1099   struct c_test dummy;
1100
1101   if (expr[0] == 0)
1102     return 1;
1103
1104   if (insn_elision_unavailable)
1105     return -1;
1106
1107   dummy.expr = expr;
1108   test = (const struct c_test *) htab_find (condition_table, &dummy);
1109   if (!test)
1110     abort ();
1111
1112   return test->value;
1113 }
1114
1115 /* Given a string, return the number of comma-separated elements in it.
1116    Return 0 for the null string.  */
1117 int
1118 n_comma_elts (s)
1119      const char *s;
1120 {
1121   int n;
1122
1123   if (*s == '\0')
1124     return 0;
1125
1126   for (n = 1; *s; s++)
1127     if (*s == ',')
1128       n++;
1129
1130   return n;
1131 }
1132
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.  */
1138
1139 const char *
1140 scan_comma_elt (pstr)
1141      const char **pstr;
1142 {
1143   const char *start;
1144   const char *p = *pstr;
1145
1146   if (*p == ',')
1147     p++;
1148   while (ISSPACE(*p))
1149     p++;
1150
1151   if (*p == '\0')
1152     return NULL;
1153
1154   start = p;
1155
1156   while (*p != ',' && *p != '\0')
1157     p++;
1158
1159   *pstr = p;
1160   return start;
1161 }