OSDN Git Service

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