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