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