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)
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
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
83 [(set (match_operand:DF 0 "general_operand" "")
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 `*'). */
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 static 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. */
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 */
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 void output_prologue
PROTO((void));
174 static void output_epilogue
PROTO((void));
175 static void scan_operands
PROTO((rtx
, int, int));
176 static void process_template
PROTO((struct data
*, char *));
177 static void validate_insn_alternatives
PROTO((struct data
*));
178 static void gen_insn
PROTO((rtx
));
179 static void gen_peephole
PROTO((rtx
));
180 static void gen_expand
PROTO((rtx
));
181 static void gen_split
PROTO((rtx
));
182 static int n_occurrences
PROTO((int, char *));
187 printf ("/* Generated automatically by the program `genoutput'\n\
188 from the machine description file `md'. */\n\n");
190 printf ("#include \"config.h\"\n");
191 printf ("#include \"system.h\"\n");
192 printf ("#include \"flags.h\"\n");
193 printf ("#include \"rtl.h\"\n");
194 printf ("#include \"regs.h\"\n");
195 printf ("#include \"hard-reg-set.h\"\n");
196 printf ("#include \"real.h\"\n");
197 printf ("#include \"insn-config.h\"\n\n");
198 printf ("#include \"conditions.h\"\n");
199 printf ("#include \"insn-flags.h\"\n");
200 printf ("#include \"insn-attr.h\"\n\n");
201 printf ("#include \"insn-codes.h\"\n\n");
202 printf ("#include \"recog.h\"\n\n");
204 printf ("#include \"output.h\"\n");
210 register struct data
*d
;
212 printf ("\nchar * const insn_template[] =\n {\n");
213 for (d
= insn_data
; d
; d
= d
->next
)
216 printf (" \"%s\",\n", d
->template);
222 printf ("\nchar *(*const insn_outfun[])() =\n {\n");
223 for (d
= insn_data
; d
; d
= d
->next
)
226 printf (" output_%d,\n", d
->code_number
);
232 printf ("\nrtx (*const insn_gen_function[]) () =\n {\n");
233 for (d
= insn_data
; d
; d
= d
->next
)
235 if (d
->name
&& d
->name
[0] != '*')
236 printf (" gen_%s,\n", d
->name
);
242 printf ("\nchar *insn_name[] =\n {\n");
246 char * last_name
= 0;
247 char * next_name
= 0;
248 register struct data
*n
;
250 for (n
= insn_data
, next
= 1; n
; n
= n
->next
, next
++)
257 for (d
= insn_data
; d
; d
= d
->next
)
261 printf (" \"%s\",\n", d
->name
);
265 for (n
= d
->next
, next
= 1; n
; n
= n
->next
, next
++)
275 if (next_name
&& (last_name
== 0 || offset
> next
/ 2))
276 printf (" \"%s-%d\",\n", next_name
, next
- offset
);
278 printf (" \"%s+%d\",\n", last_name
, offset
);
283 printf ("char **insn_name_ptr = insn_name;\n");
285 printf ("\nconst int insn_n_operands[] =\n {\n");
286 for (d
= insn_data
; d
; d
= d
->next
)
287 printf (" %d,\n", d
->n_operands
);
290 printf ("\nconst int insn_n_dups[] =\n {\n");
291 for (d
= insn_data
; d
; d
= d
->next
)
292 printf (" %d,\n", d
->n_dups
);
295 if (have_constraints
)
297 printf ("\nchar *const insn_operand_constraint[][MAX_RECOG_OPERANDS] =\n {\n");
298 for (d
= insn_data
; d
; d
= d
->next
)
302 for (i
= 0; i
< d
->n_operands
; i
++)
304 if (d
->constraints
[i
] == 0)
307 printf (" \"%s\",", d
->constraints
[i
]);
309 if (d
->n_operands
== 0)
317 printf ("\nconst char insn_operand_address_p[][MAX_RECOG_OPERANDS] =\n {\n");
318 for (d
= insn_data
; d
; d
= d
->next
)
322 for (i
= 0; i
< d
->n_operands
; i
++)
323 printf (" %d,", d
->address_p
[i
]);
324 if (d
->n_operands
== 0)
331 printf ("\nconst enum machine_mode insn_operand_mode[][MAX_RECOG_OPERANDS] =\n {\n");
332 for (d
= insn_data
; d
; d
= d
->next
)
336 for (i
= 0; i
< d
->n_operands
; i
++)
337 printf (" %smode,", GET_MODE_NAME (d
->modes
[i
]));
338 if (d
->n_operands
== 0)
339 printf (" VOIDmode");
344 printf ("\nconst char insn_operand_strict_low[][MAX_RECOG_OPERANDS] =\n {\n");
345 for (d
= insn_data
; d
; d
= d
->next
)
349 for (i
= 0; i
< d
->n_operands
; i
++)
350 printf (" %d,", d
->strict_low
[i
]);
351 if (d
->n_operands
== 0)
358 /* We need to define all predicates used. Keep a list of those we
359 have defined so far. There normally aren't very many predicates used,
360 so a linked list should be fast enough. */
361 struct predicate
{ char *name
; struct predicate
*next
; } *predicates
= 0;
366 for (d
= insn_data
; d
; d
= d
->next
)
367 for (i
= 0; i
< d
->n_operands
; i
++)
368 if (d
->predicates
[i
] && d
->predicates
[i
][0])
370 for (p
= predicates
; p
; p
= p
->next
)
371 if (! strcmp (p
->name
, d
->predicates
[i
]))
376 printf ("extern int %s ();\n", d
->predicates
[i
]);
377 p
= (struct predicate
*) alloca (sizeof (struct predicate
));
378 p
->name
= d
->predicates
[i
];
379 p
->next
= predicates
;
384 printf ("\nint (*const insn_operand_predicate[][MAX_RECOG_OPERANDS])() =\n {\n");
385 for (d
= insn_data
; d
; d
= d
->next
)
388 for (i
= 0; i
< d
->n_operands
; i
++)
389 printf (" %s,", ((d
->predicates
[i
] && d
->predicates
[i
][0])
390 ? d
->predicates
[i
] : "0"));
391 if (d
->n_operands
== 0)
398 printf ("\nconst int insn_n_alternatives[] =\n {\n");
399 for (d
= insn_data
; d
; d
= d
->next
)
400 printf (" %d,\n", d
->n_alternatives
);
404 /* scan_operands (X) stores in max_opno the largest operand
405 number present in X, if that is larger than the previous
406 value of max_opno. It stores all the constraints in `constraints'
407 and all the machine modes in `modes'.
409 THIS_ADDRESS_P is nonzero if the containing rtx was an ADDRESS.
410 THIS_STRICT_LOW is nonzero if the containing rtx was a STRICT_LOW_PART. */
414 static char *constraints
[MAX_MAX_OPERANDS
];
415 static int op_n_alternatives
[MAX_MAX_OPERANDS
];
416 static const char *predicates
[MAX_MAX_OPERANDS
];
417 static char address_p
[MAX_MAX_OPERANDS
];
418 static enum machine_mode modes
[MAX_MAX_OPERANDS
];
419 static char strict_low
[MAX_MAX_OPERANDS
];
420 static char seen
[MAX_MAX_OPERANDS
];
423 scan_operands (part
, this_address_p
, this_strict_low
)
429 register char *format_ptr
;
435 switch (GET_CODE (part
))
438 opno
= XINT (part
, 0);
441 if (max_opno
>= MAX_MAX_OPERANDS
)
443 error ("Too many operands (%d) in definition %d.\n",
444 max_opno
+ 1, next_index_number
);
448 error ("Definition %d specified operand number %d more than once.\n",
449 next_index_number
, opno
);
451 modes
[opno
] = GET_MODE (part
);
452 strict_low
[opno
] = this_strict_low
;
453 predicates
[opno
] = XSTR (part
, 1);
454 constraints
[opno
] = XSTR (part
, 2);
455 if (XSTR (part
, 2) != 0 && *XSTR (part
, 2) != 0)
457 op_n_alternatives
[opno
] = n_occurrences (',', XSTR (part
, 2)) + 1;
458 have_constraints
= 1;
460 address_p
[opno
] = this_address_p
;
464 opno
= XINT (part
, 0);
467 if (max_opno
>= MAX_MAX_OPERANDS
)
469 error ("Too many operands (%d) in definition %d.\n",
470 max_opno
+ 1, next_index_number
);
474 error ("Definition %d specified operand number %d more than once.\n",
475 next_index_number
, opno
);
477 modes
[opno
] = GET_MODE (part
);
478 strict_low
[opno
] = 0;
479 predicates
[opno
] = "scratch_operand";
480 constraints
[opno
] = XSTR (part
, 1);
481 if (XSTR (part
, 1) != 0 && *XSTR (part
, 1) != 0)
483 op_n_alternatives
[opno
] = n_occurrences (',', XSTR (part
, 1)) + 1;
484 have_constraints
= 1;
491 opno
= XINT (part
, 0);
494 if (max_opno
>= MAX_MAX_OPERANDS
)
496 error ("Too many operands (%d) in definition %d.\n",
497 max_opno
+ 1, next_index_number
);
501 error ("Definition %d specified operand number %d more than once.\n",
502 next_index_number
, opno
);
504 modes
[opno
] = GET_MODE (part
);
505 strict_low
[opno
] = 0;
506 predicates
[opno
] = XSTR (part
, 1);
507 constraints
[opno
] = 0;
509 for (i
= 0; i
< XVECLEN (part
, 2); i
++)
510 scan_operands (XVECEXP (part
, 2, i
), 0, 0);
520 scan_operands (XEXP (part
, 0), 1, 0);
523 case STRICT_LOW_PART
:
524 scan_operands (XEXP (part
, 0), 0, 1);
531 format_ptr
= GET_RTX_FORMAT (GET_CODE (part
));
533 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (part
)); i
++)
534 switch (*format_ptr
++)
538 scan_operands (XEXP (part
, i
), 0, 0);
541 if (XVEC (part
, i
) != NULL
)
542 for (j
= 0; j
< XVECLEN (part
, i
); j
++)
543 scan_operands (XVECEXP (part
, i
, j
), 0, 0);
548 /* Process an assembler template from a define_insn or a define_peephole.
549 It is either the assembler code template, a list of assembler code
550 templates, or C code to generate the assembler code template. */
553 process_template (d
, template)
560 /* We need to consider only the instructions whose assembler code template
561 starts with a * or @. These are the ones where C code is run to decide
562 on a template to use. So for all others just return now. */
564 if (template[0] != '*' && template[0] != '@')
566 d
->template = template;
574 printf ("\nstatic char *\n");
575 printf ("output_%d (operands, insn)\n", d
->code_number
);
576 printf (" rtx *operands ATTRIBUTE_UNUSED;\n");
577 printf (" rtx insn ATTRIBUTE_UNUSED;\n");
580 /* If the assembler code template starts with a @ it is a newline-separated
581 list of assembler code templates, one for each alternative. So produce
582 a routine to select the correct one. */
584 if (template[0] == '@')
587 printf (" static /*const*/ char *const strings_%d[] = {\n",
590 for (i
= 0, cp
= &template[1]; *cp
; )
592 while (*cp
== '\n' || *cp
== ' ' || *cp
== '\t')
596 while (*cp
!= '\n' && *cp
!= '\0')
607 printf (" return strings_%d[which_alternative];\n", d
->code_number
);
609 if (i
!= d
->n_alternatives
)
610 fatal ("Insn pattern %d has %d alternatives but %d assembler choices",
611 d
->index_number
, d
->n_alternatives
, i
);
616 /* The following is done in a funny way to get around problems in
617 VAX-11 "C" on VMS. It is the equivalent of:
618 printf ("%s\n", &template[1])); */
631 /* Check insn D for consistency in number of constraint alternatives. */
634 validate_insn_alternatives (d
)
637 register int n
= 0, start
;
638 /* Make sure all the operands have the same number of
639 alternatives in their constraints.
640 Let N be that number. */
641 for (start
= 0; start
< d
->n_operands
; start
++)
642 if (d
->op_n_alternatives
[start
] > 0)
645 n
= d
->op_n_alternatives
[start
];
646 else if (n
!= d
->op_n_alternatives
[start
])
647 error ("wrong number of alternatives in operand %d of insn number %d",
648 start
, d
->index_number
);
650 /* Record the insn's overall number of alternatives. */
651 d
->n_alternatives
= n
;
654 /* Look at a define_insn just read. Assign its code number.
655 Record on insn_data the template and the number of arguments.
656 If the insn has a hairy output action, output a function for now. */
662 register struct data
*d
= (struct data
*) xmalloc (sizeof (struct data
));
665 d
->code_number
= next_code_number
++;
666 d
->index_number
= next_index_number
;
667 if (XSTR (insn
, 0)[0])
668 d
->name
= XSTR (insn
, 0);
672 /* Build up the list in the same order as the insns are seen
673 in the machine description. */
675 if (end_of_insn_data
)
676 end_of_insn_data
->next
= d
;
680 end_of_insn_data
= d
;
685 memset (constraints
, 0, sizeof constraints
);
686 memset (op_n_alternatives
, 0, sizeof op_n_alternatives
);
687 memset (predicates
, 0, sizeof predicates
);
688 memset (address_p
, 0, sizeof address_p
);
689 memset (modes
, 0, sizeof modes
);
690 memset (strict_low
, 0, sizeof strict_low
);
691 memset (seen
, 0, sizeof seen
);
693 for (i
= 0; i
< XVECLEN (insn
, 1); i
++)
694 scan_operands (XVECEXP (insn
, 1, i
), 0, 0);
696 d
->n_operands
= max_opno
+ 1;
697 d
->n_dups
= num_dups
;
699 memcpy (d
->constraints
, constraints
, sizeof constraints
);
700 memcpy (d
->op_n_alternatives
, op_n_alternatives
, sizeof op_n_alternatives
);
701 memcpy (d
->predicates
, predicates
, sizeof predicates
);
702 memcpy (d
->address_p
, address_p
, sizeof address_p
);
703 memcpy (d
->modes
, modes
, sizeof modes
);
704 memcpy (d
->strict_low
, strict_low
, sizeof strict_low
);
706 validate_insn_alternatives (d
);
707 process_template (d
, XSTR (insn
, 3));
710 /* Look at a define_peephole just read. Assign its code number.
711 Record on insn_data the template and the number of arguments.
712 If the insn has a hairy output action, output it now. */
718 register struct data
*d
= (struct data
*) xmalloc (sizeof (struct data
));
721 d
->code_number
= next_code_number
++;
722 d
->index_number
= next_index_number
;
725 /* Build up the list in the same order as the insns are seen
726 in the machine description. */
728 if (end_of_insn_data
)
729 end_of_insn_data
->next
= d
;
733 end_of_insn_data
= d
;
736 memset (constraints
, 0, sizeof constraints
);
737 memset (op_n_alternatives
, 0, sizeof op_n_alternatives
);
738 memset (predicates
, 0, sizeof predicates
);
739 memset (address_p
, 0, sizeof address_p
);
740 memset (modes
, 0, sizeof modes
);
741 memset (strict_low
, 0, sizeof strict_low
);
742 memset (seen
, 0, sizeof seen
);
744 /* Get the number of operands by scanning all the
745 patterns of the peephole optimizer.
746 But ignore all the rest of the information thus obtained. */
747 for (i
= 0; i
< XVECLEN (peep
, 0); i
++)
748 scan_operands (XVECEXP (peep
, 0, i
), 0, 0);
750 d
->n_operands
= max_opno
+ 1;
753 memcpy (d
->constraints
, constraints
, sizeof constraints
);
754 memcpy (d
->op_n_alternatives
, op_n_alternatives
, sizeof op_n_alternatives
);
755 memset (d
->predicates
, 0, sizeof predicates
);
756 memset (d
->address_p
, 0, sizeof address_p
);
757 memset (d
->modes
, 0, sizeof modes
);
758 memset (d
->strict_low
, 0, sizeof strict_low
);
760 validate_insn_alternatives (d
);
761 process_template (d
, XSTR (peep
, 2));
764 /* Process a define_expand just read. Assign its code number,
765 only for the purposes of `insn_gen_function'. */
771 register struct data
*d
= (struct data
*) xmalloc (sizeof (struct data
));
774 d
->code_number
= next_code_number
++;
775 d
->index_number
= next_index_number
;
776 if (XSTR (insn
, 0)[0])
777 d
->name
= XSTR (insn
, 0);
781 /* Build up the list in the same order as the insns are seen
782 in the machine description. */
784 if (end_of_insn_data
)
785 end_of_insn_data
->next
= d
;
789 end_of_insn_data
= d
;
794 /* Scan the operands to get the specified predicates and modes,
795 since expand_binop needs to know them. */
797 memset (constraints
, 0, sizeof constraints
);
798 memset (op_n_alternatives
, 0, sizeof op_n_alternatives
);
799 memset (predicates
, 0, sizeof predicates
);
800 memset (address_p
, 0, sizeof address_p
);
801 memset (modes
, 0, sizeof modes
);
802 memset (strict_low
, 0, sizeof strict_low
);
803 memset (seen
, 0, sizeof seen
);
806 for (i
= 0; i
< XVECLEN (insn
, 1); i
++)
807 scan_operands (XVECEXP (insn
, 1, i
), 0, 0);
809 d
->n_operands
= max_opno
+ 1;
810 d
->n_dups
= num_dups
;
812 memcpy (d
->constraints
, constraints
, sizeof constraints
);
813 memcpy (d
->op_n_alternatives
, op_n_alternatives
, sizeof op_n_alternatives
);
814 memcpy (d
->predicates
, predicates
, sizeof predicates
);
815 memcpy (d
->address_p
, address_p
, sizeof address_p
);
816 memcpy (d
->modes
, modes
, sizeof modes
);
817 memcpy (d
->strict_low
, strict_low
, sizeof strict_low
);
821 validate_insn_alternatives (d
);
824 /* Process a define_split just read. Assign its code number,
825 only for reasons of consistency and to simplify genrecog. */
832 register struct data
*d
= (struct data
*) xmalloc (sizeof (struct data
));
835 d
->code_number
= next_code_number
++;
836 d
->index_number
= next_index_number
;
839 /* Build up the list in the same order as the insns are seen
840 in the machine description. */
842 if (end_of_insn_data
)
843 end_of_insn_data
->next
= d
;
847 end_of_insn_data
= d
;
852 memset (constraints
, 0, sizeof constraints
);
853 memset (op_n_alternatives
, 0, sizeof op_n_alternatives
);
854 memset (predicates
, 0, sizeof predicates
);
855 memset (address_p
, 0, sizeof address_p
);
856 memset (modes
, 0, sizeof modes
);
857 memset (strict_low
, 0, sizeof strict_low
);
858 memset (seen
, 0, sizeof seen
);
860 /* Get the number of operands by scanning all the
861 patterns of the split patterns.
862 But ignore all the rest of the information thus obtained. */
863 for (i
= 0; i
< XVECLEN (split
, 0); i
++)
864 scan_operands (XVECEXP (split
, 0, i
), 0, 0);
866 d
->n_operands
= max_opno
+ 1;
868 memset (d
->constraints
, 0, sizeof constraints
);
869 memset (d
->op_n_alternatives
, 0, sizeof op_n_alternatives
);
870 memset (d
->predicates
, 0, sizeof predicates
);
871 memset (d
->address_p
, 0, sizeof address_p
);
872 memset (d
->modes
, 0, sizeof modes
);
873 memset (d
->strict_low
, 0, sizeof strict_low
);
876 d
->n_alternatives
= 0;
885 register PTR val
= (PTR
) malloc (size
);
888 fatal ("virtual memory exhausted");
897 register PTR result
= (PTR
) realloc (ptr
, size
);
899 fatal ("virtual memory exhausted");
904 fatal
VPROTO ((const char *format
, ...))
906 #ifndef ANSI_PROTOTYPES
911 VA_START (ap
, format
);
913 #ifndef ANSI_PROTOTYPES
914 format
= va_arg (ap
, const char *);
917 fprintf (stderr
, "genoutput: ");
918 vfprintf (stderr
, format
, ap
);
920 fprintf (stderr
, "\n");
921 exit (FATAL_EXIT_CODE
);
924 /* More 'friendly' abort that prints the line and file.
925 config.h can #define abort fancy_abort if you like that sort of thing. */
930 fatal ("Internal gcc abort.");
934 error
VPROTO ((const char *format
, ...))
936 #ifndef ANSI_PROTOTYPES
941 VA_START (ap
, format
);
943 #ifndef ANSI_PROTOTYPES
944 format
= va_arg (ap
, const char *);
947 fprintf (stderr
, "genoutput: ");
948 vfprintf (stderr
, format
, ap
);
950 fprintf (stderr
, "\n");
964 obstack_init (rtl_obstack
);
967 fatal ("No input file name.");
969 infile
= fopen (argv
[1], "r");
973 exit (FATAL_EXIT_CODE
);
979 next_code_number
= 0;
980 next_index_number
= 0;
981 have_constraints
= 0;
983 /* Read the machine description. */
987 c
= read_skip_spaces (infile
);
992 desc
= read_rtx (infile
);
993 if (GET_CODE (desc
) == DEFINE_INSN
)
995 if (GET_CODE (desc
) == DEFINE_PEEPHOLE
)
997 if (GET_CODE (desc
) == DEFINE_EXPAND
)
999 if (GET_CODE (desc
) == DEFINE_SPLIT
)
1001 next_index_number
++;
1007 exit (ferror (stdout
) != 0 || have_error
1008 ? FATAL_EXIT_CODE
: SUCCESS_EXIT_CODE
);
1015 n_occurrences (c
, s
)