OSDN Git Service

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