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