]> gcc.gnu.org Git - gcc.git/blame - gcc/genoutput.c
Update FSF address.
[gcc.git] / gcc / genoutput.c
CommitLineData
9db4e0ec 1/* Generate code from to output assembler insns as recognized from rtl.
58b23af8 2 Copyright (C) 1987, 1988, 1992, 1994, 1995, 1997, 1998, 1999, 2000, 2002,
25f99665 3 2003, 2004, 2005 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;
1e9c8405 163 const char *filename;
d96a2fcd 164 int lineno;
9db4e0ec
RK
165 int n_operands; /* Number of operands this insn recognizes */
166 int n_dups; /* Number times match_dup appears in pattern */
167 int n_alternatives; /* Number of alternatives in each constraint */
a995e389 168 int operand_number; /* Operand index in the big array. */
4bbf910e 169 int output_format; /* INSN_OUTPUT_FORMAT_*. */
a995e389 170 struct operand_data operand[MAX_MAX_OPERANDS];
9db4e0ec
RK
171};
172
a995e389 173/* This variable points to the first link in the insn chain. */
9db4e0ec 174
a995e389 175static struct data *idata, **idata_end = &idata;
9db4e0ec 176\f
3d7aafde 177static void output_prologue (void);
3d7aafde
AJ
178static void output_operand_data (void);
179static void output_insn_data (void);
180static void output_get_insn_name (void);
181static void scan_operands (struct data *, rtx, int, int);
182static int compare_operands (struct operand_data *,
183 struct operand_data *);
184static void place_operands (struct data *);
185static void process_template (struct data *, const char *);
186static void validate_insn_alternatives (struct data *);
187static void validate_insn_operands (struct data *);
188static void gen_insn (rtx, int);
189static void gen_peephole (rtx, int);
190static void gen_expand (rtx, int);
191static void gen_split (rtx, int);
192static void check_constraint_len (void);
193static int constraint_len (const char *, int);
56c0e996 194\f
a995e389 195const char *
3d7aafde 196get_insn_name (int index)
8aeba909
RH
197{
198 static char buf[100];
199
200 struct data *i, *last_named = NULL;
a995e389 201 for (i = idata; i ; i = i->next)
8aeba909
RH
202 {
203 if (i->index_number == index)
204 return i->name;
205 if (i->name)
206 last_named = i;
207 }
208
209 if (last_named)
210 sprintf(buf, "%s+%d", last_named->name, index - last_named->index_number);
211 else
212 sprintf(buf, "insn %d", index);
213
214 return buf;
215}
216
9db4e0ec 217static void
3d7aafde 218output_prologue (void)
9db4e0ec 219{
9db4e0ec 220 printf ("/* Generated automatically by the program `genoutput'\n\
d96a2fcd 221 from the machine description file `md'. */\n\n");
9db4e0ec
RK
222
223 printf ("#include \"config.h\"\n");
729da3f5 224 printf ("#include \"system.h\"\n");
4977bab6
ZW
225 printf ("#include \"coretypes.h\"\n");
226 printf ("#include \"tm.h\"\n");
ccd043a9 227 printf ("#include \"flags.h\"\n");
3bc9f12b 228 printf ("#include \"ggc.h\"\n");
9db4e0ec 229 printf ("#include \"rtl.h\"\n");
f3a8030a 230 printf ("#include \"expr.h\"\n");
e78d8e51 231 printf ("#include \"insn-codes.h\"\n");
6baf1cc8 232 printf ("#include \"tm_p.h\"\n");
49ad7cfa 233 printf ("#include \"function.h\"\n");
9db4e0ec
RK
234 printf ("#include \"regs.h\"\n");
235 printf ("#include \"hard-reg-set.h\"\n");
236 printf ("#include \"real.h\"\n");
237 printf ("#include \"insn-config.h\"\n\n");
238 printf ("#include \"conditions.h\"\n");
9db4e0ec 239 printf ("#include \"insn-attr.h\"\n\n");
9db4e0ec 240 printf ("#include \"recog.h\"\n\n");
c3fc86c9 241 printf ("#include \"toplev.h\"\n");
9db4e0ec 242 printf ("#include \"output.h\"\n");
4977bab6 243 printf ("#include \"target.h\"\n");
9db4e0ec
RK
244}
245
a995e389 246static void
3d7aafde 247output_operand_data (void)
a995e389 248{
b3694847 249 struct operand_data *d;
a995e389
RH
250
251 printf ("\nstatic const struct insn_operand_data operand_data[] = \n{\n");
252
253 for (d = odata; d; d = d->next)
9db4e0ec 254 {
a995e389
RH
255 printf (" {\n");
256
257 printf (" %s,\n",
258 d->predicate && d->predicate[0] ? d->predicate : "0");
259
19af6455 260 printf (" \"%s\",\n", d->constraint ? d->constraint : "");
9db4e0ec 261
a995e389
RH
262 printf (" %smode,\n", GET_MODE_NAME (d->mode));
263
dfac187e
BS
264 printf (" %d,\n", d->strict_low);
265
266 printf (" %d\n", d->eliminable);
a995e389
RH
267
268 printf(" },\n");
269 }
270 printf("};\n\n\n");
271}
272
273static void
3d7aafde 274output_insn_data (void)
a995e389 275{
b3694847 276 struct data *d;
a995e389
RH
277 int name_offset = 0;
278 int next_name_offset;
279 const char * last_name = 0;
280 const char * next_name = 0;
b3694847 281 struct data *n;
a995e389
RH
282
283 for (n = idata, next_name_offset = 1; n; n = n->next, next_name_offset++)
284 if (n->name)
9db4e0ec 285 {
a995e389
RH
286 next_name = n->name;
287 break;
9db4e0ec 288 }
9db4e0ec 289
3897f229 290 printf ("#if GCC_VERSION >= 2007\n__extension__\n#endif\n");
a995e389 291 printf ("\nconst struct insn_data insn_data[] = \n{\n");
9db4e0ec 292
a995e389 293 for (d = idata; d; d = d->next)
9db4e0ec 294 {
1e9c8405 295 printf (" /* %s:%d */\n", d->filename, d->lineno);
a995e389
RH
296 printf (" {\n");
297
298 if (d->name)
9db4e0ec 299 {
a995e389
RH
300 printf (" \"%s\",\n", d->name);
301 name_offset = 0;
302 last_name = d->name;
303 next_name = 0;
304 for (n = d->next, next_name_offset = 1; n;
305 n = n->next, next_name_offset++)
9db4e0ec 306 {
a995e389
RH
307 if (n->name)
308 {
309 next_name = n->name;
310 break;
311 }
9db4e0ec 312 }
9db4e0ec 313 }
a995e389 314 else
9db4e0ec 315 {
a995e389
RH
316 name_offset++;
317 if (next_name && (last_name == 0
318 || name_offset > next_name_offset / 2))
319 printf (" \"%s-%d\",\n", next_name,
320 next_name_offset - name_offset);
321 else
322 printf (" \"%s+%d\",\n", last_name, name_offset);
9db4e0ec 323 }
9db4e0ec 324
4bbf910e
RH
325 switch (d->output_format)
326 {
327 case INSN_OUTPUT_FORMAT_NONE:
3897f229
JM
328 printf ("#if HAVE_DESIGNATED_INITIALIZERS\n");
329 printf (" { 0 },\n");
330 printf ("#else\n");
331 printf (" { 0, 0, 0 },\n");
332 printf ("#endif\n");
4bbf910e
RH
333 break;
334 case INSN_OUTPUT_FORMAT_SINGLE:
212d447c
DC
335 {
336 const char *p = d->template;
337 char prev = 0;
3d7aafde 338
3897f229
JM
339 printf ("#if HAVE_DESIGNATED_INITIALIZERS\n");
340 printf (" { .single =\n");
341 printf ("#else\n");
342 printf (" {\n");
343 printf ("#endif\n");
212d447c
DC
344 printf (" \"");
345 while (*p)
346 {
6b8b9d7b
CM
347 if (IS_VSPACE (*p) && prev != '\\')
348 {
349 /* Preserve two consecutive \n's or \r's, but treat \r\n
350 as a single newline. */
351 if (*p == '\n' && prev != '\r')
352 printf ("\\n\\\n");
353 }
212d447c
DC
354 else
355 putchar (*p);
356 prev = *p;
357 ++p;
358 }
359 printf ("\",\n");
3897f229
JM
360 printf ("#if HAVE_DESIGNATED_INITIALIZERS\n");
361 printf (" },\n");
362 printf ("#else\n");
363 printf (" 0, 0 },\n");
364 printf ("#endif\n");
212d447c 365 }
4bbf910e
RH
366 break;
367 case INSN_OUTPUT_FORMAT_MULTI:
3897f229
JM
368 printf ("#if HAVE_DESIGNATED_INITIALIZERS\n");
369 printf (" { .multi = output_%d },\n", d->code_number);
370 printf ("#else\n");
371 printf (" { 0, output_%d, 0 },\n", d->code_number);
372 printf ("#endif\n");
373 break;
4bbf910e 374 case INSN_OUTPUT_FORMAT_FUNCTION:
3897f229
JM
375 printf ("#if HAVE_DESIGNATED_INITIALIZERS\n");
376 printf (" { .function = output_%d },\n", d->code_number);
377 printf ("#else\n");
378 printf (" { 0, 0, output_%d },\n", d->code_number);
379 printf ("#endif\n");
4bbf910e
RH
380 break;
381 default:
b2d59f6f 382 gcc_unreachable ();
4bbf910e 383 }
a995e389
RH
384
385 if (d->name && d->name[0] != '*')
706b0f60 386 printf (" (insn_gen_fn) gen_%s,\n", d->name);
a995e389
RH
387 else
388 printf (" 0,\n");
389
390 printf (" &operand_data[%d],\n", d->operand_number);
391 printf (" %d,\n", d->n_operands);
392 printf (" %d,\n", d->n_dups);
4bbf910e
RH
393 printf (" %d,\n", d->n_alternatives);
394 printf (" %d\n", d->output_format);
a995e389
RH
395
396 printf(" },\n");
9db4e0ec 397 }
a995e389
RH
398 printf ("};\n\n\n");
399}
9db4e0ec 400
a995e389 401static void
3d7aafde 402output_get_insn_name (void)
a995e389
RH
403{
404 printf ("const char *\n");
6906ba40 405 printf ("get_insn_name (int code)\n");
a995e389 406 printf ("{\n");
a0f0e963
SB
407 printf (" if (code == NOOP_MOVE_INSN_CODE)\n");
408 printf (" return \"NOOP_MOVE\";\n");
409 printf (" else\n");
410 printf (" return insn_data[code].name;\n");
a995e389 411 printf ("}\n");
9db4e0ec 412}
a995e389 413
9db4e0ec 414\f
a995e389
RH
415/* Stores in max_opno the largest operand number present in `part', if
416 that is larger than the previous value of max_opno, and the rest of
417 the operand data into `d->operand[i]'.
9db4e0ec
RK
418
419 THIS_ADDRESS_P is nonzero if the containing rtx was an ADDRESS.
420 THIS_STRICT_LOW is nonzero if the containing rtx was a STRICT_LOW_PART. */
421
422static int max_opno;
423static int num_dups;
9db4e0ec
RK
424
425static void
3d7aafde
AJ
426scan_operands (struct data *d, rtx part, int this_address_p,
427 int this_strict_low)
9db4e0ec 428{
b3694847
SS
429 int i, j;
430 const char *format_ptr;
9db4e0ec
RK
431 int opno;
432
433 if (part == 0)
434 return;
435
436 switch (GET_CODE (part))
437 {
438 case MATCH_OPERAND:
439 opno = XINT (part, 0);
440 if (opno > max_opno)
441 max_opno = opno;
442 if (max_opno >= MAX_MAX_OPERANDS)
5a806d65 443 {
d96a2fcd
RH
444 message_with_line (d->lineno,
445 "maximum number of operands exceeded");
446 have_error = 1;
5a806d65
RK
447 return;
448 }
a995e389 449 if (d->operand[opno].seen)
d96a2fcd
RH
450 {
451 message_with_line (d->lineno,
452 "repeated operand number %d\n", opno);
453 have_error = 1;
454 }
455
a995e389
RH
456 d->operand[opno].seen = 1;
457 d->operand[opno].mode = GET_MODE (part);
458 d->operand[opno].strict_low = this_strict_low;
459 d->operand[opno].predicate = XSTR (part, 1);
665f2503
RK
460 d->operand[opno].constraint = strip_whitespace (XSTR (part, 2));
461 d->operand[opno].n_alternatives
462 = n_occurrences (',', d->operand[opno].constraint) + 1;
a995e389 463 d->operand[opno].address_p = this_address_p;
dfac187e 464 d->operand[opno].eliminable = 1;
9db4e0ec
RK
465 return;
466
467 case MATCH_SCRATCH:
468 opno = XINT (part, 0);
469 if (opno > max_opno)
470 max_opno = opno;
471 if (max_opno >= MAX_MAX_OPERANDS)
5a806d65 472 {
d96a2fcd
RH
473 message_with_line (d->lineno,
474 "maximum number of operands exceeded");
475 have_error = 1;
5a806d65
RK
476 return;
477 }
a995e389 478 if (d->operand[opno].seen)
d96a2fcd
RH
479 {
480 message_with_line (d->lineno,
481 "repeated operand number %d\n", opno);
482 have_error = 1;
483 }
484
a995e389
RH
485 d->operand[opno].seen = 1;
486 d->operand[opno].mode = GET_MODE (part);
487 d->operand[opno].strict_low = 0;
488 d->operand[opno].predicate = "scratch_operand";
665f2503
RK
489 d->operand[opno].constraint = strip_whitespace (XSTR (part, 1));
490 d->operand[opno].n_alternatives
491 = n_occurrences (',', d->operand[opno].constraint) + 1;
a995e389 492 d->operand[opno].address_p = 0;
dfac187e 493 d->operand[opno].eliminable = 0;
9db4e0ec
RK
494 return;
495
496 case MATCH_OPERATOR:
497 case MATCH_PARALLEL:
498 opno = XINT (part, 0);
499 if (opno > max_opno)
500 max_opno = opno;
501 if (max_opno >= MAX_MAX_OPERANDS)
5a806d65 502 {
d96a2fcd
RH
503 message_with_line (d->lineno,
504 "maximum number of operands exceeded");
505 have_error = 1;
5a806d65
RK
506 return;
507 }
a995e389 508 if (d->operand[opno].seen)
d96a2fcd
RH
509 {
510 message_with_line (d->lineno,
511 "repeated operand number %d\n", opno);
512 have_error = 1;
513 }
514
a995e389
RH
515 d->operand[opno].seen = 1;
516 d->operand[opno].mode = GET_MODE (part);
517 d->operand[opno].strict_low = 0;
518 d->operand[opno].predicate = XSTR (part, 1);
519 d->operand[opno].constraint = 0;
520 d->operand[opno].address_p = 0;
dfac187e 521 d->operand[opno].eliminable = 0;
9db4e0ec 522 for (i = 0; i < XVECLEN (part, 2); i++)
a995e389 523 scan_operands (d, XVECEXP (part, 2, i), 0, 0);
9db4e0ec
RK
524 return;
525
526 case MATCH_DUP:
527 case MATCH_OP_DUP:
ed18f94d 528 case MATCH_PAR_DUP:
9db4e0ec 529 ++num_dups;
6d7a1c4c 530 break;
9db4e0ec
RK
531
532 case ADDRESS:
a995e389 533 scan_operands (d, XEXP (part, 0), 1, 0);
9db4e0ec
RK
534 return;
535
536 case STRICT_LOW_PART:
a995e389 537 scan_operands (d, XEXP (part, 0), 0, 1);
9db4e0ec 538 return;
3d7aafde 539
ccd043a9
RL
540 default:
541 break;
9db4e0ec
RK
542 }
543
544 format_ptr = GET_RTX_FORMAT (GET_CODE (part));
545
546 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
547 switch (*format_ptr++)
548 {
549 case 'e':
ccd043a9 550 case 'u':
a995e389 551 scan_operands (d, XEXP (part, i), 0, 0);
9db4e0ec
RK
552 break;
553 case 'E':
554 if (XVEC (part, i) != NULL)
555 for (j = 0; j < XVECLEN (part, i); j++)
a995e389 556 scan_operands (d, XVECEXP (part, i, j), 0, 0);
9db4e0ec
RK
557 break;
558 }
559}
a995e389
RH
560
561/* Compare two operands for content equality. */
562
563static int
3d7aafde 564compare_operands (struct operand_data *d0, struct operand_data *d1)
a995e389 565{
c1b59dce 566 const char *p0, *p1;
a995e389
RH
567
568 p0 = d0->predicate;
569 if (!p0)
570 p0 = "";
571 p1 = d1->predicate;
572 if (!p1)
573 p1 = "";
574 if (strcmp (p0, p1) != 0)
575 return 0;
576
19af6455
BS
577 p0 = d0->constraint;
578 if (!p0)
579 p0 = "";
580 p1 = d1->constraint;
581 if (!p1)
582 p1 = "";
583 if (strcmp (p0, p1) != 0)
584 return 0;
a995e389
RH
585
586 if (d0->mode != d1->mode)
587 return 0;
588
a995e389
RH
589 if (d0->strict_low != d1->strict_low)
590 return 0;
591
dfac187e
BS
592 if (d0->eliminable != d1->eliminable)
593 return 0;
594
a995e389
RH
595 return 1;
596}
597
598/* Scan the list of operands we've already committed to output and either
599 find a subsequence that is the same, or allocate a new one at the end. */
600
601static void
3d7aafde 602place_operands (struct data *d)
a995e389
RH
603{
604 struct operand_data *od, *od2;
605 int i;
606
607 if (d->n_operands == 0)
608 {
609 d->operand_number = 0;
610 return;
611 }
612
613 /* Brute force substring search. */
614 for (od = odata, i = 0; od; od = od->next, i = 0)
615 if (compare_operands (od, &d->operand[0]))
616 {
617 od2 = od->next;
618 i = 1;
619 while (1)
620 {
621 if (i == d->n_operands)
622 goto full_match;
623 if (od2 == NULL)
624 goto partial_match;
625 if (! compare_operands (od2, &d->operand[i]))
626 break;
627 ++i, od2 = od2->next;
628 }
629 }
630
631 /* Either partial match at the end of the list, or no match. In either
632 case, we tack on what operands are remaining to the end of the list. */
633 partial_match:
634 d->operand_number = next_operand_number - i;
635 for (; i < d->n_operands; ++i)
636 {
637 od2 = &d->operand[i];
638 *odata_end = od2;
639 odata_end = &od2->next;
640 od2->index = next_operand_number++;
641 }
642 *odata_end = NULL;
643 return;
644
645 full_match:
646 d->operand_number = od->index;
647 return;
648}
649
9db4e0ec
RK
650\f
651/* Process an assembler template from a define_insn or a define_peephole.
652 It is either the assembler code template, a list of assembler code
653 templates, or C code to generate the assembler code template. */
654
655static void
3d7aafde 656process_template (struct data *d, const char *template)
9db4e0ec 657{
b3694847
SS
658 const char *cp;
659 int i;
9db4e0ec 660
4bbf910e
RH
661 /* Templates starting with * contain straight code to be run. */
662 if (template[0] == '*')
9db4e0ec 663 {
4bbf910e
RH
664 d->template = 0;
665 d->output_format = INSN_OUTPUT_FORMAT_FUNCTION;
9db4e0ec 666
4bbf910e 667 puts ("\nstatic const char *");
6906ba40
KG
668 printf ("output_%d (rtx *operands ATTRIBUTE_UNUSED, rtx insn ATTRIBUTE_UNUSED)\n",
669 d->code_number);
4bbf910e 670 puts ("{");
7445392c 671 print_rtx_ptr_loc (template);
4bbf910e
RH
672 puts (template + 1);
673 puts ("}");
674 }
9db4e0ec
RK
675
676 /* If the assembler code template starts with a @ it is a newline-separated
4bbf910e
RH
677 list of assembler code templates, one for each alternative. */
678 else if (template[0] == '@')
9db4e0ec 679 {
4bbf910e
RH
680 d->template = 0;
681 d->output_format = INSN_OUTPUT_FORMAT_MULTI;
9db4e0ec 682
4bbf910e 683 printf ("\nstatic const char * const output_%d[] = {\n", d->code_number);
9db4e0ec
RK
684
685 for (i = 0, cp = &template[1]; *cp; )
686 {
4112be4a
JJ
687 const char *ep, *sp;
688
6b8b9d7b 689 while (ISSPACE (*cp))
9db4e0ec
RK
690 cp++;
691
4bbf910e 692 printf (" \"");
4112be4a
JJ
693
694 for (ep = sp = cp; !IS_VSPACE (*ep) && *ep != '\0'; ++ep)
695 if (!ISSPACE (*ep))
696 sp = ep + 1;
697
698 if (sp != ep)
699 message_with_line (d->lineno,
700 "trailing whitespace in output template");
701
702 while (cp < sp)
2f013c71
RK
703 {
704 putchar (*cp);
705 cp++;
706 }
9db4e0ec
RK
707
708 printf ("\",\n");
709 i++;
710 }
c6d79bee
JH
711 if (i == 1)
712 message_with_line (d->lineno,
713 "'@' is redundant for output template with single alternative");
714 if (i != d->n_alternatives)
715 {
716 message_with_line (d->lineno,
1f978f5f 717 "wrong number of alternatives in the output template");
c6d79bee
JH
718 have_error = 1;
719 }
9db4e0ec 720
4bbf910e 721 printf ("};\n");
9db4e0ec
RK
722 }
723 else
724 {
4bbf910e
RH
725 d->template = template;
726 d->output_format = INSN_OUTPUT_FORMAT_SINGLE;
9db4e0ec 727 }
9db4e0ec
RK
728}
729\f
730/* Check insn D for consistency in number of constraint alternatives. */
731
732static void
3d7aafde 733validate_insn_alternatives (struct data *d)
9db4e0ec 734{
b3694847 735 int n = 0, start;
a995e389
RH
736
737 /* Make sure all the operands have the same number of alternatives
738 in their constraints. Let N be that number. */
9db4e0ec 739 for (start = 0; start < d->n_operands; start++)
a995e389 740 if (d->operand[start].n_alternatives > 0)
9db4e0ec 741 {
97488870
R
742 int len, i;
743 const char *p;
744 char c;
745 int which_alternative = 0;
746 int alternative_count_unsure = 0;
747
748 for (p = d->operand[start].constraint; (c = *p); p += len)
749 {
750 len = CONSTRAINT_LEN (c, p);
751
752 if (len < 1 || (len > 1 && strchr (",#*+=&%!0123456789", c)))
753 {
754 message_with_line (d->lineno,
755 "invalid length %d for char '%c' in alternative %d of operand %d",
756 len, c, which_alternative, start);
757 len = 1;
758 have_error = 1;
759 }
760
761 if (c == ',')
762 {
763 which_alternative++;
764 continue;
765 }
766
767 for (i = 1; i < len; i++)
768 if (p[i] == '\0')
769 {
770 message_with_line (d->lineno,
771 "NUL in alternative %d of operand %d",
772 which_alternative, start);
773 alternative_count_unsure = 1;
774 break;
775 }
776 else if (strchr (",#*", p[i]))
777 {
778 message_with_line (d->lineno,
779 "'%c' in alternative %d of operand %d",
780 p[i], which_alternative, start);
781 alternative_count_unsure = 1;
782 }
783 }
784 if (alternative_count_unsure)
785 have_error = 1;
786 else if (n == 0)
a995e389
RH
787 n = d->operand[start].n_alternatives;
788 else if (n != d->operand[start].n_alternatives)
d96a2fcd
RH
789 {
790 message_with_line (d->lineno,
791 "wrong number of alternatives in operand %d",
792 start);
793 have_error = 1;
794 }
9db4e0ec 795 }
a995e389 796
9db4e0ec
RK
797 /* Record the insn's overall number of alternatives. */
798 d->n_alternatives = n;
799}
c77e04ae
RH
800
801/* Verify that there are no gaps in operand numbers for INSNs. */
802
803static void
3d7aafde 804validate_insn_operands (struct data *d)
c77e04ae
RH
805{
806 int i;
807
808 for (i = 0; i < d->n_operands; ++i)
809 if (d->operand[i].seen == 0)
810 {
811 message_with_line (d->lineno, "missing operand %d", i);
812 have_error = 1;
813 }
814}
9db4e0ec 815\f
a995e389
RH
816/* Look at a define_insn just read. Assign its code number. Record
817 on idata the template and the number of arguments. If the insn has
818 a hairy output action, output a function for now. */
9db4e0ec
RK
819
820static void
3d7aafde 821gen_insn (rtx insn, int lineno)
9db4e0ec 822{
703ad42b 823 struct data *d = xmalloc (sizeof (struct data));
b3694847 824 int i;
9db4e0ec 825
c88c0d42 826 d->code_number = next_code_number;
9db4e0ec 827 d->index_number = next_index_number;
1e9c8405 828 d->filename = read_rtx_filename;
d96a2fcd 829 d->lineno = lineno;
9db4e0ec
RK
830 if (XSTR (insn, 0)[0])
831 d->name = XSTR (insn, 0);
832 else
833 d->name = 0;
834
835 /* Build up the list in the same order as the insns are seen
836 in the machine description. */
837 d->next = 0;
a995e389
RH
838 *idata_end = d;
839 idata_end = &d->next;
9db4e0ec
RK
840
841 max_opno = -1;
842 num_dups = 0;
a995e389 843 memset (d->operand, 0, sizeof (d->operand));
9db4e0ec
RK
844
845 for (i = 0; i < XVECLEN (insn, 1); i++)
a995e389 846 scan_operands (d, XVECEXP (insn, 1, i), 0, 0);
9db4e0ec
RK
847
848 d->n_operands = max_opno + 1;
849 d->n_dups = num_dups;
850
97488870 851 check_constraint_len ();
c77e04ae 852 validate_insn_operands (d);
9db4e0ec 853 validate_insn_alternatives (d);
a995e389 854 place_operands (d);
1f3b37a3 855 process_template (d, XTMPL (insn, 3));
9db4e0ec
RK
856}
857\f
858/* Look at a define_peephole just read. Assign its code number.
a995e389 859 Record on idata the template and the number of arguments.
9db4e0ec
RK
860 If the insn has a hairy output action, output it now. */
861
862static void
3d7aafde 863gen_peephole (rtx peep, int lineno)
9db4e0ec 864{
703ad42b 865 struct data *d = xmalloc (sizeof (struct data));
b3694847 866 int i;
9db4e0ec 867
c88c0d42 868 d->code_number = next_code_number;
9db4e0ec 869 d->index_number = next_index_number;
1e9c8405 870 d->filename = read_rtx_filename;
d96a2fcd 871 d->lineno = lineno;
9db4e0ec
RK
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;
a995e389
RH
881 num_dups = 0;
882 memset (d->operand, 0, sizeof (d->operand));
883
884 /* Get the number of operands by scanning all the patterns of the
885 peephole optimizer. But ignore all the rest of the information
886 thus obtained. */
9db4e0ec 887 for (i = 0; i < XVECLEN (peep, 0); i++)
a995e389 888 scan_operands (d, XVECEXP (peep, 0, i), 0, 0);
9db4e0ec
RK
889
890 d->n_operands = max_opno + 1;
891 d->n_dups = 0;
892
9db4e0ec 893 validate_insn_alternatives (d);
a995e389 894 place_operands (d);
1f3b37a3 895 process_template (d, XTMPL (peep, 2));
9db4e0ec
RK
896}
897\f
898/* Process a define_expand just read. Assign its code number,
899 only for the purposes of `insn_gen_function'. */
900
901static void
3d7aafde 902gen_expand (rtx insn, int lineno)
9db4e0ec 903{
703ad42b 904 struct data *d = xmalloc (sizeof (struct data));
b3694847 905 int i;
9db4e0ec 906
c88c0d42 907 d->code_number = next_code_number;
9db4e0ec 908 d->index_number = next_index_number;
1e9c8405 909 d->filename = read_rtx_filename;
d96a2fcd 910 d->lineno = lineno;
9db4e0ec
RK
911 if (XSTR (insn, 0)[0])
912 d->name = XSTR (insn, 0);
913 else
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
RK
925
926 /* Scan the operands to get the specified predicates and modes,
927 since expand_binop needs to know them. */
928
9db4e0ec
RK
929 if (XVEC (insn, 1))
930 for (i = 0; i < XVECLEN (insn, 1); i++)
a995e389 931 scan_operands (d, XVECEXP (insn, 1, i), 0, 0);
9db4e0ec
RK
932
933 d->n_operands = max_opno + 1;
934 d->n_dups = num_dups;
9db4e0ec 935 d->template = 0;
4bbf910e 936 d->output_format = INSN_OUTPUT_FORMAT_NONE;
a995e389 937
9db4e0ec 938 validate_insn_alternatives (d);
a995e389 939 place_operands (d);
9db4e0ec
RK
940}
941\f
942/* Process a define_split just read. Assign its code number,
943 only for reasons of consistency and to simplify genrecog. */
944
9db4e0ec 945static void
3d7aafde 946gen_split (rtx split, int lineno)
9db4e0ec 947{
703ad42b 948 struct data *d = xmalloc (sizeof (struct data));
b3694847 949 int i;
9db4e0ec 950
c88c0d42 951 d->code_number = next_code_number;
9db4e0ec 952 d->index_number = next_index_number;
1e9c8405 953 d->filename = read_rtx_filename;
d96a2fcd 954 d->lineno = lineno;
9db4e0ec
RK
955 d->name = 0;
956
957 /* Build up the list in the same order as the insns are seen
958 in the machine description. */
959 d->next = 0;
a995e389
RH
960 *idata_end = d;
961 idata_end = &d->next;
9db4e0ec
RK
962
963 max_opno = -1;
964 num_dups = 0;
a995e389 965 memset (d->operand, 0, sizeof (d->operand));
9db4e0ec 966
a995e389
RH
967 /* Get the number of operands by scanning all the patterns of the
968 split patterns. But ignore all the rest of the information thus
969 obtained. */
9db4e0ec 970 for (i = 0; i < XVECLEN (split, 0); i++)
a995e389 971 scan_operands (d, XVECEXP (split, 0, i), 0, 0);
9db4e0ec
RK
972
973 d->n_operands = max_opno + 1;
9db4e0ec 974 d->n_dups = 0;
42495ca0 975 d->n_alternatives = 0;
9db4e0ec 976 d->template = 0;
4bbf910e 977 d->output_format = INSN_OUTPUT_FORMAT_NONE;
a995e389
RH
978
979 place_operands (d);
9db4e0ec 980}
9db4e0ec 981
3d7aafde 982extern int main (int, char **);
c1b59dce 983
9db4e0ec 984int
3d7aafde 985main (int argc, char **argv)
9db4e0ec
RK
986{
987 rtx desc;
9db4e0ec 988
d80eb1e1
RH
989 progname = "genoutput";
990
04d8aa70 991 if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
c88c0d42 992 return (FATAL_EXIT_CODE);
9db4e0ec 993
9db4e0ec
RK
994 output_prologue ();
995 next_code_number = 0;
996 next_index_number = 0;
9db4e0ec
RK
997
998 /* Read the machine description. */
999
1000 while (1)
1001 {
c88c0d42
CP
1002 int line_no;
1003
1004 desc = read_md_rtx (&line_no, &next_code_number);
1005 if (desc == NULL)
9db4e0ec 1006 break;
9db4e0ec 1007
9db4e0ec 1008 if (GET_CODE (desc) == DEFINE_INSN)
d96a2fcd 1009 gen_insn (desc, line_no);
9db4e0ec 1010 if (GET_CODE (desc) == DEFINE_PEEPHOLE)
d96a2fcd 1011 gen_peephole (desc, line_no);
9db4e0ec 1012 if (GET_CODE (desc) == DEFINE_EXPAND)
d96a2fcd 1013 gen_expand (desc, line_no);
ede7cd44 1014 if (GET_CODE (desc) == DEFINE_SPLIT
3d7aafde 1015 || GET_CODE (desc) == DEFINE_PEEPHOLE2)
d96a2fcd 1016 gen_split (desc, line_no);
9db4e0ec
RK
1017 next_index_number++;
1018 }
1019
a995e389 1020 printf("\n\n");
a995e389
RH
1021 output_operand_data ();
1022 output_insn_data ();
1023 output_get_insn_name ();
9db4e0ec
RK
1024
1025 fflush (stdout);
c1b59dce 1026 return (ferror (stdout) != 0 || have_error
6a270722 1027 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
9db4e0ec
RK
1028}
1029
665f2503
RK
1030/* Return the number of occurrences of character C in string S or
1031 -1 if S is the null string. */
1032
9db4e0ec 1033static int
3d7aafde 1034n_occurrences (int c, const char *s)
9db4e0ec
RK
1035{
1036 int n = 0;
665f2503
RK
1037
1038 if (s == 0 || *s == '\0')
1039 return -1;
1040
9db4e0ec
RK
1041 while (*s)
1042 n += (*s++ == c);
665f2503 1043
9db4e0ec
RK
1044 return n;
1045}
88a56c2e 1046
665f2503
RK
1047/* Remove whitespace in `s' by moving up characters until the end.
1048 Return a new string. */
1049
1050static const char *
3d7aafde 1051strip_whitespace (const char *s)
88a56c2e 1052{
665f2503
RK
1053 char *p, *q;
1054 char ch;
1055
1056 if (s == 0)
1057 return 0;
88a56c2e 1058
665f2503 1059 p = q = xmalloc (strlen (s) + 1);
88a56c2e
HPN
1060 while ((ch = *s++) != '\0')
1061 if (! ISSPACE (ch))
1062 *p++ = ch;
1063
1064 *p = '\0';
665f2503 1065 return q;
88a56c2e 1066}
97488870
R
1067
1068/* Verify that DEFAULT_CONSTRAINT_LEN is used properly and not
1069 tampered with. This isn't bullet-proof, but it should catch
1070 most genuine mistakes. */
1071static void
3d7aafde 1072check_constraint_len (void)
97488870
R
1073{
1074 const char *p;
1075 int d;
1076
1077 for (p = ",#*+=&%!1234567890"; *p; p++)
1078 for (d = -9; d < 9; d++)
b2d59f6f 1079 gcc_assert (constraint_len (p, d) == d);
97488870
R
1080}
1081
1082static int
3d7aafde 1083constraint_len (const char *p, int genoutput_default_constraint_len)
97488870
R
1084{
1085 /* Check that we still match defaults.h . First we do a generation-time
1086 check that fails if the value is not the expected one... */
b2d59f6f 1087 gcc_assert (DEFAULT_CONSTRAINT_LEN (*p, p) == 1);
2067c116 1088 /* And now a compile-time check that should give a diagnostic if the
97488870
R
1089 definition doesn't exactly match. */
1090#define DEFAULT_CONSTRAINT_LEN(C,STR) 1
1091 /* Now re-define DEFAULT_CONSTRAINT_LEN so that we can verify it is
1092 being used. */
1093#undef DEFAULT_CONSTRAINT_LEN
1094#define DEFAULT_CONSTRAINT_LEN(C,STR) \
1095 ((C) != *p || STR != p ? -1 : genoutput_default_constraint_len)
1096 return CONSTRAINT_LEN (*p, p);
1097 /* And set it back. */
1098#undef DEFAULT_CONSTRAINT_LEN
1099#define DEFAULT_CONSTRAINT_LEN(C,STR) 1
1100}
This page took 3.331171 seconds and 5 git commands to generate.