]> gcc.gnu.org Git - gcc.git/blob - gcc/genoutput.c
genattr.c: Include stdarg.h/varargs.h.
[gcc.git] / gcc / genoutput.c
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.
3
4 This file is part of GNU CC.
5
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.
10
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.
15
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. */
20
21
22 /* This program reads the machine description for the compiler target machine
23 and produces a file containing these things:
24
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,
27
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'.
34
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.
38
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.
41
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,
44
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.
49
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.
54
55 This array is generated only if register constraints appear in
56 match_operand rtx's.
57
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.
62
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.
68
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.
72
73 11. An array of ints, `insn_n_alternatives', that gives the number
74 of alternatives in the constraints of each pattern.
75
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.
79
80 Thus, the following entry in the machine description
81
82 (define_insn "clrdf"
83 [(set (match_operand:DF 0 "general_operand" "")
84 (const_int 0))]
85 ""
86 "clrd %0")
87
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 `*'). */
92 \f
93 #include "hconfig.h"
94 #ifdef __STDC__
95 #include <stdarg.h>
96 #else
97 #include <varargs.h>
98 #endif
99 #include "system.h"
100 #include "rtl.h"
101 #include "obstack.h"
102
103 /* No instruction can have more operands than this.
104 Sorry for this arbitrary limit, but what machine will
105 have an instruction with this many operands? */
106
107 #define MAX_MAX_OPERANDS 40
108
109 static struct obstack obstack;
110 struct obstack *rtl_obstack = &obstack;
111
112 #define obstack_chunk_alloc xmalloc
113 #define obstack_chunk_free free
114
115 char *xmalloc PROTO((unsigned));
116 static void fatal PVPROTO ((char *, ...)) ATTRIBUTE_PRINTF_1;
117 void fancy_abort PROTO((void));
118 static void error PVPROTO ((char *, ...)) ATTRIBUTE_PRINTF_1;
119 static void mybcopy ();
120 static void mybzero ();
121 static int n_occurrences PROTO((int, char *));
122
123 /* Define this so we can link with print-rtl.o to get debug_rtx function. */
124 char **insn_name_ptr = 0;
125
126 /* insns in the machine description are assigned sequential code numbers
127 that are used by insn-recog.c (produced by genrecog) to communicate
128 to insn-output.c (produced by this program). */
129
130 static int next_code_number;
131
132 /* This counts all definitions in the md file,
133 for the sake of error messages. */
134
135 static int next_index_number;
136
137 /* Record in this chain all information that we will output,
138 associated with the code number of the insn. */
139
140 struct data
141 {
142 int code_number;
143 int index_number;
144 char *name;
145 char *template; /* string such as "movl %1,%0" */
146 int n_operands; /* Number of operands this insn recognizes */
147 int n_dups; /* Number times match_dup appears in pattern */
148 int n_alternatives; /* Number of alternatives in each constraint */
149 struct data *next;
150 char *constraints[MAX_MAX_OPERANDS];
151 /* Number of alternatives in constraints of operand N. */
152 int op_n_alternatives[MAX_MAX_OPERANDS];
153 char *predicates[MAX_MAX_OPERANDS];
154 char address_p[MAX_MAX_OPERANDS];
155 enum machine_mode modes[MAX_MAX_OPERANDS];
156 char strict_low[MAX_MAX_OPERANDS];
157 char outfun; /* Nonzero means this has an output function */
158 };
159
160 /* This variable points to the first link in the chain. */
161
162 struct data *insn_data;
163
164 /* Pointer to the last link in the chain, so new elements
165 can be added at the end. */
166
167 struct data *end_of_insn_data;
168
169 /* Nonzero if any match_operand has a constraint string;
170 implies that REGISTER_CONSTRAINTS will be defined
171 for this machine description. */
172
173 int have_constraints;
174
175 /* Nonzero if some error has occurred. We will make all errors fatal, but
176 might as well continue until we see all of them. */
177
178 static int have_error;
179 \f
180 static void output_prologue PROTO((void));
181 static void output_epilogue PROTO((void));
182 static void scan_operands PROTO((rtx, int, int));
183 static void process_template PROTO((struct data *, char *));
184 static void validate_insn_alternatives PROTO((struct data *));
185 static void gen_insn PROTO((rtx));
186 static void gen_peephole PROTO((rtx));
187 static void gen_expand PROTO((rtx));
188 static void gen_split PROTO((rtx));
189 static int n_occurrences PROTO((int, char *));
190 \f
191 static void
192 output_prologue ()
193 {
194 printf ("/* Generated automatically by the program `genoutput'\n\
195 from the machine description file `md'. */\n\n");
196
197 printf ("#include \"config.h\"\n");
198 printf ("#include \"system.h\"\n");
199 printf ("#include \"flags.h\"\n");
200 printf ("#include \"rtl.h\"\n");
201 printf ("#include \"regs.h\"\n");
202 printf ("#include \"hard-reg-set.h\"\n");
203 printf ("#include \"real.h\"\n");
204 printf ("#include \"insn-config.h\"\n\n");
205 printf ("#include \"conditions.h\"\n");
206 printf ("#include \"insn-flags.h\"\n");
207 printf ("#include \"insn-attr.h\"\n\n");
208 printf ("#include \"insn-codes.h\"\n\n");
209 printf ("#include \"recog.h\"\n\n");
210
211 printf ("#include \"output.h\"\n");
212 }
213
214 static void
215 output_epilogue ()
216 {
217 register struct data *d;
218
219 printf ("\nchar * const insn_template[] =\n {\n");
220 for (d = insn_data; d; d = d->next)
221 {
222 if (d->template)
223 printf (" \"%s\",\n", d->template);
224 else
225 printf (" 0,\n");
226 }
227 printf (" };\n");
228
229 printf ("\nchar *(*const insn_outfun[])() =\n {\n");
230 for (d = insn_data; d; d = d->next)
231 {
232 if (d->outfun)
233 printf (" output_%d,\n", d->code_number);
234 else
235 printf (" 0,\n");
236 }
237 printf (" };\n");
238
239 printf ("\nrtx (*const insn_gen_function[]) () =\n {\n");
240 for (d = insn_data; d; d = d->next)
241 {
242 if (d->name && d->name[0] != '*')
243 printf (" gen_%s,\n", d->name);
244 else
245 printf (" 0,\n");
246 }
247 printf (" };\n");
248
249 printf ("\nchar *insn_name[] =\n {\n");
250 {
251 int offset = 0;
252 int next;
253 char * last_name = 0;
254 char * next_name = 0;
255 register struct data *n;
256
257 for (n = insn_data, next = 1; n; n = n->next, next++)
258 if (n->name)
259 {
260 next_name = n->name;
261 break;
262 }
263
264 for (d = insn_data; d; d = d->next)
265 {
266 if (d->name)
267 {
268 printf (" \"%s\",\n", d->name);
269 offset = 0;
270 last_name = d->name;
271 next_name = 0;
272 for (n = d->next, next = 1; n; n = n->next, next++)
273 if (n->name)
274 {
275 next_name = n->name;
276 break;
277 }
278 }
279 else
280 {
281 offset++;
282 if (next_name && (last_name == 0 || offset > next / 2))
283 printf (" \"%s-%d\",\n", next_name, next - offset);
284 else
285 printf (" \"%s+%d\",\n", last_name, offset);
286 }
287 }
288 }
289 printf (" };\n");
290 printf ("char **insn_name_ptr = insn_name;\n");
291
292 printf ("\nconst int insn_n_operands[] =\n {\n");
293 for (d = insn_data; d; d = d->next)
294 printf (" %d,\n", d->n_operands);
295 printf (" };\n");
296
297 printf ("\nconst int insn_n_dups[] =\n {\n");
298 for (d = insn_data; d; d = d->next)
299 printf (" %d,\n", d->n_dups);
300 printf (" };\n");
301
302 if (have_constraints)
303 {
304 printf ("\nchar *const insn_operand_constraint[][MAX_RECOG_OPERANDS] =\n {\n");
305 for (d = insn_data; d; d = d->next)
306 {
307 register int i;
308 printf (" {");
309 for (i = 0; i < d->n_operands; i++)
310 {
311 if (d->constraints[i] == 0)
312 printf (" \"\",");
313 else
314 printf (" \"%s\",", d->constraints[i]);
315 }
316 if (d->n_operands == 0)
317 printf (" 0");
318 printf (" },\n");
319 }
320 printf (" };\n");
321 }
322 else
323 {
324 printf ("\nconst char insn_operand_address_p[][MAX_RECOG_OPERANDS] =\n {\n");
325 for (d = insn_data; d; d = d->next)
326 {
327 register int i;
328 printf (" {");
329 for (i = 0; i < d->n_operands; i++)
330 printf (" %d,", d->address_p[i]);
331 if (d->n_operands == 0)
332 printf (" 0");
333 printf (" },\n");
334 }
335 printf (" };\n");
336 }
337
338 printf ("\nconst enum machine_mode insn_operand_mode[][MAX_RECOG_OPERANDS] =\n {\n");
339 for (d = insn_data; d; d = d->next)
340 {
341 register int i;
342 printf (" {");
343 for (i = 0; i < d->n_operands; i++)
344 printf (" %smode,", GET_MODE_NAME (d->modes[i]));
345 if (d->n_operands == 0)
346 printf (" VOIDmode");
347 printf (" },\n");
348 }
349 printf (" };\n");
350
351 printf ("\nconst char insn_operand_strict_low[][MAX_RECOG_OPERANDS] =\n {\n");
352 for (d = insn_data; d; d = d->next)
353 {
354 register int i;
355 printf (" {");
356 for (i = 0; i < d->n_operands; i++)
357 printf (" %d,", d->strict_low[i]);
358 if (d->n_operands == 0)
359 printf (" 0");
360 printf (" },\n");
361 }
362 printf (" };\n");
363
364 {
365 /* We need to define all predicates used. Keep a list of those we
366 have defined so far. There normally aren't very many predicates used,
367 so a linked list should be fast enough. */
368 struct predicate { char *name; struct predicate *next; } *predicates = 0;
369 struct predicate *p;
370 int i;
371
372 printf ("\n");
373 for (d = insn_data; d; d = d->next)
374 for (i = 0; i < d->n_operands; i++)
375 if (d->predicates[i] && d->predicates[i][0])
376 {
377 for (p = predicates; p; p = p->next)
378 if (! strcmp (p->name, d->predicates[i]))
379 break;
380
381 if (p == 0)
382 {
383 printf ("extern int %s ();\n", d->predicates[i]);
384 p = (struct predicate *) alloca (sizeof (struct predicate));
385 p->name = d->predicates[i];
386 p->next = predicates;
387 predicates = p;
388 }
389 }
390
391 printf ("\nint (*const insn_operand_predicate[][MAX_RECOG_OPERANDS])() =\n {\n");
392 for (d = insn_data; d; d = d->next)
393 {
394 printf (" {");
395 for (i = 0; i < d->n_operands; i++)
396 printf (" %s,", ((d->predicates[i] && d->predicates[i][0])
397 ? d->predicates[i] : "0"));
398 if (d->n_operands == 0)
399 printf (" 0");
400 printf (" },\n");
401 }
402 printf (" };\n");
403 }
404
405 printf ("\nconst int insn_n_alternatives[] =\n {\n");
406 for (d = insn_data; d; d = d->next)
407 printf (" %d,\n", d->n_alternatives);
408 printf(" };\n");
409 }
410 \f
411 /* scan_operands (X) stores in max_opno the largest operand
412 number present in X, if that is larger than the previous
413 value of max_opno. It stores all the constraints in `constraints'
414 and all the machine modes in `modes'.
415
416 THIS_ADDRESS_P is nonzero if the containing rtx was an ADDRESS.
417 THIS_STRICT_LOW is nonzero if the containing rtx was a STRICT_LOW_PART. */
418
419 static int max_opno;
420 static int num_dups;
421 static char *constraints[MAX_MAX_OPERANDS];
422 static int op_n_alternatives[MAX_MAX_OPERANDS];
423 static char *predicates[MAX_MAX_OPERANDS];
424 static char address_p[MAX_MAX_OPERANDS];
425 static enum machine_mode modes[MAX_MAX_OPERANDS];
426 static char strict_low[MAX_MAX_OPERANDS];
427 static char seen[MAX_MAX_OPERANDS];
428
429 static void
430 scan_operands (part, this_address_p, this_strict_low)
431 rtx part;
432 int this_address_p;
433 int this_strict_low;
434 {
435 register int i, j;
436 register char *format_ptr;
437 int opno;
438
439 if (part == 0)
440 return;
441
442 switch (GET_CODE (part))
443 {
444 case MATCH_OPERAND:
445 opno = XINT (part, 0);
446 if (opno > max_opno)
447 max_opno = opno;
448 if (max_opno >= MAX_MAX_OPERANDS)
449 {
450 error ("Too many operands (%d) in definition %d.\n",
451 max_opno + 1, next_index_number);
452 return;
453 }
454 if (seen[opno])
455 error ("Definition %d specified operand number %d more than once.\n",
456 next_index_number, opno);
457 seen[opno] = 1;
458 modes[opno] = GET_MODE (part);
459 strict_low[opno] = this_strict_low;
460 predicates[opno] = XSTR (part, 1);
461 constraints[opno] = XSTR (part, 2);
462 if (XSTR (part, 2) != 0 && *XSTR (part, 2) != 0)
463 {
464 op_n_alternatives[opno] = n_occurrences (',', XSTR (part, 2)) + 1;
465 have_constraints = 1;
466 }
467 address_p[opno] = this_address_p;
468 return;
469
470 case MATCH_SCRATCH:
471 opno = XINT (part, 0);
472 if (opno > max_opno)
473 max_opno = opno;
474 if (max_opno >= MAX_MAX_OPERANDS)
475 {
476 error ("Too many operands (%d) in definition %d.\n",
477 max_opno + 1, next_index_number);
478 return;
479 }
480 if (seen[opno])
481 error ("Definition %d specified operand number %d more than once.\n",
482 next_index_number, opno);
483 seen[opno] = 1;
484 modes[opno] = GET_MODE (part);
485 strict_low[opno] = 0;
486 predicates[opno] = "scratch_operand";
487 constraints[opno] = XSTR (part, 1);
488 if (XSTR (part, 1) != 0 && *XSTR (part, 1) != 0)
489 {
490 op_n_alternatives[opno] = n_occurrences (',', XSTR (part, 1)) + 1;
491 have_constraints = 1;
492 }
493 address_p[opno] = 0;
494 return;
495
496 case MATCH_OPERATOR:
497 case MATCH_PARALLEL:
498 opno = XINT (part, 0);
499 if (opno > max_opno)
500 max_opno = opno;
501 if (max_opno >= MAX_MAX_OPERANDS)
502 {
503 error ("Too many operands (%d) in definition %d.\n",
504 max_opno + 1, next_index_number);
505 return;
506 }
507 if (seen[opno])
508 error ("Definition %d specified operand number %d more than once.\n",
509 next_index_number, opno);
510 seen[opno] = 1;
511 modes[opno] = GET_MODE (part);
512 strict_low[opno] = 0;
513 predicates[opno] = XSTR (part, 1);
514 constraints[opno] = 0;
515 address_p[opno] = 0;
516 for (i = 0; i < XVECLEN (part, 2); i++)
517 scan_operands (XVECEXP (part, 2, i), 0, 0);
518 return;
519
520 case MATCH_DUP:
521 case MATCH_OP_DUP:
522 case MATCH_PAR_DUP:
523 ++num_dups;
524 return;
525
526 case ADDRESS:
527 scan_operands (XEXP (part, 0), 1, 0);
528 return;
529
530 case STRICT_LOW_PART:
531 scan_operands (XEXP (part, 0), 0, 1);
532 return;
533
534 default:
535 break;
536 }
537
538 format_ptr = GET_RTX_FORMAT (GET_CODE (part));
539
540 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
541 switch (*format_ptr++)
542 {
543 case 'e':
544 case 'u':
545 scan_operands (XEXP (part, i), 0, 0);
546 break;
547 case 'E':
548 if (XVEC (part, i) != NULL)
549 for (j = 0; j < XVECLEN (part, i); j++)
550 scan_operands (XVECEXP (part, i, j), 0, 0);
551 break;
552 }
553 }
554 \f
555 /* Process an assembler template from a define_insn or a define_peephole.
556 It is either the assembler code template, a list of assembler code
557 templates, or C code to generate the assembler code template. */
558
559 static void
560 process_template (d, template)
561 struct data *d;
562 char *template;
563 {
564 register char *cp;
565 register int i;
566
567 /* We need to consider only the instructions whose assembler code template
568 starts with a * or @. These are the ones where C code is run to decide
569 on a template to use. So for all others just return now. */
570
571 if (template[0] != '*' && template[0] != '@')
572 {
573 d->template = template;
574 d->outfun = 0;
575 return;
576 }
577
578 d->template = 0;
579 d->outfun = 1;
580
581 printf ("\nstatic char *\n");
582 printf ("output_%d (operands, insn)\n", d->code_number);
583 printf (" rtx *operands ATTRIBUTE_UNUSED;\n");
584 printf (" rtx insn ATTRIBUTE_UNUSED;\n");
585 printf ("{\n");
586
587 /* If the assembler code template starts with a @ it is a newline-separated
588 list of assembler code templates, one for each alternative. So produce
589 a routine to select the correct one. */
590
591 if (template[0] == '@')
592 {
593
594 printf (" static /*const*/ char *const strings_%d[] = {\n",
595 d->code_number);
596
597 for (i = 0, cp = &template[1]; *cp; )
598 {
599 while (*cp == '\n' || *cp == ' ' || *cp== '\t')
600 cp++;
601
602 printf (" \"");
603 while (*cp != '\n' && *cp != '\0')
604 {
605 putchar (*cp);
606 cp++;
607 }
608
609 printf ("\",\n");
610 i++;
611 }
612
613 printf (" };\n");
614 printf (" return strings_%d[which_alternative];\n", d->code_number);
615
616 if (i != d->n_alternatives)
617 fatal ("Insn pattern %d has %d alternatives but %d assembler choices",
618 d->index_number, d->n_alternatives, i);
619
620 }
621 else
622 {
623 /* The following is done in a funny way to get around problems in
624 VAX-11 "C" on VMS. It is the equivalent of:
625 printf ("%s\n", &template[1])); */
626 cp = &template[1];
627 while (*cp)
628 {
629 putchar (*cp);
630 cp++;
631 }
632 putchar ('\n');
633 }
634
635 printf ("}\n");
636 }
637 \f
638 /* Check insn D for consistency in number of constraint alternatives. */
639
640 static void
641 validate_insn_alternatives (d)
642 struct data *d;
643 {
644 register int n = 0, start;
645 /* Make sure all the operands have the same number of
646 alternatives in their constraints.
647 Let N be that number. */
648 for (start = 0; start < d->n_operands; start++)
649 if (d->op_n_alternatives[start] > 0)
650 {
651 if (n == 0)
652 n = d->op_n_alternatives[start];
653 else if (n != d->op_n_alternatives[start])
654 error ("wrong number of alternatives in operand %d of insn number %d",
655 start, d->index_number);
656 }
657 /* Record the insn's overall number of alternatives. */
658 d->n_alternatives = n;
659 }
660 \f
661 /* Look at a define_insn just read. Assign its code number.
662 Record on insn_data the template and the number of arguments.
663 If the insn has a hairy output action, output a function for now. */
664
665 static void
666 gen_insn (insn)
667 rtx insn;
668 {
669 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
670 register int i;
671
672 d->code_number = next_code_number++;
673 d->index_number = next_index_number;
674 if (XSTR (insn, 0)[0])
675 d->name = XSTR (insn, 0);
676 else
677 d->name = 0;
678
679 /* Build up the list in the same order as the insns are seen
680 in the machine description. */
681 d->next = 0;
682 if (end_of_insn_data)
683 end_of_insn_data->next = d;
684 else
685 insn_data = d;
686
687 end_of_insn_data = d;
688
689 max_opno = -1;
690 num_dups = 0;
691
692 mybzero (constraints, sizeof constraints);
693 mybzero (op_n_alternatives, sizeof op_n_alternatives);
694 mybzero (predicates, sizeof predicates);
695 mybzero (address_p, sizeof address_p);
696 mybzero (modes, sizeof modes);
697 mybzero (strict_low, sizeof strict_low);
698 mybzero (seen, sizeof seen);
699
700 for (i = 0; i < XVECLEN (insn, 1); i++)
701 scan_operands (XVECEXP (insn, 1, i), 0, 0);
702
703 d->n_operands = max_opno + 1;
704 d->n_dups = num_dups;
705
706 mybcopy (constraints, d->constraints, sizeof constraints);
707 mybcopy (op_n_alternatives, d->op_n_alternatives, sizeof op_n_alternatives);
708 mybcopy (predicates, d->predicates, sizeof predicates);
709 mybcopy (address_p, d->address_p, sizeof address_p);
710 mybcopy (modes, d->modes, sizeof modes);
711 mybcopy (strict_low, d->strict_low, sizeof strict_low);
712
713 validate_insn_alternatives (d);
714 process_template (d, XSTR (insn, 3));
715 }
716 \f
717 /* Look at a define_peephole just read. Assign its code number.
718 Record on insn_data the template and the number of arguments.
719 If the insn has a hairy output action, output it now. */
720
721 static void
722 gen_peephole (peep)
723 rtx peep;
724 {
725 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
726 register int i;
727
728 d->code_number = next_code_number++;
729 d->index_number = next_index_number;
730 d->name = 0;
731
732 /* Build up the list in the same order as the insns are seen
733 in the machine description. */
734 d->next = 0;
735 if (end_of_insn_data)
736 end_of_insn_data->next = d;
737 else
738 insn_data = d;
739
740 end_of_insn_data = d;
741
742 max_opno = -1;
743 mybzero (constraints, sizeof constraints);
744 mybzero (op_n_alternatives, sizeof op_n_alternatives);
745 mybzero (predicates, sizeof predicates);
746 mybzero (address_p, sizeof address_p);
747 mybzero (modes, sizeof modes);
748 mybzero (strict_low, sizeof strict_low);
749 mybzero (seen, sizeof seen);
750
751 /* Get the number of operands by scanning all the
752 patterns of the peephole optimizer.
753 But ignore all the rest of the information thus obtained. */
754 for (i = 0; i < XVECLEN (peep, 0); i++)
755 scan_operands (XVECEXP (peep, 0, i), 0, 0);
756
757 d->n_operands = max_opno + 1;
758 d->n_dups = 0;
759
760 mybcopy (constraints, d->constraints, sizeof constraints);
761 mybcopy (op_n_alternatives, d->op_n_alternatives, sizeof op_n_alternatives);
762 mybzero (d->predicates, sizeof predicates);
763 mybzero (d->address_p, sizeof address_p);
764 mybzero (d->modes, sizeof modes);
765 mybzero (d->strict_low, sizeof strict_low);
766
767 validate_insn_alternatives (d);
768 process_template (d, XSTR (peep, 2));
769 }
770 \f
771 /* Process a define_expand just read. Assign its code number,
772 only for the purposes of `insn_gen_function'. */
773
774 static void
775 gen_expand (insn)
776 rtx insn;
777 {
778 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
779 register int i;
780
781 d->code_number = next_code_number++;
782 d->index_number = next_index_number;
783 if (XSTR (insn, 0)[0])
784 d->name = XSTR (insn, 0);
785 else
786 d->name = 0;
787
788 /* Build up the list in the same order as the insns are seen
789 in the machine description. */
790 d->next = 0;
791 if (end_of_insn_data)
792 end_of_insn_data->next = d;
793 else
794 insn_data = d;
795
796 end_of_insn_data = d;
797
798 max_opno = -1;
799 num_dups = 0;
800
801 /* Scan the operands to get the specified predicates and modes,
802 since expand_binop needs to know them. */
803
804 mybzero (constraints, sizeof constraints);
805 mybzero (op_n_alternatives, sizeof op_n_alternatives);
806 mybzero (predicates, sizeof predicates);
807 mybzero (address_p, sizeof address_p);
808 mybzero (modes, sizeof modes);
809 mybzero (strict_low, sizeof strict_low);
810 mybzero (seen, sizeof seen);
811
812 if (XVEC (insn, 1))
813 for (i = 0; i < XVECLEN (insn, 1); i++)
814 scan_operands (XVECEXP (insn, 1, i), 0, 0);
815
816 d->n_operands = max_opno + 1;
817 d->n_dups = num_dups;
818
819 mybcopy (constraints, d->constraints, sizeof constraints);
820 mybcopy (op_n_alternatives, d->op_n_alternatives, sizeof op_n_alternatives);
821 mybcopy (predicates, d->predicates, sizeof predicates);
822 mybcopy (address_p, d->address_p, sizeof address_p);
823 mybcopy (modes, d->modes, sizeof modes);
824 mybcopy (strict_low, d->strict_low, sizeof strict_low);
825
826 d->template = 0;
827 d->outfun = 0;
828 validate_insn_alternatives (d);
829 }
830 \f
831 /* Process a define_split just read. Assign its code number,
832 only for reasons of consistency and to simplify genrecog. */
833
834
835 static void
836 gen_split (split)
837 rtx split;
838 {
839 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
840 register int i;
841
842 d->code_number = next_code_number++;
843 d->index_number = next_index_number;
844 d->name = 0;
845
846 /* Build up the list in the same order as the insns are seen
847 in the machine description. */
848 d->next = 0;
849 if (end_of_insn_data)
850 end_of_insn_data->next = d;
851 else
852 insn_data = d;
853
854 end_of_insn_data = d;
855
856 max_opno = -1;
857 num_dups = 0;
858
859 mybzero (constraints, sizeof constraints);
860 mybzero (op_n_alternatives, sizeof op_n_alternatives);
861 mybzero (predicates, sizeof predicates);
862 mybzero (address_p, sizeof address_p);
863 mybzero (modes, sizeof modes);
864 mybzero (strict_low, sizeof strict_low);
865 mybzero (seen, sizeof seen);
866
867 /* Get the number of operands by scanning all the
868 patterns of the split patterns.
869 But ignore all the rest of the information thus obtained. */
870 for (i = 0; i < XVECLEN (split, 0); i++)
871 scan_operands (XVECEXP (split, 0, i), 0, 0);
872
873 d->n_operands = max_opno + 1;
874
875 mybzero (d->constraints, sizeof constraints);
876 mybzero (d->op_n_alternatives, sizeof op_n_alternatives);
877 mybzero (d->predicates, sizeof predicates);
878 mybzero (d->address_p, sizeof address_p);
879 mybzero (d->modes, sizeof modes);
880 mybzero (d->strict_low, sizeof strict_low);
881
882 d->n_dups = 0;
883 d->n_alternatives = 0;
884 d->template = 0;
885 d->outfun = 0;
886 }
887 \f
888 char *
889 xmalloc (size)
890 unsigned size;
891 {
892 register char *val = (char *) malloc (size);
893
894 if (val == 0)
895 fatal ("virtual memory exhausted");
896 return val;
897 }
898
899 char *
900 xrealloc (ptr, size)
901 char *ptr;
902 unsigned size;
903 {
904 char *result = (char *) realloc (ptr, size);
905 if (!result)
906 fatal ("virtual memory exhausted");
907 return result;
908 }
909
910 static void
911 mybzero (b, length)
912 register char *b;
913 register unsigned length;
914 {
915 while (length-- > 0)
916 *b++ = 0;
917 }
918
919 static void
920 mybcopy (b1, b2, length)
921 register char *b1;
922 register char *b2;
923 register unsigned length;
924 {
925 while (length-- > 0)
926 *b2++ = *b1++;
927 }
928
929 static void
930 fatal VPROTO ((char *format, ...))
931 {
932 #ifndef __STDC__
933 char *format;
934 #endif
935 va_list ap;
936
937 VA_START (ap, format);
938
939 #ifndef __STDC__
940 format = va_arg (ap, char *);
941 #endif
942
943 fprintf (stderr, "genoutput: ");
944 vfprintf (stderr, format, ap);
945 va_end (ap);
946 fprintf (stderr, "\n");
947 exit (FATAL_EXIT_CODE);
948 }
949
950 /* More 'friendly' abort that prints the line and file.
951 config.h can #define abort fancy_abort if you like that sort of thing. */
952
953 void
954 fancy_abort ()
955 {
956 fatal ("Internal gcc abort.");
957 }
958
959 static void
960 error VPROTO ((char *format, ...))
961 {
962 #ifndef __STDC__
963 char *format;
964 #endif
965 va_list ap;
966
967 VA_START (ap, format);
968
969 #ifndef __STDC__
970 format = va_arg (ap, char *);
971 #endif
972
973 fprintf (stderr, "genoutput: ");
974 vfprintf (stderr, format, ap);
975 va_end (ap);
976 fprintf (stderr, "\n");
977
978 have_error = 1;
979 }
980 \f
981 int
982 main (argc, argv)
983 int argc;
984 char **argv;
985 {
986 rtx desc;
987 FILE *infile;
988 register int c;
989
990 obstack_init (rtl_obstack);
991
992 if (argc <= 1)
993 fatal ("No input file name.");
994
995 infile = fopen (argv[1], "r");
996 if (infile == 0)
997 {
998 perror (argv[1]);
999 exit (FATAL_EXIT_CODE);
1000 }
1001
1002 init_rtl ();
1003
1004 output_prologue ();
1005 next_code_number = 0;
1006 next_index_number = 0;
1007 have_constraints = 0;
1008
1009 /* Read the machine description. */
1010
1011 while (1)
1012 {
1013 c = read_skip_spaces (infile);
1014 if (c == EOF)
1015 break;
1016 ungetc (c, infile);
1017
1018 desc = read_rtx (infile);
1019 if (GET_CODE (desc) == DEFINE_INSN)
1020 gen_insn (desc);
1021 if (GET_CODE (desc) == DEFINE_PEEPHOLE)
1022 gen_peephole (desc);
1023 if (GET_CODE (desc) == DEFINE_EXPAND)
1024 gen_expand (desc);
1025 if (GET_CODE (desc) == DEFINE_SPLIT)
1026 gen_split (desc);
1027 next_index_number++;
1028 }
1029
1030 output_epilogue ();
1031
1032 fflush (stdout);
1033 exit (ferror (stdout) != 0 || have_error
1034 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
1035
1036 /* NOTREACHED */
1037 return 0;
1038 }
1039
1040 static int
1041 n_occurrences (c, s)
1042 int c;
1043 char *s;
1044 {
1045 int n = 0;
1046 while (*s)
1047 n += (*s++ == c);
1048 return n;
1049 }
This page took 0.085887 seconds and 6 git commands to generate.