* gjavah.c (main): Handle --output-class-directory argument.
[official-gcc.git] / gcc / genoutput.c
blob1651070c96d0a17a6425dbbdeff4c58c8a8e91b6
1 /* Generate code from to output assembler insns as recognized from rtl.
2 Copyright (C) 1987, 88, 92, 94, 95, 97, 1998 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 "hconfig.h"
94 #include "system.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 char *xmalloc PROTO((unsigned));
111 static void fatal PVPROTO ((char *, ...))
112 ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
113 void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN;
114 static void error PVPROTO ((char *, ...)) ATTRIBUTE_PRINTF_1;
115 static void mybcopy ();
116 static void mybzero ();
117 static int n_occurrences PROTO((int, char *));
119 /* Define this so we can link with print-rtl.o to get debug_rtx function. */
120 char **insn_name_ptr = 0;
122 /* insns in the machine description are assigned sequential code numbers
123 that are used by insn-recog.c (produced by genrecog) to communicate
124 to insn-output.c (produced by this program). */
126 static int next_code_number;
128 /* This counts all definitions in the md file,
129 for the sake of error messages. */
131 static int next_index_number;
133 /* Record in this chain all information that we will output,
134 associated with the code number of the insn. */
136 struct data
138 int code_number;
139 int index_number;
140 char *name;
141 char *template; /* string such as "movl %1,%0" */
142 int n_operands; /* Number of operands this insn recognizes */
143 int n_dups; /* Number times match_dup appears in pattern */
144 int n_alternatives; /* Number of alternatives in each constraint */
145 struct data *next;
146 char *constraints[MAX_MAX_OPERANDS];
147 /* Number of alternatives in constraints of operand N. */
148 int op_n_alternatives[MAX_MAX_OPERANDS];
149 char *predicates[MAX_MAX_OPERANDS];
150 char address_p[MAX_MAX_OPERANDS];
151 enum machine_mode modes[MAX_MAX_OPERANDS];
152 char strict_low[MAX_MAX_OPERANDS];
153 char outfun; /* Nonzero means this has an output function */
156 /* This variable points to the first link in the chain. */
158 struct data *insn_data;
160 /* Pointer to the last link in the chain, so new elements
161 can be added at the end. */
163 struct data *end_of_insn_data;
165 /* Nonzero if any match_operand has a constraint string;
166 implies that REGISTER_CONSTRAINTS will be defined
167 for this machine description. */
169 int have_constraints;
171 /* Nonzero if some error has occurred. We will make all errors fatal, but
172 might as well continue until we see all of them. */
174 static int have_error;
176 static void output_prologue PROTO((void));
177 static void output_epilogue PROTO((void));
178 static void scan_operands PROTO((rtx, int, int));
179 static void process_template PROTO((struct data *, char *));
180 static void validate_insn_alternatives PROTO((struct data *));
181 static void gen_insn PROTO((rtx));
182 static void gen_peephole PROTO((rtx));
183 static void gen_expand PROTO((rtx));
184 static void gen_split PROTO((rtx));
185 static int n_occurrences PROTO((int, char *));
187 static void
188 output_prologue ()
190 printf ("/* Generated automatically by the program `genoutput'\n\
191 from the machine description file `md'. */\n\n");
193 printf ("#include \"config.h\"\n");
194 printf ("#include \"system.h\"\n");
195 printf ("#include \"flags.h\"\n");
196 printf ("#include \"rtl.h\"\n");
197 printf ("#include \"regs.h\"\n");
198 printf ("#include \"hard-reg-set.h\"\n");
199 printf ("#include \"real.h\"\n");
200 printf ("#include \"insn-config.h\"\n\n");
201 printf ("#include \"conditions.h\"\n");
202 printf ("#include \"insn-flags.h\"\n");
203 printf ("#include \"insn-attr.h\"\n\n");
204 printf ("#include \"insn-codes.h\"\n\n");
205 printf ("#include \"recog.h\"\n\n");
207 printf ("#include \"output.h\"\n");
210 static void
211 output_epilogue ()
213 register struct data *d;
215 printf ("\nchar * const insn_template[] =\n {\n");
216 for (d = insn_data; d; d = d->next)
218 if (d->template)
219 printf (" \"%s\",\n", d->template);
220 else
221 printf (" 0,\n");
223 printf (" };\n");
225 printf ("\nchar *(*const insn_outfun[])() =\n {\n");
226 for (d = insn_data; d; d = d->next)
228 if (d->outfun)
229 printf (" output_%d,\n", d->code_number);
230 else
231 printf (" 0,\n");
233 printf (" };\n");
235 printf ("\nrtx (*const insn_gen_function[]) () =\n {\n");
236 for (d = insn_data; d; d = d->next)
238 if (d->name && d->name[0] != '*')
239 printf (" gen_%s,\n", d->name);
240 else
241 printf (" 0,\n");
243 printf (" };\n");
245 printf ("\nchar *insn_name[] =\n {\n");
247 int offset = 0;
248 int next;
249 char * last_name = 0;
250 char * next_name = 0;
251 register struct data *n;
253 for (n = insn_data, next = 1; n; n = n->next, next++)
254 if (n->name)
256 next_name = n->name;
257 break;
260 for (d = insn_data; d; d = d->next)
262 if (d->name)
264 printf (" \"%s\",\n", d->name);
265 offset = 0;
266 last_name = d->name;
267 next_name = 0;
268 for (n = d->next, next = 1; n; n = n->next, next++)
269 if (n->name)
271 next_name = n->name;
272 break;
275 else
277 offset++;
278 if (next_name && (last_name == 0 || offset > next / 2))
279 printf (" \"%s-%d\",\n", next_name, next - offset);
280 else
281 printf (" \"%s+%d\",\n", last_name, offset);
285 printf (" };\n");
286 printf ("char **insn_name_ptr = insn_name;\n");
288 printf ("\nconst int insn_n_operands[] =\n {\n");
289 for (d = insn_data; d; d = d->next)
290 printf (" %d,\n", d->n_operands);
291 printf (" };\n");
293 printf ("\nconst int insn_n_dups[] =\n {\n");
294 for (d = insn_data; d; d = d->next)
295 printf (" %d,\n", d->n_dups);
296 printf (" };\n");
298 if (have_constraints)
300 printf ("\nchar *const insn_operand_constraint[][MAX_RECOG_OPERANDS] =\n {\n");
301 for (d = insn_data; d; d = d->next)
303 register int i;
304 printf (" {");
305 for (i = 0; i < d->n_operands; i++)
307 if (d->constraints[i] == 0)
308 printf (" \"\",");
309 else
310 printf (" \"%s\",", d->constraints[i]);
312 if (d->n_operands == 0)
313 printf (" 0");
314 printf (" },\n");
316 printf (" };\n");
318 else
320 printf ("\nconst char insn_operand_address_p[][MAX_RECOG_OPERANDS] =\n {\n");
321 for (d = insn_data; d; d = d->next)
323 register int i;
324 printf (" {");
325 for (i = 0; i < d->n_operands; i++)
326 printf (" %d,", d->address_p[i]);
327 if (d->n_operands == 0)
328 printf (" 0");
329 printf (" },\n");
331 printf (" };\n");
334 printf ("\nconst enum machine_mode insn_operand_mode[][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 (" %smode,", GET_MODE_NAME (d->modes[i]));
341 if (d->n_operands == 0)
342 printf (" VOIDmode");
343 printf (" },\n");
345 printf (" };\n");
347 printf ("\nconst char insn_operand_strict_low[][MAX_RECOG_OPERANDS] =\n {\n");
348 for (d = insn_data; d; d = d->next)
350 register int i;
351 printf (" {");
352 for (i = 0; i < d->n_operands; i++)
353 printf (" %d,", d->strict_low[i]);
354 if (d->n_operands == 0)
355 printf (" 0");
356 printf (" },\n");
358 printf (" };\n");
361 /* We need to define all predicates used. Keep a list of those we
362 have defined so far. There normally aren't very many predicates used,
363 so a linked list should be fast enough. */
364 struct predicate { char *name; struct predicate *next; } *predicates = 0;
365 struct predicate *p;
366 int i;
368 printf ("\n");
369 for (d = insn_data; d; d = d->next)
370 for (i = 0; i < d->n_operands; i++)
371 if (d->predicates[i] && d->predicates[i][0])
373 for (p = predicates; p; p = p->next)
374 if (! strcmp (p->name, d->predicates[i]))
375 break;
377 if (p == 0)
379 printf ("extern int %s ();\n", d->predicates[i]);
380 p = (struct predicate *) alloca (sizeof (struct predicate));
381 p->name = d->predicates[i];
382 p->next = predicates;
383 predicates = p;
387 printf ("\nint (*const insn_operand_predicate[][MAX_RECOG_OPERANDS])() =\n {\n");
388 for (d = insn_data; d; d = d->next)
390 printf (" {");
391 for (i = 0; i < d->n_operands; i++)
392 printf (" %s,", ((d->predicates[i] && d->predicates[i][0])
393 ? d->predicates[i] : "0"));
394 if (d->n_operands == 0)
395 printf (" 0");
396 printf (" },\n");
398 printf (" };\n");
401 printf ("\nconst int insn_n_alternatives[] =\n {\n");
402 for (d = insn_data; d; d = d->next)
403 printf (" %d,\n", d->n_alternatives);
404 printf(" };\n");
407 /* scan_operands (X) stores in max_opno the largest operand
408 number present in X, if that is larger than the previous
409 value of max_opno. It stores all the constraints in `constraints'
410 and all the machine modes in `modes'.
412 THIS_ADDRESS_P is nonzero if the containing rtx was an ADDRESS.
413 THIS_STRICT_LOW is nonzero if the containing rtx was a STRICT_LOW_PART. */
415 static int max_opno;
416 static int num_dups;
417 static char *constraints[MAX_MAX_OPERANDS];
418 static int op_n_alternatives[MAX_MAX_OPERANDS];
419 static char *predicates[MAX_MAX_OPERANDS];
420 static char address_p[MAX_MAX_OPERANDS];
421 static enum machine_mode modes[MAX_MAX_OPERANDS];
422 static char strict_low[MAX_MAX_OPERANDS];
423 static char seen[MAX_MAX_OPERANDS];
425 static void
426 scan_operands (part, this_address_p, this_strict_low)
427 rtx part;
428 int this_address_p;
429 int this_strict_low;
431 register int i, j;
432 register char *format_ptr;
433 int opno;
435 if (part == 0)
436 return;
438 switch (GET_CODE (part))
440 case MATCH_OPERAND:
441 opno = XINT (part, 0);
442 if (opno > max_opno)
443 max_opno = opno;
444 if (max_opno >= MAX_MAX_OPERANDS)
446 error ("Too many operands (%d) in definition %d.\n",
447 max_opno + 1, next_index_number);
448 return;
450 if (seen[opno])
451 error ("Definition %d specified operand number %d more than once.\n",
452 next_index_number, opno);
453 seen[opno] = 1;
454 modes[opno] = GET_MODE (part);
455 strict_low[opno] = this_strict_low;
456 predicates[opno] = XSTR (part, 1);
457 constraints[opno] = XSTR (part, 2);
458 if (XSTR (part, 2) != 0 && *XSTR (part, 2) != 0)
460 op_n_alternatives[opno] = n_occurrences (',', XSTR (part, 2)) + 1;
461 have_constraints = 1;
463 address_p[opno] = this_address_p;
464 return;
466 case MATCH_SCRATCH:
467 opno = XINT (part, 0);
468 if (opno > max_opno)
469 max_opno = opno;
470 if (max_opno >= MAX_MAX_OPERANDS)
472 error ("Too many operands (%d) in definition %d.\n",
473 max_opno + 1, next_index_number);
474 return;
476 if (seen[opno])
477 error ("Definition %d specified operand number %d more than once.\n",
478 next_index_number, opno);
479 seen[opno] = 1;
480 modes[opno] = GET_MODE (part);
481 strict_low[opno] = 0;
482 predicates[opno] = "scratch_operand";
483 constraints[opno] = XSTR (part, 1);
484 if (XSTR (part, 1) != 0 && *XSTR (part, 1) != 0)
486 op_n_alternatives[opno] = n_occurrences (',', XSTR (part, 1)) + 1;
487 have_constraints = 1;
489 address_p[opno] = 0;
490 return;
492 case MATCH_OPERATOR:
493 case MATCH_PARALLEL:
494 opno = XINT (part, 0);
495 if (opno > max_opno)
496 max_opno = opno;
497 if (max_opno >= MAX_MAX_OPERANDS)
499 error ("Too many operands (%d) in definition %d.\n",
500 max_opno + 1, next_index_number);
501 return;
503 if (seen[opno])
504 error ("Definition %d specified operand number %d more than once.\n",
505 next_index_number, opno);
506 seen[opno] = 1;
507 modes[opno] = GET_MODE (part);
508 strict_low[opno] = 0;
509 predicates[opno] = XSTR (part, 1);
510 constraints[opno] = 0;
511 address_p[opno] = 0;
512 for (i = 0; i < XVECLEN (part, 2); i++)
513 scan_operands (XVECEXP (part, 2, i), 0, 0);
514 return;
516 case MATCH_DUP:
517 case MATCH_OP_DUP:
518 case MATCH_PAR_DUP:
519 ++num_dups;
520 return;
522 case ADDRESS:
523 scan_operands (XEXP (part, 0), 1, 0);
524 return;
526 case STRICT_LOW_PART:
527 scan_operands (XEXP (part, 0), 0, 1);
528 return;
530 default:
531 break;
534 format_ptr = GET_RTX_FORMAT (GET_CODE (part));
536 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
537 switch (*format_ptr++)
539 case 'e':
540 case 'u':
541 scan_operands (XEXP (part, i), 0, 0);
542 break;
543 case 'E':
544 if (XVEC (part, i) != NULL)
545 for (j = 0; j < XVECLEN (part, i); j++)
546 scan_operands (XVECEXP (part, i, j), 0, 0);
547 break;
551 /* Process an assembler template from a define_insn or a define_peephole.
552 It is either the assembler code template, a list of assembler code
553 templates, or C code to generate the assembler code template. */
555 static void
556 process_template (d, template)
557 struct data *d;
558 char *template;
560 register char *cp;
561 register int i;
563 /* We need to consider only the instructions whose assembler code template
564 starts with a * or @. These are the ones where C code is run to decide
565 on a template to use. So for all others just return now. */
567 if (template[0] != '*' && template[0] != '@')
569 d->template = template;
570 d->outfun = 0;
571 return;
574 d->template = 0;
575 d->outfun = 1;
577 printf ("\nstatic char *\n");
578 printf ("output_%d (operands, insn)\n", d->code_number);
579 printf (" rtx *operands ATTRIBUTE_UNUSED;\n");
580 printf (" rtx insn ATTRIBUTE_UNUSED;\n");
581 printf ("{\n");
583 /* If the assembler code template starts with a @ it is a newline-separated
584 list of assembler code templates, one for each alternative. So produce
585 a routine to select the correct one. */
587 if (template[0] == '@')
590 printf (" static /*const*/ char *const strings_%d[] = {\n",
591 d->code_number);
593 for (i = 0, cp = &template[1]; *cp; )
595 while (*cp == '\n' || *cp == ' ' || *cp== '\t')
596 cp++;
598 printf (" \"");
599 while (*cp != '\n' && *cp != '\0')
601 putchar (*cp);
602 cp++;
605 printf ("\",\n");
606 i++;
609 printf (" };\n");
610 printf (" return strings_%d[which_alternative];\n", d->code_number);
612 if (i != d->n_alternatives)
613 fatal ("Insn pattern %d has %d alternatives but %d assembler choices",
614 d->index_number, d->n_alternatives, i);
617 else
619 /* The following is done in a funny way to get around problems in
620 VAX-11 "C" on VMS. It is the equivalent of:
621 printf ("%s\n", &template[1])); */
622 cp = &template[1];
623 while (*cp)
625 putchar (*cp);
626 cp++;
628 putchar ('\n');
631 printf ("}\n");
634 /* Check insn D for consistency in number of constraint alternatives. */
636 static void
637 validate_insn_alternatives (d)
638 struct data *d;
640 register int n = 0, start;
641 /* Make sure all the operands have the same number of
642 alternatives in their constraints.
643 Let N be that number. */
644 for (start = 0; start < d->n_operands; start++)
645 if (d->op_n_alternatives[start] > 0)
647 if (n == 0)
648 n = d->op_n_alternatives[start];
649 else if (n != d->op_n_alternatives[start])
650 error ("wrong number of alternatives in operand %d of insn number %d",
651 start, d->index_number);
653 /* Record the insn's overall number of alternatives. */
654 d->n_alternatives = n;
657 /* Look at a define_insn just read. Assign its code number.
658 Record on insn_data the template and the number of arguments.
659 If the insn has a hairy output action, output a function for now. */
661 static void
662 gen_insn (insn)
663 rtx insn;
665 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
666 register int i;
668 d->code_number = next_code_number++;
669 d->index_number = next_index_number;
670 if (XSTR (insn, 0)[0])
671 d->name = XSTR (insn, 0);
672 else
673 d->name = 0;
675 /* Build up the list in the same order as the insns are seen
676 in the machine description. */
677 d->next = 0;
678 if (end_of_insn_data)
679 end_of_insn_data->next = d;
680 else
681 insn_data = d;
683 end_of_insn_data = d;
685 max_opno = -1;
686 num_dups = 0;
688 mybzero (constraints, sizeof constraints);
689 mybzero (op_n_alternatives, sizeof op_n_alternatives);
690 mybzero (predicates, sizeof predicates);
691 mybzero (address_p, sizeof address_p);
692 mybzero (modes, sizeof modes);
693 mybzero (strict_low, sizeof strict_low);
694 mybzero (seen, sizeof seen);
696 for (i = 0; i < XVECLEN (insn, 1); i++)
697 scan_operands (XVECEXP (insn, 1, i), 0, 0);
699 d->n_operands = max_opno + 1;
700 d->n_dups = num_dups;
702 mybcopy (constraints, d->constraints, sizeof constraints);
703 mybcopy (op_n_alternatives, d->op_n_alternatives, sizeof op_n_alternatives);
704 mybcopy (predicates, d->predicates, sizeof predicates);
705 mybcopy (address_p, d->address_p, sizeof address_p);
706 mybcopy (modes, d->modes, sizeof modes);
707 mybcopy (strict_low, d->strict_low, sizeof strict_low);
709 validate_insn_alternatives (d);
710 process_template (d, XSTR (insn, 3));
713 /* Look at a define_peephole just read. Assign its code number.
714 Record on insn_data the template and the number of arguments.
715 If the insn has a hairy output action, output it now. */
717 static void
718 gen_peephole (peep)
719 rtx peep;
721 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
722 register int i;
724 d->code_number = next_code_number++;
725 d->index_number = next_index_number;
726 d->name = 0;
728 /* Build up the list in the same order as the insns are seen
729 in the machine description. */
730 d->next = 0;
731 if (end_of_insn_data)
732 end_of_insn_data->next = d;
733 else
734 insn_data = d;
736 end_of_insn_data = d;
738 max_opno = -1;
739 mybzero (constraints, sizeof constraints);
740 mybzero (op_n_alternatives, sizeof op_n_alternatives);
741 mybzero (predicates, sizeof predicates);
742 mybzero (address_p, sizeof address_p);
743 mybzero (modes, sizeof modes);
744 mybzero (strict_low, sizeof strict_low);
745 mybzero (seen, sizeof seen);
747 /* Get the number of operands by scanning all the
748 patterns of the peephole optimizer.
749 But ignore all the rest of the information thus obtained. */
750 for (i = 0; i < XVECLEN (peep, 0); i++)
751 scan_operands (XVECEXP (peep, 0, i), 0, 0);
753 d->n_operands = max_opno + 1;
754 d->n_dups = 0;
756 mybcopy (constraints, d->constraints, sizeof constraints);
757 mybcopy (op_n_alternatives, d->op_n_alternatives, sizeof op_n_alternatives);
758 mybzero (d->predicates, sizeof predicates);
759 mybzero (d->address_p, sizeof address_p);
760 mybzero (d->modes, sizeof modes);
761 mybzero (d->strict_low, sizeof strict_low);
763 validate_insn_alternatives (d);
764 process_template (d, XSTR (peep, 2));
767 /* Process a define_expand just read. Assign its code number,
768 only for the purposes of `insn_gen_function'. */
770 static void
771 gen_expand (insn)
772 rtx insn;
774 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
775 register int i;
777 d->code_number = next_code_number++;
778 d->index_number = next_index_number;
779 if (XSTR (insn, 0)[0])
780 d->name = XSTR (insn, 0);
781 else
782 d->name = 0;
784 /* Build up the list in the same order as the insns are seen
785 in the machine description. */
786 d->next = 0;
787 if (end_of_insn_data)
788 end_of_insn_data->next = d;
789 else
790 insn_data = d;
792 end_of_insn_data = d;
794 max_opno = -1;
795 num_dups = 0;
797 /* Scan the operands to get the specified predicates and modes,
798 since expand_binop needs to know them. */
800 mybzero (constraints, sizeof constraints);
801 mybzero (op_n_alternatives, sizeof op_n_alternatives);
802 mybzero (predicates, sizeof predicates);
803 mybzero (address_p, sizeof address_p);
804 mybzero (modes, sizeof modes);
805 mybzero (strict_low, sizeof strict_low);
806 mybzero (seen, sizeof seen);
808 if (XVEC (insn, 1))
809 for (i = 0; i < XVECLEN (insn, 1); i++)
810 scan_operands (XVECEXP (insn, 1, i), 0, 0);
812 d->n_operands = max_opno + 1;
813 d->n_dups = num_dups;
815 mybcopy (constraints, d->constraints, sizeof constraints);
816 mybcopy (op_n_alternatives, d->op_n_alternatives, sizeof op_n_alternatives);
817 mybcopy (predicates, d->predicates, sizeof predicates);
818 mybcopy (address_p, d->address_p, sizeof address_p);
819 mybcopy (modes, d->modes, sizeof modes);
820 mybcopy (strict_low, d->strict_low, sizeof strict_low);
822 d->template = 0;
823 d->outfun = 0;
824 validate_insn_alternatives (d);
827 /* Process a define_split just read. Assign its code number,
828 only for reasons of consistency and to simplify genrecog. */
831 static void
832 gen_split (split)
833 rtx split;
835 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
836 register int i;
838 d->code_number = next_code_number++;
839 d->index_number = next_index_number;
840 d->name = 0;
842 /* Build up the list in the same order as the insns are seen
843 in the machine description. */
844 d->next = 0;
845 if (end_of_insn_data)
846 end_of_insn_data->next = d;
847 else
848 insn_data = d;
850 end_of_insn_data = d;
852 max_opno = -1;
853 num_dups = 0;
855 mybzero (constraints, sizeof constraints);
856 mybzero (op_n_alternatives, sizeof op_n_alternatives);
857 mybzero (predicates, sizeof predicates);
858 mybzero (address_p, sizeof address_p);
859 mybzero (modes, sizeof modes);
860 mybzero (strict_low, sizeof strict_low);
861 mybzero (seen, sizeof seen);
863 /* Get the number of operands by scanning all the
864 patterns of the split patterns.
865 But ignore all the rest of the information thus obtained. */
866 for (i = 0; i < XVECLEN (split, 0); i++)
867 scan_operands (XVECEXP (split, 0, i), 0, 0);
869 d->n_operands = max_opno + 1;
871 mybzero (d->constraints, sizeof constraints);
872 mybzero (d->op_n_alternatives, sizeof op_n_alternatives);
873 mybzero (d->predicates, sizeof predicates);
874 mybzero (d->address_p, sizeof address_p);
875 mybzero (d->modes, sizeof modes);
876 mybzero (d->strict_low, sizeof strict_low);
878 d->n_dups = 0;
879 d->n_alternatives = 0;
880 d->template = 0;
881 d->outfun = 0;
884 char *
885 xmalloc (size)
886 unsigned size;
888 register char *val = (char *) malloc (size);
890 if (val == 0)
891 fatal ("virtual memory exhausted");
892 return val;
895 char *
896 xrealloc (ptr, size)
897 char *ptr;
898 unsigned size;
900 char *result = (char *) realloc (ptr, size);
901 if (!result)
902 fatal ("virtual memory exhausted");
903 return result;
906 static void
907 mybzero (b, length)
908 register char *b;
909 register unsigned length;
911 while (length-- > 0)
912 *b++ = 0;
915 static void
916 mybcopy (b1, b2, length)
917 register char *b1;
918 register char *b2;
919 register unsigned length;
921 while (length-- > 0)
922 *b2++ = *b1++;
925 static void
926 fatal VPROTO ((char *format, ...))
928 #ifndef ANSI_PROTOTYPES
929 char *format;
930 #endif
931 va_list ap;
933 VA_START (ap, format);
935 #ifndef ANSI_PROTOTYPES
936 format = va_arg (ap, char *);
937 #endif
939 fprintf (stderr, "genoutput: ");
940 vfprintf (stderr, format, ap);
941 va_end (ap);
942 fprintf (stderr, "\n");
943 exit (FATAL_EXIT_CODE);
946 /* More 'friendly' abort that prints the line and file.
947 config.h can #define abort fancy_abort if you like that sort of thing. */
949 void
950 fancy_abort ()
952 fatal ("Internal gcc abort.");
955 static void
956 error VPROTO ((char *format, ...))
958 #ifndef ANSI_PROTOTYPES
959 char *format;
960 #endif
961 va_list ap;
963 VA_START (ap, format);
965 #ifndef ANSI_PROTOTYPES
966 format = va_arg (ap, char *);
967 #endif
969 fprintf (stderr, "genoutput: ");
970 vfprintf (stderr, format, ap);
971 va_end (ap);
972 fprintf (stderr, "\n");
974 have_error = 1;
978 main (argc, argv)
979 int argc;
980 char **argv;
982 rtx desc;
983 FILE *infile;
984 register int c;
986 obstack_init (rtl_obstack);
988 if (argc <= 1)
989 fatal ("No input file name.");
991 infile = fopen (argv[1], "r");
992 if (infile == 0)
994 perror (argv[1]);
995 exit (FATAL_EXIT_CODE);
998 init_rtl ();
1000 output_prologue ();
1001 next_code_number = 0;
1002 next_index_number = 0;
1003 have_constraints = 0;
1005 /* Read the machine description. */
1007 while (1)
1009 c = read_skip_spaces (infile);
1010 if (c == EOF)
1011 break;
1012 ungetc (c, infile);
1014 desc = read_rtx (infile);
1015 if (GET_CODE (desc) == DEFINE_INSN)
1016 gen_insn (desc);
1017 if (GET_CODE (desc) == DEFINE_PEEPHOLE)
1018 gen_peephole (desc);
1019 if (GET_CODE (desc) == DEFINE_EXPAND)
1020 gen_expand (desc);
1021 if (GET_CODE (desc) == DEFINE_SPLIT)
1022 gen_split (desc);
1023 next_index_number++;
1026 output_epilogue ();
1028 fflush (stdout);
1029 exit (ferror (stdout) != 0 || have_error
1030 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
1032 /* NOTREACHED */
1033 return 0;
1036 static int
1037 n_occurrences (c, s)
1038 int c;
1039 char *s;
1041 int n = 0;
1042 while (*s)
1043 n += (*s++ == c);
1044 return n;