OSDN Git Service

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