1/* Generate code from to output assembler insns as recognized from rtl.
2   Copyright (C) 1987, 1988, 1992, 1994, 1995, 1997, 1998, 1999, 2000, 2002,
3   2003, 2004, 2005 Free Software Foundation, Inc.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 2, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING.  If not, write to the Free
19Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2002110-1301, USA.  */
21
22
23/* This program reads the machine description for the compiler target machine
24   and produces a file containing these things:
25
26   1. An array of `struct insn_data', which is indexed by insn code number,
27   which contains:
28
29     a. `name' is the name for that pattern.  Nameless patterns are
30     given a name.
31
32     b. `output' hold either the output template, an array of output
33     templates, or an output function.
34
35     c. `genfun' is the function to generate a body for that pattern,
36     given operands as arguments.
37
38     d. `n_operands' is the number of distinct operands in the pattern
39     for that insn,
40
41     e. `n_dups' is the number of match_dup's that appear in the insn's
42     pattern.  This says how many elements of `recog_data.dup_loc' are
43     significant after an insn has been recognized.
44
45     f. `n_alternatives' is the number of alternatives in the constraints
46     of each pattern.
47
48     g. `output_format' tells what type of thing `output' is.
49
50     h. `operand' is the base of an array of operand data for the insn.
51
52   2. An array of `struct insn_operand data', used by `operand' above.
53
54     a. `predicate', an int-valued function, is the match_operand predicate
55     for this operand.
56
57     b. `constraint' is the constraint for this operand.  This exists
58     only if register constraints appear in match_operand rtx's.
59
60     c. `address_p' indicates that the operand appears within ADDRESS
61     rtx's.  This exists only if there are *no* register constraints
62     in the match_operand rtx's.
63
64     d. `mode' is the machine mode that that operand is supposed to have.
65
66     e. `strict_low', is nonzero for operands contained in a STRICT_LOW_PART.
67
68     f. `eliminable', is nonzero for operands that are matched normally by
69     MATCH_OPERAND; it is zero for operands that should not be changed during
70     register elimination such as MATCH_OPERATORs.
71
72  The code number of an insn is simply its position in the machine
73  description; code numbers are assigned sequentially to entries in
74  the description, starting with code number 0.
75
76  Thus, the following entry in the machine description
77
78    (define_insn "clrdf"
79      [(set (match_operand:DF 0 "general_operand" "")
80	    (const_int 0))]
81      ""
82      "clrd %0")
83
84  assuming it is the 25th entry present, would cause
85  insn_data[24].template to be "clrd %0", and
86  insn_data[24].n_operands to be 1.  */
87
88#include "bconfig.h"
89#include "system.h"
90#include "coretypes.h"
91#include "tm.h"
92#include "rtl.h"
93#include "errors.h"
94#include "gensupport.h"
95
96/* No instruction can have more operands than this.  Sorry for this
97   arbitrary limit, but what machine will have an instruction with
98   this many operands?  */
99
100#define MAX_MAX_OPERANDS 40
101
102static int n_occurrences		(int, const char *);
103static const char *strip_whitespace	(const char *);
104
105/* insns in the machine description are assigned sequential code numbers
106   that are used by insn-recog.c (produced by genrecog) to communicate
107   to insn-output.c (produced by this program).  */
108
109static int next_code_number;
110
111/* This counts all definitions in the md file,
112   for the sake of error messages.  */
113
114static int next_index_number;
115
116/* This counts all operands used in the md file.  The first is null.  */
117
118static int next_operand_number = 1;
119
120/* Record in this chain all information about the operands we will output.  */
121
122struct operand_data
123{
124  struct operand_data *next;
125  int index;
126  const char *predicate;
127  const char *constraint;
128  enum machine_mode mode;
129  unsigned char n_alternatives;
130  char address_p;
131  char strict_low;
132  char eliminable;
133  char seen;
134};
135
136/* Begin with a null operand at index 0.  */
137
138static struct operand_data null_operand =
139{
140  0, 0, "", "", VOIDmode, 0, 0, 0, 0, 0
141};
142
143static struct operand_data *odata = &null_operand;
144static struct operand_data **odata_end = &null_operand.next;
145
146/* Must match the constants in recog.h.  */
147
148#define INSN_OUTPUT_FORMAT_NONE         0       /* abort */
149#define INSN_OUTPUT_FORMAT_SINGLE       1       /* const char * */
150#define INSN_OUTPUT_FORMAT_MULTI        2       /* const char * const * */
151#define INSN_OUTPUT_FORMAT_FUNCTION     3       /* const char * (*)(...) */
152
153/* Record in this chain all information that we will output,
154   associated with the code number of the insn.  */
155
156struct data
157{
158  struct data *next;
159  const char *name;
160  const char *template;
161  int code_number;
162  int index_number;
163  const char *filename;
164  int lineno;
165  int n_operands;		/* Number of operands this insn recognizes */
166  int n_dups;			/* Number times match_dup appears in pattern */
167  int n_alternatives;		/* Number of alternatives in each constraint */
168  int operand_number;		/* Operand index in the big array.  */
169  int output_format;		/* INSN_OUTPUT_FORMAT_*.  */
170  struct operand_data operand[MAX_MAX_OPERANDS];
171};
172
173/* This variable points to the first link in the insn chain.  */
174
175static struct data *idata, **idata_end = &idata;
176
177static void output_prologue (void);
178static void output_operand_data (void);
179static void output_insn_data (void);
180static void output_get_insn_name (void);
181static void scan_operands (struct data *, rtx, int, int);
182static int compare_operands (struct operand_data *,
183			     struct operand_data *);
184static void place_operands (struct data *);
185static void process_template (struct data *, const char *);
186static void validate_insn_alternatives (struct data *);
187static void validate_insn_operands (struct data *);
188static void gen_insn (rtx, int);
189static void gen_peephole (rtx, int);
190static void gen_expand (rtx, int);
191static void gen_split (rtx, int);
192static void check_constraint_len (void);
193static int constraint_len (const char *, int);
194
195const char *
196get_insn_name (int index)
197{
198  static char buf[100];
199
200  struct data *i, *last_named = NULL;
201  for (i = idata; i ; i = i->next)
202    {
203      if (i->index_number == index)
204	return i->name;
205      if (i->name)
206	last_named = i;
207    }
208
209  if (last_named)
210    sprintf(buf, "%s+%d", last_named->name, index - last_named->index_number);
211  else
212    sprintf(buf, "insn %d", index);
213
214  return buf;
215}
216
217static void
218output_prologue (void)
219{
220  printf ("/* Generated automatically by the program `genoutput'\n\
221   from the machine description file `md'.  */\n\n");
222
223  printf ("#include \"config.h\"\n");
224  printf ("#include \"system.h\"\n");
225  printf ("#include \"coretypes.h\"\n");
226  printf ("#include \"tm.h\"\n");
227  printf ("#include \"flags.h\"\n");
228  printf ("#include \"ggc.h\"\n");
229  printf ("#include \"rtl.h\"\n");
230  printf ("#include \"expr.h\"\n");
231  printf ("#include \"insn-codes.h\"\n");
232  printf ("#include \"tm_p.h\"\n");
233  printf ("#include \"function.h\"\n");
234  printf ("#include \"regs.h\"\n");
235  printf ("#include \"hard-reg-set.h\"\n");
236  printf ("#include \"real.h\"\n");
237  printf ("#include \"insn-config.h\"\n\n");
238  printf ("#include \"conditions.h\"\n");
239  printf ("#include \"insn-attr.h\"\n\n");
240  printf ("#include \"recog.h\"\n\n");
241  printf ("#include \"toplev.h\"\n");
242  printf ("#include \"output.h\"\n");
243  printf ("#include \"target.h\"\n");
244}
245
246static void
247output_operand_data (void)
248{
249  struct operand_data *d;
250
251  printf ("\nstatic const struct insn_operand_data operand_data[] = \n{\n");
252
253  for (d = odata; d; d = d->next)
254    {
255      printf ("  {\n");
256
257      printf ("    %s,\n",
258	      d->predicate && d->predicate[0] ? d->predicate : "0");
259
260      printf ("    \"%s\",\n", d->constraint ? d->constraint : "");
261
262      printf ("    %smode,\n", GET_MODE_NAME (d->mode));
263
264      printf ("    %d,\n", d->strict_low);
265
266      printf ("    %d\n", d->eliminable);
267
268      printf("  },\n");
269    }
270  printf("};\n\n\n");
271}
272
273static void
274output_insn_data (void)
275{
276  struct data *d;
277  int name_offset = 0;
278  int next_name_offset;
279  const char * last_name = 0;
280  const char * next_name = 0;
281  struct data *n;
282
283  for (n = idata, next_name_offset = 1; n; n = n->next, next_name_offset++)
284    if (n->name)
285      {
286	next_name = n->name;
287	break;
288      }
289
290  printf ("#if GCC_VERSION >= 2007\n__extension__\n#endif\n");
291  printf ("\nconst struct insn_data insn_data[] = \n{\n");
292
293  for (d = idata; d; d = d->next)
294    {
295      printf ("  /* %s:%d */\n", d->filename, d->lineno);
296      printf ("  {\n");
297
298      if (d->name)
299	{
300	  printf ("    \"%s\",\n", d->name);
301	  name_offset = 0;
302	  last_name = d->name;
303	  next_name = 0;
304	  for (n = d->next, next_name_offset = 1; n;
305	       n = n->next, next_name_offset++)
306	    {
307	      if (n->name)
308		{
309		  next_name = n->name;
310		  break;
311		}
312	    }
313	}
314      else
315	{
316	  name_offset++;
317	  if (next_name && (last_name == 0
318			    || name_offset > next_name_offset / 2))
319	    printf ("    \"%s-%d\",\n", next_name,
320		    next_name_offset - name_offset);
321	  else
322	    printf ("    \"%s+%d\",\n", last_name, name_offset);
323	}
324
325      switch (d->output_format)
326	{
327	case INSN_OUTPUT_FORMAT_NONE:
328	  printf ("#if HAVE_DESIGNATED_INITIALIZERS\n");
329	  printf ("    { 0 },\n");
330	  printf ("#else\n");
331	  printf ("    { 0, 0, 0 },\n");
332	  printf ("#endif\n");
333	  break;
334	case INSN_OUTPUT_FORMAT_SINGLE:
335	  {
336	    const char *p = d->template;
337	    char prev = 0;
338
339	    printf ("#if HAVE_DESIGNATED_INITIALIZERS\n");
340	    printf ("    { .single =\n");
341	    printf ("#else\n");
342	    printf ("    {\n");
343	    printf ("#endif\n");
344	    printf ("    \"");
345	    while (*p)
346	      {
347		if (IS_VSPACE (*p) && prev != '\\')
348		  {
349		    /* Preserve two consecutive \n's or \r's, but treat \r\n
350		       as a single newline.  */
351		    if (*p == '\n' && prev != '\r')
352		      printf ("\\n\\\n");
353		  }
354		else
355		  putchar (*p);
356		prev = *p;
357		++p;
358	      }
359	    printf ("\",\n");
360	    printf ("#if HAVE_DESIGNATED_INITIALIZERS\n");
361	    printf ("    },\n");
362	    printf ("#else\n");
363	    printf ("    0, 0 },\n");
364	    printf ("#endif\n");
365	  }
366	  break;
367	case INSN_OUTPUT_FORMAT_MULTI:
368	  printf ("#if HAVE_DESIGNATED_INITIALIZERS\n");
369	  printf ("    { .multi = output_%d },\n", d->code_number);
370	  printf ("#else\n");
371	  printf ("    { 0, output_%d, 0 },\n", d->code_number);
372	  printf ("#endif\n");
373	  break;
374	case INSN_OUTPUT_FORMAT_FUNCTION:
375	  printf ("#if HAVE_DESIGNATED_INITIALIZERS\n");
376	  printf ("    { .function = output_%d },\n", d->code_number);
377	  printf ("#else\n");
378	  printf ("    { 0, 0, output_%d },\n", d->code_number);
379	  printf ("#endif\n");
380	  break;
381	default:
382	  gcc_unreachable ();
383	}
384
385      if (d->name && d->name[0] != '*')
386	printf ("    (insn_gen_fn) gen_%s,\n", d->name);
387      else
388	printf ("    0,\n");
389
390      printf ("    &operand_data[%d],\n", d->operand_number);
391      printf ("    %d,\n", d->n_operands);
392      printf ("    %d,\n", d->n_dups);
393      printf ("    %d,\n", d->n_alternatives);
394      printf ("    %d\n", d->output_format);
395
396      printf("  },\n");
397    }
398  printf ("};\n\n\n");
399}
400
401static void
402output_get_insn_name (void)
403{
404  printf ("const char *\n");
405  printf ("get_insn_name (int code)\n");
406  printf ("{\n");
407  printf ("  if (code == NOOP_MOVE_INSN_CODE)\n");
408  printf ("    return \"NOOP_MOVE\";\n");
409  printf ("  else\n");
410  printf ("    return insn_data[code].name;\n");
411  printf ("}\n");
412}
413
414
415/* Stores in max_opno the largest operand number present in `part', if
416   that is larger than the previous value of max_opno, and the rest of
417   the operand data into `d->operand[i]'.
418
419   THIS_ADDRESS_P is nonzero if the containing rtx was an ADDRESS.
420   THIS_STRICT_LOW is nonzero if the containing rtx was a STRICT_LOW_PART.  */
421
422static int max_opno;
423static int num_dups;
424
425static void
426scan_operands (struct data *d, rtx part, int this_address_p,
427	       int this_strict_low)
428{
429  int i, j;
430  const char *format_ptr;
431  int opno;
432
433  if (part == 0)
434    return;
435
436  switch (GET_CODE (part))
437    {
438    case MATCH_OPERAND:
439      opno = XINT (part, 0);
440      if (opno > max_opno)
441	max_opno = opno;
442      if (max_opno >= MAX_MAX_OPERANDS)
443	{
444	  message_with_line (d->lineno,
445			     "maximum number of operands exceeded");
446	  have_error = 1;
447	  return;
448	}
449      if (d->operand[opno].seen)
450	{
451	  message_with_line (d->lineno,
452			     "repeated operand number %d\n", opno);
453	  have_error = 1;
454	}
455
456      d->operand[opno].seen = 1;
457      d->operand[opno].mode = GET_MODE (part);
458      d->operand[opno].strict_low = this_strict_low;
459      d->operand[opno].predicate = XSTR (part, 1);
460      d->operand[opno].constraint = strip_whitespace (XSTR (part, 2));
461      d->operand[opno].n_alternatives
462	= n_occurrences (',', d->operand[opno].constraint) + 1;
463      d->operand[opno].address_p = this_address_p;
464      d->operand[opno].eliminable = 1;
465      return;
466
467    case MATCH_SCRATCH:
468      opno = XINT (part, 0);
469      if (opno > max_opno)
470	max_opno = opno;
471      if (max_opno >= MAX_MAX_OPERANDS)
472	{
473	  message_with_line (d->lineno,
474			     "maximum number of operands exceeded");
475	  have_error = 1;
476	  return;
477	}
478      if (d->operand[opno].seen)
479	{
480	  message_with_line (d->lineno,
481			     "repeated operand number %d\n", opno);
482	  have_error = 1;
483	}
484
485      d->operand[opno].seen = 1;
486      d->operand[opno].mode = GET_MODE (part);
487      d->operand[opno].strict_low = 0;
488      d->operand[opno].predicate = "scratch_operand";
489      d->operand[opno].constraint = strip_whitespace (XSTR (part, 1));
490      d->operand[opno].n_alternatives
491	= n_occurrences (',', d->operand[opno].constraint) + 1;
492      d->operand[opno].address_p = 0;
493      d->operand[opno].eliminable = 0;
494      return;
495
496    case MATCH_OPERATOR:
497    case MATCH_PARALLEL:
498      opno = XINT (part, 0);
499      if (opno > max_opno)
500	max_opno = opno;
501      if (max_opno >= MAX_MAX_OPERANDS)
502	{
503	  message_with_line (d->lineno,
504			     "maximum number of operands exceeded");
505	  have_error = 1;
506	  return;
507	}
508      if (d->operand[opno].seen)
509	{
510	  message_with_line (d->lineno,
511			     "repeated operand number %d\n", opno);
512	  have_error = 1;
513	}
514
515      d->operand[opno].seen = 1;
516      d->operand[opno].mode = GET_MODE (part);
517      d->operand[opno].strict_low = 0;
518      d->operand[opno].predicate = XSTR (part, 1);
519      d->operand[opno].constraint = 0;
520      d->operand[opno].address_p = 0;
521      d->operand[opno].eliminable = 0;
522      for (i = 0; i < XVECLEN (part, 2); i++)
523	scan_operands (d, XVECEXP (part, 2, i), 0, 0);
524      return;
525
526    case MATCH_DUP:
527    case MATCH_OP_DUP:
528    case MATCH_PAR_DUP:
529      ++num_dups;
530      break;
531
532    case ADDRESS:
533      scan_operands (d, XEXP (part, 0), 1, 0);
534      return;
535
536    case STRICT_LOW_PART:
537      scan_operands (d, XEXP (part, 0), 0, 1);
538      return;
539
540    default:
541      break;
542    }
543
544  format_ptr = GET_RTX_FORMAT (GET_CODE (part));
545
546  for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
547    switch (*format_ptr++)
548      {
549      case 'e':
550      case 'u':
551	scan_operands (d, XEXP (part, i), 0, 0);
552	break;
553      case 'E':
554	if (XVEC (part, i) != NULL)
555	  for (j = 0; j < XVECLEN (part, i); j++)
556	    scan_operands (d, XVECEXP (part, i, j), 0, 0);
557	break;
558      }
559}
560
561/* Compare two operands for content equality.  */
562
563static int
564compare_operands (struct operand_data *d0, struct operand_data *d1)
565{
566  const char *p0, *p1;
567
568  p0 = d0->predicate;
569  if (!p0)
570    p0 = "";
571  p1 = d1->predicate;
572  if (!p1)
573    p1 = "";
574  if (strcmp (p0, p1) != 0)
575    return 0;
576
577  p0 = d0->constraint;
578  if (!p0)
579    p0 = "";
580  p1 = d1->constraint;
581  if (!p1)
582    p1 = "";
583  if (strcmp (p0, p1) != 0)
584    return 0;
585
586  if (d0->mode != d1->mode)
587    return 0;
588
589  if (d0->strict_low != d1->strict_low)
590    return 0;
591
592  if (d0->eliminable != d1->eliminable)
593    return 0;
594
595  return 1;
596}
597
598/* Scan the list of operands we've already committed to output and either
599   find a subsequence that is the same, or allocate a new one at the end.  */
600
601static void
602place_operands (struct data *d)
603{
604  struct operand_data *od, *od2;
605  int i;
606
607  if (d->n_operands == 0)
608    {
609      d->operand_number = 0;
610      return;
611    }
612
613  /* Brute force substring search.  */
614  for (od = odata, i = 0; od; od = od->next, i = 0)
615    if (compare_operands (od, &d->operand[0]))
616      {
617	od2 = od->next;
618	i = 1;
619	while (1)
620	  {
621	    if (i == d->n_operands)
622	      goto full_match;
623	    if (od2 == NULL)
624	      goto partial_match;
625	    if (! compare_operands (od2, &d->operand[i]))
626	      break;
627	    ++i, od2 = od2->next;
628	  }
629      }
630
631  /* Either partial match at the end of the list, or no match.  In either
632     case, we tack on what operands are remaining to the end of the list.  */
633 partial_match:
634  d->operand_number = next_operand_number - i;
635  for (; i < d->n_operands; ++i)
636    {
637      od2 = &d->operand[i];
638      *odata_end = od2;
639      odata_end = &od2->next;
640      od2->index = next_operand_number++;
641    }
642  *odata_end = NULL;
643  return;
644
645 full_match:
646  d->operand_number = od->index;
647  return;
648}
649
650
651/* Process an assembler template from a define_insn or a define_peephole.
652   It is either the assembler code template, a list of assembler code
653   templates, or C code to generate the assembler code template.  */
654
655static void
656process_template (struct data *d, const char *template)
657{
658  const char *cp;
659  int i;
660
661  /* Templates starting with * contain straight code to be run.  */
662  if (template[0] == '*')
663    {
664      d->template = 0;
665      d->output_format = INSN_OUTPUT_FORMAT_FUNCTION;
666
667      puts ("\nstatic const char *");
668      printf ("output_%d (rtx *operands ATTRIBUTE_UNUSED, rtx insn ATTRIBUTE_UNUSED)\n",
669	      d->code_number);
670      puts ("{");
671      print_rtx_ptr_loc (template);
672      puts (template + 1);
673      puts ("}");
674    }
675
676  /* If the assembler code template starts with a @ it is a newline-separated
677     list of assembler code templates, one for each alternative.  */
678  else if (template[0] == '@')
679    {
680      d->template = 0;
681      d->output_format = INSN_OUTPUT_FORMAT_MULTI;
682
683      printf ("\nstatic const char * const output_%d[] = {\n", d->code_number);
684
685      for (i = 0, cp = &template[1]; *cp; )
686	{
687	  const char *ep, *sp;
688
689	  while (ISSPACE (*cp))
690	    cp++;
691
692	  printf ("  \"");
693
694	  for (ep = sp = cp; !IS_VSPACE (*ep) && *ep != '\0'; ++ep)
695	    if (!ISSPACE (*ep))
696	      sp = ep + 1;
697
698	  if (sp != ep)
699	    message_with_line (d->lineno,
700			       "trailing whitespace in output template");
701
702	  while (cp < sp)
703	    {
704	      putchar (*cp);
705	      cp++;
706	    }
707
708	  printf ("\",\n");
709	  i++;
710	}
711      if (i == 1)
712	message_with_line (d->lineno,
713			   "'@' is redundant for output template with single alternative");
714      if (i != d->n_alternatives)
715	{
716	  message_with_line (d->lineno,
717			     "wrong number of alternatives in the output template");
718	  have_error = 1;
719	}
720
721      printf ("};\n");
722    }
723  else
724    {
725      d->template = template;
726      d->output_format = INSN_OUTPUT_FORMAT_SINGLE;
727    }
728}
729
730/* Check insn D for consistency in number of constraint alternatives.  */
731
732static void
733validate_insn_alternatives (struct data *d)
734{
735  int n = 0, start;
736
737  /* Make sure all the operands have the same number of alternatives
738     in their constraints.  Let N be that number.  */
739  for (start = 0; start < d->n_operands; start++)
740    if (d->operand[start].n_alternatives > 0)
741      {
742	int len, i;
743	const char *p;
744	char c;
745	int which_alternative = 0;
746	int alternative_count_unsure = 0;
747
748	for (p = d->operand[start].constraint; (c = *p); p += len)
749	  {
750	    len = CONSTRAINT_LEN (c, p);
751
752	    if (len < 1 || (len > 1 && strchr (",#*+=&%!0123456789", c)))
753	      {
754		message_with_line (d->lineno,
755				   "invalid length %d for char '%c' in alternative %d of operand %d",
756				    len, c, which_alternative, start);
757		len = 1;
758		have_error = 1;
759	      }
760
761	    if (c == ',')
762	      {
763	        which_alternative++;
764		continue;
765	      }
766
767	    for (i = 1; i < len; i++)
768	      if (p[i] == '\0')
769		{
770		  message_with_line (d->lineno,
771				     "NUL in alternative %d of operand %d",
772				     which_alternative, start);
773		  alternative_count_unsure = 1;
774		  break;
775		}
776	      else if (strchr (",#*", p[i]))
777		{
778		  message_with_line (d->lineno,
779				     "'%c' in alternative %d of operand %d",
780				     p[i], which_alternative, start);
781		  alternative_count_unsure = 1;
782		}
783	  }
784	if (alternative_count_unsure)
785	  have_error = 1;
786	else if (n == 0)
787	  n = d->operand[start].n_alternatives;
788	else if (n != d->operand[start].n_alternatives)
789	  {
790	    message_with_line (d->lineno,
791			       "wrong number of alternatives in operand %d",
792			       start);
793	    have_error = 1;
794	  }
795      }
796
797  /* Record the insn's overall number of alternatives.  */
798  d->n_alternatives = n;
799}
800
801/* Verify that there are no gaps in operand numbers for INSNs.  */
802
803static void
804validate_insn_operands (struct data *d)
805{
806  int i;
807
808  for (i = 0; i < d->n_operands; ++i)
809    if (d->operand[i].seen == 0)
810      {
811	message_with_line (d->lineno, "missing operand %d", i);
812	have_error = 1;
813      }
814}
815
816/* Look at a define_insn just read.  Assign its code number.  Record
817   on idata the template and the number of arguments.  If the insn has
818   a hairy output action, output a function for now.  */
819
820static void
821gen_insn (rtx insn, int lineno)
822{
823  struct data *d = xmalloc (sizeof (struct data));
824  int i;
825
826  d->code_number = next_code_number;
827  d->index_number = next_index_number;
828  d->filename = read_rtx_filename;
829  d->lineno = lineno;
830  if (XSTR (insn, 0)[0])
831    d->name = XSTR (insn, 0);
832  else
833    d->name = 0;
834
835  /* Build up the list in the same order as the insns are seen
836     in the machine description.  */
837  d->next = 0;
838  *idata_end = d;
839  idata_end = &d->next;
840
841  max_opno = -1;
842  num_dups = 0;
843  memset (d->operand, 0, sizeof (d->operand));
844
845  for (i = 0; i < XVECLEN (insn, 1); i++)
846    scan_operands (d, XVECEXP (insn, 1, i), 0, 0);
847
848  d->n_operands = max_opno + 1;
849  d->n_dups = num_dups;
850
851  check_constraint_len ();
852  validate_insn_operands (d);
853  validate_insn_alternatives (d);
854  place_operands (d);
855  process_template (d, XTMPL (insn, 3));
856}
857
858/* Look at a define_peephole just read.  Assign its code number.
859   Record on idata the template and the number of arguments.
860   If the insn has a hairy output action, output it now.  */
861
862static void
863gen_peephole (rtx peep, int lineno)
864{
865  struct data *d = xmalloc (sizeof (struct data));
866  int i;
867
868  d->code_number = next_code_number;
869  d->index_number = next_index_number;
870  d->filename = read_rtx_filename;
871  d->lineno = lineno;
872  d->name = 0;
873
874  /* Build up the list in the same order as the insns are seen
875     in the machine description.  */
876  d->next = 0;
877  *idata_end = d;
878  idata_end = &d->next;
879
880  max_opno = -1;
881  num_dups = 0;
882  memset (d->operand, 0, sizeof (d->operand));
883
884  /* Get the number of operands by scanning all the patterns of the
885     peephole optimizer.  But ignore all the rest of the information
886     thus obtained.  */
887  for (i = 0; i < XVECLEN (peep, 0); i++)
888    scan_operands (d, XVECEXP (peep, 0, i), 0, 0);
889
890  d->n_operands = max_opno + 1;
891  d->n_dups = 0;
892
893  validate_insn_alternatives (d);
894  place_operands (d);
895  process_template (d, XTMPL (peep, 2));
896}
897
898/* Process a define_expand just read.  Assign its code number,
899   only for the purposes of `insn_gen_function'.  */
900
901static void
902gen_expand (rtx insn, int lineno)
903{
904  struct data *d = xmalloc (sizeof (struct data));
905  int i;
906
907  d->code_number = next_code_number;
908  d->index_number = next_index_number;
909  d->filename = read_rtx_filename;
910  d->lineno = lineno;
911  if (XSTR (insn, 0)[0])
912    d->name = XSTR (insn, 0);
913  else
914    d->name = 0;
915
916  /* Build up the list in the same order as the insns are seen
917     in the machine description.  */
918  d->next = 0;
919  *idata_end = d;
920  idata_end = &d->next;
921
922  max_opno = -1;
923  num_dups = 0;
924  memset (d->operand, 0, sizeof (d->operand));
925
926  /* Scan the operands to get the specified predicates and modes,
927     since expand_binop needs to know them.  */
928
929  if (XVEC (insn, 1))
930    for (i = 0; i < XVECLEN (insn, 1); i++)
931      scan_operands (d, XVECEXP (insn, 1, i), 0, 0);
932
933  d->n_operands = max_opno + 1;
934  d->n_dups = num_dups;
935  d->template = 0;
936  d->output_format = INSN_OUTPUT_FORMAT_NONE;
937
938  validate_insn_alternatives (d);
939  place_operands (d);
940}
941
942/* Process a define_split just read.  Assign its code number,
943   only for reasons of consistency and to simplify genrecog.  */
944
945static void
946gen_split (rtx split, int lineno)
947{
948  struct data *d = xmalloc (sizeof (struct data));
949  int i;
950
951  d->code_number = next_code_number;
952  d->index_number = next_index_number;
953  d->filename = read_rtx_filename;
954  d->lineno = lineno;
955  d->name = 0;
956
957  /* Build up the list in the same order as the insns are seen
958     in the machine description.  */
959  d->next = 0;
960  *idata_end = d;
961  idata_end = &d->next;
962
963  max_opno = -1;
964  num_dups = 0;
965  memset (d->operand, 0, sizeof (d->operand));
966
967  /* Get the number of operands by scanning all the patterns of the
968     split patterns.  But ignore all the rest of the information thus
969     obtained.  */
970  for (i = 0; i < XVECLEN (split, 0); i++)
971    scan_operands (d, XVECEXP (split, 0, i), 0, 0);
972
973  d->n_operands = max_opno + 1;
974  d->n_dups = 0;
975  d->n_alternatives = 0;
976  d->template = 0;
977  d->output_format = INSN_OUTPUT_FORMAT_NONE;
978
979  place_operands (d);
980}
981
982extern int main (int, char **);
983
984int
985main (int argc, char **argv)
986{
987  rtx desc;
988
989  progname = "genoutput";
990
991  if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
992    return (FATAL_EXIT_CODE);
993
994  output_prologue ();
995  next_code_number = 0;
996  next_index_number = 0;
997
998  /* Read the machine description.  */
999
1000  while (1)
1001    {
1002      int line_no;
1003
1004      desc = read_md_rtx (&line_no, &next_code_number);
1005      if (desc == NULL)
1006	break;
1007
1008      if (GET_CODE (desc) == DEFINE_INSN)
1009	gen_insn (desc, line_no);
1010      if (GET_CODE (desc) == DEFINE_PEEPHOLE)
1011	gen_peephole (desc, line_no);
1012      if (GET_CODE (desc) == DEFINE_EXPAND)
1013	gen_expand (desc, line_no);
1014      if (GET_CODE (desc) == DEFINE_SPLIT
1015	  || GET_CODE (desc) == DEFINE_PEEPHOLE2)
1016	gen_split (desc, line_no);
1017      next_index_number++;
1018    }
1019
1020  printf("\n\n");
1021  output_operand_data ();
1022  output_insn_data ();
1023  output_get_insn_name ();
1024
1025  fflush (stdout);
1026  return (ferror (stdout) != 0 || have_error
1027	? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
1028}
1029
1030/* Return the number of occurrences of character C in string S or
1031   -1 if S is the null string.  */
1032
1033static int
1034n_occurrences (int c, const char *s)
1035{
1036  int n = 0;
1037
1038  if (s == 0 || *s == '\0')
1039    return -1;
1040
1041  while (*s)
1042    n += (*s++ == c);
1043
1044  return n;
1045}
1046
1047/* Remove whitespace in `s' by moving up characters until the end.
1048   Return a new string.  */
1049
1050static const char *
1051strip_whitespace (const char *s)
1052{
1053  char *p, *q;
1054  char ch;
1055
1056  if (s == 0)
1057    return 0;
1058
1059  p = q = xmalloc (strlen (s) + 1);
1060  while ((ch = *s++) != '\0')
1061    if (! ISSPACE (ch))
1062      *p++ = ch;
1063
1064  *p = '\0';
1065  return q;
1066}
1067
1068/* Verify that DEFAULT_CONSTRAINT_LEN is used properly and not
1069   tampered with.  This isn't bullet-proof, but it should catch
1070   most genuine mistakes.  */
1071static void
1072check_constraint_len (void)
1073{
1074  const char *p;
1075  int d;
1076
1077  for (p = ",#*+=&%!1234567890"; *p; p++)
1078    for (d = -9; d < 9; d++)
1079      gcc_assert (constraint_len (p, d) == d);
1080}
1081
1082static int
1083constraint_len (const char *p, int genoutput_default_constraint_len)
1084{
1085  /* Check that we still match defaults.h .  First we do a generation-time
1086     check that fails if the value is not the expected one...  */
1087  gcc_assert (DEFAULT_CONSTRAINT_LEN (*p, p) == 1);
1088  /* And now a compile-time check that should give a diagnostic if the
1089     definition doesn't exactly match.  */
1090#define DEFAULT_CONSTRAINT_LEN(C,STR) 1
1091  /* Now re-define DEFAULT_CONSTRAINT_LEN so that we can verify it is
1092     being used.  */
1093#undef DEFAULT_CONSTRAINT_LEN
1094#define DEFAULT_CONSTRAINT_LEN(C,STR) \
1095  ((C) != *p || STR != p ? -1 : genoutput_default_constraint_len)
1096  return CONSTRAINT_LEN (*p, p);
1097  /* And set it back.  */
1098#undef DEFAULT_CONSTRAINT_LEN
1099#define DEFAULT_CONSTRAINT_LEN(C,STR) 1
1100}
1101