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