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