OSDN Git Service

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