OSDN Git Service

* inclhack.def: Avoid changing NULL on C++ friendly systems.
[pf3gnuchains/gcc-fork.git] / gcc / gensupport.c
1 /* Support routines for the various generation passes.
2    Copyright (C) 2000, 2001, 2002, 2003, 2004
3    Free Software Foundation, Inc.
4
5    This file is part of GCC.
6
7    GCC is free software; you can redistribute it and/or modify it
8    under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2, or (at your option)
10    any later version.
11
12    GCC is distributed in the hope that it will be useful, but WITHOUT
13    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15    License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GCC; see the file COPYING.  If not, write to the Free
19    Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20    02111-1307, USA.  */
21
22 #include "bconfig.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "rtl.h"
27 #include "obstack.h"
28 #include "errors.h"
29 #include "hashtab.h"
30 #include "gensupport.h"
31
32
33 /* In case some macros used by files we include need it, define this here.  */
34 int target_flags;
35
36 int insn_elision = 1;
37
38 const char *in_fname;
39
40 static struct obstack obstack;
41 struct obstack *rtl_obstack = &obstack;
42
43 static int sequence_num;
44 static int errors;
45
46 static int predicable_default;
47 static const char *predicable_true;
48 static const char *predicable_false;
49
50 static htab_t condition_table;
51
52 static char *base_dir = NULL;
53
54 /* We initially queue all patterns, process the define_insn and
55    define_cond_exec patterns, then return them one at a time.  */
56
57 struct queue_elem
58 {
59   rtx data;
60   const char *filename;
61   int lineno;
62   struct queue_elem *next;
63   /* In a DEFINE_INSN that came from a DEFINE_INSN_AND_SPLIT, SPLIT
64      points to the generated DEFINE_SPLIT.  */
65   struct queue_elem *split;
66 };
67
68 static struct queue_elem *define_attr_queue;
69 static struct queue_elem **define_attr_tail = &define_attr_queue;
70 static struct queue_elem *define_pred_queue;
71 static struct queue_elem **define_pred_tail = &define_pred_queue;
72 static struct queue_elem *define_insn_queue;
73 static struct queue_elem **define_insn_tail = &define_insn_queue;
74 static struct queue_elem *define_cond_exec_queue;
75 static struct queue_elem **define_cond_exec_tail = &define_cond_exec_queue;
76 static struct queue_elem *other_queue;
77 static struct queue_elem **other_tail = &other_queue;
78
79 static struct queue_elem *queue_pattern (rtx, struct queue_elem ***,
80                                          const char *, int);
81
82 /* Current maximum length of directory names in the search path
83    for include files.  (Altered as we get more of them.)  */
84
85 size_t max_include_len;
86
87 struct file_name_list
88   {
89     struct file_name_list *next;
90     const char *fname;
91   };
92
93 struct file_name_list *first_dir_md_include = 0;  /* First dir to search */
94         /* First dir to search for <file> */
95 struct file_name_list *first_bracket_include = 0;
96 struct file_name_list *last_dir_md_include = 0;        /* Last in chain */
97
98 static void remove_constraints (rtx);
99 static void process_rtx (rtx, int);
100
101 static int is_predicable (struct queue_elem *);
102 static void identify_predicable_attribute (void);
103 static int n_alternatives (const char *);
104 static void collect_insn_data (rtx, int *, int *);
105 static rtx alter_predicate_for_insn (rtx, int, int, int);
106 static const char *alter_test_for_insn (struct queue_elem *,
107                                         struct queue_elem *);
108 static char *shift_output_template (char *, const char *, int);
109 static const char *alter_output_for_insn (struct queue_elem *,
110                                           struct queue_elem *,
111                                           int, int);
112 static void process_one_cond_exec (struct queue_elem *);
113 static void process_define_cond_exec (void);
114 static void process_include (rtx, int);
115 static char *save_string (const char *, int);
116 static void init_predicate_table (void);
117 \f
118 void
119 message_with_line (int lineno, const char *msg, ...)
120 {
121   va_list ap;
122
123   va_start (ap, msg);
124
125   fprintf (stderr, "%s:%d: ", read_rtx_filename, lineno);
126   vfprintf (stderr, msg, ap);
127   fputc ('\n', stderr);
128
129   va_end (ap);
130 }
131
132 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
133    the gensupport programs.  */
134
135 rtx
136 gen_rtx_CONST_INT (enum machine_mode ARG_UNUSED (mode),
137                    HOST_WIDE_INT arg)
138 {
139   rtx rt = rtx_alloc (CONST_INT);
140
141   XWINT (rt, 0) = arg;
142   return rt;
143 }
144 \f
145 /* Queue PATTERN on LIST_TAIL.  Return the address of the new queue
146    element.  */
147
148 static struct queue_elem *
149 queue_pattern (rtx pattern, struct queue_elem ***list_tail,
150                const char *filename, int lineno)
151 {
152   struct queue_elem *e = XNEW(struct queue_elem);
153   e->data = pattern;
154   e->filename = filename;
155   e->lineno = lineno;
156   e->next = NULL;
157   e->split = NULL;
158   **list_tail = e;
159   *list_tail = &e->next;
160   return e;
161 }
162
163 /* Recursively remove constraints from an rtx.  */
164
165 static void
166 remove_constraints (rtx part)
167 {
168   int i, j;
169   const char *format_ptr;
170
171   if (part == 0)
172     return;
173
174   if (GET_CODE (part) == MATCH_OPERAND)
175     XSTR (part, 2) = "";
176   else if (GET_CODE (part) == MATCH_SCRATCH)
177     XSTR (part, 1) = "";
178
179   format_ptr = GET_RTX_FORMAT (GET_CODE (part));
180
181   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
182     switch (*format_ptr++)
183       {
184       case 'e':
185       case 'u':
186         remove_constraints (XEXP (part, i));
187         break;
188       case 'E':
189         if (XVEC (part, i) != NULL)
190           for (j = 0; j < XVECLEN (part, i); j++)
191             remove_constraints (XVECEXP (part, i, j));
192         break;
193       }
194 }
195
196 /* Process an include file assuming that it lives in gcc/config/{target}/
197    if the include looks like (include "file").  */
198
199 static void
200 process_include (rtx desc, int lineno)
201 {
202   const char *filename = XSTR (desc, 0);
203   const char *old_filename;
204   int old_lineno;
205   char *pathname;
206   FILE *input_file;
207
208   /* If specified file name is absolute, skip the include stack.  */
209   if (! IS_ABSOLUTE_PATH (filename))
210     {
211       struct file_name_list *stackp;
212
213       /* Search directory path, trying to open the file.  */
214       for (stackp = first_dir_md_include; stackp; stackp = stackp->next)
215         {
216           static const char sep[2] = { DIR_SEPARATOR, '\0' };
217
218           pathname = concat (stackp->fname, sep, filename, NULL);
219           input_file = fopen (pathname, "r");
220           if (input_file != NULL)
221             goto success;
222           free (pathname);
223         }
224     }
225
226   if (base_dir)
227     pathname = concat (base_dir, filename, NULL);
228   else
229     pathname = xstrdup (filename);
230   input_file = fopen (pathname, "r");
231   if (input_file == NULL)
232     {
233       free (pathname);
234       message_with_line (lineno, "include file `%s' not found", filename);
235       errors = 1;
236       return;
237     }
238  success:
239
240   /* Save old cursor; setup new for the new file.  Note that "lineno" the
241      argument to this function is the beginning of the include statement,
242      while read_rtx_lineno has already been advanced.  */
243   old_filename = read_rtx_filename;
244   old_lineno = read_rtx_lineno;
245   read_rtx_filename = pathname;
246   read_rtx_lineno = 1;
247
248   /* Read the entire file.  */
249   while (read_rtx (input_file, &desc, &lineno))
250     process_rtx (desc, lineno);
251
252   /* Do not free pathname.  It is attached to the various rtx queue
253      elements.  */
254
255   read_rtx_filename = old_filename;
256   read_rtx_lineno = old_lineno;
257
258   fclose (input_file);
259 }
260
261 /* Process a top level rtx in some way, queuing as appropriate.  */
262
263 static void
264 process_rtx (rtx desc, int lineno)
265 {
266   switch (GET_CODE (desc))
267     {
268     case DEFINE_INSN:
269       queue_pattern (desc, &define_insn_tail, read_rtx_filename, lineno);
270       break;
271
272     case DEFINE_COND_EXEC:
273       queue_pattern (desc, &define_cond_exec_tail, read_rtx_filename, lineno);
274       break;
275
276     case DEFINE_ATTR:
277       queue_pattern (desc, &define_attr_tail, read_rtx_filename, lineno);
278       break;
279
280     case DEFINE_PREDICATE:
281     case DEFINE_SPECIAL_PREDICATE:
282       queue_pattern (desc, &define_pred_tail, read_rtx_filename, lineno);
283       break;
284
285     case INCLUDE:
286       process_include (desc, lineno);
287       break;
288
289     case DEFINE_INSN_AND_SPLIT:
290       {
291         const char *split_cond;
292         rtx split;
293         rtvec attr;
294         int i;
295         struct queue_elem *insn_elem;
296         struct queue_elem *split_elem;
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         insn_elem
325           = queue_pattern (desc, &define_insn_tail, read_rtx_filename, 
326                            lineno);
327         split_elem
328           = queue_pattern (split, &other_tail, read_rtx_filename, lineno);
329         insn_elem->split = split_elem;
330         break;
331       }
332
333     default:
334       queue_pattern (desc, &other_tail, read_rtx_filename, lineno);
335       break;
336     }
337 }
338 \f
339 /* Return true if attribute PREDICABLE is true for ELEM, which holds
340    a DEFINE_INSN.  */
341
342 static int
343 is_predicable (struct queue_elem *elem)
344 {
345   rtvec vec = XVEC (elem->data, 4);
346   const char *value;
347   int i;
348
349   if (! vec)
350     return predicable_default;
351
352   for (i = GET_NUM_ELEM (vec) - 1; i >= 0; --i)
353     {
354       rtx sub = RTVEC_ELT (vec, i);
355       switch (GET_CODE (sub))
356         {
357         case SET_ATTR:
358           if (strcmp (XSTR (sub, 0), "predicable") == 0)
359             {
360               value = XSTR (sub, 1);
361               goto found;
362             }
363           break;
364
365         case SET_ATTR_ALTERNATIVE:
366           if (strcmp (XSTR (sub, 0), "predicable") == 0)
367             {
368               message_with_line (elem->lineno,
369                                  "multiple alternatives for `predicable'");
370               errors = 1;
371               return 0;
372             }
373           break;
374
375         case SET:
376           if (GET_CODE (SET_DEST (sub)) != ATTR
377               || strcmp (XSTR (SET_DEST (sub), 0), "predicable") != 0)
378             break;
379           sub = SET_SRC (sub);
380           if (GET_CODE (sub) == CONST_STRING)
381             {
382               value = XSTR (sub, 0);
383               goto found;
384             }
385
386           /* ??? It would be possible to handle this if we really tried.
387              It's not easy though, and I'm not going to bother until it
388              really proves necessary.  */
389           message_with_line (elem->lineno,
390                              "non-constant value for `predicable'");
391           errors = 1;
392           return 0;
393
394         default:
395           gcc_unreachable ();
396         }
397     }
398
399   return predicable_default;
400
401  found:
402   /* Verify that predicability does not vary on the alternative.  */
403   /* ??? It should be possible to handle this by simply eliminating
404      the non-predicable alternatives from the insn.  FRV would like
405      to do this.  Delay this until we've got the basics solid.  */
406   if (strchr (value, ',') != NULL)
407     {
408       message_with_line (elem->lineno,
409                          "multiple alternatives for `predicable'");
410       errors = 1;
411       return 0;
412     }
413
414   /* Find out which value we're looking at.  */
415   if (strcmp (value, predicable_true) == 0)
416     return 1;
417   if (strcmp (value, predicable_false) == 0)
418     return 0;
419
420   message_with_line (elem->lineno,
421                      "unknown value `%s' for `predicable' attribute",
422                      value);
423   errors = 1;
424   return 0;
425 }
426
427 /* Examine the attribute "predicable"; discover its boolean values
428    and its default.  */
429
430 static void
431 identify_predicable_attribute (void)
432 {
433   struct queue_elem *elem;
434   char *p_true, *p_false;
435   const char *value;
436
437   /* Look for the DEFINE_ATTR for `predicable', which must exist.  */
438   for (elem = define_attr_queue; elem ; elem = elem->next)
439     if (strcmp (XSTR (elem->data, 0), "predicable") == 0)
440       goto found;
441
442   message_with_line (define_cond_exec_queue->lineno,
443                      "attribute `predicable' not defined");
444   errors = 1;
445   return;
446
447  found:
448   value = XSTR (elem->data, 1);
449   p_false = xstrdup (value);
450   p_true = strchr (p_false, ',');
451   if (p_true == NULL || strchr (++p_true, ',') != NULL)
452     {
453       message_with_line (elem->lineno,
454                          "attribute `predicable' is not a boolean");
455       errors = 1;
456       return;
457     }
458   p_true[-1] = '\0';
459
460   predicable_true = p_true;
461   predicable_false = p_false;
462
463   switch (GET_CODE (XEXP (elem->data, 2)))
464     {
465     case CONST_STRING:
466       value = XSTR (XEXP (elem->data, 2), 0);
467       break;
468
469     case CONST:
470       message_with_line (elem->lineno,
471                          "attribute `predicable' cannot be const");
472       errors = 1;
473       return;
474
475     default:
476       message_with_line (elem->lineno,
477                          "attribute `predicable' must have a constant default");
478       errors = 1;
479       return;
480     }
481
482   if (strcmp (value, p_true) == 0)
483     predicable_default = 1;
484   else if (strcmp (value, p_false) == 0)
485     predicable_default = 0;
486   else
487     {
488       message_with_line (elem->lineno,
489                          "unknown value `%s' for `predicable' attribute",
490                          value);
491       errors = 1;
492     }
493 }
494
495 /* Return the number of alternatives in constraint S.  */
496
497 static int
498 n_alternatives (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 (rtx pattern, int *palt, int *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       /* Fall through.  */
526
527     case MATCH_OPERATOR:
528     case MATCH_SCRATCH:
529     case MATCH_PARALLEL:
530       i = XINT (pattern, 0);
531       if (i > *pmax)
532         *pmax = i;
533       break;
534
535     default:
536       break;
537     }
538
539   fmt = GET_RTX_FORMAT (code);
540   len = GET_RTX_LENGTH (code);
541   for (i = 0; i < len; i++)
542     {
543       switch (fmt[i])
544         {
545         case 'e': case 'u':
546           collect_insn_data (XEXP (pattern, i), palt, pmax);
547           break;
548
549         case 'V':
550           if (XVEC (pattern, i) == NULL)
551             break;
552           /* Fall through.  */
553         case 'E':
554           for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
555             collect_insn_data (XVECEXP (pattern, i, j), palt, pmax);
556           break;
557
558         case 'i': case 'w': case '0': case 's': case 'S': case 'T':
559           break;
560
561         default:
562           gcc_unreachable ();
563         }
564     }
565 }
566
567 static rtx
568 alter_predicate_for_insn (rtx pattern, int alt, int max_op, int lineno)
569 {
570   const char *fmt;
571   enum rtx_code code;
572   int i, j, len;
573
574   code = GET_CODE (pattern);
575   switch (code)
576     {
577     case MATCH_OPERAND:
578       {
579         const char *c = XSTR (pattern, 2);
580
581         if (n_alternatives (c) != 1)
582           {
583             message_with_line (lineno,
584                                "too many alternatives for operand %d",
585                                XINT (pattern, 0));
586             errors = 1;
587             return NULL;
588           }
589
590         /* Replicate C as needed to fill out ALT alternatives.  */
591         if (c && *c && alt > 1)
592           {
593             size_t c_len = strlen (c);
594             size_t len = alt * (c_len + 1);
595             char *new_c = XNEWVEC(char, len);
596
597             memcpy (new_c, c, c_len);
598             for (i = 1; i < alt; ++i)
599               {
600                 new_c[i * (c_len + 1) - 1] = ',';
601                 memcpy (&new_c[i * (c_len + 1)], c, c_len);
602               }
603             new_c[len - 1] = '\0';
604             XSTR (pattern, 2) = new_c;
605           }
606       }
607       /* Fall through.  */
608
609     case MATCH_OPERATOR:
610     case MATCH_SCRATCH:
611     case MATCH_PARALLEL:
612       XINT (pattern, 0) += max_op;
613       break;
614
615     default:
616       break;
617     }
618
619   fmt = GET_RTX_FORMAT (code);
620   len = GET_RTX_LENGTH (code);
621   for (i = 0; i < len; i++)
622     {
623       rtx r;
624
625       switch (fmt[i])
626         {
627         case 'e': case 'u':
628           r = alter_predicate_for_insn (XEXP (pattern, i), alt,
629                                         max_op, lineno);
630           if (r == NULL)
631             return r;
632           break;
633
634         case 'E':
635           for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
636             {
637               r = alter_predicate_for_insn (XVECEXP (pattern, i, j),
638                                             alt, max_op, lineno);
639               if (r == NULL)
640                 return r;
641             }
642           break;
643
644         case 'i': case 'w': case '0': case 's':
645           break;
646
647         default:
648           gcc_unreachable ();
649         }
650     }
651
652   return pattern;
653 }
654
655 static const char *
656 alter_test_for_insn (struct queue_elem *ce_elem,
657                      struct queue_elem *insn_elem)
658 {
659   const char *ce_test, *insn_test;
660
661   ce_test = XSTR (ce_elem->data, 1);
662   insn_test = XSTR (insn_elem->data, 2);
663   if (!ce_test || *ce_test == '\0')
664     return insn_test;
665   if (!insn_test || *insn_test == '\0')
666     return ce_test;
667
668   return concat ("(", ce_test, ") && (", insn_test, ")", NULL);
669 }
670
671 /* Adjust all of the operand numbers in SRC to match the shift they'll
672    get from an operand displacement of DISP.  Return a pointer after the
673    adjusted string.  */
674
675 static char *
676 shift_output_template (char *dest, const char *src, int disp)
677 {
678   while (*src)
679     {
680       char c = *src++;
681       *dest++ = c;
682       if (c == '%')
683         {
684           c = *src++;
685           if (ISDIGIT ((unsigned char) c))
686             c += disp;
687           else if (ISALPHA (c))
688             {
689               *dest++ = c;
690               c = *src++ + disp;
691             }
692           *dest++ = c;
693         }
694     }
695
696   return dest;
697 }
698
699 static const char *
700 alter_output_for_insn (struct queue_elem *ce_elem,
701                        struct queue_elem *insn_elem,
702                        int alt, int max_op)
703 {
704   const char *ce_out, *insn_out;
705   char *result, *p;
706   size_t len, ce_len, insn_len;
707
708   /* ??? Could coordinate with genoutput to not duplicate code here.  */
709
710   ce_out = XSTR (ce_elem->data, 2);
711   insn_out = XTMPL (insn_elem->data, 3);
712   if (!ce_out || *ce_out == '\0')
713     return insn_out;
714
715   ce_len = strlen (ce_out);
716   insn_len = strlen (insn_out);
717
718   if (*insn_out == '*')
719     /* You must take care of the predicate yourself.  */
720     return insn_out;
721
722   if (*insn_out == '@')
723     {
724       len = (ce_len + 1) * alt + insn_len + 1;
725       p = result = XNEWVEC(char, len);
726
727       do
728         {
729           do
730             *p++ = *insn_out++;
731           while (ISSPACE ((unsigned char) *insn_out));
732
733           if (*insn_out != '#')
734             {
735               p = shift_output_template (p, ce_out, max_op);
736               *p++ = ' ';
737             }
738
739           do
740             *p++ = *insn_out++;
741           while (*insn_out && *insn_out != '\n');
742         }
743       while (*insn_out);
744       *p = '\0';
745     }
746   else
747     {
748       len = ce_len + 1 + insn_len + 1;
749       result = XNEWVEC (char, len);
750
751       p = shift_output_template (result, ce_out, max_op);
752       *p++ = ' ';
753       memcpy (p, insn_out, insn_len + 1);
754     }
755
756   return result;
757 }
758
759 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC.  */
760
761 static void
762 process_one_cond_exec (struct queue_elem *ce_elem)
763 {
764   struct queue_elem *insn_elem;
765   for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
766     {
767       int alternatives, max_operand;
768       rtx pred, insn, pattern, split;
769       int i;
770
771       if (! is_predicable (insn_elem))
772         continue;
773
774       alternatives = 1;
775       max_operand = -1;
776       collect_insn_data (insn_elem->data, &alternatives, &max_operand);
777       max_operand += 1;
778
779       if (XVECLEN (ce_elem->data, 0) != 1)
780         {
781           message_with_line (ce_elem->lineno,
782                              "too many patterns in predicate");
783           errors = 1;
784           return;
785         }
786
787       pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0));
788       pred = alter_predicate_for_insn (pred, alternatives, max_operand,
789                                        ce_elem->lineno);
790       if (pred == NULL)
791         return;
792
793       /* Construct a new pattern for the new insn.  */
794       insn = copy_rtx (insn_elem->data);
795       XSTR (insn, 0) = "";
796       pattern = rtx_alloc (COND_EXEC);
797       XEXP (pattern, 0) = pred;
798       if (XVECLEN (insn, 1) == 1)
799         {
800           XEXP (pattern, 1) = XVECEXP (insn, 1, 0);
801           XVECEXP (insn, 1, 0) = pattern;
802           PUT_NUM_ELEM (XVEC (insn, 1), 1);
803         }
804       else
805         {
806           XEXP (pattern, 1) = rtx_alloc (PARALLEL);
807           XVEC (XEXP (pattern, 1), 0) = XVEC (insn, 1);
808           XVEC (insn, 1) = rtvec_alloc (1);
809           XVECEXP (insn, 1, 0) = pattern;
810         }
811
812       XSTR (insn, 2) = alter_test_for_insn (ce_elem, insn_elem);
813       XTMPL (insn, 3) = alter_output_for_insn (ce_elem, insn_elem,
814                                               alternatives, max_operand);
815
816       /* ??? Set `predicable' to false.  Not crucial since it's really
817          only used here, and we won't reprocess this new pattern.  */
818
819       /* Put the new pattern on the `other' list so that it
820          (a) is not reprocessed by other define_cond_exec patterns
821          (b) appears after all normal define_insn patterns.
822
823          ??? B is debatable.  If one has normal insns that match
824          cond_exec patterns, they will be preferred over these
825          generated patterns.  Whether this matters in practice, or if
826          it's a good thing, or whether we should thread these new
827          patterns into the define_insn chain just after their generator
828          is something we'll have to experiment with.  */
829
830       queue_pattern (insn, &other_tail, insn_elem->filename,
831                      insn_elem->lineno);
832
833       if (!insn_elem->split)
834         continue;
835
836       /* If the original insn came from a define_insn_and_split,
837          generate a new split to handle the predicated insn.  */
838       split = copy_rtx (insn_elem->split->data);
839       /* Predicate the pattern matched by the split.  */
840       pattern = rtx_alloc (COND_EXEC);
841       XEXP (pattern, 0) = pred;
842       if (XVECLEN (split, 0) == 1)
843         {
844           XEXP (pattern, 1) = XVECEXP (split, 0, 0);
845           XVECEXP (split, 0, 0) = pattern;
846           PUT_NUM_ELEM (XVEC (split, 0), 1);
847         }
848       else
849         {
850           XEXP (pattern, 1) = rtx_alloc (PARALLEL);
851           XVEC (XEXP (pattern, 1), 0) = XVEC (split, 0);
852           XVEC (split, 0) = rtvec_alloc (1);
853           XVECEXP (split, 0, 0) = pattern;
854         }
855       /* Predicate all of the insns generated by the split.  */
856       for (i = 0; i < XVECLEN (split, 2); i++)
857         {
858           pattern = rtx_alloc (COND_EXEC);
859           XEXP (pattern, 0) = pred;
860           XEXP (pattern, 1) = XVECEXP (split, 2, i);
861           XVECEXP (split, 2, i) = pattern;
862         }
863       /* Add the new split to the queue.  */
864       queue_pattern (split, &other_tail, read_rtx_filename, 
865                      insn_elem->split->lineno);
866     }
867 }
868
869 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
870    patterns appropriately.  */
871
872 static void
873 process_define_cond_exec (void)
874 {
875   struct queue_elem *elem;
876
877   identify_predicable_attribute ();
878   if (errors)
879     return;
880
881   for (elem = define_cond_exec_queue; elem ; elem = elem->next)
882     process_one_cond_exec (elem);
883 }
884
885 static char *
886 save_string (const char *s, int len)
887 {
888   char *result = XNEWVEC (char, len + 1);
889
890   memcpy (result, s, len);
891   result[len] = 0;
892   return result;
893 }
894
895 \f
896 /* The entry point for initializing the reader.  */
897
898 int
899 init_md_reader_args_cb (int argc, char **argv, bool (*parse_opt)(const char *))
900 {
901   FILE *input_file;
902   int i, lineno;
903   size_t ix;
904   char *lastsl;
905   rtx desc;
906
907   for (i = 1; i < argc; i++)
908     {
909       if (argv[i][0] != '-')
910         {
911           if (in_fname)
912             fatal ("too many input files");
913
914           in_fname = argv[i];
915         }
916       else
917         {
918           int c = argv[i][1];
919           switch (c)
920             {
921             case 'I':           /* Add directory to path for includes.  */
922               {
923                 struct file_name_list *dirtmp;
924
925                 dirtmp = XNEW (struct file_name_list);
926                 dirtmp->next = 0;       /* New one goes on the end */
927                 if (first_dir_md_include == 0)
928                   first_dir_md_include = dirtmp;
929                 else
930                   last_dir_md_include->next = dirtmp;
931                 last_dir_md_include = dirtmp;   /* Tail follows the last one */
932                 if (argv[i][1] == 'I' && argv[i][2] != 0)
933                   dirtmp->fname = argv[i] + 2;
934                 else if (i + 1 == argc)
935                   fatal ("directory name missing after -I option");
936                 else
937                   dirtmp->fname = argv[++i];
938                 if (strlen (dirtmp->fname) > max_include_len)
939                   max_include_len = strlen (dirtmp->fname);
940               }
941               break;
942             default:
943               /* The program may have provided a callback so it can
944                  accept its own options.  */
945               if (parse_opt && parse_opt (argv[i]))
946                 break;
947
948               fatal ("invalid option `%s'", argv[i]);
949             }
950         }
951     }
952
953   if (!in_fname)
954     fatal ("no input file name");
955
956   lastsl = strrchr (in_fname, '/');
957   if (lastsl != NULL)
958     base_dir = save_string (in_fname, lastsl - in_fname + 1 );
959
960   read_rtx_filename = in_fname;
961   input_file = fopen (in_fname, "r");
962   if (input_file == 0)
963     {
964       perror (in_fname);
965       return FATAL_EXIT_CODE;
966     }
967
968   /* Initialize the table of insn conditions.  */
969   condition_table = htab_create (n_insn_conditions,
970                                  hash_c_test, cmp_c_test, NULL);
971
972   for (ix = 0; ix < n_insn_conditions; ix++)
973     *(htab_find_slot (condition_table, &insn_conditions[ix], INSERT))
974       = (void *) &insn_conditions[ix];
975
976   init_predicate_table ();
977
978   obstack_init (rtl_obstack);
979   errors = 0;
980   sequence_num = 0;
981
982   /* Read the entire file.  */
983   while (read_rtx (input_file, &desc, &lineno))
984     process_rtx (desc, lineno);
985   fclose (input_file);
986
987   /* Process define_cond_exec patterns.  */
988   if (define_cond_exec_queue != NULL)
989     process_define_cond_exec ();
990
991   return errors ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
992 }
993
994 /* Programs that don't have their own options can use this entry point
995    instead.  */
996 int
997 init_md_reader_args (int argc, char **argv)
998 {
999   return init_md_reader_args_cb (argc, argv, 0);
1000 }
1001 \f
1002 /* The entry point for reading a single rtx from an md file.  */
1003
1004 rtx
1005 read_md_rtx (int *lineno, int *seqnr)
1006 {
1007   struct queue_elem **queue, *elem;
1008   rtx desc;
1009
1010  discard:
1011
1012   /* Read all patterns from a given queue before moving on to the next.  */
1013   if (define_attr_queue != NULL)
1014     queue = &define_attr_queue;
1015   else if (define_pred_queue != NULL)
1016     queue = &define_pred_queue;
1017   else if (define_insn_queue != NULL)
1018     queue = &define_insn_queue;
1019   else if (other_queue != NULL)
1020     queue = &other_queue;
1021   else
1022     return NULL_RTX;
1023
1024   elem = *queue;
1025   *queue = elem->next;
1026   desc = elem->data;
1027   read_rtx_filename = elem->filename;
1028   *lineno = elem->lineno;
1029   *seqnr = sequence_num;
1030
1031   free (elem);
1032
1033   /* Discard insn patterns which we know can never match (because
1034      their C test is provably always false).  If insn_elision is
1035      false, our caller needs to see all the patterns.  Note that the
1036      elided patterns are never counted by the sequence numbering; it
1037      it is the caller's responsibility, when insn_elision is false, not
1038      to use elided pattern numbers for anything.  */
1039   switch (GET_CODE (desc))
1040     {
1041     case DEFINE_INSN:
1042     case DEFINE_EXPAND:
1043       if (maybe_eval_c_test (XSTR (desc, 2)) != 0)
1044         sequence_num++;
1045       else if (insn_elision)
1046         goto discard;
1047       break;
1048
1049     case DEFINE_SPLIT:
1050     case DEFINE_PEEPHOLE:
1051     case DEFINE_PEEPHOLE2:
1052       if (maybe_eval_c_test (XSTR (desc, 1)) != 0)
1053         sequence_num++;
1054       else if (insn_elision)
1055             goto discard;
1056       break;
1057
1058     default:
1059       break;
1060     }
1061
1062   return desc;
1063 }
1064
1065 /* Helper functions for insn elision.  */
1066
1067 /* Compute a hash function of a c_test structure, which is keyed
1068    by its ->expr field.  */
1069 hashval_t
1070 hash_c_test (const void *x)
1071 {
1072   const struct c_test *a = (const struct c_test *) x;
1073   const unsigned char *base, *s = (const unsigned char *) a->expr;
1074   hashval_t hash;
1075   unsigned char c;
1076   unsigned int len;
1077
1078   base = s;
1079   hash = 0;
1080
1081   while ((c = *s++) != '\0')
1082     {
1083       hash += c + (c << 17);
1084       hash ^= hash >> 2;
1085     }
1086
1087   len = s - base;
1088   hash += len + (len << 17);
1089   hash ^= hash >> 2;
1090
1091   return hash;
1092 }
1093
1094 /* Compare two c_test expression structures.  */
1095 int
1096 cmp_c_test (const void *x, const void *y)
1097 {
1098   const struct c_test *a = (const struct c_test *) x;
1099   const struct c_test *b = (const struct c_test *) y;
1100
1101   return !strcmp (a->expr, b->expr);
1102 }
1103
1104 /* Given a string representing a C test expression, look it up in the
1105    condition_table and report whether or not its value is known
1106    at compile time.  Returns a tristate: 1 for known true, 0 for
1107    known false, -1 for unknown.  */
1108 int
1109 maybe_eval_c_test (const char *expr)
1110 {
1111   const struct c_test *test;
1112   struct c_test dummy;
1113
1114   if (expr[0] == 0)
1115     return 1;
1116
1117   if (insn_elision_unavailable)
1118     return -1;
1119
1120   dummy.expr = expr;
1121   test = (const struct c_test *)htab_find (condition_table, &dummy);
1122   gcc_assert (test);
1123
1124   return test->value;
1125 }
1126
1127 /* Given a string, return the number of comma-separated elements in it.
1128    Return 0 for the null string.  */
1129 int
1130 n_comma_elts (const char *s)
1131 {
1132   int n;
1133
1134   if (*s == '\0')
1135     return 0;
1136
1137   for (n = 1; *s; s++)
1138     if (*s == ',')
1139       n++;
1140
1141   return n;
1142 }
1143
1144 /* Given a pointer to a (char *), return a pointer to the beginning of the
1145    next comma-separated element in the string.  Advance the pointer given
1146    to the end of that element.  Return NULL if at end of string.  Caller
1147    is responsible for copying the string if necessary.  White space between
1148    a comma and an element is ignored.  */
1149
1150 const char *
1151 scan_comma_elt (const char **pstr)
1152 {
1153   const char *start;
1154   const char *p = *pstr;
1155
1156   if (*p == ',')
1157     p++;
1158   while (ISSPACE(*p))
1159     p++;
1160
1161   if (*p == '\0')
1162     return NULL;
1163
1164   start = p;
1165
1166   while (*p != ',' && *p != '\0')
1167     p++;
1168
1169   *pstr = p;
1170   return start;
1171 }
1172
1173 /* Helper functions for define_predicate and define_special_predicate
1174    processing.  Shared between genrecog.c and genpreds.c.  */
1175
1176 static htab_t predicate_table;
1177 struct pred_data *first_predicate;
1178 static struct pred_data **last_predicate = &first_predicate;
1179
1180 static hashval_t
1181 hash_struct_pred_data (const void *ptr)
1182 {
1183   return htab_hash_string (((const struct pred_data *)ptr)->name);
1184 }
1185
1186 static int
1187 eq_struct_pred_data (const void *a, const void *b)
1188 {
1189   return !strcmp (((const struct pred_data *)a)->name,
1190                   ((const struct pred_data *)b)->name);
1191 }
1192
1193 struct pred_data *
1194 lookup_predicate (const char *name)
1195 {
1196   struct pred_data key;
1197   key.name = name;
1198   return htab_find (predicate_table, &key);
1199 }
1200
1201 void
1202 add_predicate (struct pred_data *pred)
1203 {
1204   void **slot = htab_find_slot (predicate_table, pred, INSERT);
1205   if (*slot)
1206     {
1207       error ("duplicate predicate definition for '%s'", pred->name);
1208       return;
1209     }
1210   *slot = pred;
1211   *last_predicate = pred;
1212   last_predicate = &pred->next;
1213 }
1214
1215 /* This array gives the initial content of the predicate table.  It
1216    has entries for all predicates defined in recog.c.  The back end
1217    can define PREDICATE_CODES to give additional entries for the
1218    table; this is considered an obsolete mechanism (use
1219    define_predicate instead).  */
1220
1221 struct old_pred_table
1222 {
1223   const char *name;
1224   RTX_CODE codes[NUM_RTX_CODE];
1225 };
1226
1227 static const struct old_pred_table old_preds[] = {
1228   {"general_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
1229                        LABEL_REF, SUBREG, REG, MEM }},
1230   {"address_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
1231                        LABEL_REF, SUBREG, REG, MEM,
1232                        PLUS, MINUS, MULT}},
1233   {"register_operand", {SUBREG, REG}},
1234   {"pmode_register_operand", {SUBREG, REG}},
1235   {"scratch_operand", {SCRATCH, REG}},
1236   {"immediate_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
1237                          LABEL_REF}},
1238   {"const_int_operand", {CONST_INT}},
1239   {"const_double_operand", {CONST_INT, CONST_DOUBLE}},
1240   {"nonimmediate_operand", {SUBREG, REG, MEM}},
1241   {"nonmemory_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
1242                          LABEL_REF, SUBREG, REG}},
1243   {"push_operand", {MEM}},
1244   {"pop_operand", {MEM}},
1245   {"memory_operand", {SUBREG, MEM}},
1246   {"indirect_operand", {SUBREG, MEM}},
1247   {"comparison_operator", {EQ, NE, LE, LT, GE, GT, LEU, LTU, GEU, GTU,
1248                            UNORDERED, ORDERED, UNEQ, UNGE, UNGT, UNLE,
1249                            UNLT, LTGT}},
1250 #ifdef PREDICATE_CODES
1251   PREDICATE_CODES
1252 #endif
1253 };
1254 #define NUM_KNOWN_OLD_PREDS ARRAY_SIZE (old_preds)
1255
1256 /* This table gives the initial set of special predicates.  It has
1257    entries for all special predicates defined in recog.c.  The back
1258    end can define SPECIAL_MODE_PREDICATES to give additional entries
1259    for the table; this is considered an obsolete mechanism (use
1260    define_special_predicate instead).  */
1261 static const char *const old_special_pred_table[] = {
1262   "address_operand",
1263   "pmode_register_operand",
1264 #ifdef SPECIAL_MODE_PREDICATES
1265   SPECIAL_MODE_PREDICATES
1266 #endif
1267 };
1268
1269 #define NUM_OLD_SPECIAL_MODE_PREDS ARRAY_SIZE (old_special_pred_table)
1270
1271 /* Initialize the table of predicate definitions, starting with
1272    the information we have on generic predicates, and the old-style
1273    PREDICATE_CODES definitions.  */
1274
1275 static void
1276 init_predicate_table (void)
1277 {
1278   size_t i, j;
1279   struct pred_data *pred;
1280
1281   predicate_table = htab_create_alloc (37, hash_struct_pred_data,
1282                                        eq_struct_pred_data, 0,
1283                                        xcalloc, free);
1284
1285   for (i = 0; i < NUM_KNOWN_OLD_PREDS; i++)
1286     {
1287       pred = xcalloc (sizeof (struct pred_data), 1);
1288       pred->name = old_preds[i].name;
1289
1290       for (j = 0; old_preds[i].codes[j] != 0; j++)
1291         {
1292           enum rtx_code code = old_preds[i].codes[j];
1293
1294           pred->codes[code] = true;
1295           if (GET_RTX_CLASS (code) != RTX_CONST_OBJ)
1296             pred->allows_non_const = true;
1297           if (code != REG
1298               && code != SUBREG
1299               && code != MEM
1300               && code != CONCAT
1301               && code != PARALLEL
1302               && code != STRICT_LOW_PART)
1303             pred->allows_non_lvalue = true;
1304         }
1305       if (j == 1)
1306         pred->singleton = old_preds[i].codes[0];
1307       
1308       add_predicate (pred);
1309     }
1310
1311   for (i = 0; i < NUM_OLD_SPECIAL_MODE_PREDS; i++)
1312     {
1313       pred = lookup_predicate (old_special_pred_table[i]);
1314       if (!pred)
1315         {
1316           error ("old-style special predicate list refers "
1317                  "to unknown predicate '%s'", old_special_pred_table[i]);
1318           continue;
1319         }
1320       pred->special = true;
1321     }
1322 }