]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/genoutput.c
genopinit.c: Use $ for escape sequences in optab patterns.
[thirdparty/gcc.git] / gcc / genoutput.c
1 /* Generate code from to output assembler insns as recognized from rtl.
2 Copyright (C) 1987, 1988, 1992, 1994, 1995, 1997, 1998, 1999, 2000
3 Free Software Foundation, Inc.
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, 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 \f
88 #include "hconfig.h"
89 #include "system.h"
90 #include "rtl.h"
91 #include "errors.h"
92 #include "gensupport.h"
93
94 /* No instruction can have more operands than this. Sorry for this
95 arbitrary limit, but what machine will have an instruction with
96 this many operands? */
97
98 #define MAX_MAX_OPERANDS 40
99
100 static int n_occurrences PARAMS ((int, const char *));
101 static const char *strip_whitespace PARAMS ((const char *));
102
103 /* insns in the machine description are assigned sequential code numbers
104 that are used by insn-recog.c (produced by genrecog) to communicate
105 to insn-output.c (produced by this program). */
106
107 static int next_code_number;
108
109 /* This counts all definitions in the md file,
110 for the sake of error messages. */
111
112 static int next_index_number;
113
114 /* This counts all operands used in the md file. The first is null. */
115
116 static int next_operand_number = 1;
117
118 /* Record in this chain all information about the operands we will output. */
119
120 struct operand_data
121 {
122 struct operand_data *next;
123 int index;
124 const char *predicate;
125 const char *constraint;
126 enum machine_mode mode;
127 unsigned char n_alternatives;
128 char address_p;
129 char strict_low;
130 char eliminable;
131 char seen;
132 };
133
134 /* Begin with a null operand at index 0. */
135
136 static struct operand_data null_operand =
137 {
138 0, 0, "", "", VOIDmode, 0, 0, 0, 0, 0
139 };
140
141 static struct operand_data *odata = &null_operand;
142 static struct operand_data **odata_end = &null_operand.next;
143
144 /* Must match the constants in recog.h. */
145
146 #define INSN_OUTPUT_FORMAT_NONE 0 /* abort */
147 #define INSN_OUTPUT_FORMAT_SINGLE 1 /* const char * */
148 #define INSN_OUTPUT_FORMAT_MULTI 2 /* const char * const * */
149 #define INSN_OUTPUT_FORMAT_FUNCTION 3 /* const char * (*)(...) */
150
151 /* Record in this chain all information that we will output,
152 associated with the code number of the insn. */
153
154 struct data
155 {
156 struct data *next;
157 const char *name;
158 const char *template;
159 int code_number;
160 int index_number;
161 int n_operands; /* Number of operands this insn recognizes */
162 int n_dups; /* Number times match_dup appears in pattern */
163 int n_alternatives; /* Number of alternatives in each constraint */
164 int operand_number; /* Operand index in the big array. */
165 int output_format; /* INSN_OUTPUT_FORMAT_*. */
166 struct operand_data operand[MAX_MAX_OPERANDS];
167 };
168
169 /* This variable points to the first link in the insn chain. */
170
171 static struct data *idata, **idata_end = &idata;
172 \f
173 static void output_prologue PARAMS ((void));
174 static void output_predicate_decls PARAMS ((void));
175 static void output_operand_data PARAMS ((void));
176 static void output_insn_data PARAMS ((void));
177 static void output_get_insn_name PARAMS ((void));
178 static void scan_operands PARAMS ((struct data *, rtx, int, int));
179 static int compare_operands PARAMS ((struct operand_data *,
180 struct operand_data *));
181 static void place_operands PARAMS ((struct data *));
182 static void process_template PARAMS ((struct data *, const char *));
183 static void validate_insn_alternatives PARAMS ((struct data *));
184 static void gen_insn PARAMS ((rtx));
185 static void gen_peephole PARAMS ((rtx));
186 static void gen_expand PARAMS ((rtx));
187 static void gen_split PARAMS ((rtx));
188 \f
189 const char *
190 get_insn_name (index)
191 int index;
192 {
193 static char buf[100];
194
195 struct data *i, *last_named = NULL;
196 for (i = idata; i ; i = i->next)
197 {
198 if (i->index_number == index)
199 return i->name;
200 if (i->name)
201 last_named = i;
202 }
203
204 if (last_named)
205 sprintf(buf, "%s+%d", last_named->name, index - last_named->index_number);
206 else
207 sprintf(buf, "insn %d", index);
208
209 return buf;
210 }
211
212 static void
213 output_prologue ()
214 {
215 printf ("/* Generated automatically by the program `genoutput'\n\
216 from the machine description file `md'. */\n\n");
217
218 printf ("#include \"config.h\"\n");
219 printf ("#include \"system.h\"\n");
220 printf ("#include \"flags.h\"\n");
221 printf ("#include \"ggc.h\"\n");
222 printf ("#include \"rtl.h\"\n");
223 printf ("#include \"tm_p.h\"\n");
224 printf ("#include \"function.h\"\n");
225 printf ("#include \"regs.h\"\n");
226 printf ("#include \"hard-reg-set.h\"\n");
227 printf ("#include \"real.h\"\n");
228 printf ("#include \"insn-config.h\"\n\n");
229 printf ("#include \"conditions.h\"\n");
230 printf ("#include \"insn-flags.h\"\n");
231 printf ("#include \"insn-attr.h\"\n\n");
232 printf ("#include \"insn-codes.h\"\n\n");
233 printf ("#include \"recog.h\"\n\n");
234 printf ("#include \"toplev.h\"\n");
235 printf ("#include \"output.h\"\n");
236 }
237
238
239 /* We need to define all predicates used. Keep a list of those we
240 have defined so far. There normally aren't very many predicates
241 used, so a linked list should be fast enough. */
242
243 static void
244 output_predicate_decls ()
245 {
246 struct predicate { const char *name; struct predicate *next; } *predicates = 0;
247 register struct operand_data *d;
248 struct predicate *p;
249
250 for (d = odata; d; d = d->next)
251 if (d->predicate && d->predicate[0])
252 {
253 for (p = predicates; p; p = p->next)
254 if (strcmp (p->name, d->predicate) == 0)
255 break;
256
257 if (p == 0)
258 {
259 printf ("extern int %s PARAMS ((rtx, enum machine_mode));\n",
260 d->predicate);
261 p = (struct predicate *) alloca (sizeof (struct predicate));
262 p->name = d->predicate;
263 p->next = predicates;
264 predicates = p;
265 }
266 }
267
268 printf ("\n\n");
269 }
270
271 static void
272 output_operand_data ()
273 {
274 register struct operand_data *d;
275
276 printf ("\nstatic const struct insn_operand_data operand_data[] = \n{\n");
277
278 for (d = odata; d; d = d->next)
279 {
280 printf (" {\n");
281
282 printf (" %s,\n",
283 d->predicate && d->predicate[0] ? d->predicate : "0");
284
285 printf (" \"%s\",\n", d->constraint ? d->constraint : "");
286
287 printf (" %smode,\n", GET_MODE_NAME (d->mode));
288
289 printf (" %d,\n", d->strict_low);
290
291 printf (" %d\n", d->eliminable);
292
293 printf(" },\n");
294 }
295 printf("};\n\n\n");
296 }
297
298 static void
299 output_insn_data ()
300 {
301 register struct data *d;
302 int name_offset = 0;
303 int next_name_offset;
304 const char * last_name = 0;
305 const char * next_name = 0;
306 register struct data *n;
307
308 for (n = idata, next_name_offset = 1; n; n = n->next, next_name_offset++)
309 if (n->name)
310 {
311 next_name = n->name;
312 break;
313 }
314
315 printf ("\nconst struct insn_data insn_data[] = \n{\n");
316
317 for (d = idata; d; d = d->next)
318 {
319 printf (" {\n");
320
321 if (d->name)
322 {
323 printf (" \"%s\",\n", d->name);
324 name_offset = 0;
325 last_name = d->name;
326 next_name = 0;
327 for (n = d->next, next_name_offset = 1; n;
328 n = n->next, next_name_offset++)
329 {
330 if (n->name)
331 {
332 next_name = n->name;
333 break;
334 }
335 }
336 }
337 else
338 {
339 name_offset++;
340 if (next_name && (last_name == 0
341 || name_offset > next_name_offset / 2))
342 printf (" \"%s-%d\",\n", next_name,
343 next_name_offset - name_offset);
344 else
345 printf (" \"%s+%d\",\n", last_name, name_offset);
346 }
347
348 switch (d->output_format)
349 {
350 case INSN_OUTPUT_FORMAT_NONE:
351 printf (" 0,\n");
352 break;
353 case INSN_OUTPUT_FORMAT_SINGLE:
354 printf (" \"%s\",\n", d->template);
355 break;
356 case INSN_OUTPUT_FORMAT_MULTI:
357 case INSN_OUTPUT_FORMAT_FUNCTION:
358 printf (" (const PTR) output_%d,\n", d->code_number);
359 break;
360 default:
361 abort ();
362 }
363
364 if (d->name && d->name[0] != '*')
365 printf (" (insn_gen_fn) gen_%s,\n", d->name);
366 else
367 printf (" 0,\n");
368
369 printf (" &operand_data[%d],\n", d->operand_number);
370 printf (" %d,\n", d->n_operands);
371 printf (" %d,\n", d->n_dups);
372 printf (" %d,\n", d->n_alternatives);
373 printf (" %d\n", d->output_format);
374
375 printf(" },\n");
376 }
377 printf ("};\n\n\n");
378 }
379
380 static void
381 output_get_insn_name ()
382 {
383 printf ("const char *\n");
384 printf ("get_insn_name (code)\n");
385 printf (" int code;\n");
386 printf ("{\n");
387 printf (" return insn_data[code].name;\n");
388 printf ("}\n");
389 }
390
391 \f
392 /* Stores in max_opno the largest operand number present in `part', if
393 that is larger than the previous value of max_opno, and the rest of
394 the operand data into `d->operand[i]'.
395
396 THIS_ADDRESS_P is nonzero if the containing rtx was an ADDRESS.
397 THIS_STRICT_LOW is nonzero if the containing rtx was a STRICT_LOW_PART. */
398
399 static int max_opno;
400 static int num_dups;
401
402 static void
403 scan_operands (d, part, this_address_p, this_strict_low)
404 struct data *d;
405 rtx part;
406 int this_address_p;
407 int this_strict_low;
408 {
409 register int i, j;
410 register const char *format_ptr;
411 int opno;
412
413 if (part == 0)
414 return;
415
416 switch (GET_CODE (part))
417 {
418 case MATCH_OPERAND:
419 opno = XINT (part, 0);
420 if (opno > max_opno)
421 max_opno = opno;
422 if (max_opno >= MAX_MAX_OPERANDS)
423 {
424 error ("Too many operands (%d) in definition %s.\n",
425 max_opno + 1, get_insn_name (next_index_number));
426 return;
427 }
428 if (d->operand[opno].seen)
429 error ("Definition %s specified operand number %d more than once.\n",
430 get_insn_name (next_index_number), opno);
431 d->operand[opno].seen = 1;
432 d->operand[opno].mode = GET_MODE (part);
433 d->operand[opno].strict_low = this_strict_low;
434 d->operand[opno].predicate = XSTR (part, 1);
435 d->operand[opno].constraint = strip_whitespace (XSTR (part, 2));
436 d->operand[opno].n_alternatives
437 = n_occurrences (',', d->operand[opno].constraint) + 1;
438 d->operand[opno].address_p = this_address_p;
439 d->operand[opno].eliminable = 1;
440 return;
441
442 case MATCH_SCRATCH:
443 opno = XINT (part, 0);
444 if (opno > max_opno)
445 max_opno = opno;
446 if (max_opno >= MAX_MAX_OPERANDS)
447 {
448 error ("Too many operands (%d) in definition %s.\n",
449 max_opno + 1, get_insn_name (next_index_number));
450 return;
451 }
452 if (d->operand[opno].seen)
453 error ("Definition %s specified operand number %d more than once.\n",
454 get_insn_name (next_index_number), opno);
455 d->operand[opno].seen = 1;
456 d->operand[opno].mode = GET_MODE (part);
457 d->operand[opno].strict_low = 0;
458 d->operand[opno].predicate = "scratch_operand";
459 d->operand[opno].constraint = strip_whitespace (XSTR (part, 1));
460 d->operand[opno].n_alternatives
461 = n_occurrences (',', d->operand[opno].constraint) + 1;
462 d->operand[opno].address_p = 0;
463 d->operand[opno].eliminable = 0;
464 return;
465
466 case MATCH_OPERATOR:
467 case MATCH_PARALLEL:
468 opno = XINT (part, 0);
469 if (opno > max_opno)
470 max_opno = opno;
471 if (max_opno >= MAX_MAX_OPERANDS)
472 {
473 error ("Too many operands (%d) in definition %s.\n",
474 max_opno + 1, get_insn_name (next_index_number));
475 return;
476 }
477 if (d->operand[opno].seen)
478 error ("Definition %s specified operand number %d more than once.\n",
479 get_insn_name (next_index_number), opno);
480 d->operand[opno].seen = 1;
481 d->operand[opno].mode = GET_MODE (part);
482 d->operand[opno].strict_low = 0;
483 d->operand[opno].predicate = XSTR (part, 1);
484 d->operand[opno].constraint = 0;
485 d->operand[opno].address_p = 0;
486 d->operand[opno].eliminable = 0;
487 for (i = 0; i < XVECLEN (part, 2); i++)
488 scan_operands (d, XVECEXP (part, 2, i), 0, 0);
489 return;
490
491 case MATCH_DUP:
492 case MATCH_OP_DUP:
493 case MATCH_PAR_DUP:
494 ++num_dups;
495 return;
496
497 case ADDRESS:
498 scan_operands (d, XEXP (part, 0), 1, 0);
499 return;
500
501 case STRICT_LOW_PART:
502 scan_operands (d, XEXP (part, 0), 0, 1);
503 return;
504
505 default:
506 break;
507 }
508
509 format_ptr = GET_RTX_FORMAT (GET_CODE (part));
510
511 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
512 switch (*format_ptr++)
513 {
514 case 'e':
515 case 'u':
516 scan_operands (d, XEXP (part, i), 0, 0);
517 break;
518 case 'E':
519 if (XVEC (part, i) != NULL)
520 for (j = 0; j < XVECLEN (part, i); j++)
521 scan_operands (d, XVECEXP (part, i, j), 0, 0);
522 break;
523 }
524 }
525
526 /* Compare two operands for content equality. */
527
528 static int
529 compare_operands (d0, d1)
530 struct operand_data *d0, *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
568 place_operands (d)
569 struct data *d;
570 {
571 struct operand_data *od, *od2;
572 int i;
573
574 if (d->n_operands == 0)
575 {
576 d->operand_number = 0;
577 return;
578 }
579
580 /* Brute force substring search. */
581 for (od = odata, i = 0; od; od = od->next, i = 0)
582 if (compare_operands (od, &d->operand[0]))
583 {
584 od2 = od->next;
585 i = 1;
586 while (1)
587 {
588 if (i == d->n_operands)
589 goto full_match;
590 if (od2 == NULL)
591 goto partial_match;
592 if (! compare_operands (od2, &d->operand[i]))
593 break;
594 ++i, od2 = od2->next;
595 }
596 }
597
598 /* Either partial match at the end of the list, or no match. In either
599 case, we tack on what operands are remaining to the end of the list. */
600 partial_match:
601 d->operand_number = next_operand_number - i;
602 for (; i < d->n_operands; ++i)
603 {
604 od2 = &d->operand[i];
605 *odata_end = od2;
606 odata_end = &od2->next;
607 od2->index = next_operand_number++;
608 }
609 *odata_end = NULL;
610 return;
611
612 full_match:
613 d->operand_number = od->index;
614 return;
615 }
616
617 \f
618 /* Process an assembler template from a define_insn or a define_peephole.
619 It is either the assembler code template, a list of assembler code
620 templates, or C code to generate the assembler code template. */
621
622 static void
623 process_template (d, template)
624 struct data *d;
625 const char *template;
626 {
627 register const char *cp;
628 register int i;
629
630 /* Templates starting with * contain straight code to be run. */
631 if (template[0] == '*')
632 {
633 d->template = 0;
634 d->output_format = INSN_OUTPUT_FORMAT_FUNCTION;
635
636 printf ("\nstatic const char *output_%d PARAMS ((rtx *, rtx));\n",
637 d->code_number);
638 puts ("\nstatic const char *");
639 printf ("output_%d (operands, insn)\n", d->code_number);
640 puts (" rtx *operands ATTRIBUTE_UNUSED;");
641 puts (" rtx insn ATTRIBUTE_UNUSED;");
642 puts ("{");
643
644 puts (template + 1);
645 puts ("}");
646 }
647
648 /* If the assembler code template starts with a @ it is a newline-separated
649 list of assembler code templates, one for each alternative. */
650 else if (template[0] == '@')
651 {
652 d->template = 0;
653 d->output_format = INSN_OUTPUT_FORMAT_MULTI;
654
655 printf ("\nstatic const char * const output_%d[] = {\n", d->code_number);
656
657 for (i = 0, cp = &template[1]; *cp; )
658 {
659 while (*cp == '\n' || *cp == ' ' || *cp== '\t')
660 cp++;
661
662 printf (" \"");
663 while (*cp != '\n' && *cp != '\0')
664 {
665 putchar (*cp);
666 cp++;
667 }
668
669 printf ("\",\n");
670 i++;
671 }
672
673 printf ("};\n");
674 }
675 else
676 {
677 d->template = template;
678 d->output_format = INSN_OUTPUT_FORMAT_SINGLE;
679 }
680 }
681 \f
682 /* Check insn D for consistency in number of constraint alternatives. */
683
684 static void
685 validate_insn_alternatives (d)
686 struct data *d;
687 {
688 register int n = 0, start;
689
690 /* Make sure all the operands have the same number of alternatives
691 in their constraints. Let N be that number. */
692 for (start = 0; start < d->n_operands; start++)
693 if (d->operand[start].n_alternatives > 0)
694 {
695 if (n == 0)
696 n = d->operand[start].n_alternatives;
697 else if (n != d->operand[start].n_alternatives)
698 error ("wrong number of alternatives in operand %d of insn %s",
699 start, get_insn_name (d->index_number));
700 }
701
702 /* Record the insn's overall number of alternatives. */
703 d->n_alternatives = n;
704 }
705 \f
706 /* Look at a define_insn just read. Assign its code number. Record
707 on idata the template and the number of arguments. If the insn has
708 a hairy output action, output a function for now. */
709
710 static void
711 gen_insn (insn)
712 rtx insn;
713 {
714 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
715 register int i;
716
717 d->code_number = next_code_number;
718 d->index_number = next_index_number;
719 if (XSTR (insn, 0)[0])
720 d->name = XSTR (insn, 0);
721 else
722 d->name = 0;
723
724 /* Build up the list in the same order as the insns are seen
725 in the machine description. */
726 d->next = 0;
727 *idata_end = d;
728 idata_end = &d->next;
729
730 max_opno = -1;
731 num_dups = 0;
732 memset (d->operand, 0, sizeof (d->operand));
733
734 for (i = 0; i < XVECLEN (insn, 1); i++)
735 scan_operands (d, XVECEXP (insn, 1, i), 0, 0);
736
737 d->n_operands = max_opno + 1;
738 d->n_dups = num_dups;
739
740 validate_insn_alternatives (d);
741 place_operands (d);
742 process_template (d, XSTR (insn, 3));
743 }
744 \f
745 /* Look at a define_peephole just read. Assign its code number.
746 Record on idata the template and the number of arguments.
747 If the insn has a hairy output action, output it now. */
748
749 static void
750 gen_peephole (peep)
751 rtx peep;
752 {
753 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
754 register int i;
755
756 d->code_number = next_code_number;
757 d->index_number = next_index_number;
758 d->name = 0;
759
760 /* Build up the list in the same order as the insns are seen
761 in the machine description. */
762 d->next = 0;
763 *idata_end = d;
764 idata_end = &d->next;
765
766 max_opno = -1;
767 num_dups = 0;
768 memset (d->operand, 0, sizeof (d->operand));
769
770 /* Get the number of operands by scanning all the patterns of the
771 peephole optimizer. But ignore all the rest of the information
772 thus obtained. */
773 for (i = 0; i < XVECLEN (peep, 0); i++)
774 scan_operands (d, XVECEXP (peep, 0, i), 0, 0);
775
776 d->n_operands = max_opno + 1;
777 d->n_dups = 0;
778
779 validate_insn_alternatives (d);
780 place_operands (d);
781 process_template (d, XSTR (peep, 2));
782 }
783 \f
784 /* Process a define_expand just read. Assign its code number,
785 only for the purposes of `insn_gen_function'. */
786
787 static void
788 gen_expand (insn)
789 rtx insn;
790 {
791 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
792 register int i;
793
794 d->code_number = next_code_number;
795 d->index_number = next_index_number;
796 if (XSTR (insn, 0)[0])
797 d->name = XSTR (insn, 0);
798 else
799 d->name = 0;
800
801 /* Build up the list in the same order as the insns are seen
802 in the machine description. */
803 d->next = 0;
804 *idata_end = d;
805 idata_end = &d->next;
806
807 max_opno = -1;
808 num_dups = 0;
809 memset (d->operand, 0, sizeof (d->operand));
810
811 /* Scan the operands to get the specified predicates and modes,
812 since expand_binop needs to know them. */
813
814 if (XVEC (insn, 1))
815 for (i = 0; i < XVECLEN (insn, 1); i++)
816 scan_operands (d, XVECEXP (insn, 1, i), 0, 0);
817
818 d->n_operands = max_opno + 1;
819 d->n_dups = num_dups;
820 d->template = 0;
821 d->output_format = INSN_OUTPUT_FORMAT_NONE;
822
823 validate_insn_alternatives (d);
824 place_operands (d);
825 }
826 \f
827 /* Process a define_split just read. Assign its code number,
828 only for reasons of consistency and to simplify genrecog. */
829
830 static void
831 gen_split (split)
832 rtx split;
833 {
834 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
835 register int i;
836
837 d->code_number = next_code_number;
838 d->index_number = next_index_number;
839 d->name = 0;
840
841 /* Build up the list in the same order as the insns are seen
842 in the machine description. */
843 d->next = 0;
844 *idata_end = d;
845 idata_end = &d->next;
846
847 max_opno = -1;
848 num_dups = 0;
849 memset (d->operand, 0, sizeof (d->operand));
850
851 /* Get the number of operands by scanning all the patterns of the
852 split patterns. But ignore all the rest of the information thus
853 obtained. */
854 for (i = 0; i < XVECLEN (split, 0); i++)
855 scan_operands (d, XVECEXP (split, 0, i), 0, 0);
856
857 d->n_operands = max_opno + 1;
858 d->n_dups = 0;
859 d->n_alternatives = 0;
860 d->template = 0;
861 d->output_format = INSN_OUTPUT_FORMAT_NONE;
862
863 place_operands (d);
864 }
865
866 extern int main PARAMS ((int, char **));
867
868 int
869 main (argc, argv)
870 int argc;
871 char **argv;
872 {
873 rtx desc;
874
875 progname = "genoutput";
876
877 if (argc <= 1)
878 fatal ("No input file name.");
879
880 if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
881 return (FATAL_EXIT_CODE);
882
883 output_prologue ();
884 next_code_number = 0;
885 next_index_number = 0;
886
887 /* Read the machine description. */
888
889 while (1)
890 {
891 int line_no;
892
893 desc = read_md_rtx (&line_no, &next_code_number);
894 if (desc == NULL)
895 break;
896
897 if (GET_CODE (desc) == DEFINE_INSN)
898 gen_insn (desc);
899 if (GET_CODE (desc) == DEFINE_PEEPHOLE)
900 gen_peephole (desc);
901 if (GET_CODE (desc) == DEFINE_EXPAND)
902 gen_expand (desc);
903 if (GET_CODE (desc) == DEFINE_SPLIT
904 || GET_CODE (desc) == DEFINE_PEEPHOLE2)
905 gen_split (desc);
906 next_index_number++;
907 }
908
909 printf("\n\n");
910 output_predicate_decls ();
911 output_operand_data ();
912 output_insn_data ();
913 output_get_insn_name ();
914
915 fflush (stdout);
916 return (ferror (stdout) != 0 || have_error
917 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
918 }
919
920 /* Return the number of occurrences of character C in string S or
921 -1 if S is the null string. */
922
923 static int
924 n_occurrences (c, s)
925 int c;
926 const char *s;
927 {
928 int n = 0;
929
930 if (s == 0 || *s == '\0')
931 return -1;
932
933 while (*s)
934 n += (*s++ == c);
935
936 return n;
937 }
938
939 /* Remove whitespace in `s' by moving up characters until the end.
940 Return a new string. */
941
942 static const char *
943 strip_whitespace (s)
944 const char *s;
945 {
946 char *p, *q;
947 char ch;
948
949 if (s == 0)
950 return 0;
951
952 p = q = xmalloc (strlen (s) + 1);
953 while ((ch = *s++) != '\0')
954 if (! ISSPACE (ch))
955 *p++ = ch;
956
957 *p = '\0';
958 return q;
959 }