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