Import final gcc2 snapshot (990109)
[official-gcc.git] / gcc / genoutput.c
blob8f3bd910ee16b9fbb095f14dcbbca47a3978227c
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 extern void free ();
111 extern rtx read_rtx ();
113 char *xmalloc ();
114 #ifdef HAVE_VPRINTF
115 void fatal PVPROTO((char *, ...));
116 #else
117 /* We must not provide any prototype here, even if ANSI C. */
118 void fatal PROTO(());
119 #endif
120 void fancy_abort ();
121 static void error ();
122 static void mybcopy ();
123 static void mybzero ();
124 static int n_occurrences ();
126 /* insns in the machine description are assigned sequential code numbers
127 that are used by insn-recog.c (produced by genrecog) to communicate
128 to insn-output.c (produced by this program). */
130 static int next_code_number;
132 /* This counts all definitions in the md file,
133 for the sake of error messages. */
135 static int next_index_number;
137 /* Record in this chain all information that we will output,
138 associated with the code number of the insn. */
140 struct data
142 int code_number;
143 int index_number;
144 char *name;
145 char *template; /* string such as "movl %1,%0" */
146 int n_operands; /* Number of operands this insn recognizes */
147 int n_dups; /* Number times match_dup appears in pattern */
148 int n_alternatives; /* Number of alternatives in each constraint */
149 struct data *next;
150 char *constraints[MAX_MAX_OPERANDS];
151 /* Number of alternatives in constraints of operand N. */
152 int op_n_alternatives[MAX_MAX_OPERANDS];
153 char *predicates[MAX_MAX_OPERANDS];
154 char address_p[MAX_MAX_OPERANDS];
155 enum machine_mode modes[MAX_MAX_OPERANDS];
156 char strict_low[MAX_MAX_OPERANDS];
157 char outfun; /* Nonzero means this has an output function */
160 /* This variable points to the first link in the chain. */
162 struct data *insn_data;
164 /* Pointer to the last link in the chain, so new elements
165 can be added at the end. */
167 struct data *end_of_insn_data;
169 /* Nonzero if any match_operand has a constraint string;
170 implies that REGISTER_CONSTRAINTS will be defined
171 for this machine description. */
173 int have_constraints;
175 /* Nonzero if some error has occurred. We will make all errors fatal, but
176 might as well continue until we see all of them. */
178 static int have_error;
180 static void
181 output_prologue ()
184 printf ("/* Generated automatically by the program `genoutput'\n\
185 from the machine description file `md'. */\n\n");
187 printf ("#include \"config.h\"\n");
188 printf ("#include \"system.h\"\n");
189 printf ("#include \"flags.h\"\n");
190 printf ("#include \"rtl.h\"\n");
191 printf ("#include \"regs.h\"\n");
192 printf ("#include \"hard-reg-set.h\"\n");
193 printf ("#include \"real.h\"\n");
194 printf ("#include \"insn-config.h\"\n\n");
195 printf ("#include \"conditions.h\"\n");
196 printf ("#include \"insn-flags.h\"\n");
197 printf ("#include \"insn-attr.h\"\n\n");
198 printf ("#include \"insn-codes.h\"\n\n");
199 printf ("#include \"recog.h\"\n\n");
201 printf ("#include \"output.h\"\n");
204 static void
205 output_epilogue ()
207 register struct data *d;
209 printf ("\nchar * const insn_template[] =\n {\n");
210 for (d = insn_data; d; d = d->next)
212 if (d->template)
213 printf (" \"%s\",\n", d->template);
214 else
215 printf (" 0,\n");
217 printf (" };\n");
219 printf ("\nchar *(*const insn_outfun[])() =\n {\n");
220 for (d = insn_data; d; d = d->next)
222 if (d->outfun)
223 printf (" output_%d,\n", d->code_number);
224 else
225 printf (" 0,\n");
227 printf (" };\n");
229 printf ("\nrtx (*const insn_gen_function[]) () =\n {\n");
230 for (d = insn_data; d; d = d->next)
232 if (d->name && d->name[0] != '*')
233 printf (" gen_%s,\n", d->name);
234 else
235 printf (" 0,\n");
237 printf (" };\n");
239 printf ("\nchar *insn_name[] =\n {\n");
241 int offset = 0;
242 int next;
243 char * last_name = 0;
244 char * next_name;
245 register struct data *n;
247 for (n = insn_data, next = 1; n; n = n->next, next++)
248 if (n->name)
250 next_name = n->name;
251 break;
254 for (d = insn_data; d; d = d->next)
256 if (d->name)
258 printf (" \"%s\",\n", d->name);
259 offset = 0;
260 last_name = d->name;
261 next_name = 0;
262 for (n = d->next, next = 1; n; n = n->next, next++)
263 if (n->name)
265 next_name = n->name;
266 break;
269 else
271 offset++;
272 if (next_name && (last_name == 0 || offset > next / 2))
273 printf (" \"%s-%d\",\n", next_name, next - offset);
274 else
275 printf (" \"%s+%d\",\n", last_name, offset);
279 printf (" };\n");
280 printf ("char **insn_name_ptr = insn_name;\n");
282 printf ("\nconst int insn_n_operands[] =\n {\n");
283 for (d = insn_data; d; d = d->next)
284 printf (" %d,\n", d->n_operands);
285 printf (" };\n");
287 printf ("\nconst int insn_n_dups[] =\n {\n");
288 for (d = insn_data; d; d = d->next)
289 printf (" %d,\n", d->n_dups);
290 printf (" };\n");
292 if (have_constraints)
294 printf ("\nchar *const insn_operand_constraint[][MAX_RECOG_OPERANDS] =\n {\n");
295 for (d = insn_data; d; d = d->next)
297 register int i;
298 printf (" {");
299 for (i = 0; i < d->n_operands; i++)
301 if (d->constraints[i] == 0)
302 printf (" \"\",");
303 else
304 printf (" \"%s\",", d->constraints[i]);
306 if (d->n_operands == 0)
307 printf (" 0");
308 printf (" },\n");
310 printf (" };\n");
312 else
314 printf ("\nconst char insn_operand_address_p[][MAX_RECOG_OPERANDS] =\n {\n");
315 for (d = insn_data; d; d = d->next)
317 register int i;
318 printf (" {");
319 for (i = 0; i < d->n_operands; i++)
320 printf (" %d,", d->address_p[i]);
321 if (d->n_operands == 0)
322 printf (" 0");
323 printf (" },\n");
325 printf (" };\n");
328 printf ("\nconst enum machine_mode insn_operand_mode[][MAX_RECOG_OPERANDS] =\n {\n");
329 for (d = insn_data; d; d = d->next)
331 register int i;
332 printf (" {");
333 for (i = 0; i < d->n_operands; i++)
334 printf (" %smode,", GET_MODE_NAME (d->modes[i]));
335 if (d->n_operands == 0)
336 printf (" VOIDmode");
337 printf (" },\n");
339 printf (" };\n");
341 printf ("\nconst char insn_operand_strict_low[][MAX_RECOG_OPERANDS] =\n {\n");
342 for (d = insn_data; d; d = d->next)
344 register int i;
345 printf (" {");
346 for (i = 0; i < d->n_operands; i++)
347 printf (" %d,", d->strict_low[i]);
348 if (d->n_operands == 0)
349 printf (" 0");
350 printf (" },\n");
352 printf (" };\n");
355 /* We need to define all predicates used. Keep a list of those we
356 have defined so far. There normally aren't very many predicates used,
357 so a linked list should be fast enough. */
358 struct predicate { char *name; struct predicate *next; } *predicates = 0;
359 struct predicate *p;
360 int i;
362 printf ("\n");
363 for (d = insn_data; d; d = d->next)
364 for (i = 0; i < d->n_operands; i++)
365 if (d->predicates[i] && d->predicates[i][0])
367 for (p = predicates; p; p = p->next)
368 if (! strcmp (p->name, d->predicates[i]))
369 break;
371 if (p == 0)
373 printf ("extern int %s ();\n", d->predicates[i]);
374 p = (struct predicate *) alloca (sizeof (struct predicate));
375 p->name = d->predicates[i];
376 p->next = predicates;
377 predicates = p;
381 printf ("\nint (*const insn_operand_predicate[][MAX_RECOG_OPERANDS])() =\n {\n");
382 for (d = insn_data; d; d = d->next)
384 printf (" {");
385 for (i = 0; i < d->n_operands; i++)
386 printf (" %s,", ((d->predicates[i] && d->predicates[i][0])
387 ? d->predicates[i] : "0"));
388 if (d->n_operands == 0)
389 printf (" 0");
390 printf (" },\n");
392 printf (" };\n");
395 printf ("\nconst int insn_n_alternatives[] =\n {\n");
396 for (d = insn_data; d; d = d->next)
397 printf (" %d,\n", d->n_alternatives);
398 printf(" };\n");
401 /* scan_operands (X) stores in max_opno the largest operand
402 number present in X, if that is larger than the previous
403 value of max_opno. It stores all the constraints in `constraints'
404 and all the machine modes in `modes'.
406 THIS_ADDRESS_P is nonzero if the containing rtx was an ADDRESS.
407 THIS_STRICT_LOW is nonzero if the containing rtx was a STRICT_LOW_PART. */
409 static int max_opno;
410 static int num_dups;
411 static char *constraints[MAX_MAX_OPERANDS];
412 static int op_n_alternatives[MAX_MAX_OPERANDS];
413 static char *predicates[MAX_MAX_OPERANDS];
414 static char address_p[MAX_MAX_OPERANDS];
415 static enum machine_mode modes[MAX_MAX_OPERANDS];
416 static char strict_low[MAX_MAX_OPERANDS];
417 static char seen[MAX_MAX_OPERANDS];
419 static void
420 scan_operands (part, this_address_p, this_strict_low)
421 rtx part;
422 int this_address_p;
423 int this_strict_low;
425 register int i, j;
426 register char *format_ptr;
427 int opno;
429 if (part == 0)
430 return;
432 switch (GET_CODE (part))
434 case MATCH_OPERAND:
435 opno = XINT (part, 0);
436 if (opno > max_opno)
437 max_opno = opno;
438 if (max_opno >= MAX_MAX_OPERANDS)
440 error ("Too many operands (%d) in definition %d.\n",
441 max_opno + 1, next_index_number);
442 return;
444 if (seen[opno])
445 error ("Definition %d specified operand number %d more than once.\n",
446 next_index_number, opno);
447 seen[opno] = 1;
448 modes[opno] = GET_MODE (part);
449 strict_low[opno] = this_strict_low;
450 predicates[opno] = XSTR (part, 1);
451 constraints[opno] = XSTR (part, 2);
452 if (XSTR (part, 2) != 0 && *XSTR (part, 2) != 0)
454 op_n_alternatives[opno] = n_occurrences (',', XSTR (part, 2)) + 1;
455 have_constraints = 1;
457 address_p[opno] = this_address_p;
458 return;
460 case MATCH_SCRATCH:
461 opno = XINT (part, 0);
462 if (opno > max_opno)
463 max_opno = opno;
464 if (max_opno >= MAX_MAX_OPERANDS)
466 error ("Too many operands (%d) in definition %d.\n",
467 max_opno + 1, next_index_number);
468 return;
470 if (seen[opno])
471 error ("Definition %d specified operand number %d more than once.\n",
472 next_index_number, opno);
473 seen[opno] = 1;
474 modes[opno] = GET_MODE (part);
475 strict_low[opno] = 0;
476 predicates[opno] = "scratch_operand";
477 constraints[opno] = XSTR (part, 1);
478 if (XSTR (part, 1) != 0 && *XSTR (part, 1) != 0)
480 op_n_alternatives[opno] = n_occurrences (',', XSTR (part, 1)) + 1;
481 have_constraints = 1;
483 address_p[opno] = 0;
484 return;
486 case MATCH_OPERATOR:
487 case MATCH_PARALLEL:
488 opno = XINT (part, 0);
489 if (opno > max_opno)
490 max_opno = opno;
491 if (max_opno >= MAX_MAX_OPERANDS)
493 error ("Too many operands (%d) in definition %d.\n",
494 max_opno + 1, next_index_number);
495 return;
497 if (seen[opno])
498 error ("Definition %d specified operand number %d more than once.\n",
499 next_index_number, opno);
500 seen[opno] = 1;
501 modes[opno] = GET_MODE (part);
502 strict_low[opno] = 0;
503 predicates[opno] = XSTR (part, 1);
504 constraints[opno] = 0;
505 address_p[opno] = 0;
506 for (i = 0; i < XVECLEN (part, 2); i++)
507 scan_operands (XVECEXP (part, 2, i), 0, 0);
508 return;
510 case MATCH_DUP:
511 case MATCH_OP_DUP:
512 case MATCH_PAR_DUP:
513 ++num_dups;
514 return;
516 case ADDRESS:
517 scan_operands (XEXP (part, 0), 1, 0);
518 return;
520 case STRICT_LOW_PART:
521 scan_operands (XEXP (part, 0), 0, 1);
522 return;
524 default:
525 break;
528 format_ptr = GET_RTX_FORMAT (GET_CODE (part));
530 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
531 switch (*format_ptr++)
533 case 'e':
534 case 'u':
535 scan_operands (XEXP (part, i), 0, 0);
536 break;
537 case 'E':
538 if (XVEC (part, i) != NULL)
539 for (j = 0; j < XVECLEN (part, i); j++)
540 scan_operands (XVECEXP (part, i, j), 0, 0);
541 break;
545 /* Process an assembler template from a define_insn or a define_peephole.
546 It is either the assembler code template, a list of assembler code
547 templates, or C code to generate the assembler code template. */
549 static void
550 process_template (d, template)
551 struct data *d;
552 char *template;
554 register char *cp;
555 register int i;
557 /* We need to consider only the instructions whose assembler code template
558 starts with a * or @. These are the ones where C code is run to decide
559 on a template to use. So for all others just return now. */
561 if (template[0] != '*' && template[0] != '@')
563 d->template = template;
564 d->outfun = 0;
565 return;
568 d->template = 0;
569 d->outfun = 1;
571 printf ("\nstatic char *\n");
572 printf ("output_%d (operands, insn)\n", d->code_number);
573 printf (" rtx *operands;\n");
574 printf (" rtx insn;\n");
575 printf ("{\n");
577 /* If the assembler code template starts with a @ it is a newline-separated
578 list of assembler code templates, one for each alternative. So produce
579 a routine to select the correct one. */
581 if (template[0] == '@')
584 printf (" static /*const*/ char *const strings_%d[] = {\n",
585 d->code_number);
587 for (i = 0, cp = &template[1]; *cp; )
589 while (*cp == '\n' || *cp == ' ' || *cp== '\t')
590 cp++;
592 printf (" \"");
593 while (*cp != '\n' && *cp != '\0')
595 putchar (*cp);
596 cp++;
599 printf ("\",\n");
600 i++;
603 printf (" };\n");
604 printf (" return strings_%d[which_alternative];\n", d->code_number);
606 if (i != d->n_alternatives)
607 fatal ("Insn pattern %d has %d alternatives but %d assembler choices",
608 d->index_number, d->n_alternatives, i);
611 else
613 /* The following is done in a funny way to get around problems in
614 VAX-11 "C" on VMS. It is the equivalent of:
615 printf ("%s\n", &template[1])); */
616 cp = &template[1];
617 while (*cp)
619 putchar (*cp);
620 cp++;
622 putchar ('\n');
625 printf ("}\n");
628 /* Check insn D for consistency in number of constraint alternatives. */
630 static void
631 validate_insn_alternatives (d)
632 struct data *d;
634 register int n = 0, start;
635 /* Make sure all the operands have the same number of
636 alternatives in their constraints.
637 Let N be that number. */
638 for (start = 0; start < d->n_operands; start++)
639 if (d->op_n_alternatives[start] > 0)
641 if (n == 0)
642 n = d->op_n_alternatives[start];
643 else if (n != d->op_n_alternatives[start])
644 error ("wrong number of alternatives in operand %d of insn number %d",
645 start, d->index_number);
647 /* Record the insn's overall number of alternatives. */
648 d->n_alternatives = n;
651 /* Look at a define_insn just read. Assign its code number.
652 Record on insn_data the template and the number of arguments.
653 If the insn has a hairy output action, output a function for now. */
655 static void
656 gen_insn (insn)
657 rtx insn;
659 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
660 register int i;
662 d->code_number = next_code_number++;
663 d->index_number = next_index_number;
664 if (XSTR (insn, 0)[0])
665 d->name = XSTR (insn, 0);
666 else
667 d->name = 0;
669 /* Build up the list in the same order as the insns are seen
670 in the machine description. */
671 d->next = 0;
672 if (end_of_insn_data)
673 end_of_insn_data->next = d;
674 else
675 insn_data = d;
677 end_of_insn_data = d;
679 max_opno = -1;
680 num_dups = 0;
682 mybzero (constraints, sizeof constraints);
683 mybzero (op_n_alternatives, sizeof op_n_alternatives);
684 mybzero (predicates, sizeof predicates);
685 mybzero (address_p, sizeof address_p);
686 mybzero (modes, sizeof modes);
687 mybzero (strict_low, sizeof strict_low);
688 mybzero (seen, sizeof seen);
690 for (i = 0; i < XVECLEN (insn, 1); i++)
691 scan_operands (XVECEXP (insn, 1, i), 0, 0);
693 d->n_operands = max_opno + 1;
694 d->n_dups = num_dups;
696 mybcopy (constraints, d->constraints, sizeof constraints);
697 mybcopy (op_n_alternatives, d->op_n_alternatives, sizeof op_n_alternatives);
698 mybcopy (predicates, d->predicates, sizeof predicates);
699 mybcopy (address_p, d->address_p, sizeof address_p);
700 mybcopy (modes, d->modes, sizeof modes);
701 mybcopy (strict_low, d->strict_low, sizeof strict_low);
703 validate_insn_alternatives (d);
704 process_template (d, XSTR (insn, 3));
707 /* Look at a define_peephole just read. Assign its code number.
708 Record on insn_data the template and the number of arguments.
709 If the insn has a hairy output action, output it now. */
711 static void
712 gen_peephole (peep)
713 rtx peep;
715 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
716 register int i;
718 d->code_number = next_code_number++;
719 d->index_number = next_index_number;
720 d->name = 0;
722 /* Build up the list in the same order as the insns are seen
723 in the machine description. */
724 d->next = 0;
725 if (end_of_insn_data)
726 end_of_insn_data->next = d;
727 else
728 insn_data = d;
730 end_of_insn_data = d;
732 max_opno = -1;
733 mybzero (constraints, sizeof constraints);
734 mybzero (op_n_alternatives, sizeof op_n_alternatives);
735 mybzero (predicates, sizeof predicates);
736 mybzero (address_p, sizeof address_p);
737 mybzero (modes, sizeof modes);
738 mybzero (strict_low, sizeof strict_low);
739 mybzero (seen, sizeof seen);
741 /* Get the number of operands by scanning all the
742 patterns of the peephole optimizer.
743 But ignore all the rest of the information thus obtained. */
744 for (i = 0; i < XVECLEN (peep, 0); i++)
745 scan_operands (XVECEXP (peep, 0, i), 0, 0);
747 d->n_operands = max_opno + 1;
748 d->n_dups = 0;
750 mybcopy (constraints, d->constraints, sizeof constraints);
751 mybcopy (op_n_alternatives, d->op_n_alternatives, sizeof op_n_alternatives);
752 mybzero (d->predicates, sizeof predicates);
753 mybzero (d->address_p, sizeof address_p);
754 mybzero (d->modes, sizeof modes);
755 mybzero (d->strict_low, sizeof strict_low);
757 validate_insn_alternatives (d);
758 process_template (d, XSTR (peep, 2));
761 /* Process a define_expand just read. Assign its code number,
762 only for the purposes of `insn_gen_function'. */
764 static void
765 gen_expand (insn)
766 rtx insn;
768 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
769 register int i;
771 d->code_number = next_code_number++;
772 d->index_number = next_index_number;
773 if (XSTR (insn, 0)[0])
774 d->name = XSTR (insn, 0);
775 else
776 d->name = 0;
778 /* Build up the list in the same order as the insns are seen
779 in the machine description. */
780 d->next = 0;
781 if (end_of_insn_data)
782 end_of_insn_data->next = d;
783 else
784 insn_data = d;
786 end_of_insn_data = d;
788 max_opno = -1;
789 num_dups = 0;
791 /* Scan the operands to get the specified predicates and modes,
792 since expand_binop needs to know them. */
794 mybzero (constraints, sizeof constraints);
795 mybzero (op_n_alternatives, sizeof op_n_alternatives);
796 mybzero (predicates, sizeof predicates);
797 mybzero (address_p, sizeof address_p);
798 mybzero (modes, sizeof modes);
799 mybzero (strict_low, sizeof strict_low);
800 mybzero (seen, sizeof seen);
802 if (XVEC (insn, 1))
803 for (i = 0; i < XVECLEN (insn, 1); i++)
804 scan_operands (XVECEXP (insn, 1, i), 0, 0);
806 d->n_operands = max_opno + 1;
807 d->n_dups = num_dups;
809 mybcopy (constraints, d->constraints, sizeof constraints);
810 mybcopy (op_n_alternatives, d->op_n_alternatives, sizeof op_n_alternatives);
811 mybcopy (predicates, d->predicates, sizeof predicates);
812 mybcopy (address_p, d->address_p, sizeof address_p);
813 mybcopy (modes, d->modes, sizeof modes);
814 mybcopy (strict_low, d->strict_low, sizeof strict_low);
816 d->template = 0;
817 d->outfun = 0;
818 validate_insn_alternatives (d);
821 /* Process a define_split just read. Assign its code number,
822 only for reasons of consistency and to simplify genrecog. */
825 static void
826 gen_split (split)
827 rtx split;
829 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
830 register int i;
832 d->code_number = next_code_number++;
833 d->index_number = next_index_number;
834 d->name = 0;
836 /* Build up the list in the same order as the insns are seen
837 in the machine description. */
838 d->next = 0;
839 if (end_of_insn_data)
840 end_of_insn_data->next = d;
841 else
842 insn_data = d;
844 end_of_insn_data = d;
846 max_opno = -1;
847 num_dups = 0;
849 mybzero (constraints, sizeof constraints);
850 mybzero (op_n_alternatives, sizeof op_n_alternatives);
851 mybzero (predicates, sizeof predicates);
852 mybzero (address_p, sizeof address_p);
853 mybzero (modes, sizeof modes);
854 mybzero (strict_low, sizeof strict_low);
855 mybzero (seen, sizeof seen);
857 /* Get the number of operands by scanning all the
858 patterns of the split patterns.
859 But ignore all the rest of the information thus obtained. */
860 for (i = 0; i < XVECLEN (split, 0); i++)
861 scan_operands (XVECEXP (split, 0, i), 0, 0);
863 d->n_operands = max_opno + 1;
865 mybzero (d->constraints, sizeof constraints);
866 mybzero (d->op_n_alternatives, sizeof op_n_alternatives);
867 mybzero (d->predicates, sizeof predicates);
868 mybzero (d->address_p, sizeof address_p);
869 mybzero (d->modes, sizeof modes);
870 mybzero (d->strict_low, sizeof strict_low);
872 d->n_dups = 0;
873 d->n_alternatives = 0;
874 d->template = 0;
875 d->outfun = 0;
878 char *
879 xmalloc (size)
880 unsigned size;
882 register char *val = (char *) malloc (size);
884 if (val == 0)
885 fatal ("virtual memory exhausted");
886 return val;
889 char *
890 xrealloc (ptr, size)
891 char *ptr;
892 unsigned size;
894 char *result = (char *) realloc (ptr, size);
895 if (!result)
896 fatal ("virtual memory exhausted");
897 return result;
900 static void
901 mybzero (b, length)
902 register char *b;
903 register unsigned length;
905 while (length-- > 0)
906 *b++ = 0;
909 static void
910 mybcopy (b1, b2, length)
911 register char *b1;
912 register char *b2;
913 register unsigned length;
915 while (length-- > 0)
916 *b2++ = *b1++;
919 #ifdef HAVE_VPRINTF
920 void
921 fatal VPROTO((char *s, ...))
923 #ifndef ANSI_PROTOTYPES
924 char *s;
925 #endif
926 va_list ap;
928 VA_START (ap, s);
930 #ifndef ANSI_PROTOTYPES
931 s = va_arg (ap, char *);
932 #endif
934 fprintf (stderr, "genoutput: ");
935 vfprintf (stderr, s, ap);
936 va_end (ap);
937 fprintf (stderr, "\n");
938 exit (FATAL_EXIT_CODE);
940 #else /* not HAVE_VPRINTF */
942 void
943 fatal (s, a1, a2, a3, a4)
944 char *s;
946 fprintf (stderr, "genoutput: ");
947 fprintf (stderr, s, a1, a2, a3, a4);
948 fprintf (stderr, "\n");
949 exit (FATAL_EXIT_CODE);
951 #endif /* not HAVE_VPRINTF */
953 /* More 'friendly' abort that prints the line and file.
954 config.h can #define abort fancy_abort if you like that sort of thing. */
956 void
957 fancy_abort ()
959 fatal ("Internal gcc abort.");
962 static void
963 error (s, a1, a2)
964 char *s;
966 fprintf (stderr, "genoutput: ");
967 fprintf (stderr, s, a1, a2);
968 fprintf (stderr, "\n");
970 have_error = 1;
974 main (argc, argv)
975 int argc;
976 char **argv;
978 rtx desc;
979 FILE *infile;
980 register int c;
982 obstack_init (rtl_obstack);
984 if (argc <= 1)
985 fatal ("No input file name.");
987 infile = fopen (argv[1], "r");
988 if (infile == 0)
990 perror (argv[1]);
991 exit (FATAL_EXIT_CODE);
994 init_rtl ();
996 output_prologue ();
997 next_code_number = 0;
998 next_index_number = 0;
999 have_constraints = 0;
1001 /* Read the machine description. */
1003 while (1)
1005 c = read_skip_spaces (infile);
1006 if (c == EOF)
1007 break;
1008 ungetc (c, infile);
1010 desc = read_rtx (infile);
1011 if (GET_CODE (desc) == DEFINE_INSN)
1012 gen_insn (desc);
1013 if (GET_CODE (desc) == DEFINE_PEEPHOLE)
1014 gen_peephole (desc);
1015 if (GET_CODE (desc) == DEFINE_EXPAND)
1016 gen_expand (desc);
1017 if (GET_CODE (desc) == DEFINE_SPLIT)
1018 gen_split (desc);
1019 next_index_number++;
1022 output_epilogue ();
1024 fflush (stdout);
1025 exit (ferror (stdout) != 0 || have_error
1026 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
1028 /* NOTREACHED */
1029 return 0;
1032 static int
1033 n_occurrences (c, s)
1034 int c;
1035 char *s;
1037 int n = 0;
1038 while (*s)
1039 n += (*s++ == c);
1040 return n;