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