Daily bump.
[official-gcc.git] / gcc / genoutput.c
blob2956ec6594ce15dbad6d76e04da497bc85c0b2c8
1 /* Generate code from to output assembler insns as recognized from rtl.
2 Copyright (C) 1987, 88, 92, 94-95, 97-98, 1999 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 void fatal PVPROTO ((const char *, ...))
111 ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
112 void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN;
113 static void error PVPROTO ((const char *, ...)) ATTRIBUTE_PRINTF_1;
114 static int n_occurrences PROTO((int, char *));
116 /* Define this so we can link with print-rtl.o to get debug_rtx function. */
117 char **insn_name_ptr = 0;
119 /* insns in the machine description are assigned sequential code numbers
120 that are used by insn-recog.c (produced by genrecog) to communicate
121 to insn-output.c (produced by this program). */
123 static int next_code_number;
125 /* This counts all definitions in the md file,
126 for the sake of error messages. */
128 static int next_index_number;
130 /* Record in this chain all information that we will output,
131 associated with the code number of the insn. */
133 struct data
135 int code_number;
136 int index_number;
137 char *name;
138 char *template; /* string such as "movl %1,%0" */
139 int n_operands; /* Number of operands this insn recognizes */
140 int n_dups; /* Number times match_dup appears in pattern */
141 int n_alternatives; /* Number of alternatives in each constraint */
142 struct data *next;
143 char *constraints[MAX_MAX_OPERANDS];
144 /* Number of alternatives in constraints of operand N. */
145 int op_n_alternatives[MAX_MAX_OPERANDS];
146 char *predicates[MAX_MAX_OPERANDS];
147 char address_p[MAX_MAX_OPERANDS];
148 enum machine_mode modes[MAX_MAX_OPERANDS];
149 char strict_low[MAX_MAX_OPERANDS];
150 char outfun; /* Nonzero means this has an output function */
153 /* This variable points to the first link in the chain. */
155 struct data *insn_data;
157 /* Pointer to the last link in the chain, so new elements
158 can be added at the end. */
160 struct data *end_of_insn_data;
162 /* Nonzero if any match_operand has a constraint string;
163 implies that REGISTER_CONSTRAINTS will be defined
164 for this machine description. */
166 int have_constraints;
168 /* Nonzero if some error has occurred. We will make all errors fatal, but
169 might as well continue until we see all of them. */
171 static int have_error;
173 static char * name_for_index PROTO((int));
174 static void output_prologue PROTO((void));
175 static void output_epilogue PROTO((void));
176 static void scan_operands PROTO((rtx, int, int));
177 static void process_template PROTO((struct data *, char *));
178 static void validate_insn_alternatives PROTO((struct data *));
179 static void gen_insn PROTO((rtx));
180 static void gen_peephole PROTO((rtx));
181 static void gen_expand PROTO((rtx));
182 static void gen_split PROTO((rtx));
183 static int n_occurrences PROTO((int, char *));
185 static char *
186 name_for_index (index)
187 int index;
189 static char buf[100];
191 struct data *i, *last_named = NULL;
192 for (i = insn_data; i ; i = i->next)
194 if (i->index_number == index)
195 return i->name;
196 if (i->name)
197 last_named = i;
200 if (last_named)
201 sprintf(buf, "%s+%d", last_named->name, index - last_named->index_number);
202 else
203 sprintf(buf, "insn %d", index);
205 return buf;
208 static void
209 output_prologue ()
211 printf ("/* Generated automatically by the program `genoutput'\n\
212 from the machine description file `md'. */\n\n");
214 printf ("#include \"config.h\"\n");
215 printf ("#include \"system.h\"\n");
216 printf ("#include \"flags.h\"\n");
217 printf ("#include \"rtl.h\"\n");
218 printf ("#include \"regs.h\"\n");
219 printf ("#include \"hard-reg-set.h\"\n");
220 printf ("#include \"real.h\"\n");
221 printf ("#include \"insn-config.h\"\n\n");
222 printf ("#include \"conditions.h\"\n");
223 printf ("#include \"insn-flags.h\"\n");
224 printf ("#include \"insn-attr.h\"\n\n");
225 printf ("#include \"insn-codes.h\"\n\n");
226 printf ("#include \"recog.h\"\n\n");
228 printf ("#include \"output.h\"\n");
231 static void
232 output_epilogue ()
234 register struct data *d;
236 printf ("\nconst char * const insn_template[] =\n {\n");
237 for (d = insn_data; d; d = d->next)
239 if (d->template)
240 printf (" \"%s\",\n", d->template);
241 else
242 printf (" 0,\n");
244 printf (" };\n");
246 printf ("\nconst char *(*const insn_outfun[])() =\n {\n");
247 for (d = insn_data; d; d = d->next)
249 if (d->outfun)
250 printf (" output_%d,\n", d->code_number);
251 else
252 printf (" 0,\n");
254 printf (" };\n");
256 printf ("\nrtx (*const insn_gen_function[]) () =\n {\n");
257 for (d = insn_data; d; d = d->next)
259 if (d->name && d->name[0] != '*')
260 printf (" gen_%s,\n", d->name);
261 else
262 printf (" 0,\n");
264 printf (" };\n");
266 printf ("\nconst char *insn_name[] =\n {\n");
268 int offset = 0;
269 int next;
270 char * last_name = 0;
271 char * next_name = 0;
272 register struct data *n;
274 for (n = insn_data, next = 1; n; n = n->next, next++)
275 if (n->name)
277 next_name = n->name;
278 break;
281 for (d = insn_data; d; d = d->next)
283 if (d->name)
285 printf (" \"%s\",\n", d->name);
286 offset = 0;
287 last_name = d->name;
288 next_name = 0;
289 for (n = d->next, next = 1; n; n = n->next, next++)
290 if (n->name)
292 next_name = n->name;
293 break;
296 else
298 offset++;
299 if (next_name && (last_name == 0 || offset > next / 2))
300 printf (" \"%s-%d\",\n", next_name, next - offset);
301 else
302 printf (" \"%s+%d\",\n", last_name, offset);
306 printf (" };\n");
307 printf ("const char **insn_name_ptr = insn_name;\n");
309 printf ("\nconst int insn_n_operands[] =\n {\n");
310 for (d = insn_data; d; d = d->next)
311 printf (" %d,\n", d->n_operands);
312 printf (" };\n");
314 printf ("\nconst int insn_n_dups[] =\n {\n");
315 for (d = insn_data; d; d = d->next)
316 printf (" %d,\n", d->n_dups);
317 printf (" };\n");
319 if (have_constraints)
321 printf ("\nconst char *const insn_operand_constraint[][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++)
328 if (d->constraints[i] == 0)
329 printf (" \"\",");
330 else
331 printf (" \"%s\",", d->constraints[i]);
333 if (d->n_operands == 0)
334 printf (" 0");
335 printf (" },\n");
337 printf (" };\n");
339 else
341 printf ("\nconst char insn_operand_address_p[][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->address_p[i]);
348 if (d->n_operands == 0)
349 printf (" 0");
350 printf (" },\n");
352 printf (" };\n");
355 printf ("\nconst enum machine_mode insn_operand_mode[][MAX_RECOG_OPERANDS] =\n {\n");
356 for (d = insn_data; d; d = d->next)
358 register int i;
359 printf (" {");
360 for (i = 0; i < d->n_operands; i++)
361 printf (" %smode,", GET_MODE_NAME (d->modes[i]));
362 if (d->n_operands == 0)
363 printf (" VOIDmode");
364 printf (" },\n");
366 printf (" };\n");
368 printf ("\nconst char insn_operand_strict_low[][MAX_RECOG_OPERANDS] =\n {\n");
369 for (d = insn_data; d; d = d->next)
371 register int i;
372 printf (" {");
373 for (i = 0; i < d->n_operands; i++)
374 printf (" %d,", d->strict_low[i]);
375 if (d->n_operands == 0)
376 printf (" 0");
377 printf (" },\n");
379 printf (" };\n");
382 /* We need to define all predicates used. Keep a list of those we
383 have defined so far. There normally aren't very many predicates used,
384 so a linked list should be fast enough. */
385 struct predicate { char *name; struct predicate *next; } *predicates = 0;
386 struct predicate *p;
387 int i;
389 printf ("\n");
390 for (d = insn_data; d; d = d->next)
391 for (i = 0; i < d->n_operands; i++)
392 if (d->predicates[i] && d->predicates[i][0])
394 for (p = predicates; p; p = p->next)
395 if (! strcmp (p->name, d->predicates[i]))
396 break;
398 if (p == 0)
400 printf ("extern int %s ();\n", d->predicates[i]);
401 p = (struct predicate *) alloca (sizeof (struct predicate));
402 p->name = d->predicates[i];
403 p->next = predicates;
404 predicates = p;
408 printf ("\nint (*const insn_operand_predicate[][MAX_RECOG_OPERANDS])() =\n {\n");
409 for (d = insn_data; d; d = d->next)
411 printf (" {");
412 for (i = 0; i < d->n_operands; i++)
413 printf (" %s,", ((d->predicates[i] && d->predicates[i][0])
414 ? d->predicates[i] : "0"));
415 if (d->n_operands == 0)
416 printf (" 0");
417 printf (" },\n");
419 printf (" };\n");
422 printf ("\nconst int insn_n_alternatives[] =\n {\n");
423 for (d = insn_data; d; d = d->next)
424 printf (" %d,\n", d->n_alternatives);
425 printf(" };\n");
428 /* scan_operands (X) stores in max_opno the largest operand
429 number present in X, if that is larger than the previous
430 value of max_opno. It stores all the constraints in `constraints'
431 and all the machine modes in `modes'.
433 THIS_ADDRESS_P is nonzero if the containing rtx was an ADDRESS.
434 THIS_STRICT_LOW is nonzero if the containing rtx was a STRICT_LOW_PART. */
436 static int max_opno;
437 static int num_dups;
438 static char *constraints[MAX_MAX_OPERANDS];
439 static int op_n_alternatives[MAX_MAX_OPERANDS];
440 static const char *predicates[MAX_MAX_OPERANDS];
441 static char address_p[MAX_MAX_OPERANDS];
442 static enum machine_mode modes[MAX_MAX_OPERANDS];
443 static char strict_low[MAX_MAX_OPERANDS];
444 static char seen[MAX_MAX_OPERANDS];
446 static void
447 scan_operands (part, this_address_p, this_strict_low)
448 rtx part;
449 int this_address_p;
450 int this_strict_low;
452 register int i, j;
453 register char *format_ptr;
454 int opno;
456 if (part == 0)
457 return;
459 switch (GET_CODE (part))
461 case MATCH_OPERAND:
462 opno = XINT (part, 0);
463 if (opno > max_opno)
464 max_opno = opno;
465 if (max_opno >= MAX_MAX_OPERANDS)
467 error ("Too many operands (%d) in definition %s.\n",
468 max_opno + 1, name_for_index (next_index_number));
469 return;
471 if (seen[opno])
472 error ("Definition %s specified operand number %d more than once.\n",
473 name_for_index (next_index_number), opno);
474 seen[opno] = 1;
475 modes[opno] = GET_MODE (part);
476 strict_low[opno] = this_strict_low;
477 predicates[opno] = XSTR (part, 1);
478 constraints[opno] = XSTR (part, 2);
479 if (XSTR (part, 2) != 0 && *XSTR (part, 2) != 0)
481 op_n_alternatives[opno] = n_occurrences (',', XSTR (part, 2)) + 1;
482 have_constraints = 1;
484 address_p[opno] = this_address_p;
485 return;
487 case MATCH_SCRATCH:
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 %s.\n",
494 max_opno + 1, name_for_index (next_index_number));
495 return;
497 if (seen[opno])
498 error ("Definition %s specified operand number %d more than once.\n",
499 name_for_index (next_index_number), opno);
500 seen[opno] = 1;
501 modes[opno] = GET_MODE (part);
502 strict_low[opno] = 0;
503 predicates[opno] = "scratch_operand";
504 constraints[opno] = XSTR (part, 1);
505 if (XSTR (part, 1) != 0 && *XSTR (part, 1) != 0)
507 op_n_alternatives[opno] = n_occurrences (',', XSTR (part, 1)) + 1;
508 have_constraints = 1;
510 address_p[opno] = 0;
511 return;
513 case MATCH_OPERATOR:
514 case MATCH_PARALLEL:
515 opno = XINT (part, 0);
516 if (opno > max_opno)
517 max_opno = opno;
518 if (max_opno >= MAX_MAX_OPERANDS)
520 error ("Too many operands (%d) in definition %s.\n",
521 max_opno + 1, name_for_index (next_index_number));
522 return;
524 if (seen[opno])
525 error ("Definition %s specified operand number %d more than once.\n",
526 name_for_index (next_index_number), opno);
527 seen[opno] = 1;
528 modes[opno] = GET_MODE (part);
529 strict_low[opno] = 0;
530 predicates[opno] = XSTR (part, 1);
531 constraints[opno] = 0;
532 address_p[opno] = 0;
533 for (i = 0; i < XVECLEN (part, 2); i++)
534 scan_operands (XVECEXP (part, 2, i), 0, 0);
535 return;
537 case MATCH_DUP:
538 case MATCH_OP_DUP:
539 case MATCH_PAR_DUP:
540 ++num_dups;
541 return;
543 case ADDRESS:
544 scan_operands (XEXP (part, 0), 1, 0);
545 return;
547 case STRICT_LOW_PART:
548 scan_operands (XEXP (part, 0), 0, 1);
549 return;
551 default:
552 break;
555 format_ptr = GET_RTX_FORMAT (GET_CODE (part));
557 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
558 switch (*format_ptr++)
560 case 'e':
561 case 'u':
562 scan_operands (XEXP (part, i), 0, 0);
563 break;
564 case 'E':
565 if (XVEC (part, i) != NULL)
566 for (j = 0; j < XVECLEN (part, i); j++)
567 scan_operands (XVECEXP (part, i, j), 0, 0);
568 break;
572 /* Process an assembler template from a define_insn or a define_peephole.
573 It is either the assembler code template, a list of assembler code
574 templates, or C code to generate the assembler code template. */
576 static void
577 process_template (d, template)
578 struct data *d;
579 char *template;
581 register char *cp;
582 register int i;
584 /* We need to consider only the instructions whose assembler code template
585 starts with a * or @. These are the ones where C code is run to decide
586 on a template to use. So for all others just return now. */
588 if (template[0] != '*' && template[0] != '@')
590 d->template = template;
591 d->outfun = 0;
592 return;
595 d->template = 0;
596 d->outfun = 1;
598 printf ("\nstatic const char *\n");
599 printf ("output_%d (operands, insn)\n", d->code_number);
600 printf (" rtx *operands ATTRIBUTE_UNUSED;\n");
601 printf (" rtx insn ATTRIBUTE_UNUSED;\n");
602 printf ("{\n");
604 /* If the assembler code template starts with a @ it is a newline-separated
605 list of assembler code templates, one for each alternative. So produce
606 a routine to select the correct one. */
608 if (template[0] == '@')
611 printf (" static const char *const strings_%d[] = {\n",
612 d->code_number);
614 for (i = 0, cp = &template[1]; *cp; )
616 while (*cp == '\n' || *cp == ' ' || *cp== '\t')
617 cp++;
619 printf (" \"");
620 while (*cp != '\n' && *cp != '\0')
622 putchar (*cp);
623 cp++;
626 printf ("\",\n");
627 i++;
630 printf (" };\n");
631 printf (" return strings_%d[which_alternative];\n", d->code_number);
633 if (i != d->n_alternatives)
634 fatal ("Insn pattern %d has %d alternatives but %d assembler choices",
635 d->index_number, d->n_alternatives, i);
638 else
640 /* The following is done in a funny way to get around problems in
641 VAX-11 "C" on VMS. It is the equivalent of:
642 printf ("%s\n", &template[1])); */
643 cp = &template[1];
644 while (*cp)
646 putchar (*cp);
647 cp++;
649 putchar ('\n');
652 printf ("}\n");
655 /* Check insn D for consistency in number of constraint alternatives. */
657 static void
658 validate_insn_alternatives (d)
659 struct data *d;
661 register int n = 0, start;
662 /* Make sure all the operands have the same number of
663 alternatives in their constraints.
664 Let N be that number. */
665 for (start = 0; start < d->n_operands; start++)
666 if (d->op_n_alternatives[start] > 0)
668 if (n == 0)
669 n = d->op_n_alternatives[start];
670 else if (n != d->op_n_alternatives[start])
671 error ("wrong number of alternatives in operand %d of insn %s",
672 start, name_for_index (d->index_number));
674 /* Record the insn's overall number of alternatives. */
675 d->n_alternatives = n;
678 /* Look at a define_insn just read. Assign its code number.
679 Record on insn_data the template and the number of arguments.
680 If the insn has a hairy output action, output a function for now. */
682 static void
683 gen_insn (insn)
684 rtx insn;
686 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
687 register int i;
689 d->code_number = next_code_number++;
690 d->index_number = next_index_number;
691 if (XSTR (insn, 0)[0])
692 d->name = XSTR (insn, 0);
693 else
694 d->name = 0;
696 /* Build up the list in the same order as the insns are seen
697 in the machine description. */
698 d->next = 0;
699 if (end_of_insn_data)
700 end_of_insn_data->next = d;
701 else
702 insn_data = d;
704 end_of_insn_data = d;
706 max_opno = -1;
707 num_dups = 0;
709 memset (constraints, 0, sizeof constraints);
710 memset (op_n_alternatives, 0, sizeof op_n_alternatives);
711 memset (predicates, 0, sizeof predicates);
712 memset (address_p, 0, sizeof address_p);
713 memset (modes, 0, sizeof modes);
714 memset (strict_low, 0, sizeof strict_low);
715 memset (seen, 0, sizeof seen);
717 for (i = 0; i < XVECLEN (insn, 1); i++)
718 scan_operands (XVECEXP (insn, 1, i), 0, 0);
720 d->n_operands = max_opno + 1;
721 d->n_dups = num_dups;
723 memcpy (d->constraints, constraints, sizeof constraints);
724 memcpy (d->op_n_alternatives, op_n_alternatives, sizeof op_n_alternatives);
725 memcpy (d->predicates, predicates, sizeof predicates);
726 memcpy (d->address_p, address_p, sizeof address_p);
727 memcpy (d->modes, modes, sizeof modes);
728 memcpy (d->strict_low, strict_low, sizeof strict_low);
730 validate_insn_alternatives (d);
731 process_template (d, XSTR (insn, 3));
734 /* Look at a define_peephole just read. Assign its code number.
735 Record on insn_data the template and the number of arguments.
736 If the insn has a hairy output action, output it now. */
738 static void
739 gen_peephole (peep)
740 rtx peep;
742 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
743 register int i;
745 d->code_number = next_code_number++;
746 d->index_number = next_index_number;
747 d->name = 0;
749 /* Build up the list in the same order as the insns are seen
750 in the machine description. */
751 d->next = 0;
752 if (end_of_insn_data)
753 end_of_insn_data->next = d;
754 else
755 insn_data = d;
757 end_of_insn_data = d;
759 max_opno = -1;
760 memset (constraints, 0, sizeof constraints);
761 memset (op_n_alternatives, 0, sizeof op_n_alternatives);
762 memset (predicates, 0, sizeof predicates);
763 memset (address_p, 0, sizeof address_p);
764 memset (modes, 0, sizeof modes);
765 memset (strict_low, 0, sizeof strict_low);
766 memset (seen, 0, sizeof seen);
768 /* Get the number of operands by scanning all the
769 patterns of the peephole optimizer.
770 But ignore all the rest of the information thus obtained. */
771 for (i = 0; i < XVECLEN (peep, 0); i++)
772 scan_operands (XVECEXP (peep, 0, i), 0, 0);
774 d->n_operands = max_opno + 1;
775 d->n_dups = 0;
777 memcpy (d->constraints, constraints, sizeof constraints);
778 memcpy (d->op_n_alternatives, op_n_alternatives, sizeof op_n_alternatives);
779 memset (d->predicates, 0, sizeof predicates);
780 memset (d->address_p, 0, sizeof address_p);
781 memset (d->modes, 0, sizeof modes);
782 memset (d->strict_low, 0, sizeof strict_low);
784 validate_insn_alternatives (d);
785 process_template (d, XSTR (peep, 2));
788 /* Process a define_expand just read. Assign its code number,
789 only for the purposes of `insn_gen_function'. */
791 static void
792 gen_expand (insn)
793 rtx insn;
795 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
796 register int i;
798 d->code_number = next_code_number++;
799 d->index_number = next_index_number;
800 if (XSTR (insn, 0)[0])
801 d->name = XSTR (insn, 0);
802 else
803 d->name = 0;
805 /* Build up the list in the same order as the insns are seen
806 in the machine description. */
807 d->next = 0;
808 if (end_of_insn_data)
809 end_of_insn_data->next = d;
810 else
811 insn_data = d;
813 end_of_insn_data = d;
815 max_opno = -1;
816 num_dups = 0;
818 /* Scan the operands to get the specified predicates and modes,
819 since expand_binop needs to know them. */
821 memset (constraints, 0, sizeof constraints);
822 memset (op_n_alternatives, 0, sizeof op_n_alternatives);
823 memset (predicates, 0, sizeof predicates);
824 memset (address_p, 0, sizeof address_p);
825 memset (modes, 0, sizeof modes);
826 memset (strict_low, 0, sizeof strict_low);
827 memset (seen, 0, sizeof seen);
829 if (XVEC (insn, 1))
830 for (i = 0; i < XVECLEN (insn, 1); i++)
831 scan_operands (XVECEXP (insn, 1, i), 0, 0);
833 d->n_operands = max_opno + 1;
834 d->n_dups = num_dups;
836 memcpy (d->constraints, constraints, sizeof constraints);
837 memcpy (d->op_n_alternatives, op_n_alternatives, sizeof op_n_alternatives);
838 memcpy (d->predicates, predicates, sizeof predicates);
839 memcpy (d->address_p, address_p, sizeof address_p);
840 memcpy (d->modes, modes, sizeof modes);
841 memcpy (d->strict_low, strict_low, sizeof strict_low);
843 d->template = 0;
844 d->outfun = 0;
845 validate_insn_alternatives (d);
848 /* Process a define_split just read. Assign its code number,
849 only for reasons of consistency and to simplify genrecog. */
852 static void
853 gen_split (split)
854 rtx split;
856 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
857 register int i;
859 d->code_number = next_code_number++;
860 d->index_number = next_index_number;
861 d->name = 0;
863 /* Build up the list in the same order as the insns are seen
864 in the machine description. */
865 d->next = 0;
866 if (end_of_insn_data)
867 end_of_insn_data->next = d;
868 else
869 insn_data = d;
871 end_of_insn_data = d;
873 max_opno = -1;
874 num_dups = 0;
876 memset (constraints, 0, sizeof constraints);
877 memset (op_n_alternatives, 0, sizeof op_n_alternatives);
878 memset (predicates, 0, sizeof predicates);
879 memset (address_p, 0, sizeof address_p);
880 memset (modes, 0, sizeof modes);
881 memset (strict_low, 0, sizeof strict_low);
882 memset (seen, 0, sizeof seen);
884 /* Get the number of operands by scanning all the
885 patterns of the split patterns.
886 But ignore all the rest of the information thus obtained. */
887 for (i = 0; i < XVECLEN (split, 0); i++)
888 scan_operands (XVECEXP (split, 0, i), 0, 0);
890 d->n_operands = max_opno + 1;
892 memset (d->constraints, 0, sizeof constraints);
893 memset (d->op_n_alternatives, 0, sizeof op_n_alternatives);
894 memset (d->predicates, 0, sizeof predicates);
895 memset (d->address_p, 0, sizeof address_p);
896 memset (d->modes, 0, sizeof modes);
897 memset (d->strict_low, 0, sizeof strict_low);
899 d->n_dups = 0;
900 d->n_alternatives = 0;
901 d->template = 0;
902 d->outfun = 0;
906 xmalloc (size)
907 size_t size;
909 register PTR val = (PTR) malloc (size);
911 if (val == 0)
912 fatal ("virtual memory exhausted");
913 return val;
917 xrealloc (old, size)
918 PTR old;
919 size_t size;
921 register PTR ptr;
922 if (old)
923 ptr = (PTR) realloc (old, size);
924 else
925 ptr = (PTR) malloc (size);
926 if (!ptr)
927 fatal ("virtual memory exhausted");
928 return ptr;
931 void
932 fatal VPROTO ((const char *format, ...))
934 #ifndef ANSI_PROTOTYPES
935 const char *format;
936 #endif
937 va_list ap;
939 VA_START (ap, format);
941 #ifndef ANSI_PROTOTYPES
942 format = va_arg (ap, const char *);
943 #endif
945 fprintf (stderr, "genoutput: ");
946 vfprintf (stderr, format, ap);
947 va_end (ap);
948 fprintf (stderr, "\n");
949 exit (FATAL_EXIT_CODE);
952 /* More 'friendly' abort that prints the line and file.
953 config.h can #define abort fancy_abort if you like that sort of thing. */
955 void
956 fancy_abort ()
958 fatal ("Internal gcc abort.");
961 static void
962 error VPROTO ((const char *format, ...))
964 #ifndef ANSI_PROTOTYPES
965 const char *format;
966 #endif
967 va_list ap;
969 VA_START (ap, format);
971 #ifndef ANSI_PROTOTYPES
972 format = va_arg (ap, const char *);
973 #endif
975 fprintf (stderr, "genoutput: ");
976 vfprintf (stderr, format, ap);
977 va_end (ap);
978 fprintf (stderr, "\n");
980 have_error = 1;
984 main (argc, argv)
985 int argc;
986 char **argv;
988 rtx desc;
989 FILE *infile;
990 register int c;
992 obstack_init (rtl_obstack);
994 if (argc <= 1)
995 fatal ("No input file name.");
997 infile = fopen (argv[1], "r");
998 if (infile == 0)
1000 perror (argv[1]);
1001 exit (FATAL_EXIT_CODE);
1004 init_rtl ();
1006 output_prologue ();
1007 next_code_number = 0;
1008 next_index_number = 0;
1009 have_constraints = 0;
1011 /* Read the machine description. */
1013 while (1)
1015 c = read_skip_spaces (infile);
1016 if (c == EOF)
1017 break;
1018 ungetc (c, infile);
1020 desc = read_rtx (infile);
1021 if (GET_CODE (desc) == DEFINE_INSN)
1022 gen_insn (desc);
1023 if (GET_CODE (desc) == DEFINE_PEEPHOLE)
1024 gen_peephole (desc);
1025 if (GET_CODE (desc) == DEFINE_EXPAND)
1026 gen_expand (desc);
1027 if (GET_CODE (desc) == DEFINE_SPLIT)
1028 gen_split (desc);
1029 next_index_number++;
1032 output_epilogue ();
1034 fflush (stdout);
1035 exit (ferror (stdout) != 0 || have_error
1036 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
1038 /* NOTREACHED */
1039 return 0;
1042 static int
1043 n_occurrences (c, s)
1044 int c;
1045 char *s;
1047 int n = 0;
1048 while (*s)
1049 n += (*s++ == c);
1050 return n;