OSDN Git Service

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