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