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