OSDN Git Service

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