OSDN Git Service

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