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