OSDN Git Service

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