OSDN Git Service

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