OSDN Git Service

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