OSDN Git Service

eaa4461c3041147fdfbd492ef23d3bba29c79819
[pf3gnuchains/gcc-fork.git] / gcc / genoutput.c
1 /* Generate code from to output assembler insns as recognized from rtl.
2    Copyright (C) 1987, 88, 92, 94-95, 97-98, 1999 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it 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 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING.  If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.  */
20
21
22 /* This program reads the machine description for the compiler target machine
23    and produces a file containing these things:
24
25    1. An array of strings `insn_template' which is indexed by insn code number
26    and contains the template for output of that insn,
27
28    2. An array of functions `insn_outfun' which, indexed by the insn code
29    number, gives the function that returns a template to use for output of
30    that insn.  This is used only in the cases where the template is not
31    constant.  These cases are specified by a * or @ at the beginning of the
32    template string in the machine description.  They are identified for the
33    sake of other parts of the compiler by a zero element in `insn_template'.
34   
35    3. An array of functions `insn_gen_function' which, indexed
36    by insn code number, gives the function to generate a body
37    for that pattern, given operands as arguments.
38
39    4. An array of strings `insn_name' which, indexed by insn code number,
40    gives the name for that pattern.  Nameless patterns are given a name.
41
42    5. An array of ints `insn_n_operands' which is indexed by insn code number
43    and contains the number of distinct operands in the pattern for that insn,
44
45    6. An array of ints `insn_n_dups' which is indexed by insn code number
46    and contains the number of match_dup's that appear in the insn's pattern.
47    This says how many elements of `recog_dup_loc' are significant
48    after an insn has been recognized.
49
50    7. An array of arrays of operand constraint strings,
51    `insn_operand_constraint',
52    indexed first by insn code number and second by operand number,
53    containing the constraint for that operand.
54
55    This array is generated only if register constraints appear in 
56    match_operand rtx's.
57
58    8. An array of arrays of chars which indicate which operands of
59    which insn patterns appear within ADDRESS rtx's.  This array is
60    called `insn_operand_address_p' and is generated only if there
61    are *no* register constraints in the match_operand rtx's.
62
63    9. An array of arrays of machine modes, `insn_operand_mode',
64    indexed first by insn code number and second by operand number,
65    containing the machine mode that that operand is supposed to have.
66    Also `insn_operand_strict_low', which is nonzero for operands
67    contained in a STRICT_LOW_PART.
68
69    10. An array of arrays of int-valued functions, `insn_operand_predicate',
70    indexed first by insn code number and second by operand number,
71    containing the match_operand predicate for this operand.
72
73    11. An array of ints, `insn_n_alternatives', that gives the number
74    of alternatives in the constraints of each pattern.
75
76 The code number of an insn is simply its position in the machine description;
77 code numbers are assigned sequentially to entries in the description,
78 starting with code number 0.
79
80 Thus, the following entry in the machine description
81
82     (define_insn "clrdf"
83       [(set (match_operand:DF 0 "general_operand" "")
84             (const_int 0))]
85       ""
86       "clrd %0")
87
88 assuming it is the 25th entry present, would cause
89 insn_template[24] to be "clrd %0", and insn_n_operands[24] to be 1.
90 It would not make an case in output_insn_hairy because the template
91 given in the entry is a constant (it does not start with `*').  */
92 \f
93 #include "hconfig.h"
94 #include "system.h"
95 #include "rtl.h"
96 #include "obstack.h"
97
98 /* No instruction can have more operands than this.
99    Sorry for this arbitrary limit, but what machine will
100    have an instruction with this many operands?  */
101
102 #define MAX_MAX_OPERANDS 40
103
104 static struct obstack obstack;
105 struct obstack *rtl_obstack = &obstack;
106
107 #define obstack_chunk_alloc xmalloc
108 #define obstack_chunk_free free
109
110 static void fatal PVPROTO ((const char *, ...))
111   ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
112 void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN;
113 static void error PVPROTO ((const char *, ...)) ATTRIBUTE_PRINTF_1;
114 static int n_occurrences PROTO((int, char *));
115
116 /* Define this so we can link with print-rtl.o to get debug_rtx function.  */
117 char **insn_name_ptr = 0;
118
119 /* insns in the machine description are assigned sequential code numbers
120    that are used by insn-recog.c (produced by genrecog) to communicate
121    to insn-output.c (produced by this program).  */
122
123 static int next_code_number;
124
125 /* This counts all definitions in the md file,
126    for the sake of error messages.  */
127
128 static int next_index_number;
129
130 /* Record in this chain all information that we will output,
131    associated with the code number of the insn.  */
132
133 struct data
134 {
135   int code_number;
136   int index_number;
137   char *name;
138   char *template;               /* string such as "movl %1,%0" */
139   int n_operands;               /* Number of operands this insn recognizes */
140   int n_dups;                   /* Number times match_dup appears in pattern */
141   int n_alternatives;           /* Number of alternatives in each constraint */
142   struct data *next;
143   char *constraints[MAX_MAX_OPERANDS];
144   /* Number of alternatives in constraints of operand N.  */
145   int op_n_alternatives[MAX_MAX_OPERANDS];
146   char *predicates[MAX_MAX_OPERANDS];
147   char address_p[MAX_MAX_OPERANDS];
148   enum machine_mode modes[MAX_MAX_OPERANDS];
149   char strict_low[MAX_MAX_OPERANDS];
150   char outfun;                  /* Nonzero means this has an output function */
151 };
152
153 /* This variable points to the first link in the chain.  */
154
155 struct data *insn_data;
156
157 /* Pointer to the last link in the chain, so new elements
158    can be added at the end.  */
159
160 struct data *end_of_insn_data;
161
162 /* Nonzero if any match_operand has a constraint string;
163    implies that REGISTER_CONSTRAINTS will be defined
164    for this machine description.  */
165
166 int have_constraints;
167
168 /* Nonzero if some error has occurred.  We will make all errors fatal, but
169    might as well continue until we see all of them.  */
170
171 static int have_error;
172 \f
173 static void output_prologue PROTO((void));
174 static void output_epilogue PROTO((void));
175 static void scan_operands PROTO((rtx, int, int));
176 static void process_template PROTO((struct data *, char *));
177 static void validate_insn_alternatives PROTO((struct data *));
178 static void gen_insn PROTO((rtx));
179 static void gen_peephole PROTO((rtx));
180 static void gen_expand PROTO((rtx));
181 static void gen_split PROTO((rtx));
182 static int n_occurrences PROTO((int, char *));
183 \f
184 static void
185 output_prologue ()
186 {
187   printf ("/* Generated automatically by the program `genoutput'\n\
188 from the machine description file `md'.  */\n\n");
189
190   printf ("#include \"config.h\"\n");
191   printf ("#include \"system.h\"\n");
192   printf ("#include \"flags.h\"\n");
193   printf ("#include \"rtl.h\"\n");
194   printf ("#include \"regs.h\"\n");
195   printf ("#include \"hard-reg-set.h\"\n");
196   printf ("#include \"real.h\"\n");
197   printf ("#include \"insn-config.h\"\n\n");
198   printf ("#include \"conditions.h\"\n");
199   printf ("#include \"insn-flags.h\"\n");
200   printf ("#include \"insn-attr.h\"\n\n");
201   printf ("#include \"insn-codes.h\"\n\n");
202   printf ("#include \"recog.h\"\n\n");
203
204   printf ("#include \"output.h\"\n");
205 }
206
207 static void
208 output_epilogue ()
209 {
210   register struct data *d;
211
212   printf ("\nchar * const insn_template[] =\n  {\n");
213   for (d = insn_data; d; d = d->next)
214     {
215       if (d->template)
216         printf ("    \"%s\",\n", d->template);
217       else
218         printf ("    0,\n");
219     }
220   printf ("  };\n");
221
222   printf ("\nchar *(*const insn_outfun[])() =\n  {\n");
223   for (d = insn_data; d; d = d->next)
224     {
225       if (d->outfun)
226         printf ("    output_%d,\n", d->code_number);
227       else
228         printf ("    0,\n");
229     }
230   printf ("  };\n");
231
232   printf ("\nrtx (*const insn_gen_function[]) () =\n  {\n");
233   for (d = insn_data; d; d = d->next)
234     {
235       if (d->name && d->name[0] != '*')
236         printf ("    gen_%s,\n", d->name);
237       else
238         printf ("    0,\n");
239     }
240   printf ("  };\n");
241
242   printf ("\nchar *insn_name[] =\n  {\n");
243   {
244     int offset = 0;
245     int next;
246     char * last_name = 0;
247     char * next_name = 0;
248     register struct data *n;
249
250     for (n = insn_data, next = 1; n; n = n->next, next++)
251       if (n->name)
252         {
253           next_name = n->name;
254           break;
255         }
256
257     for (d = insn_data; d; d = d->next)
258       {
259         if (d->name)
260           {
261             printf ("    \"%s\",\n", d->name);
262             offset = 0;
263             last_name = d->name;
264             next_name = 0;
265             for (n = d->next, next = 1; n; n = n->next, next++)
266               if (n->name)
267                 {
268                   next_name = n->name;
269                   break;
270                 }
271           }
272         else
273           {
274             offset++;
275             if (next_name && (last_name == 0 || offset > next / 2))
276               printf ("    \"%s-%d\",\n", next_name, next - offset);
277             else
278               printf ("    \"%s+%d\",\n", last_name, offset);
279           }
280       }
281   }
282   printf ("  };\n");
283   printf ("char **insn_name_ptr = insn_name;\n");
284
285   printf ("\nconst int insn_n_operands[] =\n  {\n");
286   for (d = insn_data; d; d = d->next)
287     printf ("    %d,\n", d->n_operands);
288   printf ("  };\n");
289
290   printf ("\nconst int insn_n_dups[] =\n  {\n");
291   for (d = insn_data; d; d = d->next)
292     printf ("    %d,\n", d->n_dups);
293   printf ("  };\n");
294
295   if (have_constraints)
296     {
297       printf ("\nchar *const insn_operand_constraint[][MAX_RECOG_OPERANDS] =\n  {\n");
298       for (d = insn_data; d; d = d->next)
299         {
300           register int i;
301           printf ("    {");
302           for (i = 0; i < d->n_operands; i++)
303             {
304               if (d->constraints[i] == 0)
305                 printf (" \"\",");
306               else
307                 printf (" \"%s\",", d->constraints[i]);
308             }
309           if (d->n_operands == 0)
310             printf (" 0");
311           printf (" },\n");
312         }
313       printf ("  };\n");
314     }
315   else
316     {
317       printf ("\nconst char insn_operand_address_p[][MAX_RECOG_OPERANDS] =\n  {\n");
318       for (d = insn_data; d; d = d->next)
319         {
320           register int i;
321           printf ("    {");
322           for (i = 0; i < d->n_operands; i++)
323             printf (" %d,", d->address_p[i]);
324           if (d->n_operands == 0)
325             printf (" 0");
326           printf (" },\n");
327         }
328       printf ("  };\n");
329     }
330
331   printf ("\nconst enum machine_mode insn_operand_mode[][MAX_RECOG_OPERANDS] =\n  {\n");
332   for (d = insn_data; d; d = d->next)
333     {
334       register int i;
335       printf ("    {");
336       for (i = 0; i < d->n_operands; i++)
337         printf (" %smode,", GET_MODE_NAME (d->modes[i]));
338       if (d->n_operands == 0)
339         printf (" VOIDmode");
340       printf (" },\n");
341     }
342   printf ("  };\n");
343
344   printf ("\nconst char insn_operand_strict_low[][MAX_RECOG_OPERANDS] =\n  {\n");
345   for (d = insn_data; d; d = d->next)
346     {
347       register int i;
348       printf ("    {");
349       for (i = 0; i < d->n_operands; i++)
350         printf (" %d,", d->strict_low[i]);
351       if (d->n_operands == 0)
352         printf (" 0");
353       printf (" },\n");
354     }
355   printf ("  };\n");
356
357   {
358     /* We need to define all predicates used.  Keep a list of those we
359        have defined so far.  There normally aren't very many predicates used,
360        so a linked list should be fast enough.  */
361     struct predicate { char *name; struct predicate *next; } *predicates = 0;
362     struct predicate *p;
363     int i;
364
365     printf ("\n");
366     for (d = insn_data; d; d = d->next)
367       for (i = 0; i < d->n_operands; i++)
368         if (d->predicates[i] && d->predicates[i][0])
369           {
370             for (p = predicates; p; p = p->next)
371               if (! strcmp (p->name, d->predicates[i]))
372                 break;
373
374             if (p == 0)
375               {
376                 printf ("extern int %s ();\n", d->predicates[i]);
377                 p = (struct predicate *) alloca (sizeof (struct predicate));
378                 p->name = d->predicates[i];
379                 p->next = predicates;
380                 predicates = p;
381               }
382           }
383     
384     printf ("\nint (*const insn_operand_predicate[][MAX_RECOG_OPERANDS])() =\n  {\n");
385     for (d = insn_data; d; d = d->next)
386       {
387         printf ("    {");
388         for (i = 0; i < d->n_operands; i++)
389           printf (" %s,", ((d->predicates[i] && d->predicates[i][0])
390                            ? d->predicates[i] : "0"));
391         if (d->n_operands == 0)
392           printf (" 0");
393         printf (" },\n");
394       }
395     printf ("  };\n");
396   }
397
398   printf ("\nconst int insn_n_alternatives[] =\n  {\n");
399   for (d = insn_data; d; d = d->next)
400     printf ("    %d,\n", d->n_alternatives);
401   printf("  };\n");
402 }
403 \f
404 /* scan_operands (X) stores in max_opno the largest operand
405    number present in X, if that is larger than the previous
406    value of max_opno.  It stores all the constraints in `constraints'
407    and all the machine modes in `modes'.
408
409    THIS_ADDRESS_P is nonzero if the containing rtx was an ADDRESS.
410    THIS_STRICT_LOW is nonzero if the containing rtx was a STRICT_LOW_PART.  */
411
412 static int max_opno;
413 static int num_dups;
414 static char *constraints[MAX_MAX_OPERANDS];
415 static int op_n_alternatives[MAX_MAX_OPERANDS];
416 static const char *predicates[MAX_MAX_OPERANDS];
417 static char address_p[MAX_MAX_OPERANDS];
418 static enum machine_mode modes[MAX_MAX_OPERANDS];
419 static char strict_low[MAX_MAX_OPERANDS];
420 static char seen[MAX_MAX_OPERANDS];
421
422 static void
423 scan_operands (part, this_address_p, this_strict_low)
424      rtx part;
425      int this_address_p;
426      int this_strict_low;
427 {
428   register int i, j;
429   register char *format_ptr;
430   int opno;
431
432   if (part == 0)
433     return;
434
435   switch (GET_CODE (part))
436     {
437     case MATCH_OPERAND:
438       opno = XINT (part, 0);
439       if (opno > max_opno)
440         max_opno = opno;
441       if (max_opno >= MAX_MAX_OPERANDS)
442         {
443           error ("Too many operands (%d) in definition %d.\n",
444                  max_opno + 1, next_index_number);
445           return;
446         }
447       if (seen[opno])
448         error ("Definition %d specified operand number %d more than once.\n",
449                next_index_number, opno);
450       seen[opno] = 1;
451       modes[opno] = GET_MODE (part);
452       strict_low[opno] = this_strict_low;
453       predicates[opno] = XSTR (part, 1);
454       constraints[opno] = XSTR (part, 2);
455       if (XSTR (part, 2) != 0 && *XSTR (part, 2) != 0)
456         {
457           op_n_alternatives[opno] = n_occurrences (',', XSTR (part, 2)) + 1;
458           have_constraints = 1;
459         }
460       address_p[opno] = this_address_p;
461       return;
462
463     case MATCH_SCRATCH:
464       opno = XINT (part, 0);
465       if (opno > max_opno)
466         max_opno = opno;
467       if (max_opno >= MAX_MAX_OPERANDS)
468         {
469           error ("Too many operands (%d) in definition %d.\n",
470                  max_opno + 1, next_index_number);
471           return;
472         }
473       if (seen[opno])
474         error ("Definition %d specified operand number %d more than once.\n",
475                next_index_number, opno);
476       seen[opno] = 1;
477       modes[opno] = GET_MODE (part);
478       strict_low[opno] = 0;
479       predicates[opno] = "scratch_operand";
480       constraints[opno] = XSTR (part, 1);
481       if (XSTR (part, 1) != 0 && *XSTR (part, 1) != 0)
482         {
483           op_n_alternatives[opno] = n_occurrences (',', XSTR (part, 1)) + 1;
484           have_constraints = 1;
485         }
486       address_p[opno] = 0;
487       return;
488
489     case MATCH_OPERATOR:
490     case MATCH_PARALLEL:
491       opno = XINT (part, 0);
492       if (opno > max_opno)
493         max_opno = opno;
494       if (max_opno >= MAX_MAX_OPERANDS)
495         {
496           error ("Too many operands (%d) in definition %d.\n",
497                  max_opno + 1, next_index_number);
498           return;
499         }
500       if (seen[opno])
501         error ("Definition %d specified operand number %d more than once.\n",
502                next_index_number, opno);
503       seen[opno] = 1;
504       modes[opno] = GET_MODE (part);
505       strict_low[opno] = 0;
506       predicates[opno] = XSTR (part, 1);
507       constraints[opno] = 0;
508       address_p[opno] = 0;
509       for (i = 0; i < XVECLEN (part, 2); i++)
510         scan_operands (XVECEXP (part, 2, i), 0, 0);
511       return;
512
513     case MATCH_DUP:
514     case MATCH_OP_DUP:
515     case MATCH_PAR_DUP:
516       ++num_dups;
517       return;
518
519     case ADDRESS:
520       scan_operands (XEXP (part, 0), 1, 0);
521       return;
522
523     case STRICT_LOW_PART:
524       scan_operands (XEXP (part, 0), 0, 1);
525       return;
526       
527     default:
528       break;
529     }
530
531   format_ptr = GET_RTX_FORMAT (GET_CODE (part));
532
533   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
534     switch (*format_ptr++)
535       {
536       case 'e':
537       case 'u':
538         scan_operands (XEXP (part, i), 0, 0);
539         break;
540       case 'E':
541         if (XVEC (part, i) != NULL)
542           for (j = 0; j < XVECLEN (part, i); j++)
543             scan_operands (XVECEXP (part, i, j), 0, 0);
544         break;
545       }
546 }
547 \f
548 /* Process an assembler template from a define_insn or a define_peephole.
549    It is either the assembler code template, a list of assembler code
550    templates, or C code to generate the assembler code template.  */
551
552 static void
553 process_template (d, template)
554     struct data *d;
555     char *template;
556 {
557   register char *cp;
558   register int i;
559
560   /* We need to consider only the instructions whose assembler code template
561      starts with a * or @.  These are the ones where C code is run to decide
562      on a template to use.  So for all others just return now.  */
563
564   if (template[0] != '*' && template[0] != '@')
565     {
566       d->template = template;
567       d->outfun = 0;
568       return;
569     }
570
571   d->template = 0;
572   d->outfun = 1;
573
574   printf ("\nstatic char *\n");
575   printf ("output_%d (operands, insn)\n", d->code_number);
576   printf ("     rtx *operands ATTRIBUTE_UNUSED;\n");
577   printf ("     rtx insn ATTRIBUTE_UNUSED;\n");
578   printf ("{\n");
579
580   /* If the assembler code template starts with a @ it is a newline-separated
581      list of assembler code templates, one for each alternative.  So produce
582      a routine to select the correct one.  */
583
584   if (template[0] == '@')
585     {
586
587       printf ("  static /*const*/ char *const strings_%d[] = {\n",
588               d->code_number);
589
590       for (i = 0, cp = &template[1]; *cp; )
591         {
592           while (*cp == '\n' || *cp == ' ' || *cp== '\t')
593             cp++;
594
595           printf ("    \"");
596           while (*cp != '\n' && *cp != '\0')
597             {
598               putchar (*cp);
599               cp++;
600             }
601
602           printf ("\",\n");
603           i++;
604         }
605
606       printf ("  };\n");
607       printf ("  return strings_%d[which_alternative];\n", d->code_number);
608
609       if (i != d->n_alternatives)
610         fatal ("Insn pattern %d has %d alternatives but %d assembler choices",
611                d->index_number, d->n_alternatives, i);
612
613     }
614   else
615     {
616        /* The following is done in a funny way to get around problems in
617           VAX-11 "C" on VMS.  It is the equivalent of:
618                 printf ("%s\n", &template[1])); */
619       cp = &template[1];
620       while (*cp)
621         {
622           putchar (*cp);
623           cp++;
624         }
625       putchar ('\n');
626     }
627
628   printf ("}\n");
629 }
630 \f
631 /* Check insn D for consistency in number of constraint alternatives.  */
632
633 static void
634 validate_insn_alternatives (d)
635      struct data *d;
636 {
637   register int n = 0, start;
638   /* Make sure all the operands have the same number of
639      alternatives in their constraints.
640      Let N be that number.  */
641   for (start = 0; start < d->n_operands; start++)
642     if (d->op_n_alternatives[start] > 0)
643       {
644         if (n == 0)
645           n = d->op_n_alternatives[start];
646         else if (n != d->op_n_alternatives[start])
647           error ("wrong number of alternatives in operand %d of insn number %d",
648                  start, d->index_number);
649       }
650   /* Record the insn's overall number of alternatives.  */
651   d->n_alternatives = n;
652 }
653 \f
654 /* Look at a define_insn just read.  Assign its code number.
655    Record on insn_data the template and the number of arguments.
656    If the insn has a hairy output action, output a function for now.  */
657
658 static void
659 gen_insn (insn)
660      rtx insn;
661 {
662   register struct data *d = (struct data *) xmalloc (sizeof (struct data));
663   register int i;
664
665   d->code_number = next_code_number++;
666   d->index_number = next_index_number;
667   if (XSTR (insn, 0)[0])
668     d->name = XSTR (insn, 0);
669   else
670     d->name = 0;
671
672   /* Build up the list in the same order as the insns are seen
673      in the machine description.  */
674   d->next = 0;
675   if (end_of_insn_data)
676     end_of_insn_data->next = d;
677   else
678     insn_data = d;
679
680   end_of_insn_data = d;
681
682   max_opno = -1;
683   num_dups = 0;
684
685   memset (constraints, 0, sizeof constraints);
686   memset (op_n_alternatives, 0, sizeof op_n_alternatives);
687   memset (predicates, 0, sizeof predicates);
688   memset (address_p, 0, sizeof address_p);
689   memset (modes, 0, sizeof modes);
690   memset (strict_low, 0, sizeof strict_low);
691   memset (seen, 0, sizeof seen);
692
693   for (i = 0; i < XVECLEN (insn, 1); i++)
694     scan_operands (XVECEXP (insn, 1, i), 0, 0);
695
696   d->n_operands = max_opno + 1;
697   d->n_dups = num_dups;
698
699   memcpy (d->constraints, constraints, sizeof constraints);
700   memcpy (d->op_n_alternatives, op_n_alternatives, sizeof op_n_alternatives);
701   memcpy (d->predicates, predicates, sizeof predicates);
702   memcpy (d->address_p, address_p, sizeof address_p);
703   memcpy (d->modes, modes, sizeof modes);
704   memcpy (d->strict_low, strict_low, sizeof strict_low);
705
706   validate_insn_alternatives (d);
707   process_template (d, XSTR (insn, 3));
708 }
709 \f
710 /* Look at a define_peephole just read.  Assign its code number.
711    Record on insn_data the template and the number of arguments.
712    If the insn has a hairy output action, output it now.  */
713
714 static void
715 gen_peephole (peep)
716      rtx peep;
717 {
718   register struct data *d = (struct data *) xmalloc (sizeof (struct data));
719   register int i;
720
721   d->code_number = next_code_number++;
722   d->index_number = next_index_number;
723   d->name = 0;
724
725   /* Build up the list in the same order as the insns are seen
726      in the machine description.  */
727   d->next = 0;
728   if (end_of_insn_data)
729     end_of_insn_data->next = d;
730   else
731     insn_data = d;
732
733   end_of_insn_data = d;
734
735   max_opno = -1;
736   memset (constraints, 0, sizeof constraints);
737   memset (op_n_alternatives, 0, sizeof op_n_alternatives);
738   memset (predicates, 0, sizeof predicates);
739   memset (address_p, 0, sizeof address_p);
740   memset (modes, 0, sizeof modes);
741   memset (strict_low, 0, sizeof strict_low);
742   memset (seen, 0, sizeof seen);
743
744   /* Get the number of operands by scanning all the
745      patterns of the peephole optimizer.
746      But ignore all the rest of the information thus obtained.  */
747   for (i = 0; i < XVECLEN (peep, 0); i++)
748     scan_operands (XVECEXP (peep, 0, i), 0, 0);
749
750   d->n_operands = max_opno + 1;
751   d->n_dups = 0;
752
753   memcpy (d->constraints, constraints, sizeof constraints);
754   memcpy (d->op_n_alternatives, op_n_alternatives, sizeof op_n_alternatives);
755   memset (d->predicates, 0, sizeof predicates);
756   memset (d->address_p, 0, sizeof address_p);
757   memset (d->modes, 0, sizeof modes);
758   memset (d->strict_low, 0, sizeof strict_low);
759
760   validate_insn_alternatives (d);
761   process_template (d, XSTR (peep, 2));
762 }
763 \f
764 /* Process a define_expand just read.  Assign its code number,
765    only for the purposes of `insn_gen_function'.  */
766
767 static void
768 gen_expand (insn)
769      rtx insn;
770 {
771   register struct data *d = (struct data *) xmalloc (sizeof (struct data));
772   register int i;
773
774   d->code_number = next_code_number++;
775   d->index_number = next_index_number;
776   if (XSTR (insn, 0)[0])
777     d->name = XSTR (insn, 0);
778   else
779     d->name = 0;
780
781   /* Build up the list in the same order as the insns are seen
782      in the machine description.  */
783   d->next = 0;
784   if (end_of_insn_data)
785     end_of_insn_data->next = d;
786   else
787     insn_data = d;
788
789   end_of_insn_data = d;
790
791   max_opno = -1;
792   num_dups = 0;
793
794   /* Scan the operands to get the specified predicates and modes,
795      since expand_binop needs to know them.  */
796
797   memset (constraints, 0, sizeof constraints);
798   memset (op_n_alternatives, 0, sizeof op_n_alternatives);
799   memset (predicates, 0, sizeof predicates);
800   memset (address_p, 0, sizeof address_p);
801   memset (modes, 0, sizeof modes);
802   memset (strict_low, 0, sizeof strict_low);
803   memset (seen, 0, sizeof seen);
804
805   if (XVEC (insn, 1))
806     for (i = 0; i < XVECLEN (insn, 1); i++)
807       scan_operands (XVECEXP (insn, 1, i), 0, 0);
808
809   d->n_operands = max_opno + 1;
810   d->n_dups = num_dups;
811
812   memcpy (d->constraints, constraints, sizeof constraints);
813   memcpy (d->op_n_alternatives, op_n_alternatives, sizeof op_n_alternatives);
814   memcpy (d->predicates, predicates, sizeof predicates);
815   memcpy (d->address_p, address_p, sizeof address_p);
816   memcpy (d->modes, modes, sizeof modes);
817   memcpy (d->strict_low, strict_low, sizeof strict_low);
818
819   d->template = 0;
820   d->outfun = 0;
821   validate_insn_alternatives (d);
822 }
823 \f
824 /* Process a define_split just read.  Assign its code number,
825    only for reasons of consistency and to simplify genrecog.  */
826
827
828 static void
829 gen_split (split)
830      rtx split;
831 {
832   register struct data *d = (struct data *) xmalloc (sizeof (struct data));
833   register int i;
834
835   d->code_number = next_code_number++;
836   d->index_number = next_index_number;
837   d->name = 0;
838
839   /* Build up the list in the same order as the insns are seen
840      in the machine description.  */
841   d->next = 0;
842   if (end_of_insn_data)
843     end_of_insn_data->next = d;
844   else
845     insn_data = d;
846
847   end_of_insn_data = d;
848
849   max_opno = -1;
850   num_dups = 0;
851
852   memset (constraints, 0, sizeof constraints);
853   memset (op_n_alternatives, 0, sizeof op_n_alternatives);
854   memset (predicates, 0, sizeof predicates);
855   memset (address_p, 0, sizeof address_p);
856   memset (modes, 0, sizeof modes);
857   memset (strict_low, 0, sizeof strict_low);
858   memset (seen, 0, sizeof seen);
859
860   /* Get the number of operands by scanning all the
861      patterns of the split patterns.
862      But ignore all the rest of the information thus obtained.  */
863   for (i = 0; i < XVECLEN (split, 0); i++)
864     scan_operands (XVECEXP (split, 0, i), 0, 0);
865
866   d->n_operands = max_opno + 1;
867
868   memset (d->constraints, 0, sizeof constraints);
869   memset (d->op_n_alternatives, 0, sizeof op_n_alternatives);
870   memset (d->predicates, 0, sizeof predicates);
871   memset (d->address_p, 0, sizeof address_p);
872   memset (d->modes, 0, sizeof modes);
873   memset (d->strict_low, 0, sizeof strict_low);
874
875   d->n_dups = 0;
876   d->n_alternatives = 0;
877   d->template = 0;
878   d->outfun = 0;
879 }
880 \f
881 PTR
882 xmalloc (size)
883   size_t size;
884 {
885   register PTR val = (PTR) malloc (size);
886
887   if (val == 0)
888     fatal ("virtual memory exhausted");
889   return val;
890 }
891
892 PTR
893 xrealloc (ptr, size)
894   PTR ptr;
895   size_t size;
896 {
897   register PTR result = (PTR) realloc (ptr, size);
898   if (!result)
899     fatal ("virtual memory exhausted");
900   return result;
901 }
902
903 static void
904 fatal VPROTO ((const char *format, ...))
905 {
906 #ifndef ANSI_PROTOTYPES
907   const char *format;
908 #endif
909   va_list ap;
910
911   VA_START (ap, format);
912
913 #ifndef ANSI_PROTOTYPES
914   format = va_arg (ap, const char *);
915 #endif
916
917   fprintf (stderr, "genoutput: ");
918   vfprintf (stderr, format, ap);
919   va_end (ap);
920   fprintf (stderr, "\n");
921   exit (FATAL_EXIT_CODE);
922 }
923
924 /* More 'friendly' abort that prints the line and file.
925    config.h can #define abort fancy_abort if you like that sort of thing.  */
926
927 void
928 fancy_abort ()
929 {
930   fatal ("Internal gcc abort.");
931 }
932
933 static void
934 error VPROTO ((const char *format, ...))
935 {
936 #ifndef ANSI_PROTOTYPES
937   const char *format;
938 #endif
939   va_list ap;
940
941   VA_START (ap, format);
942
943 #ifndef ANSI_PROTOTYPES
944   format = va_arg (ap, const char *);
945 #endif
946
947   fprintf (stderr, "genoutput: ");
948   vfprintf (stderr, format, ap);
949   va_end (ap);
950   fprintf (stderr, "\n");
951
952   have_error = 1;
953 }
954 \f
955 int
956 main (argc, argv)
957      int argc;
958      char **argv;
959 {
960   rtx desc;
961   FILE *infile;
962   register int c;
963
964   obstack_init (rtl_obstack);
965
966   if (argc <= 1)
967     fatal ("No input file name.");
968
969   infile = fopen (argv[1], "r");
970   if (infile == 0)
971     {
972       perror (argv[1]);
973       exit (FATAL_EXIT_CODE);
974     }
975
976   init_rtl ();
977
978   output_prologue ();
979   next_code_number = 0;
980   next_index_number = 0;
981   have_constraints = 0;
982
983   /* Read the machine description.  */
984
985   while (1)
986     {
987       c = read_skip_spaces (infile);
988       if (c == EOF)
989         break;
990       ungetc (c, infile);
991
992       desc = read_rtx (infile);
993       if (GET_CODE (desc) == DEFINE_INSN)
994         gen_insn (desc);
995       if (GET_CODE (desc) == DEFINE_PEEPHOLE)
996         gen_peephole (desc);
997       if (GET_CODE (desc) == DEFINE_EXPAND)
998         gen_expand (desc);
999       if (GET_CODE (desc) == DEFINE_SPLIT)
1000         gen_split (desc);
1001       next_index_number++;
1002     }
1003
1004   output_epilogue ();
1005
1006   fflush (stdout);
1007   exit (ferror (stdout) != 0 || have_error
1008         ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
1009
1010   /* NOTREACHED */
1011   return 0;
1012 }
1013
1014 static int
1015 n_occurrences (c, s)
1016      int c;
1017      char *s;
1018 {
1019   int n = 0;
1020   while (*s)
1021     n += (*s++ == c);
1022   return n;
1023 }