]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/genoutput.c
Oops, missed ChangeLog in last checkin...
[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
665f2503
RK
106static int n_occurrences PARAMS ((int, const char *));
107static const char *strip_whitespace PARAMS ((const 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);
665f2503
RK
441 d->operand[opno].constraint = strip_whitespace (XSTR (part, 2));
442 d->operand[opno].n_alternatives
443 = n_occurrences (',', d->operand[opno].constraint) + 1;
a995e389 444 d->operand[opno].address_p = this_address_p;
dfac187e 445 d->operand[opno].eliminable = 1;
9db4e0ec
RK
446 return;
447
448 case MATCH_SCRATCH:
449 opno = XINT (part, 0);
450 if (opno > max_opno)
451 max_opno = opno;
452 if (max_opno >= MAX_MAX_OPERANDS)
5a806d65 453 {
8aeba909 454 error ("Too many operands (%d) in definition %s.\n",
a995e389 455 max_opno + 1, get_insn_name (next_index_number));
5a806d65
RK
456 return;
457 }
a995e389 458 if (d->operand[opno].seen)
8aeba909 459 error ("Definition %s specified operand number %d more than once.\n",
a995e389
RH
460 get_insn_name (next_index_number), opno);
461 d->operand[opno].seen = 1;
462 d->operand[opno].mode = GET_MODE (part);
463 d->operand[opno].strict_low = 0;
464 d->operand[opno].predicate = "scratch_operand";
665f2503
RK
465 d->operand[opno].constraint = strip_whitespace (XSTR (part, 1));
466 d->operand[opno].n_alternatives
467 = n_occurrences (',', d->operand[opno].constraint) + 1;
a995e389 468 d->operand[opno].address_p = 0;
dfac187e 469 d->operand[opno].eliminable = 0;
9db4e0ec
RK
470 return;
471
472 case MATCH_OPERATOR:
473 case MATCH_PARALLEL:
474 opno = XINT (part, 0);
475 if (opno > max_opno)
476 max_opno = opno;
477 if (max_opno >= MAX_MAX_OPERANDS)
5a806d65 478 {
8aeba909 479 error ("Too many operands (%d) in definition %s.\n",
a995e389 480 max_opno + 1, get_insn_name (next_index_number));
5a806d65
RK
481 return;
482 }
a995e389 483 if (d->operand[opno].seen)
8aeba909 484 error ("Definition %s specified operand number %d more than once.\n",
a995e389
RH
485 get_insn_name (next_index_number), opno);
486 d->operand[opno].seen = 1;
487 d->operand[opno].mode = GET_MODE (part);
488 d->operand[opno].strict_low = 0;
489 d->operand[opno].predicate = XSTR (part, 1);
490 d->operand[opno].constraint = 0;
491 d->operand[opno].address_p = 0;
dfac187e 492 d->operand[opno].eliminable = 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{
c1b59dce 538 const char *p0, *p1;
a995e389
RH
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
19af6455
BS
549 p0 = d0->constraint;
550 if (!p0)
551 p0 = "";
552 p1 = d1->constraint;
553 if (!p1)
554 p1 = "";
555 if (strcmp (p0, p1) != 0)
556 return 0;
a995e389
RH
557
558 if (d0->mode != d1->mode)
559 return 0;
560
a995e389
RH
561 if (d0->strict_low != d1->strict_low)
562 return 0;
563
dfac187e
BS
564 if (d0->eliminable != d1->eliminable)
565 return 0;
566
a995e389
RH
567 return 1;
568}
569
570/* Scan the list of operands we've already committed to output and either
571 find a subsequence that is the same, or allocate a new one at the end. */
572
573static void
574place_operands (d)
575 struct data *d;
576{
577 struct operand_data *od, *od2;
578 int i;
579
580 if (d->n_operands == 0)
581 {
582 d->operand_number = 0;
583 return;
584 }
585
586 /* Brute force substring search. */
587 for (od = odata, i = 0; od; od = od->next, i = 0)
588 if (compare_operands (od, &d->operand[0]))
589 {
590 od2 = od->next;
591 i = 1;
592 while (1)
593 {
594 if (i == d->n_operands)
595 goto full_match;
596 if (od2 == NULL)
597 goto partial_match;
598 if (! compare_operands (od2, &d->operand[i]))
599 break;
600 ++i, od2 = od2->next;
601 }
602 }
603
604 /* Either partial match at the end of the list, or no match. In either
605 case, we tack on what operands are remaining to the end of the list. */
606 partial_match:
607 d->operand_number = next_operand_number - i;
608 for (; i < d->n_operands; ++i)
609 {
610 od2 = &d->operand[i];
611 *odata_end = od2;
612 odata_end = &od2->next;
613 od2->index = next_operand_number++;
614 }
615 *odata_end = NULL;
616 return;
617
618 full_match:
619 d->operand_number = od->index;
620 return;
621}
622
9db4e0ec
RK
623\f
624/* Process an assembler template from a define_insn or a define_peephole.
625 It is either the assembler code template, a list of assembler code
626 templates, or C code to generate the assembler code template. */
627
628static void
629process_template (d, template)
630 struct data *d;
3cce094d 631 const char *template;
9db4e0ec 632{
3cce094d 633 register const char *cp;
9db4e0ec
RK
634 register int i;
635
4bbf910e
RH
636 /* Templates starting with * contain straight code to be run. */
637 if (template[0] == '*')
9db4e0ec 638 {
4bbf910e
RH
639 d->template = 0;
640 d->output_format = INSN_OUTPUT_FORMAT_FUNCTION;
9db4e0ec 641
a94ae8f5 642 printf ("\nstatic const char *output_%d PARAMS ((rtx *, rtx));\n",
4bbf910e
RH
643 d->code_number);
644 puts ("\nstatic const char *");
645 printf ("output_%d (operands, insn)\n", d->code_number);
646 puts (" rtx *operands ATTRIBUTE_UNUSED;");
647 puts (" rtx insn ATTRIBUTE_UNUSED;");
648 puts ("{");
649
650 puts (template + 1);
651 puts ("}");
652 }
9db4e0ec
RK
653
654 /* If the assembler code template starts with a @ it is a newline-separated
4bbf910e
RH
655 list of assembler code templates, one for each alternative. */
656 else if (template[0] == '@')
9db4e0ec 657 {
4bbf910e
RH
658 d->template = 0;
659 d->output_format = INSN_OUTPUT_FORMAT_MULTI;
9db4e0ec 660
4bbf910e 661 printf ("\nstatic const char * const output_%d[] = {\n", d->code_number);
9db4e0ec
RK
662
663 for (i = 0, cp = &template[1]; *cp; )
664 {
665 while (*cp == '\n' || *cp == ' ' || *cp== '\t')
666 cp++;
667
4bbf910e 668 printf (" \"");
9db4e0ec 669 while (*cp != '\n' && *cp != '\0')
2f013c71
RK
670 {
671 putchar (*cp);
672 cp++;
673 }
9db4e0ec
RK
674
675 printf ("\",\n");
676 i++;
677 }
678
4bbf910e 679 printf ("};\n");
9db4e0ec
RK
680 }
681 else
682 {
4bbf910e
RH
683 d->template = template;
684 d->output_format = INSN_OUTPUT_FORMAT_SINGLE;
9db4e0ec 685 }
9db4e0ec
RK
686}
687\f
688/* Check insn D for consistency in number of constraint alternatives. */
689
690static void
691validate_insn_alternatives (d)
692 struct data *d;
693{
694 register int n = 0, start;
a995e389
RH
695
696 /* Make sure all the operands have the same number of alternatives
697 in their constraints. Let N be that number. */
9db4e0ec 698 for (start = 0; start < d->n_operands; start++)
a995e389 699 if (d->operand[start].n_alternatives > 0)
9db4e0ec
RK
700 {
701 if (n == 0)
a995e389
RH
702 n = d->operand[start].n_alternatives;
703 else if (n != d->operand[start].n_alternatives)
8aeba909 704 error ("wrong number of alternatives in operand %d of insn %s",
a995e389 705 start, get_insn_name (d->index_number));
9db4e0ec 706 }
a995e389 707
9db4e0ec
RK
708 /* Record the insn's overall number of alternatives. */
709 d->n_alternatives = n;
710}
711\f
a995e389
RH
712/* Look at a define_insn just read. Assign its code number. Record
713 on idata the template and the number of arguments. If the insn has
714 a hairy output action, output a function for now. */
9db4e0ec
RK
715
716static void
717gen_insn (insn)
718 rtx insn;
719{
720 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
721 register int i;
722
723 d->code_number = next_code_number++;
724 d->index_number = next_index_number;
725 if (XSTR (insn, 0)[0])
726 d->name = XSTR (insn, 0);
727 else
728 d->name = 0;
729
730 /* Build up the list in the same order as the insns are seen
731 in the machine description. */
732 d->next = 0;
a995e389
RH
733 *idata_end = d;
734 idata_end = &d->next;
9db4e0ec
RK
735
736 max_opno = -1;
737 num_dups = 0;
a995e389 738 memset (d->operand, 0, sizeof (d->operand));
9db4e0ec
RK
739
740 for (i = 0; i < XVECLEN (insn, 1); i++)
a995e389 741 scan_operands (d, XVECEXP (insn, 1, i), 0, 0);
9db4e0ec
RK
742
743 d->n_operands = max_opno + 1;
744 d->n_dups = num_dups;
745
9db4e0ec 746 validate_insn_alternatives (d);
a995e389 747 place_operands (d);
9db4e0ec
RK
748 process_template (d, XSTR (insn, 3));
749}
750\f
751/* Look at a define_peephole just read. Assign its code number.
a995e389 752 Record on idata the template and the number of arguments.
9db4e0ec
RK
753 If the insn has a hairy output action, output it now. */
754
755static void
756gen_peephole (peep)
757 rtx peep;
758{
759 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
760 register int i;
761
762 d->code_number = next_code_number++;
763 d->index_number = next_index_number;
764 d->name = 0;
765
766 /* Build up the list in the same order as the insns are seen
767 in the machine description. */
768 d->next = 0;
a995e389
RH
769 *idata_end = d;
770 idata_end = &d->next;
9db4e0ec
RK
771
772 max_opno = -1;
a995e389
RH
773 num_dups = 0;
774 memset (d->operand, 0, sizeof (d->operand));
775
776 /* Get the number of operands by scanning all the patterns of the
777 peephole optimizer. But ignore all the rest of the information
778 thus obtained. */
9db4e0ec 779 for (i = 0; i < XVECLEN (peep, 0); i++)
a995e389 780 scan_operands (d, XVECEXP (peep, 0, i), 0, 0);
9db4e0ec
RK
781
782 d->n_operands = max_opno + 1;
783 d->n_dups = 0;
784
9db4e0ec 785 validate_insn_alternatives (d);
a995e389 786 place_operands (d);
9db4e0ec
RK
787 process_template (d, XSTR (peep, 2));
788}
789\f
790/* Process a define_expand just read. Assign its code number,
791 only for the purposes of `insn_gen_function'. */
792
793static void
794gen_expand (insn)
795 rtx insn;
796{
797 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
798 register int i;
799
800 d->code_number = next_code_number++;
801 d->index_number = next_index_number;
802 if (XSTR (insn, 0)[0])
803 d->name = XSTR (insn, 0);
804 else
805 d->name = 0;
806
807 /* Build up the list in the same order as the insns are seen
808 in the machine description. */
809 d->next = 0;
a995e389
RH
810 *idata_end = d;
811 idata_end = &d->next;
9db4e0ec
RK
812
813 max_opno = -1;
814 num_dups = 0;
a995e389 815 memset (d->operand, 0, sizeof (d->operand));
9db4e0ec
RK
816
817 /* Scan the operands to get the specified predicates and modes,
818 since expand_binop needs to know them. */
819
9db4e0ec
RK
820 if (XVEC (insn, 1))
821 for (i = 0; i < XVECLEN (insn, 1); i++)
a995e389 822 scan_operands (d, XVECEXP (insn, 1, i), 0, 0);
9db4e0ec
RK
823
824 d->n_operands = max_opno + 1;
825 d->n_dups = num_dups;
9db4e0ec 826 d->template = 0;
4bbf910e 827 d->output_format = INSN_OUTPUT_FORMAT_NONE;
a995e389 828
9db4e0ec 829 validate_insn_alternatives (d);
a995e389 830 place_operands (d);
9db4e0ec
RK
831}
832\f
833/* Process a define_split just read. Assign its code number,
834 only for reasons of consistency and to simplify genrecog. */
835
9db4e0ec
RK
836static void
837gen_split (split)
838 rtx split;
839{
840 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
841 register int i;
842
843 d->code_number = next_code_number++;
844 d->index_number = next_index_number;
845 d->name = 0;
846
847 /* Build up the list in the same order as the insns are seen
848 in the machine description. */
849 d->next = 0;
a995e389
RH
850 *idata_end = d;
851 idata_end = &d->next;
9db4e0ec
RK
852
853 max_opno = -1;
854 num_dups = 0;
a995e389 855 memset (d->operand, 0, sizeof (d->operand));
9db4e0ec 856
a995e389
RH
857 /* Get the number of operands by scanning all the patterns of the
858 split patterns. But ignore all the rest of the information thus
859 obtained. */
9db4e0ec 860 for (i = 0; i < XVECLEN (split, 0); i++)
a995e389 861 scan_operands (d, XVECEXP (split, 0, i), 0, 0);
9db4e0ec
RK
862
863 d->n_operands = max_opno + 1;
9db4e0ec 864 d->n_dups = 0;
42495ca0 865 d->n_alternatives = 0;
9db4e0ec 866 d->template = 0;
4bbf910e 867 d->output_format = INSN_OUTPUT_FORMAT_NONE;
a995e389
RH
868
869 place_operands (d);
9db4e0ec
RK
870}
871\f
2778b98d 872PTR
9db4e0ec 873xmalloc (size)
2778b98d 874 size_t size;
9db4e0ec 875{
2778b98d 876 register PTR val = (PTR) malloc (size);
9db4e0ec
RK
877
878 if (val == 0)
879 fatal ("virtual memory exhausted");
880 return val;
881}
882
2778b98d 883PTR
470b68c0
RH
884xrealloc (old, size)
885 PTR old;
2778b98d 886 size_t size;
9db4e0ec 887{
470b68c0 888 register PTR ptr;
09d83d25 889 if (old)
470b68c0
RH
890 ptr = (PTR) realloc (old, size);
891 else
892 ptr = (PTR) malloc (size);
893 if (!ptr)
9db4e0ec 894 fatal ("virtual memory exhausted");
470b68c0 895 return ptr;
9db4e0ec
RK
896}
897
a94ae8f5 898extern int main PARAMS ((int, char **));
c1b59dce 899
9db4e0ec
RK
900int
901main (argc, argv)
902 int argc;
903 char **argv;
904{
905 rtx desc;
906 FILE *infile;
9db4e0ec
RK
907 register int c;
908
f8b6598e 909 progname = "genoutput";
9db4e0ec
RK
910 obstack_init (rtl_obstack);
911
912 if (argc <= 1)
913 fatal ("No input file name.");
914
915 infile = fopen (argv[1], "r");
916 if (infile == 0)
917 {
918 perror (argv[1]);
c1b59dce 919 return (FATAL_EXIT_CODE);
9db4e0ec 920 }
bcdaba58 921 read_rtx_filename = argv[1];
9db4e0ec 922
9db4e0ec
RK
923 output_prologue ();
924 next_code_number = 0;
925 next_index_number = 0;
9db4e0ec
RK
926
927 /* Read the machine description. */
928
929 while (1)
930 {
931 c = read_skip_spaces (infile);
932 if (c == EOF)
933 break;
934 ungetc (c, infile);
935
936 desc = read_rtx (infile);
937 if (GET_CODE (desc) == DEFINE_INSN)
938 gen_insn (desc);
939 if (GET_CODE (desc) == DEFINE_PEEPHOLE)
940 gen_peephole (desc);
941 if (GET_CODE (desc) == DEFINE_EXPAND)
942 gen_expand (desc);
ede7cd44
RH
943 if (GET_CODE (desc) == DEFINE_SPLIT
944 || GET_CODE (desc) == DEFINE_PEEPHOLE2)
9db4e0ec
RK
945 gen_split (desc);
946 next_index_number++;
947 }
948
a995e389
RH
949 printf("\n\n");
950 output_predicate_decls ();
951 output_operand_data ();
952 output_insn_data ();
953 output_get_insn_name ();
9db4e0ec
RK
954
955 fflush (stdout);
c1b59dce 956 return (ferror (stdout) != 0 || have_error
6a270722 957 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
9db4e0ec
RK
958}
959
665f2503
RK
960/* Return the number of occurrences of character C in string S or
961 -1 if S is the null string. */
962
9db4e0ec
RK
963static int
964n_occurrences (c, s)
d149d5f5 965 int c;
3cce094d 966 const char *s;
9db4e0ec
RK
967{
968 int n = 0;
665f2503
RK
969
970 if (s == 0 || *s == '\0')
971 return -1;
972
9db4e0ec
RK
973 while (*s)
974 n += (*s++ == c);
665f2503 975
9db4e0ec
RK
976 return n;
977}
88a56c2e 978
665f2503
RK
979/* Remove whitespace in `s' by moving up characters until the end.
980 Return a new string. */
981
982static const char *
88a56c2e 983strip_whitespace (s)
665f2503 984 const char *s;
88a56c2e 985{
665f2503
RK
986 char *p, *q;
987 char ch;
988
989 if (s == 0)
990 return 0;
88a56c2e 991
665f2503 992 p = q = xmalloc (strlen (s) + 1);
88a56c2e
HPN
993 while ((ch = *s++) != '\0')
994 if (! ISSPACE (ch))
995 *p++ = ch;
996
997 *p = '\0';
665f2503 998 return q;
88a56c2e 999}