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 `*'). */
99 /* No instruction can have more operands than this.
100 Sorry for this arbitrary limit, but what machine will
101 have an instruction with this many operands? */
103 #define MAX_MAX_OPERANDS 40
105 static struct obstack obstack
;
106 struct obstack
*rtl_obstack
= &obstack
;
108 #define obstack_chunk_alloc xmalloc
109 #define obstack_chunk_free free
111 static int n_occurrences
PROTO((int, char *));
113 /* Define this so we can link with print-rtl.o to get debug_rtx function. */
114 char **insn_name_ptr
= 0;
116 /* insns in the machine description are assigned sequential code numbers
117 that are used by insn-recog.c (produced by genrecog) to communicate
118 to insn-output.c (produced by this program). */
120 static int next_code_number
;
122 /* This counts all definitions in the md file,
123 for the sake of error messages. */
125 static int next_index_number
;
127 /* Record in this chain all information that we will output,
128 associated with the code number of the insn. */
135 char *template; /* string such as "movl %1,%0" */
136 int n_operands
; /* Number of operands this insn recognizes */
137 int n_dups
; /* Number times match_dup appears in pattern */
138 int n_alternatives
; /* Number of alternatives in each constraint */
140 char *constraints
[MAX_MAX_OPERANDS
];
141 /* Number of alternatives in constraints of operand N. */
142 int op_n_alternatives
[MAX_MAX_OPERANDS
];
143 char *predicates
[MAX_MAX_OPERANDS
];
144 char address_p
[MAX_MAX_OPERANDS
];
145 enum machine_mode modes
[MAX_MAX_OPERANDS
];
146 char strict_low
[MAX_MAX_OPERANDS
];
147 char outfun
; /* Nonzero means this has an output function */
150 /* This variable points to the first link in the chain. */
152 struct data
*insn_data
;
154 /* Pointer to the last link in the chain, so new elements
155 can be added at the end. */
157 struct data
*end_of_insn_data
;
159 /* Nonzero if any match_operand has a constraint string;
160 implies that REGISTER_CONSTRAINTS will be defined
161 for this machine description. */
163 int have_constraints
;
166 static char * name_for_index
PROTO((int));
167 static void output_prologue
PROTO((void));
168 static void output_epilogue
PROTO((void));
169 static void scan_operands
PROTO((rtx
, int, int));
170 static void process_template
PROTO((struct data
*, char *));
171 static void validate_insn_alternatives
PROTO((struct data
*));
172 static void gen_insn
PROTO((rtx
));
173 static void gen_peephole
PROTO((rtx
));
174 static void gen_expand
PROTO((rtx
));
175 static void gen_split
PROTO((rtx
));
176 static int n_occurrences
PROTO((int, char *));
179 name_for_index (index
)
182 static char buf
[100];
184 struct data
*i
, *last_named
= NULL
;
185 for (i
= insn_data
; i
; i
= i
->next
)
187 if (i
->index_number
== index
)
194 sprintf(buf
, "%s+%d", last_named
->name
, index
- last_named
->index_number
);
196 sprintf(buf
, "insn %d", index
);
204 printf ("/* Generated automatically by the program `genoutput'\n\
205 from the machine description file `md'. */\n\n");
207 printf ("#include \"config.h\"\n");
208 printf ("#include \"system.h\"\n");
209 printf ("#include \"flags.h\"\n");
210 printf ("#include \"rtl.h\"\n");
211 printf ("#include \"function.h\"\n");
212 printf ("#include \"regs.h\"\n");
213 printf ("#include \"hard-reg-set.h\"\n");
214 printf ("#include \"real.h\"\n");
215 printf ("#include \"insn-config.h\"\n\n");
216 printf ("#include \"conditions.h\"\n");
217 printf ("#include \"insn-flags.h\"\n");
218 printf ("#include \"insn-attr.h\"\n\n");
219 printf ("#include \"insn-codes.h\"\n\n");
220 printf ("#include \"recog.h\"\n\n");
222 printf ("#include \"output.h\"\n");
228 register struct data
*d
;
230 printf ("\nconst char * const insn_template[] =\n {\n");
231 for (d
= insn_data
; d
; d
= d
->next
)
234 printf (" \"%s\",\n", d
->template);
240 printf ("\nconst char *(*const insn_outfun[]) PROTO((rtx *, rtx)) =\n {\n");
241 for (d
= insn_data
; d
; d
= d
->next
)
244 printf (" output_%d,\n", d
->code_number
);
250 printf ("\nrtx (*const insn_gen_function[]) () =\n {\n");
251 for (d
= insn_data
; d
; d
= d
->next
)
253 if (d
->name
&& d
->name
[0] != '*')
254 printf (" gen_%s,\n", d
->name
);
260 printf ("\nconst char *insn_name[] =\n {\n");
264 char * last_name
= 0;
265 char * next_name
= 0;
266 register struct data
*n
;
268 for (n
= insn_data
, next
= 1; n
; n
= n
->next
, next
++)
275 for (d
= insn_data
; d
; d
= d
->next
)
279 printf (" \"%s\",\n", d
->name
);
283 for (n
= d
->next
, next
= 1; n
; n
= n
->next
, next
++)
293 if (next_name
&& (last_name
== 0 || offset
> next
/ 2))
294 printf (" \"%s-%d\",\n", next_name
, next
- offset
);
296 printf (" \"%s+%d\",\n", last_name
, offset
);
301 printf ("const char **insn_name_ptr = insn_name;\n");
303 printf ("\nconst int insn_n_operands[] =\n {\n");
304 for (d
= insn_data
; d
; d
= d
->next
)
305 printf (" %d,\n", d
->n_operands
);
308 printf ("\nconst int insn_n_dups[] =\n {\n");
309 for (d
= insn_data
; d
; d
= d
->next
)
310 printf (" %d,\n", d
->n_dups
);
313 if (have_constraints
)
315 printf ("\nconst char *const insn_operand_constraint[][MAX_RECOG_OPERANDS] =\n {\n");
316 for (d
= insn_data
; d
; d
= d
->next
)
320 for (i
= 0; i
< d
->n_operands
; i
++)
322 if (d
->constraints
[i
] == 0)
325 printf (" \"%s\",", d
->constraints
[i
]);
327 if (d
->n_operands
== 0)
335 printf ("\nconst char insn_operand_address_p[][MAX_RECOG_OPERANDS] =\n {\n");
336 for (d
= insn_data
; d
; d
= d
->next
)
340 for (i
= 0; i
< d
->n_operands
; i
++)
341 printf (" %d,", d
->address_p
[i
]);
342 if (d
->n_operands
== 0)
349 printf ("\nconst enum machine_mode insn_operand_mode[][MAX_RECOG_OPERANDS] =\n {\n");
350 for (d
= insn_data
; d
; d
= d
->next
)
354 for (i
= 0; i
< d
->n_operands
; i
++)
355 printf (" %smode,", GET_MODE_NAME (d
->modes
[i
]));
356 if (d
->n_operands
== 0)
357 printf (" VOIDmode");
362 printf ("\nconst char insn_operand_strict_low[][MAX_RECOG_OPERANDS] =\n {\n");
363 for (d
= insn_data
; d
; d
= d
->next
)
367 for (i
= 0; i
< d
->n_operands
; i
++)
368 printf (" %d,", d
->strict_low
[i
]);
369 if (d
->n_operands
== 0)
376 /* We need to define all predicates used. Keep a list of those we
377 have defined so far. There normally aren't very many predicates used,
378 so a linked list should be fast enough. */
379 struct predicate
{ char *name
; struct predicate
*next
; } *predicates
= 0;
384 for (d
= insn_data
; d
; d
= d
->next
)
385 for (i
= 0; i
< d
->n_operands
; i
++)
386 if (d
->predicates
[i
] && d
->predicates
[i
][0])
388 for (p
= predicates
; p
; p
= p
->next
)
389 if (! strcmp (p
->name
, d
->predicates
[i
]))
394 printf ("extern int %s PROTO ((rtx, enum machine_mode));\n",
396 p
= (struct predicate
*) alloca (sizeof (struct predicate
));
397 p
->name
= d
->predicates
[i
];
398 p
->next
= predicates
;
403 printf ("\nint (*const insn_operand_predicate[][MAX_RECOG_OPERANDS]) PROTO ((rtx, enum machine_mode)) =\n {\n");
404 for (d
= insn_data
; d
; d
= d
->next
)
407 for (i
= 0; i
< d
->n_operands
; i
++)
408 printf (" %s,", ((d
->predicates
[i
] && d
->predicates
[i
][0])
409 ? d
->predicates
[i
] : "0"));
410 if (d
->n_operands
== 0)
417 printf ("\nconst int insn_n_alternatives[] =\n {\n");
418 for (d
= insn_data
; d
; d
= d
->next
)
419 printf (" %d,\n", d
->n_alternatives
);
423 /* scan_operands (X) stores in max_opno the largest operand
424 number present in X, if that is larger than the previous
425 value of max_opno. It stores all the constraints in `constraints'
426 and all the machine modes in `modes'.
428 THIS_ADDRESS_P is nonzero if the containing rtx was an ADDRESS.
429 THIS_STRICT_LOW is nonzero if the containing rtx was a STRICT_LOW_PART. */
433 static char *constraints
[MAX_MAX_OPERANDS
];
434 static int op_n_alternatives
[MAX_MAX_OPERANDS
];
435 static const char *predicates
[MAX_MAX_OPERANDS
];
436 static char address_p
[MAX_MAX_OPERANDS
];
437 static enum machine_mode modes
[MAX_MAX_OPERANDS
];
438 static char strict_low
[MAX_MAX_OPERANDS
];
439 static char seen
[MAX_MAX_OPERANDS
];
442 scan_operands (part
, this_address_p
, this_strict_low
)
448 register const char *format_ptr
;
454 switch (GET_CODE (part
))
457 opno
= XINT (part
, 0);
460 if (max_opno
>= MAX_MAX_OPERANDS
)
462 error ("Too many operands (%d) in definition %s.\n",
463 max_opno
+ 1, name_for_index (next_index_number
));
467 error ("Definition %s specified operand number %d more than once.\n",
468 name_for_index (next_index_number
), opno
);
470 modes
[opno
] = GET_MODE (part
);
471 strict_low
[opno
] = this_strict_low
;
472 predicates
[opno
] = XSTR (part
, 1);
473 constraints
[opno
] = XSTR (part
, 2);
474 if (XSTR (part
, 2) != 0 && *XSTR (part
, 2) != 0)
476 op_n_alternatives
[opno
] = n_occurrences (',', XSTR (part
, 2)) + 1;
477 have_constraints
= 1;
479 address_p
[opno
] = this_address_p
;
483 opno
= XINT (part
, 0);
486 if (max_opno
>= MAX_MAX_OPERANDS
)
488 error ("Too many operands (%d) in definition %s.\n",
489 max_opno
+ 1, name_for_index (next_index_number
));
493 error ("Definition %s specified operand number %d more than once.\n",
494 name_for_index (next_index_number
), opno
);
496 modes
[opno
] = GET_MODE (part
);
497 strict_low
[opno
] = 0;
498 predicates
[opno
] = "scratch_operand";
499 constraints
[opno
] = XSTR (part
, 1);
500 if (XSTR (part
, 1) != 0 && *XSTR (part
, 1) != 0)
502 op_n_alternatives
[opno
] = n_occurrences (',', XSTR (part
, 1)) + 1;
503 have_constraints
= 1;
510 opno
= XINT (part
, 0);
513 if (max_opno
>= MAX_MAX_OPERANDS
)
515 error ("Too many operands (%d) in definition %s.\n",
516 max_opno
+ 1, name_for_index (next_index_number
));
520 error ("Definition %s specified operand number %d more than once.\n",
521 name_for_index (next_index_number
), opno
);
523 modes
[opno
] = GET_MODE (part
);
524 strict_low
[opno
] = 0;
525 predicates
[opno
] = XSTR (part
, 1);
526 constraints
[opno
] = 0;
528 for (i
= 0; i
< XVECLEN (part
, 2); i
++)
529 scan_operands (XVECEXP (part
, 2, i
), 0, 0);
539 scan_operands (XEXP (part
, 0), 1, 0);
542 case STRICT_LOW_PART
:
543 scan_operands (XEXP (part
, 0), 0, 1);
550 format_ptr
= GET_RTX_FORMAT (GET_CODE (part
));
552 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (part
)); i
++)
553 switch (*format_ptr
++)
557 scan_operands (XEXP (part
, i
), 0, 0);
560 if (XVEC (part
, i
) != NULL
)
561 for (j
= 0; j
< XVECLEN (part
, i
); j
++)
562 scan_operands (XVECEXP (part
, i
, j
), 0, 0);
567 /* Process an assembler template from a define_insn or a define_peephole.
568 It is either the assembler code template, a list of assembler code
569 templates, or C code to generate the assembler code template. */
572 process_template (d
, template)
579 /* We need to consider only the instructions whose assembler code template
580 starts with a * or @. These are the ones where C code is run to decide
581 on a template to use. So for all others just return now. */
583 if (template[0] != '*' && template[0] != '@')
585 d
->template = template;
593 printf ("\nstatic const char *output_%d PROTO ((rtx *, rtx));\n",
595 printf ("\nstatic const char *\n");
596 printf ("output_%d (operands, insn)\n", d
->code_number
);
597 printf (" rtx *operands ATTRIBUTE_UNUSED;\n");
598 printf (" rtx insn ATTRIBUTE_UNUSED;\n");
601 /* If the assembler code template starts with a @ it is a newline-separated
602 list of assembler code templates, one for each alternative. So produce
603 a routine to select the correct one. */
605 if (template[0] == '@')
608 printf (" static const char *const strings_%d[] = {\n",
611 for (i
= 0, cp
= &template[1]; *cp
; )
613 while (*cp
== '\n' || *cp
== ' ' || *cp
== '\t')
617 while (*cp
!= '\n' && *cp
!= '\0')
628 printf (" return strings_%d[which_alternative];\n", d
->code_number
);
630 if (i
!= d
->n_alternatives
)
631 fatal ("Insn pattern %d has %d alternatives but %d assembler choices",
632 d
->index_number
, d
->n_alternatives
, i
);
637 /* The following is done in a funny way to get around problems in
638 VAX-11 "C" on VMS. It is the equivalent of:
639 printf ("%s\n", &template[1])); */
652 /* Check insn D for consistency in number of constraint alternatives. */
655 validate_insn_alternatives (d
)
658 register int n
= 0, start
;
659 /* Make sure all the operands have the same number of
660 alternatives in their constraints.
661 Let N be that number. */
662 for (start
= 0; start
< d
->n_operands
; start
++)
663 if (d
->op_n_alternatives
[start
] > 0)
666 n
= d
->op_n_alternatives
[start
];
667 else if (n
!= d
->op_n_alternatives
[start
])
668 error ("wrong number of alternatives in operand %d of insn %s",
669 start
, name_for_index (d
->index_number
));
671 /* Record the insn's overall number of alternatives. */
672 d
->n_alternatives
= n
;
675 /* Look at a define_insn just read. Assign its code number.
676 Record on insn_data the template and the number of arguments.
677 If the insn has a hairy output action, output a function for now. */
683 register struct data
*d
= (struct data
*) xmalloc (sizeof (struct data
));
686 d
->code_number
= next_code_number
++;
687 d
->index_number
= next_index_number
;
688 if (XSTR (insn
, 0)[0])
689 d
->name
= XSTR (insn
, 0);
693 /* Build up the list in the same order as the insns are seen
694 in the machine description. */
696 if (end_of_insn_data
)
697 end_of_insn_data
->next
= d
;
701 end_of_insn_data
= d
;
706 memset (constraints
, 0, sizeof constraints
);
707 memset (op_n_alternatives
, 0, sizeof op_n_alternatives
);
708 memset (predicates
, 0, sizeof predicates
);
709 memset (address_p
, 0, sizeof address_p
);
710 memset (modes
, 0, sizeof modes
);
711 memset (strict_low
, 0, sizeof strict_low
);
712 memset (seen
, 0, sizeof seen
);
714 for (i
= 0; i
< XVECLEN (insn
, 1); i
++)
715 scan_operands (XVECEXP (insn
, 1, i
), 0, 0);
717 d
->n_operands
= max_opno
+ 1;
718 d
->n_dups
= num_dups
;
720 memcpy (d
->constraints
, constraints
, sizeof constraints
);
721 memcpy (d
->op_n_alternatives
, op_n_alternatives
, sizeof op_n_alternatives
);
722 memcpy (d
->predicates
, predicates
, sizeof predicates
);
723 memcpy (d
->address_p
, address_p
, sizeof address_p
);
724 memcpy (d
->modes
, modes
, sizeof modes
);
725 memcpy (d
->strict_low
, strict_low
, sizeof strict_low
);
727 validate_insn_alternatives (d
);
728 process_template (d
, XSTR (insn
, 3));
731 /* Look at a define_peephole just read. Assign its code number.
732 Record on insn_data the template and the number of arguments.
733 If the insn has a hairy output action, output it now. */
739 register struct data
*d
= (struct data
*) xmalloc (sizeof (struct data
));
742 d
->code_number
= next_code_number
++;
743 d
->index_number
= next_index_number
;
746 /* Build up the list in the same order as the insns are seen
747 in the machine description. */
749 if (end_of_insn_data
)
750 end_of_insn_data
->next
= d
;
754 end_of_insn_data
= d
;
757 memset (constraints
, 0, sizeof constraints
);
758 memset (op_n_alternatives
, 0, sizeof op_n_alternatives
);
759 memset (predicates
, 0, sizeof predicates
);
760 memset (address_p
, 0, sizeof address_p
);
761 memset (modes
, 0, sizeof modes
);
762 memset (strict_low
, 0, sizeof strict_low
);
763 memset (seen
, 0, sizeof seen
);
765 /* Get the number of operands by scanning all the
766 patterns of the peephole optimizer.
767 But ignore all the rest of the information thus obtained. */
768 for (i
= 0; i
< XVECLEN (peep
, 0); i
++)
769 scan_operands (XVECEXP (peep
, 0, i
), 0, 0);
771 d
->n_operands
= max_opno
+ 1;
774 memcpy (d
->constraints
, constraints
, sizeof constraints
);
775 memcpy (d
->op_n_alternatives
, op_n_alternatives
, sizeof op_n_alternatives
);
776 memset (d
->predicates
, 0, sizeof predicates
);
777 memset (d
->address_p
, 0, sizeof address_p
);
778 memset (d
->modes
, 0, sizeof modes
);
779 memset (d
->strict_low
, 0, sizeof strict_low
);
781 validate_insn_alternatives (d
);
782 process_template (d
, XSTR (peep
, 2));
785 /* Process a define_expand just read. Assign its code number,
786 only for the purposes of `insn_gen_function'. */
792 register struct data
*d
= (struct data
*) xmalloc (sizeof (struct data
));
795 d
->code_number
= next_code_number
++;
796 d
->index_number
= next_index_number
;
797 if (XSTR (insn
, 0)[0])
798 d
->name
= XSTR (insn
, 0);
802 /* Build up the list in the same order as the insns are seen
803 in the machine description. */
805 if (end_of_insn_data
)
806 end_of_insn_data
->next
= d
;
810 end_of_insn_data
= d
;
815 /* Scan the operands to get the specified predicates and modes,
816 since expand_binop needs to know them. */
818 memset (constraints
, 0, sizeof constraints
);
819 memset (op_n_alternatives
, 0, sizeof op_n_alternatives
);
820 memset (predicates
, 0, sizeof predicates
);
821 memset (address_p
, 0, sizeof address_p
);
822 memset (modes
, 0, sizeof modes
);
823 memset (strict_low
, 0, sizeof strict_low
);
824 memset (seen
, 0, sizeof seen
);
827 for (i
= 0; i
< XVECLEN (insn
, 1); i
++)
828 scan_operands (XVECEXP (insn
, 1, i
), 0, 0);
830 d
->n_operands
= max_opno
+ 1;
831 d
->n_dups
= num_dups
;
833 memcpy (d
->constraints
, constraints
, sizeof constraints
);
834 memcpy (d
->op_n_alternatives
, op_n_alternatives
, sizeof op_n_alternatives
);
835 memcpy (d
->predicates
, predicates
, sizeof predicates
);
836 memcpy (d
->address_p
, address_p
, sizeof address_p
);
837 memcpy (d
->modes
, modes
, sizeof modes
);
838 memcpy (d
->strict_low
, strict_low
, sizeof strict_low
);
842 validate_insn_alternatives (d
);
845 /* Process a define_split just read. Assign its code number,
846 only for reasons of consistency and to simplify genrecog. */
853 register struct data
*d
= (struct data
*) xmalloc (sizeof (struct data
));
856 d
->code_number
= next_code_number
++;
857 d
->index_number
= next_index_number
;
860 /* Build up the list in the same order as the insns are seen
861 in the machine description. */
863 if (end_of_insn_data
)
864 end_of_insn_data
->next
= d
;
868 end_of_insn_data
= d
;
873 memset (constraints
, 0, sizeof constraints
);
874 memset (op_n_alternatives
, 0, sizeof op_n_alternatives
);
875 memset (predicates
, 0, sizeof predicates
);
876 memset (address_p
, 0, sizeof address_p
);
877 memset (modes
, 0, sizeof modes
);
878 memset (strict_low
, 0, sizeof strict_low
);
879 memset (seen
, 0, sizeof seen
);
881 /* Get the number of operands by scanning all the
882 patterns of the split patterns.
883 But ignore all the rest of the information thus obtained. */
884 for (i
= 0; i
< XVECLEN (split
, 0); i
++)
885 scan_operands (XVECEXP (split
, 0, i
), 0, 0);
887 d
->n_operands
= max_opno
+ 1;
889 memset (d
->constraints
, 0, sizeof constraints
);
890 memset (d
->op_n_alternatives
, 0, sizeof op_n_alternatives
);
891 memset (d
->predicates
, 0, sizeof predicates
);
892 memset (d
->address_p
, 0, sizeof address_p
);
893 memset (d
->modes
, 0, sizeof modes
);
894 memset (d
->strict_low
, 0, sizeof strict_low
);
897 d
->n_alternatives
= 0;
906 register PTR val
= (PTR
) malloc (size
);
909 fatal ("virtual memory exhausted");
920 ptr
= (PTR
) realloc (old
, size
);
922 ptr
= (PTR
) malloc (size
);
924 fatal ("virtual memory exhausted");
937 progname
= "genoutput";
938 obstack_init (rtl_obstack
);
941 fatal ("No input file name.");
943 infile
= fopen (argv
[1], "r");
947 exit (FATAL_EXIT_CODE
);
951 next_code_number
= 0;
952 next_index_number
= 0;
953 have_constraints
= 0;
955 /* Read the machine description. */
959 c
= read_skip_spaces (infile
);
964 desc
= read_rtx (infile
);
965 if (GET_CODE (desc
) == DEFINE_INSN
)
967 if (GET_CODE (desc
) == DEFINE_PEEPHOLE
)
969 if (GET_CODE (desc
) == DEFINE_EXPAND
)
971 if (GET_CODE (desc
) == DEFINE_SPLIT
972 || GET_CODE (desc
) == DEFINE_PEEPHOLE2
)
980 exit (ferror (stdout
) != 0 || have_error
981 ? FATAL_EXIT_CODE
: SUCCESS_EXIT_CODE
);