(decl_attributes): If TREE_TYPE for the DECL is updated,
[official-gcc.git] / gcc / genoutput.c
blob81f8a5fd0e09a4bbb34dc1dc88b86e6bfc5c3ebd
1 /* Generate code from to output assembler insns as recognized from rtl.
2 Copyright (C) 1987, 1988, 1992, 1994 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
21 /* This program reads the machine description for the compiler target machine
22 and produces a file containing these things:
24 1. An array of strings `insn_template' which is indexed by insn code number
25 and contains the template for output of that insn,
27 2. An array of functions `insn_outfun' which, indexed by the insn code
28 number, gives the function that returns a template to use for output of
29 that insn. This is used only in the cases where the template is not
30 constant. These cases are specified by a * or @ at the beginning of the
31 template string in the machine description. They are identified for the
32 sake of other parts of the compiler by a zero element in `insn_template'.
34 3. An array of functions `insn_gen_function' which, indexed
35 by insn code number, gives the function to generate a body
36 for that pattern, given operands as arguments.
38 4. An array of strings `insn_name' which, indexed by insn code number,
39 gives the name for that pattern. Nameless patterns are given a name.
41 5. An array of ints `insn_n_operands' which is indexed by insn code number
42 and contains the number of distinct operands in the pattern for that insn,
44 6. An array of ints `insn_n_dups' which is indexed by insn code number
45 and contains the number of match_dup's that appear in the insn's pattern.
46 This says how many elements of `recog_dup_loc' are significant
47 after an insn has been recognized.
49 7. An array of arrays of operand constraint strings,
50 `insn_operand_constraint',
51 indexed first by insn code number and second by operand number,
52 containing the constraint for that operand.
54 This array is generated only if register constraints appear in
55 match_operand rtx's.
57 8. An array of arrays of chars which indicate which operands of
58 which insn patterns appear within ADDRESS rtx's. This array is
59 called `insn_operand_address_p' and is generated only if there
60 are *no* register constraints in the match_operand rtx's.
62 9. An array of arrays of machine modes, `insn_operand_mode',
63 indexed first by insn code number and second by operand number,
64 containing the machine mode that that operand is supposed to have.
65 Also `insn_operand_strict_low', which is nonzero for operands
66 contained in a STRICT_LOW_PART.
68 10. An array of arrays of int-valued functions, `insn_operand_predicate',
69 indexed first by insn code number and second by operand number,
70 containing the match_operand predicate for this operand.
72 11. An array of ints, `insn_n_alternatives', that gives the number
73 of alternatives in the constraints of each pattern.
75 The code number of an insn is simply its position in the machine description;
76 code numbers are assigned sequentially to entries in the description,
77 starting with code number 0.
79 Thus, the following entry in the machine description
81 (define_insn "clrdf"
82 [(set (match_operand:DF 0 "general_operand" "")
83 (const_int 0))]
85 "clrd %0")
87 assuming it is the 25th entry present, would cause
88 insn_template[24] to be "clrd %0", and insn_n_operands[24] to be 1.
89 It would not make an case in output_insn_hairy because the template
90 given in the entry is a constant (it does not start with `*'). */
92 #include <stdio.h>
93 #include "hconfig.h"
94 #include "rtl.h"
95 #include "obstack.h"
97 /* No instruction can have more operands than this.
98 Sorry for this arbitrary limit, but what machine will
99 have an instruction with this many operands? */
101 #define MAX_MAX_OPERANDS 40
103 static struct obstack obstack;
104 struct obstack *rtl_obstack = &obstack;
106 #define obstack_chunk_alloc xmalloc
107 #define obstack_chunk_free free
109 extern void free ();
110 extern rtx read_rtx ();
112 char *xmalloc ();
113 static void fatal ();
114 void fancy_abort ();
115 static void error ();
116 static void mybcopy ();
117 static void mybzero ();
118 static int n_occurrences ();
120 /* insns in the machine description are assigned sequential code numbers
121 that are used by insn-recog.c (produced by genrecog) to communicate
122 to insn-output.c (produced by this program). */
124 static int next_code_number;
126 /* This counts all definitions in the md file,
127 for the sake of error messages. */
129 static int next_index_number;
131 /* Record in this chain all information that we will output,
132 associated with the code number of the insn. */
134 struct data
136 int code_number;
137 int index_number;
138 char *name;
139 char *template; /* string such as "movl %1,%0" */
140 int n_operands; /* Number of operands this insn recognizes */
141 int n_dups; /* Number times match_dup appears in pattern */
142 int n_alternatives; /* Number of alternatives in each constraint */
143 struct data *next;
144 char *constraints[MAX_MAX_OPERANDS];
145 /* Number of alternatives in constraints of operand N. */
146 int op_n_alternatives[MAX_MAX_OPERANDS];
147 char *predicates[MAX_MAX_OPERANDS];
148 char address_p[MAX_MAX_OPERANDS];
149 enum machine_mode modes[MAX_MAX_OPERANDS];
150 char strict_low[MAX_MAX_OPERANDS];
151 char outfun; /* Nonzero means this has an output function */
154 /* This variable points to the first link in the chain. */
156 struct data *insn_data;
158 /* Pointer to the last link in the chain, so new elements
159 can be added at the end. */
161 struct data *end_of_insn_data;
163 /* Nonzero if any match_operand has a constraint string;
164 implies that REGISTER_CONSTRAINTS will be defined
165 for this machine description. */
167 int have_constraints;
169 /* Nonzero if some error has occurred. We will make all errors fatal, but
170 might as well continue until we see all of them. */
172 static int have_error;
174 static void
175 output_prologue ()
178 printf ("/* Generated automatically by the program `genoutput'\n\
179 from the machine description file `md'. */\n\n");
181 printf ("#include \"config.h\"\n");
182 printf ("#include \"rtl.h\"\n");
183 printf ("#include \"regs.h\"\n");
184 printf ("#include \"hard-reg-set.h\"\n");
185 printf ("#include \"real.h\"\n");
186 printf ("#include \"insn-config.h\"\n\n");
187 printf ("#include \"conditions.h\"\n");
188 printf ("#include \"insn-flags.h\"\n");
189 printf ("#include \"insn-attr.h\"\n\n");
190 printf ("#include \"insn-codes.h\"\n\n");
191 printf ("#include \"recog.h\"\n\n");
193 printf ("#include <stdio.h>\n");
194 printf ("#include \"output.h\"\n");
197 static void
198 output_epilogue ()
200 register struct data *d;
202 printf ("\nchar * const insn_template[] =\n {\n");
203 for (d = insn_data; d; d = d->next)
205 if (d->template)
206 printf (" \"%s\",\n", d->template);
207 else
208 printf (" 0,\n");
210 printf (" };\n");
212 printf ("\nchar *(*const insn_outfun[])() =\n {\n");
213 for (d = insn_data; d; d = d->next)
215 if (d->outfun)
216 printf (" output_%d,\n", d->code_number);
217 else
218 printf (" 0,\n");
220 printf (" };\n");
222 printf ("\nrtx (*const insn_gen_function[]) () =\n {\n");
223 for (d = insn_data; d; d = d->next)
225 if (d->name)
226 printf (" gen_%s,\n", d->name);
227 else
228 printf (" 0,\n");
230 printf (" };\n");
232 printf ("\nchar *insn_name[] =\n {\n");
234 int offset = 0;
235 int next;
236 char * last_name = 0;
237 char * next_name;
238 register struct data *n;
240 for (n = insn_data, next = 1; n; n = n->next, next++)
241 if (n->name)
243 next_name = n->name;
244 break;
247 for (d = insn_data; d; d = d->next)
249 if (d->name)
251 printf (" \"%s\",\n", d->name);
252 offset = 0;
253 last_name = d->name;
254 next_name = 0;
255 for (n = d->next, next = 1; n; n = n->next, next++)
256 if (n->name)
258 next_name = n->name;
259 break;
262 else
264 offset++;
265 if (next_name && (last_name == 0 || offset > next / 2))
266 printf (" \"%s-%d\",\n", next_name, next - offset);
267 else
268 printf (" \"%s+%d\",\n", last_name, offset);
272 printf (" };\n");
273 printf ("char **insn_name_ptr = insn_name;\n");
275 printf ("\nconst int insn_n_operands[] =\n {\n");
276 for (d = insn_data; d; d = d->next)
277 printf (" %d,\n", d->n_operands);
278 printf (" };\n");
280 printf ("\nconst int insn_n_dups[] =\n {\n");
281 for (d = insn_data; d; d = d->next)
282 printf (" %d,\n", d->n_dups);
283 printf (" };\n");
285 if (have_constraints)
287 printf ("\nchar *const insn_operand_constraint[][MAX_RECOG_OPERANDS] =\n {\n");
288 for (d = insn_data; d; d = d->next)
290 register int i;
291 printf (" {");
292 for (i = 0; i < d->n_operands; i++)
294 if (d->constraints[i] == 0)
295 printf (" \"\",");
296 else
297 printf (" \"%s\",", d->constraints[i]);
299 if (d->n_operands == 0)
300 printf (" 0");
301 printf (" },\n");
303 printf (" };\n");
305 else
307 printf ("\nconst char insn_operand_address_p[][MAX_RECOG_OPERANDS] =\n {\n");
308 for (d = insn_data; d; d = d->next)
310 register int i;
311 printf (" {");
312 for (i = 0; i < d->n_operands; i++)
313 printf (" %d,", d->address_p[i]);
314 if (d->n_operands == 0)
315 printf (" 0");
316 printf (" },\n");
318 printf (" };\n");
321 printf ("\nconst enum machine_mode insn_operand_mode[][MAX_RECOG_OPERANDS] =\n {\n");
322 for (d = insn_data; d; d = d->next)
324 register int i;
325 printf (" {");
326 for (i = 0; i < d->n_operands; i++)
327 printf (" %smode,", GET_MODE_NAME (d->modes[i]));
328 if (d->n_operands == 0)
329 printf (" VOIDmode");
330 printf (" },\n");
332 printf (" };\n");
334 printf ("\nconst char insn_operand_strict_low[][MAX_RECOG_OPERANDS] =\n {\n");
335 for (d = insn_data; d; d = d->next)
337 register int i;
338 printf (" {");
339 for (i = 0; i < d->n_operands; i++)
340 printf (" %d,", d->strict_low[i]);
341 if (d->n_operands == 0)
342 printf (" 0");
343 printf (" },\n");
345 printf (" };\n");
348 /* We need to define all predicates used. Keep a list of those we
349 have defined so far. There normally aren't very many predicates used,
350 so a linked list should be fast enough. */
351 struct predicate { char *name; struct predicate *next; } *predicates = 0;
352 struct predicate *p;
353 int i;
355 printf ("\n");
356 for (d = insn_data; d; d = d->next)
357 for (i = 0; i < d->n_operands; i++)
358 if (d->predicates[i] && d->predicates[i][0])
360 for (p = predicates; p; p = p->next)
361 if (! strcmp (p->name, d->predicates[i]))
362 break;
364 if (p == 0)
366 printf ("extern int %s ();\n", d->predicates[i]);
367 p = (struct predicate *) alloca (sizeof (struct predicate));
368 p->name = d->predicates[i];
369 p->next = predicates;
370 predicates = p;
374 printf ("\nint (*const insn_operand_predicate[][MAX_RECOG_OPERANDS])() =\n {\n");
375 for (d = insn_data; d; d = d->next)
377 printf (" {");
378 for (i = 0; i < d->n_operands; i++)
379 printf (" %s,", ((d->predicates[i] && d->predicates[i][0])
380 ? d->predicates[i] : "0"));
381 if (d->n_operands == 0)
382 printf (" 0");
383 printf (" },\n");
385 printf (" };\n");
388 printf ("\nconst int insn_n_alternatives[] =\n {\n");
389 for (d = insn_data; d; d = d->next)
390 printf (" %d,\n", d->n_alternatives);
391 printf(" };\n");
394 /* scan_operands (X) stores in max_opno the largest operand
395 number present in X, if that is larger than the previous
396 value of max_opno. It stores all the constraints in `constraints'
397 and all the machine modes in `modes'.
399 THIS_ADDRESS_P is nonzero if the containing rtx was an ADDRESS.
400 THIS_STRICT_LOW is nonzero if the containing rtx was a STRICT_LOW_PART. */
402 static int max_opno;
403 static int num_dups;
404 static char *constraints[MAX_MAX_OPERANDS];
405 static int op_n_alternatives[MAX_MAX_OPERANDS];
406 static char *predicates[MAX_MAX_OPERANDS];
407 static char address_p[MAX_MAX_OPERANDS];
408 static enum machine_mode modes[MAX_MAX_OPERANDS];
409 static char strict_low[MAX_MAX_OPERANDS];
410 static char seen[MAX_MAX_OPERANDS];
412 static void
413 scan_operands (part, this_address_p, this_strict_low)
414 rtx part;
415 int this_address_p;
416 int this_strict_low;
418 register int i, j;
419 register char *format_ptr;
420 int opno;
422 if (part == 0)
423 return;
425 switch (GET_CODE (part))
427 case MATCH_OPERAND:
428 opno = XINT (part, 0);
429 if (opno > max_opno)
430 max_opno = opno;
431 if (max_opno >= MAX_MAX_OPERANDS)
433 error ("Too many operands (%d) in definition %d.\n",
434 max_opno + 1, next_index_number);
435 return;
437 if (seen[opno])
438 error ("Definition %d specified operand number %d more than once.\n",
439 next_index_number, opno);
440 seen[opno] = 1;
441 modes[opno] = GET_MODE (part);
442 strict_low[opno] = this_strict_low;
443 predicates[opno] = XSTR (part, 1);
444 constraints[opno] = XSTR (part, 2);
445 if (XSTR (part, 2) != 0 && *XSTR (part, 2) != 0)
447 op_n_alternatives[opno] = n_occurrences (',', XSTR (part, 2)) + 1;
448 have_constraints = 1;
450 address_p[opno] = this_address_p;
451 return;
453 case MATCH_SCRATCH:
454 opno = XINT (part, 0);
455 if (opno > max_opno)
456 max_opno = opno;
457 if (max_opno >= MAX_MAX_OPERANDS)
459 error ("Too many operands (%d) in definition %d.\n",
460 max_opno + 1, next_index_number);
461 return;
463 if (seen[opno])
464 error ("Definition %d specified operand number %d more than once.\n",
465 next_index_number, opno);
466 seen[opno] = 1;
467 modes[opno] = GET_MODE (part);
468 strict_low[opno] = 0;
469 predicates[opno] = "scratch_operand";
470 constraints[opno] = XSTR (part, 1);
471 if (XSTR (part, 1) != 0 && *XSTR (part, 1) != 0)
473 op_n_alternatives[opno] = n_occurrences (',', XSTR (part, 1)) + 1;
474 have_constraints = 1;
476 address_p[opno] = 0;
477 return;
479 case MATCH_OPERATOR:
480 case MATCH_PARALLEL:
481 opno = XINT (part, 0);
482 if (opno > max_opno)
483 max_opno = opno;
484 if (max_opno >= MAX_MAX_OPERANDS)
486 error ("Too many operands (%d) in definition %d.\n",
487 max_opno + 1, next_index_number);
488 return;
490 if (seen[opno])
491 error ("Definition %d specified operand number %d more than once.\n",
492 next_index_number, opno);
493 seen[opno] = 1;
494 modes[opno] = GET_MODE (part);
495 strict_low[opno] = 0;
496 predicates[opno] = XSTR (part, 1);
497 constraints[opno] = 0;
498 address_p[opno] = 0;
499 for (i = 0; i < XVECLEN (part, 2); i++)
500 scan_operands (XVECEXP (part, 2, i), 0, 0);
501 return;
503 case MATCH_DUP:
504 case MATCH_OP_DUP:
505 case MATCH_PAR_DUP:
506 ++num_dups;
507 return;
509 case ADDRESS:
510 scan_operands (XEXP (part, 0), 1, 0);
511 return;
513 case STRICT_LOW_PART:
514 scan_operands (XEXP (part, 0), 0, 1);
515 return;
518 format_ptr = GET_RTX_FORMAT (GET_CODE (part));
520 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
521 switch (*format_ptr++)
523 case 'e':
524 scan_operands (XEXP (part, i), 0, 0);
525 break;
526 case 'E':
527 if (XVEC (part, i) != NULL)
528 for (j = 0; j < XVECLEN (part, i); j++)
529 scan_operands (XVECEXP (part, i, j), 0, 0);
530 break;
534 /* Process an assembler template from a define_insn or a define_peephole.
535 It is either the assembler code template, a list of assembler code
536 templates, or C code to generate the assembler code template. */
538 static void
539 process_template (d, template)
540 struct data *d;
541 char *template;
543 register char *cp;
544 register int i;
546 /* We need to consider only the instructions whose assembler code template
547 starts with a * or @. These are the ones where C code is run to decide
548 on a template to use. So for all others just return now. */
550 if (template[0] != '*' && template[0] != '@')
552 d->template = template;
553 d->outfun = 0;
554 return;
557 d->template = 0;
558 d->outfun = 1;
560 printf ("\nstatic char *\n");
561 printf ("output_%d (operands, insn)\n", d->code_number);
562 printf (" rtx *operands;\n");
563 printf (" rtx insn;\n");
564 printf ("{\n");
566 /* If the assembler code template starts with a @ it is a newline-separated
567 list of assembler code templates, one for each alternative. So produce
568 a routine to select the correct one. */
570 if (template[0] == '@')
573 printf (" static /*const*/ char *const strings_%d[] = {\n",
574 d->code_number);
576 for (i = 0, cp = &template[1]; *cp; )
578 while (*cp == '\n' || *cp == ' ' || *cp== '\t')
579 cp++;
581 printf (" \"");
582 while (*cp != '\n' && *cp != '\0')
583 putchar (*cp++);
585 printf ("\",\n");
586 i++;
589 printf (" };\n");
590 printf (" return strings_%d[which_alternative];\n", d->code_number);
592 if (i != d->n_alternatives)
593 fatal ("Insn pattern %d has %d alternatives but %d assembler choices",
594 d->index_number, d->n_alternatives, i);
597 else
599 /* The following is done in a funny way to get around problems in
600 VAX-11 "C" on VMS. It is the equivalent of:
601 printf ("%s\n", &template[1])); */
602 cp = &template[1];
603 while (*cp) putchar (*cp++);
604 putchar ('\n');
607 printf ("}\n");
610 /* Check insn D for consistency in number of constraint alternatives. */
612 static void
613 validate_insn_alternatives (d)
614 struct data *d;
616 register int n = 0, start;
617 /* Make sure all the operands have the same number of
618 alternatives in their constraints.
619 Let N be that number. */
620 for (start = 0; start < d->n_operands; start++)
621 if (d->op_n_alternatives[start] > 0)
623 if (n == 0)
624 n = d->op_n_alternatives[start];
625 else if (n != d->op_n_alternatives[start])
626 error ("wrong number of alternatives in operand %d of insn number %d",
627 start, d->index_number);
629 /* Record the insn's overall number of alternatives. */
630 d->n_alternatives = n;
633 /* Look at a define_insn just read. Assign its code number.
634 Record on insn_data the template and the number of arguments.
635 If the insn has a hairy output action, output a function for now. */
637 static void
638 gen_insn (insn)
639 rtx insn;
641 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
642 register int i;
644 d->code_number = next_code_number++;
645 d->index_number = next_index_number;
646 if (XSTR (insn, 0)[0])
647 d->name = XSTR (insn, 0);
648 else
649 d->name = 0;
651 /* Build up the list in the same order as the insns are seen
652 in the machine description. */
653 d->next = 0;
654 if (end_of_insn_data)
655 end_of_insn_data->next = d;
656 else
657 insn_data = d;
659 end_of_insn_data = d;
661 max_opno = -1;
662 num_dups = 0;
664 mybzero (constraints, sizeof constraints);
665 mybzero (op_n_alternatives, sizeof op_n_alternatives);
666 mybzero (predicates, sizeof predicates);
667 mybzero (address_p, sizeof address_p);
668 mybzero (modes, sizeof modes);
669 mybzero (strict_low, sizeof strict_low);
670 mybzero (seen, sizeof seen);
672 for (i = 0; i < XVECLEN (insn, 1); i++)
673 scan_operands (XVECEXP (insn, 1, i), 0, 0);
675 d->n_operands = max_opno + 1;
676 d->n_dups = num_dups;
678 mybcopy (constraints, d->constraints, sizeof constraints);
679 mybcopy (op_n_alternatives, d->op_n_alternatives, sizeof op_n_alternatives);
680 mybcopy (predicates, d->predicates, sizeof predicates);
681 mybcopy (address_p, d->address_p, sizeof address_p);
682 mybcopy (modes, d->modes, sizeof modes);
683 mybcopy (strict_low, d->strict_low, sizeof strict_low);
685 validate_insn_alternatives (d);
686 process_template (d, XSTR (insn, 3));
689 /* Look at a define_peephole just read. Assign its code number.
690 Record on insn_data the template and the number of arguments.
691 If the insn has a hairy output action, output it now. */
693 static void
694 gen_peephole (peep)
695 rtx peep;
697 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
698 register int i;
700 d->code_number = next_code_number++;
701 d->index_number = next_index_number;
702 d->name = 0;
704 /* Build up the list in the same order as the insns are seen
705 in the machine description. */
706 d->next = 0;
707 if (end_of_insn_data)
708 end_of_insn_data->next = d;
709 else
710 insn_data = d;
712 end_of_insn_data = d;
714 max_opno = -1;
715 mybzero (constraints, sizeof constraints);
716 mybzero (op_n_alternatives, sizeof op_n_alternatives);
717 mybzero (predicates, sizeof predicates);
718 mybzero (address_p, sizeof address_p);
719 mybzero (modes, sizeof modes);
720 mybzero (strict_low, sizeof strict_low);
721 mybzero (seen, sizeof seen);
723 /* Get the number of operands by scanning all the
724 patterns of the peephole optimizer.
725 But ignore all the rest of the information thus obtained. */
726 for (i = 0; i < XVECLEN (peep, 0); i++)
727 scan_operands (XVECEXP (peep, 0, i), 0, 0);
729 d->n_operands = max_opno + 1;
730 d->n_dups = 0;
732 mybcopy (constraints, d->constraints, sizeof constraints);
733 mybcopy (op_n_alternatives, d->op_n_alternatives, sizeof op_n_alternatives);
734 mybzero (d->predicates, sizeof predicates);
735 mybzero (d->address_p, sizeof address_p);
736 mybzero (d->modes, sizeof modes);
737 mybzero (d->strict_low, sizeof strict_low);
739 validate_insn_alternatives (d);
740 process_template (d, XSTR (peep, 2));
743 /* Process a define_expand just read. Assign its code number,
744 only for the purposes of `insn_gen_function'. */
746 static void
747 gen_expand (insn)
748 rtx insn;
750 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
751 register int i;
753 d->code_number = next_code_number++;
754 d->index_number = next_index_number;
755 if (XSTR (insn, 0)[0])
756 d->name = XSTR (insn, 0);
757 else
758 d->name = 0;
760 /* Build up the list in the same order as the insns are seen
761 in the machine description. */
762 d->next = 0;
763 if (end_of_insn_data)
764 end_of_insn_data->next = d;
765 else
766 insn_data = d;
768 end_of_insn_data = d;
770 max_opno = -1;
771 num_dups = 0;
773 /* Scan the operands to get the specified predicates and modes,
774 since expand_binop needs to know them. */
776 mybzero (constraints, sizeof constraints);
777 mybzero (op_n_alternatives, sizeof op_n_alternatives);
778 mybzero (predicates, sizeof predicates);
779 mybzero (address_p, sizeof address_p);
780 mybzero (modes, sizeof modes);
781 mybzero (strict_low, sizeof strict_low);
782 mybzero (seen, sizeof seen);
784 if (XVEC (insn, 1))
785 for (i = 0; i < XVECLEN (insn, 1); i++)
786 scan_operands (XVECEXP (insn, 1, i), 0, 0);
788 d->n_operands = max_opno + 1;
789 d->n_dups = num_dups;
791 mybcopy (constraints, d->constraints, sizeof constraints);
792 mybcopy (op_n_alternatives, d->op_n_alternatives, sizeof op_n_alternatives);
793 mybcopy (predicates, d->predicates, sizeof predicates);
794 mybcopy (address_p, d->address_p, sizeof address_p);
795 mybcopy (modes, d->modes, sizeof modes);
796 mybcopy (strict_low, d->strict_low, sizeof strict_low);
798 d->template = 0;
799 d->outfun = 0;
800 validate_insn_alternatives (d);
803 /* Process a define_split just read. Assign its code number,
804 only for reasons of consistency and to simplify genrecog. */
807 static void
808 gen_split (split)
809 rtx split;
811 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
812 register int i;
814 d->code_number = next_code_number++;
815 d->index_number = next_index_number;
816 d->name = 0;
818 /* Build up the list in the same order as the insns are seen
819 in the machine description. */
820 d->next = 0;
821 if (end_of_insn_data)
822 end_of_insn_data->next = d;
823 else
824 insn_data = d;
826 end_of_insn_data = d;
828 max_opno = -1;
829 num_dups = 0;
831 mybzero (constraints, sizeof constraints);
832 mybzero (op_n_alternatives, sizeof op_n_alternatives);
833 mybzero (predicates, sizeof predicates);
834 mybzero (address_p, sizeof address_p);
835 mybzero (modes, sizeof modes);
836 mybzero (strict_low, sizeof strict_low);
837 mybzero (seen, sizeof seen);
839 /* Get the number of operands by scanning all the
840 patterns of the split patterns.
841 But ignore all the rest of the information thus obtained. */
842 for (i = 0; i < XVECLEN (split, 0); i++)
843 scan_operands (XVECEXP (split, 0, i), 0, 0);
845 d->n_operands = max_opno + 1;
847 mybzero (d->constraints, sizeof constraints);
848 mybzero (d->op_n_alternatives, sizeof op_n_alternatives);
849 mybzero (d->predicates, sizeof predicates);
850 mybzero (d->address_p, sizeof address_p);
851 mybzero (d->modes, sizeof modes);
852 mybzero (d->strict_low, sizeof strict_low);
854 d->n_dups = 0;
855 d->n_alternatives = 0;
856 d->template = 0;
857 d->outfun = 0;
860 char *
861 xmalloc (size)
862 unsigned size;
864 register char *val = (char *) malloc (size);
866 if (val == 0)
867 fatal ("virtual memory exhausted");
868 return val;
871 char *
872 xrealloc (ptr, size)
873 char *ptr;
874 unsigned size;
876 char *result = (char *) realloc (ptr, size);
877 if (!result)
878 fatal ("virtual memory exhausted");
879 return result;
882 static void
883 mybzero (b, length)
884 register char *b;
885 register unsigned length;
887 while (length-- > 0)
888 *b++ = 0;
891 static void
892 mybcopy (b1, b2, length)
893 register char *b1;
894 register char *b2;
895 register unsigned length;
897 while (length-- > 0)
898 *b2++ = *b1++;
901 static void
902 fatal (s, a1, a2, a3, a4)
903 char *s;
905 fprintf (stderr, "genoutput: ");
906 fprintf (stderr, s, a1, a2, a3, a4);
907 fprintf (stderr, "\n");
908 exit (FATAL_EXIT_CODE);
911 /* More 'friendly' abort that prints the line and file.
912 config.h can #define abort fancy_abort if you like that sort of thing. */
914 void
915 fancy_abort ()
917 fatal ("Internal gcc abort.");
920 static void
921 error (s, a1, a2)
922 char *s;
924 fprintf (stderr, "genoutput: ");
925 fprintf (stderr, s, a1, a2);
926 fprintf (stderr, "\n");
928 have_error = 1;
932 main (argc, argv)
933 int argc;
934 char **argv;
936 rtx desc;
937 FILE *infile;
938 register int c;
940 obstack_init (rtl_obstack);
942 if (argc <= 1)
943 fatal ("No input file name.");
945 infile = fopen (argv[1], "r");
946 if (infile == 0)
948 perror (argv[1]);
949 exit (FATAL_EXIT_CODE);
952 init_rtl ();
954 output_prologue ();
955 next_code_number = 0;
956 next_index_number = 0;
957 have_constraints = 0;
959 /* Read the machine description. */
961 while (1)
963 c = read_skip_spaces (infile);
964 if (c == EOF)
965 break;
966 ungetc (c, infile);
968 desc = read_rtx (infile);
969 if (GET_CODE (desc) == DEFINE_INSN)
970 gen_insn (desc);
971 if (GET_CODE (desc) == DEFINE_PEEPHOLE)
972 gen_peephole (desc);
973 if (GET_CODE (desc) == DEFINE_EXPAND)
974 gen_expand (desc);
975 if (GET_CODE (desc) == DEFINE_SPLIT)
976 gen_split (desc);
977 next_index_number++;
980 output_epilogue ();
982 fflush (stdout);
983 exit (ferror (stdout) != 0 || have_error
984 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
986 /* NOTREACHED */
987 return 0;
990 static int
991 n_occurrences (c, s)
992 char c;
993 char *s;
995 int n = 0;
996 while (*s)
997 n += (*s++ == c);
998 return n;