OSDN Git Service

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