OSDN Git Service

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