]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/genoutput.c
genattr.c (internal_dfa_insn_code): Output prototype.
[thirdparty/gcc.git] / gcc / genoutput.c
CommitLineData
9db4e0ec 1/* Generate code from to output assembler insns as recognized from rtl.
58b23af8
JR
2 Copyright (C) 1987, 1988, 1992, 1994, 1995, 1997, 1998, 1999, 2000, 2002,
3 2003 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
3d7aafde
AJ
102static int n_occurrences (int, const char *);
103static const char *strip_whitespace (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
3d7aafde 176static void output_prologue (void);
3d7aafde
AJ
177static void output_operand_data (void);
178static void output_insn_data (void);
179static void output_get_insn_name (void);
180static void scan_operands (struct data *, rtx, int, int);
181static int compare_operands (struct operand_data *,
182 struct operand_data *);
183static void place_operands (struct data *);
184static void process_template (struct data *, const char *);
185static void validate_insn_alternatives (struct data *);
186static void validate_insn_operands (struct data *);
187static void gen_insn (rtx, int);
188static void gen_peephole (rtx, int);
189static void gen_expand (rtx, int);
190static void gen_split (rtx, int);
191static void check_constraint_len (void);
192static int constraint_len (const char *, int);
56c0e996 193\f
a995e389 194const char *
3d7aafde 195get_insn_name (int index)
8aeba909
RH
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 216static void
3d7aafde 217output_prologue (void)
9db4e0ec 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 245static void
3d7aafde 246output_operand_data (void)
a995e389 247{
b3694847 248 struct operand_data *d;
a995e389
RH
249
250 printf ("\nstatic const struct insn_operand_data operand_data[] = \n{\n");
251
252 for (d = odata; d; d = d->next)
9db4e0ec 253 {
a995e389
RH
254 printf (" {\n");
255
256 printf (" %s,\n",
257 d->predicate && d->predicate[0] ? d->predicate : "0");
258
19af6455 259 printf (" \"%s\",\n", d->constraint ? d->constraint : "");
9db4e0ec 260
a995e389
RH
261 printf (" %smode,\n", GET_MODE_NAME (d->mode));
262
dfac187e
BS
263 printf (" %d,\n", d->strict_low);
264
265 printf (" %d\n", d->eliminable);
a995e389
RH
266
267 printf(" },\n");
268 }
269 printf("};\n\n\n");
270}
271
272static void
3d7aafde 273output_insn_data (void)
a995e389 274{
b3694847 275 struct data *d;
a995e389
RH
276 int name_offset = 0;
277 int next_name_offset;
278 const char * last_name = 0;
279 const char * next_name = 0;
b3694847 280 struct data *n;
a995e389
RH
281
282 for (n = idata, next_name_offset = 1; n; n = n->next, next_name_offset++)
283 if (n->name)
9db4e0ec 284 {
a995e389
RH
285 next_name = n->name;
286 break;
9db4e0ec 287 }
9db4e0ec 288
a995e389 289 printf ("\nconst struct insn_data insn_data[] = \n{\n");
9db4e0ec 290
a995e389 291 for (d = idata; d; d = d->next)
9db4e0ec 292 {
a995e389
RH
293 printf (" {\n");
294
295 if (d->name)
9db4e0ec 296 {
a995e389
RH
297 printf (" \"%s\",\n", d->name);
298 name_offset = 0;
299 last_name = d->name;
300 next_name = 0;
301 for (n = d->next, next_name_offset = 1; n;
302 n = n->next, next_name_offset++)
9db4e0ec 303 {
a995e389
RH
304 if (n->name)
305 {
306 next_name = n->name;
307 break;
308 }
9db4e0ec 309 }
9db4e0ec 310 }
a995e389 311 else
9db4e0ec 312 {
a995e389
RH
313 name_offset++;
314 if (next_name && (last_name == 0
315 || name_offset > next_name_offset / 2))
316 printf (" \"%s-%d\",\n", next_name,
317 next_name_offset - name_offset);
318 else
319 printf (" \"%s+%d\",\n", last_name, name_offset);
9db4e0ec 320 }
9db4e0ec 321
4bbf910e
RH
322 switch (d->output_format)
323 {
324 case INSN_OUTPUT_FORMAT_NONE:
325 printf (" 0,\n");
326 break;
327 case INSN_OUTPUT_FORMAT_SINGLE:
212d447c
DC
328 {
329 const char *p = d->template;
330 char prev = 0;
3d7aafde 331
212d447c
DC
332 printf (" \"");
333 while (*p)
334 {
6b8b9d7b
CM
335 if (IS_VSPACE (*p) && prev != '\\')
336 {
337 /* Preserve two consecutive \n's or \r's, but treat \r\n
338 as a single newline. */
339 if (*p == '\n' && prev != '\r')
340 printf ("\\n\\\n");
341 }
212d447c
DC
342 else
343 putchar (*p);
344 prev = *p;
345 ++p;
346 }
347 printf ("\",\n");
348 }
4bbf910e
RH
349 break;
350 case INSN_OUTPUT_FORMAT_MULTI:
351 case INSN_OUTPUT_FORMAT_FUNCTION:
fad205ff 352 printf (" (const void *) output_%d,\n", d->code_number);
4bbf910e
RH
353 break;
354 default:
355 abort ();
356 }
a995e389
RH
357
358 if (d->name && d->name[0] != '*')
706b0f60 359 printf (" (insn_gen_fn) gen_%s,\n", d->name);
a995e389
RH
360 else
361 printf (" 0,\n");
362
363 printf (" &operand_data[%d],\n", d->operand_number);
364 printf (" %d,\n", d->n_operands);
365 printf (" %d,\n", d->n_dups);
4bbf910e
RH
366 printf (" %d,\n", d->n_alternatives);
367 printf (" %d\n", d->output_format);
a995e389
RH
368
369 printf(" },\n");
9db4e0ec 370 }
a995e389
RH
371 printf ("};\n\n\n");
372}
9db4e0ec 373
a995e389 374static void
3d7aafde 375output_get_insn_name (void)
a995e389
RH
376{
377 printf ("const char *\n");
6906ba40 378 printf ("get_insn_name (int code)\n");
a995e389 379 printf ("{\n");
a0f0e963
SB
380 printf (" if (code == NOOP_MOVE_INSN_CODE)\n");
381 printf (" return \"NOOP_MOVE\";\n");
382 printf (" else\n");
383 printf (" return insn_data[code].name;\n");
a995e389 384 printf ("}\n");
9db4e0ec 385}
a995e389 386
9db4e0ec 387\f
a995e389
RH
388/* Stores in max_opno the largest operand number present in `part', if
389 that is larger than the previous value of max_opno, and the rest of
390 the operand data into `d->operand[i]'.
9db4e0ec
RK
391
392 THIS_ADDRESS_P is nonzero if the containing rtx was an ADDRESS.
393 THIS_STRICT_LOW is nonzero if the containing rtx was a STRICT_LOW_PART. */
394
395static int max_opno;
396static int num_dups;
9db4e0ec
RK
397
398static void
3d7aafde
AJ
399scan_operands (struct data *d, rtx part, int this_address_p,
400 int this_strict_low)
9db4e0ec 401{
b3694847
SS
402 int i, j;
403 const char *format_ptr;
9db4e0ec
RK
404 int opno;
405
406 if (part == 0)
407 return;
408
409 switch (GET_CODE (part))
410 {
411 case MATCH_OPERAND:
412 opno = XINT (part, 0);
413 if (opno > max_opno)
414 max_opno = opno;
415 if (max_opno >= MAX_MAX_OPERANDS)
5a806d65 416 {
d96a2fcd
RH
417 message_with_line (d->lineno,
418 "maximum number of operands exceeded");
419 have_error = 1;
5a806d65
RK
420 return;
421 }
a995e389 422 if (d->operand[opno].seen)
d96a2fcd
RH
423 {
424 message_with_line (d->lineno,
425 "repeated operand number %d\n", opno);
426 have_error = 1;
427 }
428
a995e389
RH
429 d->operand[opno].seen = 1;
430 d->operand[opno].mode = GET_MODE (part);
431 d->operand[opno].strict_low = this_strict_low;
432 d->operand[opno].predicate = XSTR (part, 1);
665f2503
RK
433 d->operand[opno].constraint = strip_whitespace (XSTR (part, 2));
434 d->operand[opno].n_alternatives
435 = n_occurrences (',', d->operand[opno].constraint) + 1;
a995e389 436 d->operand[opno].address_p = this_address_p;
dfac187e 437 d->operand[opno].eliminable = 1;
9db4e0ec
RK
438 return;
439
440 case MATCH_SCRATCH:
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 = 0;
461 d->operand[opno].predicate = "scratch_operand";
665f2503
RK
462 d->operand[opno].constraint = strip_whitespace (XSTR (part, 1));
463 d->operand[opno].n_alternatives
464 = n_occurrences (',', d->operand[opno].constraint) + 1;
a995e389 465 d->operand[opno].address_p = 0;
dfac187e 466 d->operand[opno].eliminable = 0;
9db4e0ec
RK
467 return;
468
469 case MATCH_OPERATOR:
470 case MATCH_PARALLEL:
471 opno = XINT (part, 0);
472 if (opno > max_opno)
473 max_opno = opno;
474 if (max_opno >= MAX_MAX_OPERANDS)
5a806d65 475 {
d96a2fcd
RH
476 message_with_line (d->lineno,
477 "maximum number of operands exceeded");
478 have_error = 1;
5a806d65
RK
479 return;
480 }
a995e389 481 if (d->operand[opno].seen)
d96a2fcd
RH
482 {
483 message_with_line (d->lineno,
484 "repeated operand number %d\n", opno);
485 have_error = 1;
486 }
487
a995e389
RH
488 d->operand[opno].seen = 1;
489 d->operand[opno].mode = GET_MODE (part);
490 d->operand[opno].strict_low = 0;
491 d->operand[opno].predicate = XSTR (part, 1);
492 d->operand[opno].constraint = 0;
493 d->operand[opno].address_p = 0;
dfac187e 494 d->operand[opno].eliminable = 0;
9db4e0ec 495 for (i = 0; i < XVECLEN (part, 2); i++)
a995e389 496 scan_operands (d, XVECEXP (part, 2, i), 0, 0);
9db4e0ec
RK
497 return;
498
499 case MATCH_DUP:
500 case MATCH_OP_DUP:
ed18f94d 501 case MATCH_PAR_DUP:
9db4e0ec 502 ++num_dups;
6d7a1c4c 503 break;
9db4e0ec
RK
504
505 case ADDRESS:
a995e389 506 scan_operands (d, XEXP (part, 0), 1, 0);
9db4e0ec
RK
507 return;
508
509 case STRICT_LOW_PART:
a995e389 510 scan_operands (d, XEXP (part, 0), 0, 1);
9db4e0ec 511 return;
3d7aafde 512
ccd043a9
RL
513 default:
514 break;
9db4e0ec
RK
515 }
516
517 format_ptr = GET_RTX_FORMAT (GET_CODE (part));
518
519 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
520 switch (*format_ptr++)
521 {
522 case 'e':
ccd043a9 523 case 'u':
a995e389 524 scan_operands (d, XEXP (part, i), 0, 0);
9db4e0ec
RK
525 break;
526 case 'E':
527 if (XVEC (part, i) != NULL)
528 for (j = 0; j < XVECLEN (part, i); j++)
a995e389 529 scan_operands (d, XVECEXP (part, i, j), 0, 0);
9db4e0ec
RK
530 break;
531 }
532}
a995e389
RH
533
534/* Compare two operands for content equality. */
535
536static int
3d7aafde 537compare_operands (struct operand_data *d0, struct operand_data *d1)
a995e389 538{
c1b59dce 539 const char *p0, *p1;
a995e389
RH
540
541 p0 = d0->predicate;
542 if (!p0)
543 p0 = "";
544 p1 = d1->predicate;
545 if (!p1)
546 p1 = "";
547 if (strcmp (p0, p1) != 0)
548 return 0;
549
19af6455
BS
550 p0 = d0->constraint;
551 if (!p0)
552 p0 = "";
553 p1 = d1->constraint;
554 if (!p1)
555 p1 = "";
556 if (strcmp (p0, p1) != 0)
557 return 0;
a995e389
RH
558
559 if (d0->mode != d1->mode)
560 return 0;
561
a995e389
RH
562 if (d0->strict_low != d1->strict_low)
563 return 0;
564
dfac187e
BS
565 if (d0->eliminable != d1->eliminable)
566 return 0;
567
a995e389
RH
568 return 1;
569}
570
571/* Scan the list of operands we've already committed to output and either
572 find a subsequence that is the same, or allocate a new one at the end. */
573
574static void
3d7aafde 575place_operands (struct data *d)
a995e389
RH
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
3d7aafde 629process_template (struct data *d, const char *template)
9db4e0ec 630{
b3694847
SS
631 const char *cp;
632 int i;
9db4e0ec 633
4bbf910e
RH
634 /* Templates starting with * contain straight code to be run. */
635 if (template[0] == '*')
9db4e0ec 636 {
4bbf910e
RH
637 d->template = 0;
638 d->output_format = INSN_OUTPUT_FORMAT_FUNCTION;
9db4e0ec 639
4bbf910e 640 puts ("\nstatic const char *");
6906ba40
KG
641 printf ("output_%d (rtx *operands ATTRIBUTE_UNUSED, rtx insn ATTRIBUTE_UNUSED)\n",
642 d->code_number);
4bbf910e
RH
643 puts ("{");
644
645 puts (template + 1);
646 puts ("}");
647 }
9db4e0ec
RK
648
649 /* If the assembler code template starts with a @ it is a newline-separated
4bbf910e
RH
650 list of assembler code templates, one for each alternative. */
651 else if (template[0] == '@')
9db4e0ec 652 {
4bbf910e
RH
653 d->template = 0;
654 d->output_format = INSN_OUTPUT_FORMAT_MULTI;
9db4e0ec 655
4bbf910e 656 printf ("\nstatic const char * const output_%d[] = {\n", d->code_number);
9db4e0ec
RK
657
658 for (i = 0, cp = &template[1]; *cp; )
659 {
6b8b9d7b 660 while (ISSPACE (*cp))
9db4e0ec
RK
661 cp++;
662
4bbf910e 663 printf (" \"");
6b8b9d7b 664 while (!IS_VSPACE (*cp) && *cp != '\0')
2f013c71
RK
665 {
666 putchar (*cp);
667 cp++;
668 }
9db4e0ec
RK
669
670 printf ("\",\n");
671 i++;
672 }
c6d79bee
JH
673 if (i == 1)
674 message_with_line (d->lineno,
675 "'@' is redundant for output template with single alternative");
676 if (i != d->n_alternatives)
677 {
678 message_with_line (d->lineno,
1f978f5f 679 "wrong number of alternatives in the output template");
c6d79bee
JH
680 have_error = 1;
681 }
9db4e0ec 682
4bbf910e 683 printf ("};\n");
9db4e0ec
RK
684 }
685 else
686 {
4bbf910e
RH
687 d->template = template;
688 d->output_format = INSN_OUTPUT_FORMAT_SINGLE;
9db4e0ec 689 }
9db4e0ec
RK
690}
691\f
692/* Check insn D for consistency in number of constraint alternatives. */
693
694static void
3d7aafde 695validate_insn_alternatives (struct data *d)
9db4e0ec 696{
b3694847 697 int n = 0, start;
a995e389
RH
698
699 /* Make sure all the operands have the same number of alternatives
700 in their constraints. Let N be that number. */
9db4e0ec 701 for (start = 0; start < d->n_operands; start++)
a995e389 702 if (d->operand[start].n_alternatives > 0)
9db4e0ec 703 {
97488870
R
704 int len, i;
705 const char *p;
706 char c;
707 int which_alternative = 0;
708 int alternative_count_unsure = 0;
709
710 for (p = d->operand[start].constraint; (c = *p); p += len)
711 {
712 len = CONSTRAINT_LEN (c, p);
713
714 if (len < 1 || (len > 1 && strchr (",#*+=&%!0123456789", c)))
715 {
716 message_with_line (d->lineno,
717 "invalid length %d for char '%c' in alternative %d of operand %d",
718 len, c, which_alternative, start);
719 len = 1;
720 have_error = 1;
721 }
722
723 if (c == ',')
724 {
725 which_alternative++;
726 continue;
727 }
728
729 for (i = 1; i < len; i++)
730 if (p[i] == '\0')
731 {
732 message_with_line (d->lineno,
733 "NUL in alternative %d of operand %d",
734 which_alternative, start);
735 alternative_count_unsure = 1;
736 break;
737 }
738 else if (strchr (",#*", p[i]))
739 {
740 message_with_line (d->lineno,
741 "'%c' in alternative %d of operand %d",
742 p[i], which_alternative, start);
743 alternative_count_unsure = 1;
744 }
745 }
746 if (alternative_count_unsure)
747 have_error = 1;
748 else if (n == 0)
a995e389
RH
749 n = d->operand[start].n_alternatives;
750 else if (n != d->operand[start].n_alternatives)
d96a2fcd
RH
751 {
752 message_with_line (d->lineno,
753 "wrong number of alternatives in operand %d",
754 start);
755 have_error = 1;
756 }
9db4e0ec 757 }
a995e389 758
9db4e0ec
RK
759 /* Record the insn's overall number of alternatives. */
760 d->n_alternatives = n;
761}
c77e04ae
RH
762
763/* Verify that there are no gaps in operand numbers for INSNs. */
764
765static void
3d7aafde 766validate_insn_operands (struct data *d)
c77e04ae
RH
767{
768 int i;
769
770 for (i = 0; i < d->n_operands; ++i)
771 if (d->operand[i].seen == 0)
772 {
773 message_with_line (d->lineno, "missing operand %d", i);
774 have_error = 1;
775 }
776}
9db4e0ec 777\f
a995e389
RH
778/* Look at a define_insn just read. Assign its code number. Record
779 on idata the template and the number of arguments. If the insn has
780 a hairy output action, output a function for now. */
9db4e0ec
RK
781
782static void
3d7aafde 783gen_insn (rtx insn, int lineno)
9db4e0ec 784{
b3694847
SS
785 struct data *d = (struct data *) xmalloc (sizeof (struct data));
786 int i;
9db4e0ec 787
c88c0d42 788 d->code_number = next_code_number;
9db4e0ec 789 d->index_number = next_index_number;
d96a2fcd 790 d->lineno = lineno;
9db4e0ec
RK
791 if (XSTR (insn, 0)[0])
792 d->name = XSTR (insn, 0);
793 else
794 d->name = 0;
795
796 /* Build up the list in the same order as the insns are seen
797 in the machine description. */
798 d->next = 0;
a995e389
RH
799 *idata_end = d;
800 idata_end = &d->next;
9db4e0ec
RK
801
802 max_opno = -1;
803 num_dups = 0;
a995e389 804 memset (d->operand, 0, sizeof (d->operand));
9db4e0ec
RK
805
806 for (i = 0; i < XVECLEN (insn, 1); i++)
a995e389 807 scan_operands (d, XVECEXP (insn, 1, i), 0, 0);
9db4e0ec
RK
808
809 d->n_operands = max_opno + 1;
810 d->n_dups = num_dups;
811
97488870 812 check_constraint_len ();
c77e04ae 813 validate_insn_operands (d);
9db4e0ec 814 validate_insn_alternatives (d);
a995e389 815 place_operands (d);
1f3b37a3 816 process_template (d, XTMPL (insn, 3));
9db4e0ec
RK
817}
818\f
819/* Look at a define_peephole just read. Assign its code number.
a995e389 820 Record on idata the template and the number of arguments.
9db4e0ec
RK
821 If the insn has a hairy output action, output it now. */
822
823static void
3d7aafde 824gen_peephole (rtx peep, int lineno)
9db4e0ec 825{
b3694847
SS
826 struct data *d = (struct data *) xmalloc (sizeof (struct data));
827 int i;
9db4e0ec 828
c88c0d42 829 d->code_number = next_code_number;
9db4e0ec 830 d->index_number = next_index_number;
d96a2fcd 831 d->lineno = lineno;
9db4e0ec
RK
832 d->name = 0;
833
834 /* Build up the list in the same order as the insns are seen
835 in the machine description. */
836 d->next = 0;
a995e389
RH
837 *idata_end = d;
838 idata_end = &d->next;
9db4e0ec
RK
839
840 max_opno = -1;
a995e389
RH
841 num_dups = 0;
842 memset (d->operand, 0, sizeof (d->operand));
843
844 /* Get the number of operands by scanning all the patterns of the
845 peephole optimizer. But ignore all the rest of the information
846 thus obtained. */
9db4e0ec 847 for (i = 0; i < XVECLEN (peep, 0); i++)
a995e389 848 scan_operands (d, XVECEXP (peep, 0, i), 0, 0);
9db4e0ec
RK
849
850 d->n_operands = max_opno + 1;
851 d->n_dups = 0;
852
9db4e0ec 853 validate_insn_alternatives (d);
a995e389 854 place_operands (d);
1f3b37a3 855 process_template (d, XTMPL (peep, 2));
9db4e0ec
RK
856}
857\f
858/* Process a define_expand just read. Assign its code number,
859 only for the purposes of `insn_gen_function'. */
860
861static void
3d7aafde 862gen_expand (rtx insn, int lineno)
9db4e0ec 863{
b3694847
SS
864 struct data *d = (struct data *) xmalloc (sizeof (struct data));
865 int i;
9db4e0ec 866
c88c0d42 867 d->code_number = next_code_number;
9db4e0ec 868 d->index_number = next_index_number;
d96a2fcd 869 d->lineno = lineno;
9db4e0ec
RK
870 if (XSTR (insn, 0)[0])
871 d->name = XSTR (insn, 0);
872 else
873 d->name = 0;
874
875 /* Build up the list in the same order as the insns are seen
876 in the machine description. */
877 d->next = 0;
a995e389
RH
878 *idata_end = d;
879 idata_end = &d->next;
9db4e0ec
RK
880
881 max_opno = -1;
882 num_dups = 0;
a995e389 883 memset (d->operand, 0, sizeof (d->operand));
9db4e0ec
RK
884
885 /* Scan the operands to get the specified predicates and modes,
886 since expand_binop needs to know them. */
887
9db4e0ec
RK
888 if (XVEC (insn, 1))
889 for (i = 0; i < XVECLEN (insn, 1); i++)
a995e389 890 scan_operands (d, XVECEXP (insn, 1, i), 0, 0);
9db4e0ec
RK
891
892 d->n_operands = max_opno + 1;
893 d->n_dups = num_dups;
9db4e0ec 894 d->template = 0;
4bbf910e 895 d->output_format = INSN_OUTPUT_FORMAT_NONE;
a995e389 896
9db4e0ec 897 validate_insn_alternatives (d);
a995e389 898 place_operands (d);
9db4e0ec
RK
899}
900\f
901/* Process a define_split just read. Assign its code number,
902 only for reasons of consistency and to simplify genrecog. */
903
9db4e0ec 904static void
3d7aafde 905gen_split (rtx split, int lineno)
9db4e0ec 906{
b3694847
SS
907 struct data *d = (struct data *) xmalloc (sizeof (struct data));
908 int i;
9db4e0ec 909
c88c0d42 910 d->code_number = next_code_number;
9db4e0ec 911 d->index_number = next_index_number;
d96a2fcd 912 d->lineno = lineno;
9db4e0ec
RK
913 d->name = 0;
914
915 /* Build up the list in the same order as the insns are seen
916 in the machine description. */
917 d->next = 0;
a995e389
RH
918 *idata_end = d;
919 idata_end = &d->next;
9db4e0ec
RK
920
921 max_opno = -1;
922 num_dups = 0;
a995e389 923 memset (d->operand, 0, sizeof (d->operand));
9db4e0ec 924
a995e389
RH
925 /* Get the number of operands by scanning all the patterns of the
926 split patterns. But ignore all the rest of the information thus
927 obtained. */
9db4e0ec 928 for (i = 0; i < XVECLEN (split, 0); i++)
a995e389 929 scan_operands (d, XVECEXP (split, 0, i), 0, 0);
9db4e0ec
RK
930
931 d->n_operands = max_opno + 1;
9db4e0ec 932 d->n_dups = 0;
42495ca0 933 d->n_alternatives = 0;
9db4e0ec 934 d->template = 0;
4bbf910e 935 d->output_format = INSN_OUTPUT_FORMAT_NONE;
a995e389
RH
936
937 place_operands (d);
9db4e0ec 938}
9db4e0ec 939
3d7aafde 940extern int main (int, char **);
c1b59dce 941
9db4e0ec 942int
3d7aafde 943main (int argc, char **argv)
9db4e0ec
RK
944{
945 rtx desc;
9db4e0ec 946
d80eb1e1
RH
947 progname = "genoutput";
948
9db4e0ec 949 if (argc <= 1)
1f978f5f 950 fatal ("no input file name");
9db4e0ec 951
04d8aa70 952 if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
c88c0d42 953 return (FATAL_EXIT_CODE);
9db4e0ec 954
9db4e0ec
RK
955 output_prologue ();
956 next_code_number = 0;
957 next_index_number = 0;
9db4e0ec
RK
958
959 /* Read the machine description. */
960
961 while (1)
962 {
c88c0d42
CP
963 int line_no;
964
965 desc = read_md_rtx (&line_no, &next_code_number);
966 if (desc == NULL)
9db4e0ec 967 break;
9db4e0ec 968
9db4e0ec 969 if (GET_CODE (desc) == DEFINE_INSN)
d96a2fcd 970 gen_insn (desc, line_no);
9db4e0ec 971 if (GET_CODE (desc) == DEFINE_PEEPHOLE)
d96a2fcd 972 gen_peephole (desc, line_no);
9db4e0ec 973 if (GET_CODE (desc) == DEFINE_EXPAND)
d96a2fcd 974 gen_expand (desc, line_no);
ede7cd44 975 if (GET_CODE (desc) == DEFINE_SPLIT
3d7aafde 976 || GET_CODE (desc) == DEFINE_PEEPHOLE2)
d96a2fcd 977 gen_split (desc, line_no);
9db4e0ec
RK
978 next_index_number++;
979 }
980
a995e389 981 printf("\n\n");
a995e389
RH
982 output_operand_data ();
983 output_insn_data ();
984 output_get_insn_name ();
9db4e0ec
RK
985
986 fflush (stdout);
c1b59dce 987 return (ferror (stdout) != 0 || have_error
6a270722 988 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
9db4e0ec
RK
989}
990
665f2503
RK
991/* Return the number of occurrences of character C in string S or
992 -1 if S is the null string. */
993
9db4e0ec 994static int
3d7aafde 995n_occurrences (int c, const char *s)
9db4e0ec
RK
996{
997 int n = 0;
665f2503
RK
998
999 if (s == 0 || *s == '\0')
1000 return -1;
1001
9db4e0ec
RK
1002 while (*s)
1003 n += (*s++ == c);
665f2503 1004
9db4e0ec
RK
1005 return n;
1006}
88a56c2e 1007
665f2503
RK
1008/* Remove whitespace in `s' by moving up characters until the end.
1009 Return a new string. */
1010
1011static const char *
3d7aafde 1012strip_whitespace (const char *s)
88a56c2e 1013{
665f2503
RK
1014 char *p, *q;
1015 char ch;
1016
1017 if (s == 0)
1018 return 0;
88a56c2e 1019
665f2503 1020 p = q = xmalloc (strlen (s) + 1);
88a56c2e
HPN
1021 while ((ch = *s++) != '\0')
1022 if (! ISSPACE (ch))
1023 *p++ = ch;
1024
1025 *p = '\0';
665f2503 1026 return q;
88a56c2e 1027}
97488870
R
1028
1029/* Verify that DEFAULT_CONSTRAINT_LEN is used properly and not
1030 tampered with. This isn't bullet-proof, but it should catch
1031 most genuine mistakes. */
1032static void
3d7aafde 1033check_constraint_len (void)
97488870
R
1034{
1035 const char *p;
1036 int d;
1037
1038 for (p = ",#*+=&%!1234567890"; *p; p++)
1039 for (d = -9; d < 9; d++)
1040 if (constraint_len (p, d) != d)
1041 abort ();
1042}
1043
1044static int
3d7aafde 1045constraint_len (const char *p, int genoutput_default_constraint_len)
97488870
R
1046{
1047 /* Check that we still match defaults.h . First we do a generation-time
1048 check that fails if the value is not the expected one... */
1049 if (DEFAULT_CONSTRAINT_LEN (*p, p) != 1)
1050 abort ();
1051 /* And now a comile-time check that should give a diagnostic if the
1052 definition doesn't exactly match. */
1053#define DEFAULT_CONSTRAINT_LEN(C,STR) 1
1054 /* Now re-define DEFAULT_CONSTRAINT_LEN so that we can verify it is
1055 being used. */
1056#undef DEFAULT_CONSTRAINT_LEN
1057#define DEFAULT_CONSTRAINT_LEN(C,STR) \
1058 ((C) != *p || STR != p ? -1 : genoutput_default_constraint_len)
1059 return CONSTRAINT_LEN (*p, p);
1060 /* And set it back. */
1061#undef DEFAULT_CONSTRAINT_LEN
1062#define DEFAULT_CONSTRAINT_LEN(C,STR) 1
1063}