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