Add support for ARM's Thumb instruction set.
[official-gcc.git] / gcc / genoutput.c
bloba2d7c713b0d1aad190bdc06e2dff9680a617241d
1 /* Generate code from to output assembler insns as recognized from rtl.
2 Copyright (C) 1987, 88, 92, 94, 95, 97, 1998 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
22 /* This program reads the machine description for the compiler target machine
23 and produces a file containing these things:
25 1. An array of strings `insn_template' which is indexed by insn code number
26 and contains the template for output of that insn,
28 2. An array of functions `insn_outfun' which, indexed by the insn code
29 number, gives the function that returns a template to use for output of
30 that insn. This is used only in the cases where the template is not
31 constant. These cases are specified by a * or @ at the beginning of the
32 template string in the machine description. They are identified for the
33 sake of other parts of the compiler by a zero element in `insn_template'.
35 3. An array of functions `insn_gen_function' which, indexed
36 by insn code number, gives the function to generate a body
37 for that pattern, given operands as arguments.
39 4. An array of strings `insn_name' which, indexed by insn code number,
40 gives the name for that pattern. Nameless patterns are given a name.
42 5. An array of ints `insn_n_operands' which is indexed by insn code number
43 and contains the number of distinct operands in the pattern for that insn,
45 6. An array of ints `insn_n_dups' which is indexed by insn code number
46 and contains the number of match_dup's that appear in the insn's pattern.
47 This says how many elements of `recog_dup_loc' are significant
48 after an insn has been recognized.
50 7. An array of arrays of operand constraint strings,
51 `insn_operand_constraint',
52 indexed first by insn code number and second by operand number,
53 containing the constraint for that operand.
55 This array is generated only if register constraints appear in
56 match_operand rtx's.
58 8. An array of arrays of chars which indicate which operands of
59 which insn patterns appear within ADDRESS rtx's. This array is
60 called `insn_operand_address_p' and is generated only if there
61 are *no* register constraints in the match_operand rtx's.
63 9. An array of arrays of machine modes, `insn_operand_mode',
64 indexed first by insn code number and second by operand number,
65 containing the machine mode that that operand is supposed to have.
66 Also `insn_operand_strict_low', which is nonzero for operands
67 contained in a STRICT_LOW_PART.
69 10. An array of arrays of int-valued functions, `insn_operand_predicate',
70 indexed first by insn code number and second by operand number,
71 containing the match_operand predicate for this operand.
73 11. An array of ints, `insn_n_alternatives', that gives the number
74 of alternatives in the constraints of each pattern.
76 The code number of an insn is simply its position in the machine description;
77 code numbers are assigned sequentially to entries in the description,
78 starting with code number 0.
80 Thus, the following entry in the machine description
82 (define_insn "clrdf"
83 [(set (match_operand:DF 0 "general_operand" "")
84 (const_int 0))]
86 "clrd %0")
88 assuming it is the 25th entry present, would cause
89 insn_template[24] to be "clrd %0", and insn_n_operands[24] to be 1.
90 It would not make an case in output_insn_hairy because the template
91 given in the entry is a constant (it does not start with `*'). */
93 #include "hconfig.h"
94 #include "system.h"
95 #include "rtl.h"
96 #include "obstack.h"
98 /* No instruction can have more operands than this.
99 Sorry for this arbitrary limit, but what machine will
100 have an instruction with this many operands? */
102 #define MAX_MAX_OPERANDS 40
104 static struct obstack obstack;
105 struct obstack *rtl_obstack = &obstack;
107 #define obstack_chunk_alloc xmalloc
108 #define obstack_chunk_free free
110 char *xmalloc PROTO((unsigned));
111 static void fatal ();
112 void fancy_abort PROTO((void));
113 static void error ();
114 static void mybcopy ();
115 static void mybzero ();
116 static int n_occurrences PROTO((int, char *));
118 /* insns in the machine description are assigned sequential code numbers
119 that are used by insn-recog.c (produced by genrecog) to communicate
120 to insn-output.c (produced by this program). */
122 static int next_code_number;
124 /* This counts all definitions in the md file,
125 for the sake of error messages. */
127 static int next_index_number;
129 /* Record in this chain all information that we will output,
130 associated with the code number of the insn. */
132 struct data
134 int code_number;
135 int index_number;
136 char *name;
137 char *template; /* string such as "movl %1,%0" */
138 int n_operands; /* Number of operands this insn recognizes */
139 int n_dups; /* Number times match_dup appears in pattern */
140 int n_alternatives; /* Number of alternatives in each constraint */
141 struct data *next;
142 char *constraints[MAX_MAX_OPERANDS];
143 /* Number of alternatives in constraints of operand N. */
144 int op_n_alternatives[MAX_MAX_OPERANDS];
145 char *predicates[MAX_MAX_OPERANDS];
146 char address_p[MAX_MAX_OPERANDS];
147 enum machine_mode modes[MAX_MAX_OPERANDS];
148 char strict_low[MAX_MAX_OPERANDS];
149 char outfun; /* Nonzero means this has an output function */
152 /* This variable points to the first link in the chain. */
154 struct data *insn_data;
156 /* Pointer to the last link in the chain, so new elements
157 can be added at the end. */
159 struct data *end_of_insn_data;
161 /* Nonzero if any match_operand has a constraint string;
162 implies that REGISTER_CONSTRAINTS will be defined
163 for this machine description. */
165 int have_constraints;
167 /* Nonzero if some error has occurred. We will make all errors fatal, but
168 might as well continue until we see all of them. */
170 static int have_error;
172 static void
173 output_prologue ()
176 printf ("/* Generated automatically by the program `genoutput'\n\
177 from the machine description file `md'. */\n\n");
179 printf ("#include \"config.h\"\n");
180 printf ("#include <stdio.h>\n");
181 printf ("#include \"flags.h\"\n");
182 printf ("#include \"rtl.h\"\n");
183 printf ("#include \"regs.h\"\n");
184 printf ("#include \"hard-reg-set.h\"\n");
185 printf ("#include \"real.h\"\n");
186 printf ("#include \"insn-config.h\"\n\n");
187 printf ("#include \"conditions.h\"\n");
188 printf ("#include \"insn-flags.h\"\n");
189 printf ("#include \"insn-attr.h\"\n\n");
190 printf ("#include \"insn-codes.h\"\n\n");
191 printf ("#include \"recog.h\"\n\n");
193 printf ("#include \"output.h\"\n");
196 static void
197 output_epilogue ()
199 register struct data *d;
201 printf ("\nchar * const insn_template[] =\n {\n");
202 for (d = insn_data; d; d = d->next)
204 if (d->template)
205 printf (" \"%s\",\n", d->template);
206 else
207 printf (" 0,\n");
209 printf (" };\n");
211 printf ("\nchar *(*const insn_outfun[])() =\n {\n");
212 for (d = insn_data; d; d = d->next)
214 if (d->outfun)
215 printf (" output_%d,\n", d->code_number);
216 else
217 printf (" 0,\n");
219 printf (" };\n");
221 printf ("\nrtx (*const insn_gen_function[]) () =\n {\n");
222 for (d = insn_data; d; d = d->next)
224 if (d->name && d->name[0] != '*')
225 printf (" gen_%s,\n", d->name);
226 else
227 printf (" 0,\n");
229 printf (" };\n");
231 printf ("\nchar *insn_name[] =\n {\n");
233 int offset = 0;
234 int next;
235 char * last_name = 0;
236 char * next_name = 0;
237 register struct data *n;
239 for (n = insn_data, next = 1; n; n = n->next, next++)
240 if (n->name)
242 next_name = n->name;
243 break;
246 for (d = insn_data; d; d = d->next)
248 if (d->name)
250 printf (" \"%s\",\n", d->name);
251 offset = 0;
252 last_name = d->name;
253 next_name = 0;
254 for (n = d->next, next = 1; n; n = n->next, next++)
255 if (n->name)
257 next_name = n->name;
258 break;
261 else
263 offset++;
264 if (next_name && (last_name == 0 || offset > next / 2))
265 printf (" \"%s-%d\",\n", next_name, next - offset);
266 else
267 printf (" \"%s+%d\",\n", last_name, offset);
271 printf (" };\n");
272 printf ("char **insn_name_ptr = insn_name;\n");
274 printf ("\nconst int insn_n_operands[] =\n {\n");
275 for (d = insn_data; d; d = d->next)
276 printf (" %d,\n", d->n_operands);
277 printf (" };\n");
279 printf ("\nconst int insn_n_dups[] =\n {\n");
280 for (d = insn_data; d; d = d->next)
281 printf (" %d,\n", d->n_dups);
282 printf (" };\n");
284 if (have_constraints)
286 printf ("\nchar *const insn_operand_constraint[][MAX_RECOG_OPERANDS] =\n {\n");
287 for (d = insn_data; d; d = d->next)
289 register int i;
290 printf (" {");
291 for (i = 0; i < d->n_operands; i++)
293 if (d->constraints[i] == 0)
294 printf (" \"\",");
295 else
296 printf (" \"%s\",", d->constraints[i]);
298 if (d->n_operands == 0)
299 printf (" 0");
300 printf (" },\n");
302 printf (" };\n");
304 else
306 printf ("\nconst char insn_operand_address_p[][MAX_RECOG_OPERANDS] =\n {\n");
307 for (d = insn_data; d; d = d->next)
309 register int i;
310 printf (" {");
311 for (i = 0; i < d->n_operands; i++)
312 printf (" %d,", d->address_p[i]);
313 if (d->n_operands == 0)
314 printf (" 0");
315 printf (" },\n");
317 printf (" };\n");
320 printf ("\nconst enum machine_mode insn_operand_mode[][MAX_RECOG_OPERANDS] =\n {\n");
321 for (d = insn_data; d; d = d->next)
323 register int i;
324 printf (" {");
325 for (i = 0; i < d->n_operands; i++)
326 printf (" %smode,", GET_MODE_NAME (d->modes[i]));
327 if (d->n_operands == 0)
328 printf (" VOIDmode");
329 printf (" },\n");
331 printf (" };\n");
333 printf ("\nconst char insn_operand_strict_low[][MAX_RECOG_OPERANDS] =\n {\n");
334 for (d = insn_data; d; d = d->next)
336 register int i;
337 printf (" {");
338 for (i = 0; i < d->n_operands; i++)
339 printf (" %d,", d->strict_low[i]);
340 if (d->n_operands == 0)
341 printf (" 0");
342 printf (" },\n");
344 printf (" };\n");
347 /* We need to define all predicates used. Keep a list of those we
348 have defined so far. There normally aren't very many predicates used,
349 so a linked list should be fast enough. */
350 struct predicate { char *name; struct predicate *next; } *predicates = 0;
351 struct predicate *p;
352 int i;
354 printf ("\n");
355 for (d = insn_data; d; d = d->next)
356 for (i = 0; i < d->n_operands; i++)
357 if (d->predicates[i] && d->predicates[i][0])
359 for (p = predicates; p; p = p->next)
360 if (! strcmp (p->name, d->predicates[i]))
361 break;
363 if (p == 0)
365 printf ("extern int %s ();\n", d->predicates[i]);
366 p = (struct predicate *) alloca (sizeof (struct predicate));
367 p->name = d->predicates[i];
368 p->next = predicates;
369 predicates = p;
373 printf ("\nint (*const insn_operand_predicate[][MAX_RECOG_OPERANDS])() =\n {\n");
374 for (d = insn_data; d; d = d->next)
376 printf (" {");
377 for (i = 0; i < d->n_operands; i++)
378 printf (" %s,", ((d->predicates[i] && d->predicates[i][0])
379 ? d->predicates[i] : "0"));
380 if (d->n_operands == 0)
381 printf (" 0");
382 printf (" },\n");
384 printf (" };\n");
387 printf ("\nconst int insn_n_alternatives[] =\n {\n");
388 for (d = insn_data; d; d = d->next)
389 printf (" %d,\n", d->n_alternatives);
390 printf(" };\n");
393 /* scan_operands (X) stores in max_opno the largest operand
394 number present in X, if that is larger than the previous
395 value of max_opno. It stores all the constraints in `constraints'
396 and all the machine modes in `modes'.
398 THIS_ADDRESS_P is nonzero if the containing rtx was an ADDRESS.
399 THIS_STRICT_LOW is nonzero if the containing rtx was a STRICT_LOW_PART. */
401 static int max_opno;
402 static int num_dups;
403 static char *constraints[MAX_MAX_OPERANDS];
404 static int op_n_alternatives[MAX_MAX_OPERANDS];
405 static char *predicates[MAX_MAX_OPERANDS];
406 static char address_p[MAX_MAX_OPERANDS];
407 static enum machine_mode modes[MAX_MAX_OPERANDS];
408 static char strict_low[MAX_MAX_OPERANDS];
409 static char seen[MAX_MAX_OPERANDS];
411 static void
412 scan_operands (part, this_address_p, this_strict_low)
413 rtx part;
414 int this_address_p;
415 int this_strict_low;
417 register int i, j;
418 register char *format_ptr;
419 int opno;
421 if (part == 0)
422 return;
424 switch (GET_CODE (part))
426 case MATCH_OPERAND:
427 opno = XINT (part, 0);
428 if (opno > max_opno)
429 max_opno = opno;
430 if (max_opno >= MAX_MAX_OPERANDS)
432 error ("Too many operands (%d) in definition %d.\n",
433 max_opno + 1, next_index_number);
434 return;
436 if (seen[opno])
437 error ("Definition %d specified operand number %d more than once.\n",
438 next_index_number, opno);
439 seen[opno] = 1;
440 modes[opno] = GET_MODE (part);
441 strict_low[opno] = this_strict_low;
442 predicates[opno] = XSTR (part, 1);
443 constraints[opno] = XSTR (part, 2);
444 if (XSTR (part, 2) != 0 && *XSTR (part, 2) != 0)
446 op_n_alternatives[opno] = n_occurrences (',', XSTR (part, 2)) + 1;
447 have_constraints = 1;
449 address_p[opno] = this_address_p;
450 return;
452 case MATCH_SCRATCH:
453 opno = XINT (part, 0);
454 if (opno > max_opno)
455 max_opno = opno;
456 if (max_opno >= MAX_MAX_OPERANDS)
458 error ("Too many operands (%d) in definition %d.\n",
459 max_opno + 1, next_index_number);
460 return;
462 if (seen[opno])
463 error ("Definition %d specified operand number %d more than once.\n",
464 next_index_number, opno);
465 seen[opno] = 1;
466 modes[opno] = GET_MODE (part);
467 strict_low[opno] = 0;
468 predicates[opno] = "scratch_operand";
469 constraints[opno] = XSTR (part, 1);
470 if (XSTR (part, 1) != 0 && *XSTR (part, 1) != 0)
472 op_n_alternatives[opno] = n_occurrences (',', XSTR (part, 1)) + 1;
473 have_constraints = 1;
475 address_p[opno] = 0;
476 return;
478 case MATCH_OPERATOR:
479 case MATCH_PARALLEL:
480 opno = XINT (part, 0);
481 if (opno > max_opno)
482 max_opno = opno;
483 if (max_opno >= MAX_MAX_OPERANDS)
485 error ("Too many operands (%d) in definition %d.\n",
486 max_opno + 1, next_index_number);
487 return;
489 if (seen[opno])
490 error ("Definition %d specified operand number %d more than once.\n",
491 next_index_number, opno);
492 seen[opno] = 1;
493 modes[opno] = GET_MODE (part);
494 strict_low[opno] = 0;
495 predicates[opno] = XSTR (part, 1);
496 constraints[opno] = 0;
497 address_p[opno] = 0;
498 for (i = 0; i < XVECLEN (part, 2); i++)
499 scan_operands (XVECEXP (part, 2, i), 0, 0);
500 return;
502 case MATCH_DUP:
503 case MATCH_OP_DUP:
504 case MATCH_PAR_DUP:
505 ++num_dups;
506 return;
508 case ADDRESS:
509 scan_operands (XEXP (part, 0), 1, 0);
510 return;
512 case STRICT_LOW_PART:
513 scan_operands (XEXP (part, 0), 0, 1);
514 return;
516 default:
517 break;
520 format_ptr = GET_RTX_FORMAT (GET_CODE (part));
522 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
523 switch (*format_ptr++)
525 case 'e':
526 case 'u':
527 scan_operands (XEXP (part, i), 0, 0);
528 break;
529 case 'E':
530 if (XVEC (part, i) != NULL)
531 for (j = 0; j < XVECLEN (part, i); j++)
532 scan_operands (XVECEXP (part, i, j), 0, 0);
533 break;
537 /* Process an assembler template from a define_insn or a define_peephole.
538 It is either the assembler code template, a list of assembler code
539 templates, or C code to generate the assembler code template. */
541 static void
542 process_template (d, template)
543 struct data *d;
544 char *template;
546 register char *cp;
547 register int i;
549 /* We need to consider only the instructions whose assembler code template
550 starts with a * or @. These are the ones where C code is run to decide
551 on a template to use. So for all others just return now. */
553 if (template[0] != '*' && template[0] != '@')
555 d->template = template;
556 d->outfun = 0;
557 return;
560 d->template = 0;
561 d->outfun = 1;
563 printf ("\nstatic char *\n");
564 printf ("output_%d (operands, insn)\n", d->code_number);
565 printf (" rtx *operands;\n");
566 printf (" rtx insn;\n");
567 printf ("{\n");
569 /* If the assembler code template starts with a @ it is a newline-separated
570 list of assembler code templates, one for each alternative. So produce
571 a routine to select the correct one. */
573 if (template[0] == '@')
576 printf (" static /*const*/ char *const strings_%d[] = {\n",
577 d->code_number);
579 for (i = 0, cp = &template[1]; *cp; )
581 while (*cp == '\n' || *cp == ' ' || *cp== '\t')
582 cp++;
584 printf (" \"");
585 while (*cp != '\n' && *cp != '\0')
587 putchar (*cp);
588 cp++;
591 printf ("\",\n");
592 i++;
595 printf (" };\n");
596 printf (" return strings_%d[which_alternative];\n", d->code_number);
598 if (i != d->n_alternatives)
599 fatal ("Insn pattern %d has %d alternatives but %d assembler choices",
600 d->index_number, d->n_alternatives, i);
603 else
605 /* The following is done in a funny way to get around problems in
606 VAX-11 "C" on VMS. It is the equivalent of:
607 printf ("%s\n", &template[1])); */
608 cp = &template[1];
609 while (*cp)
611 putchar (*cp);
612 cp++;
614 putchar ('\n');
617 printf ("}\n");
620 /* Check insn D for consistency in number of constraint alternatives. */
622 static void
623 validate_insn_alternatives (d)
624 struct data *d;
626 register int n = 0, start;
627 /* Make sure all the operands have the same number of
628 alternatives in their constraints.
629 Let N be that number. */
630 for (start = 0; start < d->n_operands; start++)
631 if (d->op_n_alternatives[start] > 0)
633 if (n == 0)
634 n = d->op_n_alternatives[start];
635 else if (n != d->op_n_alternatives[start])
636 error ("wrong number of alternatives in operand %d of insn number %d",
637 start, d->index_number);
639 /* Record the insn's overall number of alternatives. */
640 d->n_alternatives = n;
643 /* Look at a define_insn just read. Assign its code number.
644 Record on insn_data the template and the number of arguments.
645 If the insn has a hairy output action, output a function for now. */
647 static void
648 gen_insn (insn)
649 rtx insn;
651 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
652 register int i;
654 d->code_number = next_code_number++;
655 d->index_number = next_index_number;
656 if (XSTR (insn, 0)[0])
657 d->name = XSTR (insn, 0);
658 else
659 d->name = 0;
661 /* Build up the list in the same order as the insns are seen
662 in the machine description. */
663 d->next = 0;
664 if (end_of_insn_data)
665 end_of_insn_data->next = d;
666 else
667 insn_data = d;
669 end_of_insn_data = d;
671 max_opno = -1;
672 num_dups = 0;
674 mybzero (constraints, sizeof constraints);
675 mybzero (op_n_alternatives, sizeof op_n_alternatives);
676 mybzero (predicates, sizeof predicates);
677 mybzero (address_p, sizeof address_p);
678 mybzero (modes, sizeof modes);
679 mybzero (strict_low, sizeof strict_low);
680 mybzero (seen, sizeof seen);
682 for (i = 0; i < XVECLEN (insn, 1); i++)
683 scan_operands (XVECEXP (insn, 1, i), 0, 0);
685 d->n_operands = max_opno + 1;
686 d->n_dups = num_dups;
688 mybcopy (constraints, d->constraints, sizeof constraints);
689 mybcopy (op_n_alternatives, d->op_n_alternatives, sizeof op_n_alternatives);
690 mybcopy (predicates, d->predicates, sizeof predicates);
691 mybcopy (address_p, d->address_p, sizeof address_p);
692 mybcopy (modes, d->modes, sizeof modes);
693 mybcopy (strict_low, d->strict_low, sizeof strict_low);
695 validate_insn_alternatives (d);
696 process_template (d, XSTR (insn, 3));
699 /* Look at a define_peephole just read. Assign its code number.
700 Record on insn_data the template and the number of arguments.
701 If the insn has a hairy output action, output it now. */
703 static void
704 gen_peephole (peep)
705 rtx peep;
707 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
708 register int i;
710 d->code_number = next_code_number++;
711 d->index_number = next_index_number;
712 d->name = 0;
714 /* Build up the list in the same order as the insns are seen
715 in the machine description. */
716 d->next = 0;
717 if (end_of_insn_data)
718 end_of_insn_data->next = d;
719 else
720 insn_data = d;
722 end_of_insn_data = d;
724 max_opno = -1;
725 mybzero (constraints, sizeof constraints);
726 mybzero (op_n_alternatives, sizeof op_n_alternatives);
727 mybzero (predicates, sizeof predicates);
728 mybzero (address_p, sizeof address_p);
729 mybzero (modes, sizeof modes);
730 mybzero (strict_low, sizeof strict_low);
731 mybzero (seen, sizeof seen);
733 /* Get the number of operands by scanning all the
734 patterns of the peephole optimizer.
735 But ignore all the rest of the information thus obtained. */
736 for (i = 0; i < XVECLEN (peep, 0); i++)
737 scan_operands (XVECEXP (peep, 0, i), 0, 0);
739 d->n_operands = max_opno + 1;
740 d->n_dups = 0;
742 mybcopy (constraints, d->constraints, sizeof constraints);
743 mybcopy (op_n_alternatives, d->op_n_alternatives, sizeof op_n_alternatives);
744 mybzero (d->predicates, sizeof predicates);
745 mybzero (d->address_p, sizeof address_p);
746 mybzero (d->modes, sizeof modes);
747 mybzero (d->strict_low, sizeof strict_low);
749 validate_insn_alternatives (d);
750 process_template (d, XSTR (peep, 2));
753 /* Process a define_expand just read. Assign its code number,
754 only for the purposes of `insn_gen_function'. */
756 static void
757 gen_expand (insn)
758 rtx insn;
760 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
761 register int i;
763 d->code_number = next_code_number++;
764 d->index_number = next_index_number;
765 if (XSTR (insn, 0)[0])
766 d->name = XSTR (insn, 0);
767 else
768 d->name = 0;
770 /* Build up the list in the same order as the insns are seen
771 in the machine description. */
772 d->next = 0;
773 if (end_of_insn_data)
774 end_of_insn_data->next = d;
775 else
776 insn_data = d;
778 end_of_insn_data = d;
780 max_opno = -1;
781 num_dups = 0;
783 /* Scan the operands to get the specified predicates and modes,
784 since expand_binop needs to know them. */
786 mybzero (constraints, sizeof constraints);
787 mybzero (op_n_alternatives, sizeof op_n_alternatives);
788 mybzero (predicates, sizeof predicates);
789 mybzero (address_p, sizeof address_p);
790 mybzero (modes, sizeof modes);
791 mybzero (strict_low, sizeof strict_low);
792 mybzero (seen, sizeof seen);
794 if (XVEC (insn, 1))
795 for (i = 0; i < XVECLEN (insn, 1); i++)
796 scan_operands (XVECEXP (insn, 1, i), 0, 0);
798 d->n_operands = max_opno + 1;
799 d->n_dups = num_dups;
801 mybcopy (constraints, d->constraints, sizeof constraints);
802 mybcopy (op_n_alternatives, d->op_n_alternatives, sizeof op_n_alternatives);
803 mybcopy (predicates, d->predicates, sizeof predicates);
804 mybcopy (address_p, d->address_p, sizeof address_p);
805 mybcopy (modes, d->modes, sizeof modes);
806 mybcopy (strict_low, d->strict_low, sizeof strict_low);
808 d->template = 0;
809 d->outfun = 0;
810 validate_insn_alternatives (d);
813 /* Process a define_split just read. Assign its code number,
814 only for reasons of consistency and to simplify genrecog. */
817 static void
818 gen_split (split)
819 rtx split;
821 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
822 register int i;
824 d->code_number = next_code_number++;
825 d->index_number = next_index_number;
826 d->name = 0;
828 /* Build up the list in the same order as the insns are seen
829 in the machine description. */
830 d->next = 0;
831 if (end_of_insn_data)
832 end_of_insn_data->next = d;
833 else
834 insn_data = d;
836 end_of_insn_data = d;
838 max_opno = -1;
839 num_dups = 0;
841 mybzero (constraints, sizeof constraints);
842 mybzero (op_n_alternatives, sizeof op_n_alternatives);
843 mybzero (predicates, sizeof predicates);
844 mybzero (address_p, sizeof address_p);
845 mybzero (modes, sizeof modes);
846 mybzero (strict_low, sizeof strict_low);
847 mybzero (seen, sizeof seen);
849 /* Get the number of operands by scanning all the
850 patterns of the split patterns.
851 But ignore all the rest of the information thus obtained. */
852 for (i = 0; i < XVECLEN (split, 0); i++)
853 scan_operands (XVECEXP (split, 0, i), 0, 0);
855 d->n_operands = max_opno + 1;
857 mybzero (d->constraints, sizeof constraints);
858 mybzero (d->op_n_alternatives, sizeof op_n_alternatives);
859 mybzero (d->predicates, sizeof predicates);
860 mybzero (d->address_p, sizeof address_p);
861 mybzero (d->modes, sizeof modes);
862 mybzero (d->strict_low, sizeof strict_low);
864 d->n_dups = 0;
865 d->n_alternatives = 0;
866 d->template = 0;
867 d->outfun = 0;
870 char *
871 xmalloc (size)
872 unsigned size;
874 register char *val = (char *) malloc (size);
876 if (val == 0)
877 fatal ("virtual memory exhausted");
878 return val;
881 char *
882 xrealloc (ptr, size)
883 char *ptr;
884 unsigned size;
886 char *result = (char *) realloc (ptr, size);
887 if (!result)
888 fatal ("virtual memory exhausted");
889 return result;
892 static void
893 mybzero (b, length)
894 register char *b;
895 register unsigned length;
897 while (length-- > 0)
898 *b++ = 0;
901 static void
902 mybcopy (b1, b2, length)
903 register char *b1;
904 register char *b2;
905 register unsigned length;
907 while (length-- > 0)
908 *b2++ = *b1++;
911 static void
912 fatal (s, a1, a2, a3, a4)
913 char *s;
915 fprintf (stderr, "genoutput: ");
916 fprintf (stderr, s, a1, a2, a3, a4);
917 fprintf (stderr, "\n");
918 exit (FATAL_EXIT_CODE);
921 /* More 'friendly' abort that prints the line and file.
922 config.h can #define abort fancy_abort if you like that sort of thing. */
924 void
925 fancy_abort ()
927 fatal ("Internal gcc abort.");
930 static void
931 error (s, a1, a2)
932 char *s;
934 fprintf (stderr, "genoutput: ");
935 fprintf (stderr, s, a1, a2);
936 fprintf (stderr, "\n");
938 have_error = 1;
942 main (argc, argv)
943 int argc;
944 char **argv;
946 rtx desc;
947 FILE *infile;
948 register int c;
950 obstack_init (rtl_obstack);
952 if (argc <= 1)
953 fatal ("No input file name.");
955 infile = fopen (argv[1], "r");
956 if (infile == 0)
958 perror (argv[1]);
959 exit (FATAL_EXIT_CODE);
962 init_rtl ();
964 output_prologue ();
965 next_code_number = 0;
966 next_index_number = 0;
967 have_constraints = 0;
969 /* Read the machine description. */
971 while (1)
973 c = read_skip_spaces (infile);
974 if (c == EOF)
975 break;
976 ungetc (c, infile);
978 desc = read_rtx (infile);
979 if (GET_CODE (desc) == DEFINE_INSN)
980 gen_insn (desc);
981 if (GET_CODE (desc) == DEFINE_PEEPHOLE)
982 gen_peephole (desc);
983 if (GET_CODE (desc) == DEFINE_EXPAND)
984 gen_expand (desc);
985 if (GET_CODE (desc) == DEFINE_SPLIT)
986 gen_split (desc);
987 next_index_number++;
990 output_epilogue ();
992 fflush (stdout);
993 exit (ferror (stdout) != 0 || have_error
994 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
996 /* NOTREACHED */
997 return 0;
1000 static int
1001 n_occurrences (c, s)
1002 int c;
1003 char *s;
1005 int n = 0;
1006 while (*s)
1007 n += (*s++ == c);
1008 return n;