]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/genoutput.c
Update copyright years.
[thirdparty/gcc.git] / gcc / genoutput.c
CommitLineData
e1a1a29d 1/* Generate code from to output assembler insns as recognized from rtl.
f1717362 2 Copyright (C) 1987-2016 Free Software Foundation, Inc.
e1a1a29d 3
f12b58b3 4This file is part of GCC.
e1a1a29d 5
f12b58b3 6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8c4c00c1 8Software Foundation; either version 3, or (at your option) any later
f12b58b3 9version.
e1a1a29d 10
f12b58b3 11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
e1a1a29d 15
16You should have received a copy of the GNU General Public License
8c4c00c1 17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
e1a1a29d 19
20
21/* This program reads the machine description for the compiler target machine
22 and produces a file containing these things:
23
f2956fc5 24 1. An array of `struct insn_data_d', which is indexed by insn code number,
6357eaae 25 which contains:
e1a1a29d 26
6357eaae 27 a. `name' is the name for that pattern. Nameless patterns are
28 given a name.
29
ae9660c8 30 b. `output' hold either the output template, an array of output
31 templates, or an output function.
32
33 c. `genfun' is the function to generate a body for that pattern,
6357eaae 34 given operands as arguments.
35
ae9660c8 36 d. `n_operands' is the number of distinct operands in the pattern
6357eaae 37 for that insn,
e1a1a29d 38
ae9660c8 39 e. `n_dups' is the number of match_dup's that appear in the insn's
6357eaae 40 pattern. This says how many elements of `recog_data.dup_loc' are
41 significant after an insn has been recognized.
e1a1a29d 42
ae9660c8 43 f. `n_alternatives' is the number of alternatives in the constraints
6357eaae 44 of each pattern.
e1a1a29d 45
ae9660c8 46 g. `output_format' tells what type of thing `output' is.
47
6357eaae 48 h. `operand' is the base of an array of operand data for the insn.
e1a1a29d 49
6357eaae 50 2. An array of `struct insn_operand data', used by `operand' above.
e1a1a29d 51
6357eaae 52 a. `predicate', an int-valued function, is the match_operand predicate
53 for this operand.
e1a1a29d 54
026d3868 55 b. `constraint' is the constraint for this operand.
e1a1a29d 56
6357eaae 57 c. `address_p' indicates that the operand appears within ADDRESS
026d3868 58 rtx's.
e1a1a29d 59
6357eaae 60 d. `mode' is the machine mode that that operand is supposed to have.
e1a1a29d 61
6357eaae 62 e. `strict_low', is nonzero for operands contained in a STRICT_LOW_PART.
e1a1a29d 63
6b21946f 64 f. `eliminable', is nonzero for operands that are matched normally by
65 MATCH_OPERAND; it is zero for operands that should not be changed during
66 register elimination such as MATCH_OPERATORs.
67
48eb616d 68 g. `allows_mem', is true for operands that accept MEM rtxes.
69
6357eaae 70 The code number of an insn is simply its position in the machine
71 description; code numbers are assigned sequentially to entries in
72 the description, starting with code number 0.
e1a1a29d 73
6357eaae 74 Thus, the following entry in the machine description
e1a1a29d 75
76 (define_insn "clrdf"
77 [(set (match_operand:DF 0 "general_operand" "")
78 (const_int 0))]
79 ""
80 "clrd %0")
81
6357eaae 82 assuming it is the 25th entry present, would cause
83 insn_data[24].template to be "clrd %0", and
84 insn_data[24].n_operands to be 1. */
e1a1a29d 85\f
805e22b2 86#include "bconfig.h"
5ce88198 87#include "system.h"
805e22b2 88#include "coretypes.h"
89#include "tm.h"
e1a1a29d 90#include "rtl.h"
05806416 91#include "errors.h"
960ebfe7 92#include "read-md.h"
c5ddd6b5 93#include "gensupport.h"
e1a1a29d 94
6357eaae 95/* No instruction can have more operands than this. Sorry for this
96 arbitrary limit, but what machine will have an instruction with
97 this many operands? */
e1a1a29d 98
99#define MAX_MAX_OPERANDS 40
100
69449463 101static char general_mem[] = { TARGET_MEM_CONSTRAINT, 0 };
102
1a97be37 103static int n_occurrences (int, const char *);
104static const char *strip_whitespace (const char *);
e1a1a29d 105
6357eaae 106/* This counts all operands used in the md file. The first is null. */
107
108static int next_operand_number = 1;
109
110/* Record in this chain all information about the operands we will output. */
111
112struct operand_data
113{
114 struct operand_data *next;
115 int index;
947491b7 116 const char *predicate;
117 const char *constraint;
3754d046 118 machine_mode mode;
6357eaae 119 unsigned char n_alternatives;
120 char address_p;
121 char strict_low;
6b21946f 122 char eliminable;
6357eaae 123 char seen;
124};
125
126/* Begin with a null operand at index 0. */
127
128static struct operand_data null_operand =
129{
087cf8a6 130 0, 0, "", "", VOIDmode, 0, 0, 0, 0, 0
6357eaae 131};
132
133static struct operand_data *odata = &null_operand;
134static struct operand_data **odata_end = &null_operand.next;
135
ae9660c8 136/* Must match the constants in recog.h. */
137
138#define INSN_OUTPUT_FORMAT_NONE 0 /* abort */
139#define INSN_OUTPUT_FORMAT_SINGLE 1 /* const char * */
140#define INSN_OUTPUT_FORMAT_MULTI 2 /* const char * const * */
141#define INSN_OUTPUT_FORMAT_FUNCTION 3 /* const char * (*)(...) */
142
e1a1a29d 143/* Record in this chain all information that we will output,
144 associated with the code number of the insn. */
145
146struct data
147{
6357eaae 148 struct data *next;
947491b7 149 const char *name;
2657a7d5 150 const char *template_code;
48bf1a90 151 file_location loc;
6357eaae 152 int code_number;
cf85f835 153 int n_generator_args; /* Number of arguments passed to generator */
e1a1a29d 154 int n_operands; /* Number of operands this insn recognizes */
155 int n_dups; /* Number times match_dup appears in pattern */
156 int n_alternatives; /* Number of alternatives in each constraint */
6357eaae 157 int operand_number; /* Operand index in the big array. */
ae9660c8 158 int output_format; /* INSN_OUTPUT_FORMAT_*. */
6357eaae 159 struct operand_data operand[MAX_MAX_OPERANDS];
e1a1a29d 160};
161
6357eaae 162/* This variable points to the first link in the insn chain. */
48bf1a90 163static struct data *idata;
5ab7f285 164
165/* This variable points to the end of the insn chain. This is where
166 everything relevant from the machien description is appended to. */
48bf1a90 167static struct data **idata_end;
e1a1a29d 168
e1a1a29d 169\f
1a97be37 170static void output_prologue (void);
1a97be37 171static void output_operand_data (void);
172static void output_insn_data (void);
173static void output_get_insn_name (void);
174static void scan_operands (struct data *, rtx, int, int);
175static int compare_operands (struct operand_data *,
176 struct operand_data *);
177static void place_operands (struct data *);
178static void process_template (struct data *, const char *);
179static void validate_insn_alternatives (struct data *);
180static void validate_insn_operands (struct data *);
026d3868 181
026d3868 182struct constraint_data
183{
184 struct constraint_data *next_this_letter;
48bf1a90 185 file_location loc;
026d3868 186 unsigned int namelen;
48bf1a90 187 char name[1];
026d3868 188};
189
69449463 190/* All machine-independent constraint characters (except digits) that
191 are handled outside the define*_constraint mechanism. */
ed6272f7 192static const char indep_constraints[] = ",=+%*?!^$#&g";
026d3868 193
194static struct constraint_data *
195constraints_by_letter_table[1 << CHAR_BIT];
196
48bf1a90 197static int mdep_constraint_len (const char *, file_location, int);
c04601c1 198static void note_constraint (md_rtx_info *);
12693c81 199\f
e1a1a29d 200static void
1a97be37 201output_prologue (void)
e1a1a29d 202{
e1a1a29d 203 printf ("/* Generated automatically by the program `genoutput'\n\
36deab5f 204 from the machine description file `md'. */\n\n");
e1a1a29d 205
206 printf ("#include \"config.h\"\n");
9aaa1fcc 207 printf ("#include \"system.h\"\n");
805e22b2 208 printf ("#include \"coretypes.h\"\n");
9ef16211 209 printf ("#include \"backend.h\"\n");
d040a5b0 210 printf ("#include \"predict.h\"\n");
9ef16211 211 printf ("#include \"tree.h\"\n");
212 printf ("#include \"rtl.h\"\n");
3ef9782d 213 printf ("#include \"flags.h\"\n");
b20a8bb4 214 printf ("#include \"alias.h\"\n");
9ed99284 215 printf ("#include \"varasm.h\"\n");
216 printf ("#include \"stor-layout.h\"\n");
217 printf ("#include \"calls.h\"\n");
d53441c8 218 printf ("#include \"insn-config.h\"\n");
219 printf ("#include \"expmed.h\"\n");
220 printf ("#include \"dojump.h\"\n");
221 printf ("#include \"explow.h\"\n");
222 printf ("#include \"emit-rtl.h\"\n");
223 printf ("#include \"stmt.h\"\n");
9ff0b0fd 224 printf ("#include \"expr.h\"\n");
d8fc4d0b 225 printf ("#include \"insn-codes.h\"\n");
7953c610 226 printf ("#include \"tm_p.h\"\n");
e1a1a29d 227 printf ("#include \"regs.h\"\n");
e1a1a29d 228 printf ("#include \"conditions.h\"\n");
e1a1a29d 229 printf ("#include \"insn-attr.h\"\n\n");
e1a1a29d 230 printf ("#include \"recog.h\"\n\n");
c18cb818 231 printf ("#include \"diagnostic-core.h\"\n");
e1a1a29d 232 printf ("#include \"output.h\"\n");
805e22b2 233 printf ("#include \"target.h\"\n");
a014ec0f 234 printf ("#include \"tm-constrs.h\"\n");
e1a1a29d 235}
236
6357eaae 237static void
1a97be37 238output_operand_data (void)
6357eaae 239{
19cb6b50 240 struct operand_data *d;
6357eaae 241
242 printf ("\nstatic const struct insn_operand_data operand_data[] = \n{\n");
243
244 for (d = odata; d; d = d->next)
e1a1a29d 245 {
48eb616d 246 struct pred_data *pred;
247
6357eaae 248 printf (" {\n");
249
250 printf (" %s,\n",
251 d->predicate && d->predicate[0] ? d->predicate : "0");
252
15b50aec 253 printf (" \"%s\",\n", d->constraint ? d->constraint : "");
e1a1a29d 254
6357eaae 255 printf (" %smode,\n", GET_MODE_NAME (d->mode));
256
6b21946f 257 printf (" %d,\n", d->strict_low);
258
a67a82ef 259 printf (" %d,\n", d->constraint == NULL ? 1 : 0);
260
48eb616d 261 printf (" %d,\n", d->eliminable);
262
263 pred = NULL;
264 if (d->predicate)
265 pred = lookup_predicate (d->predicate);
266 printf (" %d\n", pred && pred->codes[MEM]);
6357eaae 267
9af5ce0c 268 printf (" },\n");
6357eaae 269 }
9af5ce0c 270 printf ("};\n\n\n");
6357eaae 271}
272
273static void
1a97be37 274output_insn_data (void)
6357eaae 275{
19cb6b50 276 struct data *d;
6357eaae 277 int name_offset = 0;
278 int next_name_offset;
279 const char * last_name = 0;
280 const char * next_name = 0;
19cb6b50 281 struct data *n;
6357eaae 282
283 for (n = idata, next_name_offset = 1; n; n = n->next, next_name_offset++)
284 if (n->name)
e1a1a29d 285 {
6357eaae 286 next_name = n->name;
287 break;
e1a1a29d 288 }
e1a1a29d 289
48b3d385 290 printf ("#if GCC_VERSION >= 2007\n__extension__\n#endif\n");
f2956fc5 291 printf ("\nconst struct insn_data_d insn_data[] = \n{\n");
e1a1a29d 292
6357eaae 293 for (d = idata; d; d = d->next)
e1a1a29d 294 {
48bf1a90 295 printf (" /* %s:%d */\n", d->loc.filename, d->loc.lineno);
6357eaae 296 printf (" {\n");
297
298 if (d->name)
e1a1a29d 299 {
6357eaae 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++)
e1a1a29d 306 {
6357eaae 307 if (n->name)
308 {
309 next_name = n->name;
310 break;
311 }
e1a1a29d 312 }
e1a1a29d 313 }
6357eaae 314 else
e1a1a29d 315 {
6357eaae 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);
e1a1a29d 323 }
e1a1a29d 324
ae9660c8 325 switch (d->output_format)
326 {
327 case INSN_OUTPUT_FORMAT_NONE:
a88d399f 328 printf ("#if HAVE_DESIGNATED_UNION_INITIALIZERS\n");
48b3d385 329 printf (" { 0 },\n");
330 printf ("#else\n");
331 printf (" { 0, 0, 0 },\n");
332 printf ("#endif\n");
ae9660c8 333 break;
334 case INSN_OUTPUT_FORMAT_SINGLE:
4062b755 335 {
2657a7d5 336 const char *p = d->template_code;
4062b755 337 char prev = 0;
1a97be37 338
a88d399f 339 printf ("#if HAVE_DESIGNATED_UNION_INITIALIZERS\n");
48b3d385 340 printf (" { .single =\n");
341 printf ("#else\n");
342 printf (" {\n");
343 printf ("#endif\n");
4062b755 344 printf (" \"");
345 while (*p)
346 {
337057dd 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 }
4062b755 354 else
355 putchar (*p);
356 prev = *p;
357 ++p;
358 }
359 printf ("\",\n");
a88d399f 360 printf ("#if HAVE_DESIGNATED_UNION_INITIALIZERS\n");
48b3d385 361 printf (" },\n");
362 printf ("#else\n");
363 printf (" 0, 0 },\n");
364 printf ("#endif\n");
4062b755 365 }
ae9660c8 366 break;
367 case INSN_OUTPUT_FORMAT_MULTI:
a88d399f 368 printf ("#if HAVE_DESIGNATED_UNION_INITIALIZERS\n");
48b3d385 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;
ae9660c8 374 case INSN_OUTPUT_FORMAT_FUNCTION:
a88d399f 375 printf ("#if HAVE_DESIGNATED_UNION_INITIALIZERS\n");
48b3d385 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");
ae9660c8 380 break;
381 default:
e0a4c0c2 382 gcc_unreachable ();
ae9660c8 383 }
6357eaae 384
385 if (d->name && d->name[0] != '*')
3d953cb1 386 printf (" { (insn_gen_fn::stored_funcptr) gen_%s },\n", d->name);
6357eaae 387 else
3d953cb1 388 printf (" { 0 },\n");
6357eaae 389
390 printf (" &operand_data[%d],\n", d->operand_number);
cf85f835 391 printf (" %d,\n", d->n_generator_args);
6357eaae 392 printf (" %d,\n", d->n_operands);
393 printf (" %d,\n", d->n_dups);
ae9660c8 394 printf (" %d,\n", d->n_alternatives);
395 printf (" %d\n", d->output_format);
6357eaae 396
9af5ce0c 397 printf (" },\n");
e1a1a29d 398 }
6357eaae 399 printf ("};\n\n\n");
400}
e1a1a29d 401
6357eaae 402static void
1a97be37 403output_get_insn_name (void)
6357eaae 404{
405 printf ("const char *\n");
69dc4d00 406 printf ("get_insn_name (int code)\n");
6357eaae 407 printf ("{\n");
4951824a 408 printf (" if (code == NOOP_MOVE_INSN_CODE)\n");
409 printf (" return \"NOOP_MOVE\";\n");
410 printf (" else\n");
411 printf (" return insn_data[code].name;\n");
6357eaae 412 printf ("}\n");
e1a1a29d 413}
6357eaae 414
e1a1a29d 415\f
cf85f835 416/* Stores the operand data into `d->operand[i]'.
e1a1a29d 417
418 THIS_ADDRESS_P is nonzero if the containing rtx was an ADDRESS.
419 THIS_STRICT_LOW is nonzero if the containing rtx was a STRICT_LOW_PART. */
420
e1a1a29d 421static void
1a97be37 422scan_operands (struct data *d, rtx part, int this_address_p,
423 int this_strict_low)
e1a1a29d 424{
19cb6b50 425 int i, j;
426 const char *format_ptr;
e1a1a29d 427 int opno;
428
429 if (part == 0)
430 return;
431
432 switch (GET_CODE (part))
433 {
434 case MATCH_OPERAND:
435 opno = XINT (part, 0);
cf85f835 436 if (opno >= MAX_MAX_OPERANDS)
a29c013c 437 {
48bf1a90 438 error_at (d->loc, "maximum number of operands exceeded");
a29c013c 439 return;
440 }
6357eaae 441 if (d->operand[opno].seen)
48bf1a90 442 error_at (d->loc, "repeated operand number %d\n", opno);
36deab5f 443
6357eaae 444 d->operand[opno].seen = 1;
445 d->operand[opno].mode = GET_MODE (part);
446 d->operand[opno].strict_low = this_strict_low;
447 d->operand[opno].predicate = XSTR (part, 1);
5d844ba2 448 d->operand[opno].constraint = strip_whitespace (XSTR (part, 2));
449 d->operand[opno].n_alternatives
450 = n_occurrences (',', d->operand[opno].constraint) + 1;
6357eaae 451 d->operand[opno].address_p = this_address_p;
6b21946f 452 d->operand[opno].eliminable = 1;
e1a1a29d 453 return;
454
455 case MATCH_SCRATCH:
456 opno = XINT (part, 0);
cf85f835 457 if (opno >= MAX_MAX_OPERANDS)
a29c013c 458 {
48bf1a90 459 error_at (d->loc, "maximum number of operands exceeded");
a29c013c 460 return;
461 }
6357eaae 462 if (d->operand[opno].seen)
48bf1a90 463 error_at (d->loc, "repeated operand number %d\n", opno);
36deab5f 464
6357eaae 465 d->operand[opno].seen = 1;
466 d->operand[opno].mode = GET_MODE (part);
467 d->operand[opno].strict_low = 0;
468 d->operand[opno].predicate = "scratch_operand";
5d844ba2 469 d->operand[opno].constraint = strip_whitespace (XSTR (part, 1));
470 d->operand[opno].n_alternatives
471 = n_occurrences (',', d->operand[opno].constraint) + 1;
6357eaae 472 d->operand[opno].address_p = 0;
6b21946f 473 d->operand[opno].eliminable = 0;
e1a1a29d 474 return;
475
476 case MATCH_OPERATOR:
477 case MATCH_PARALLEL:
478 opno = XINT (part, 0);
cf85f835 479 if (opno >= MAX_MAX_OPERANDS)
a29c013c 480 {
48bf1a90 481 error_at (d->loc, "maximum number of operands exceeded");
a29c013c 482 return;
483 }
6357eaae 484 if (d->operand[opno].seen)
48bf1a90 485 error_at (d->loc, "repeated operand number %d\n", opno);
36deab5f 486
6357eaae 487 d->operand[opno].seen = 1;
488 d->operand[opno].mode = GET_MODE (part);
489 d->operand[opno].strict_low = 0;
490 d->operand[opno].predicate = XSTR (part, 1);
491 d->operand[opno].constraint = 0;
492 d->operand[opno].address_p = 0;
6b21946f 493 d->operand[opno].eliminable = 0;
e1a1a29d 494 for (i = 0; i < XVECLEN (part, 2); i++)
6357eaae 495 scan_operands (d, XVECEXP (part, 2, i), 0, 0);
e1a1a29d 496 return;
497
e1a1a29d 498 case STRICT_LOW_PART:
6357eaae 499 scan_operands (d, XEXP (part, 0), 0, 1);
e1a1a29d 500 return;
1a97be37 501
3ef9782d 502 default:
503 break;
e1a1a29d 504 }
505
506 format_ptr = GET_RTX_FORMAT (GET_CODE (part));
507
508 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
509 switch (*format_ptr++)
510 {
511 case 'e':
3ef9782d 512 case 'u':
6357eaae 513 scan_operands (d, XEXP (part, i), 0, 0);
e1a1a29d 514 break;
515 case 'E':
516 if (XVEC (part, i) != NULL)
517 for (j = 0; j < XVECLEN (part, i); j++)
6357eaae 518 scan_operands (d, XVECEXP (part, i, j), 0, 0);
e1a1a29d 519 break;
520 }
521}
6357eaae 522
523/* Compare two operands for content equality. */
524
525static int
1a97be37 526compare_operands (struct operand_data *d0, struct operand_data *d1)
6357eaae 527{
947491b7 528 const char *p0, *p1;
6357eaae 529
530 p0 = d0->predicate;
531 if (!p0)
532 p0 = "";
533 p1 = d1->predicate;
534 if (!p1)
535 p1 = "";
536 if (strcmp (p0, p1) != 0)
537 return 0;
538
15b50aec 539 p0 = d0->constraint;
540 if (!p0)
541 p0 = "";
542 p1 = d1->constraint;
543 if (!p1)
544 p1 = "";
545 if (strcmp (p0, p1) != 0)
546 return 0;
6357eaae 547
548 if (d0->mode != d1->mode)
549 return 0;
550
6357eaae 551 if (d0->strict_low != d1->strict_low)
552 return 0;
553
6b21946f 554 if (d0->eliminable != d1->eliminable)
555 return 0;
556
6357eaae 557 return 1;
558}
559
560/* Scan the list of operands we've already committed to output and either
561 find a subsequence that is the same, or allocate a new one at the end. */
562
563static void
1a97be37 564place_operands (struct data *d)
6357eaae 565{
566 struct operand_data *od, *od2;
567 int i;
568
569 if (d->n_operands == 0)
570 {
571 d->operand_number = 0;
572 return;
573 }
574
575 /* Brute force substring search. */
576 for (od = odata, i = 0; od; od = od->next, i = 0)
577 if (compare_operands (od, &d->operand[0]))
578 {
579 od2 = od->next;
580 i = 1;
581 while (1)
582 {
583 if (i == d->n_operands)
584 goto full_match;
585 if (od2 == NULL)
586 goto partial_match;
587 if (! compare_operands (od2, &d->operand[i]))
588 break;
589 ++i, od2 = od2->next;
590 }
591 }
592
593 /* Either partial match at the end of the list, or no match. In either
594 case, we tack on what operands are remaining to the end of the list. */
595 partial_match:
596 d->operand_number = next_operand_number - i;
597 for (; i < d->n_operands; ++i)
598 {
599 od2 = &d->operand[i];
600 *odata_end = od2;
601 odata_end = &od2->next;
602 od2->index = next_operand_number++;
603 }
604 *odata_end = NULL;
605 return;
606
607 full_match:
608 d->operand_number = od->index;
609 return;
610}
611
e1a1a29d 612\f
613/* Process an assembler template from a define_insn or a define_peephole.
614 It is either the assembler code template, a list of assembler code
615 templates, or C code to generate the assembler code template. */
616
617static void
2657a7d5 618process_template (struct data *d, const char *template_code)
e1a1a29d 619{
19cb6b50 620 const char *cp;
621 int i;
e1a1a29d 622
ae9660c8 623 /* Templates starting with * contain straight code to be run. */
2657a7d5 624 if (template_code[0] == '*')
e1a1a29d 625 {
2657a7d5 626 d->template_code = 0;
ae9660c8 627 d->output_format = INSN_OUTPUT_FORMAT_FUNCTION;
e1a1a29d 628
ae9660c8 629 puts ("\nstatic const char *");
bf59a32d 630 printf ("output_%d (rtx *operands ATTRIBUTE_UNUSED, rtx_insn *insn ATTRIBUTE_UNUSED)\n",
69dc4d00 631 d->code_number);
ae9660c8 632 puts ("{");
77c2564f 633 print_md_ptr_loc (template_code);
2657a7d5 634 puts (template_code + 1);
ae9660c8 635 puts ("}");
636 }
e1a1a29d 637
638 /* If the assembler code template starts with a @ it is a newline-separated
ae9660c8 639 list of assembler code templates, one for each alternative. */
2657a7d5 640 else if (template_code[0] == '@')
e1a1a29d 641 {
66799bd7 642 int found_star = 0;
e1a1a29d 643
66799bd7 644 for (cp = &template_code[1]; *cp; )
645 {
646 while (ISSPACE (*cp))
647 cp++;
648 if (*cp == '*')
649 found_star = 1;
650 while (!IS_VSPACE (*cp) && *cp != '\0')
651 ++cp;
652 }
653 d->template_code = 0;
654 if (found_star)
655 {
656 d->output_format = INSN_OUTPUT_FORMAT_FUNCTION;
657 puts ("\nstatic const char *");
658 printf ("output_%d (rtx *operands ATTRIBUTE_UNUSED, "
bf59a32d 659 "rtx_insn *insn ATTRIBUTE_UNUSED)\n", d->code_number);
66799bd7 660 puts ("{");
661 puts (" switch (which_alternative)\n {");
662 }
663 else
664 {
665 d->output_format = INSN_OUTPUT_FORMAT_MULTI;
666 printf ("\nstatic const char * const output_%d[] = {\n",
667 d->code_number);
668 }
e1a1a29d 669
2657a7d5 670 for (i = 0, cp = &template_code[1]; *cp; )
e1a1a29d 671 {
66799bd7 672 const char *ep, *sp, *bp;
742e47a0 673
337057dd 674 while (ISSPACE (*cp))
e1a1a29d 675 cp++;
676
66799bd7 677 bp = cp;
678 if (found_star)
679 {
680 printf (" case %d:", i);
681 if (*cp == '*')
682 {
683 printf ("\n ");
684 cp++;
685 }
686 else
687 printf (" return \"");
688 }
689 else
690 printf (" \"");
742e47a0 691
692 for (ep = sp = cp; !IS_VSPACE (*ep) && *ep != '\0'; ++ep)
693 if (!ISSPACE (*ep))
694 sp = ep + 1;
695
696 if (sp != ep)
48bf1a90 697 message_at (d->loc, "trailing whitespace in output template");
742e47a0 698
699 while (cp < sp)
534fd0c8 700 {
701 putchar (*cp);
702 cp++;
703 }
e1a1a29d 704
66799bd7 705 if (!found_star)
706 puts ("\",");
707 else if (*bp != '*')
708 puts ("\";");
709 else
710 {
711 /* The usual action will end with a return.
712 If there is neither break or return at the end, this is
713 assumed to be intentional; this allows to have multiple
714 consecutive alternatives share some code. */
715 puts ("");
716 }
e1a1a29d 717 i++;
718 }
c21cb186 719 if (i == 1)
48bf1a90 720 message_at (d->loc, "'@' is redundant for output template with"
721 " single alternative");
c21cb186 722 if (i != d->n_alternatives)
48bf1a90 723 error_at (d->loc, "wrong number of alternatives in the output"
724 " template");
e1a1a29d 725
66799bd7 726 if (found_star)
727 puts (" default: gcc_unreachable ();\n }\n}");
728 else
729 printf ("};\n");
e1a1a29d 730 }
731 else
732 {
2657a7d5 733 d->template_code = template_code;
ae9660c8 734 d->output_format = INSN_OUTPUT_FORMAT_SINGLE;
e1a1a29d 735 }
e1a1a29d 736}
737\f
738/* Check insn D for consistency in number of constraint alternatives. */
739
740static void
1a97be37 741validate_insn_alternatives (struct data *d)
e1a1a29d 742{
19cb6b50 743 int n = 0, start;
6357eaae 744
745 /* Make sure all the operands have the same number of alternatives
746 in their constraints. Let N be that number. */
e1a1a29d 747 for (start = 0; start < d->n_operands; start++)
6357eaae 748 if (d->operand[start].n_alternatives > 0)
e1a1a29d 749 {
48ea5577 750 int len, i;
751 const char *p;
752 char c;
753 int which_alternative = 0;
754 int alternative_count_unsure = 0;
ffcd6b16 755 bool seen_write = false;
48ea5577 756
757 for (p = d->operand[start].constraint; (c = *p); p += len)
758 {
205c3b0a 759 if ((c == '%' || c == '=' || c == '+')
760 && p != d->operand[start].constraint)
48bf1a90 761 error_at (d->loc, "character '%c' can only be used at the"
762 " beginning of a constraint string", c);
ffcd6b16 763
764 if (c == '=' || c == '+')
765 seen_write = true;
766
767 /* Earlyclobber operands must always be marked write-only
768 or read/write. */
769 if (!seen_write && c == '&')
48bf1a90 770 error_at (d->loc, "earlyclobber operands may not be"
771 " read-only in alternative %d", which_alternative);
ffcd6b16 772
026d3868 773 if (ISSPACE (c) || strchr (indep_constraints, c))
774 len = 1;
775 else if (ISDIGIT (c))
776 {
777 const char *q = p;
778 do
779 q++;
780 while (ISDIGIT (*q));
781 len = q - p;
782 }
783 else
48bf1a90 784 len = mdep_constraint_len (p, d->loc, start);
48ea5577 785
786 if (c == ',')
787 {
788 which_alternative++;
789 continue;
790 }
791
792 for (i = 1; i < len; i++)
793 if (p[i] == '\0')
794 {
48bf1a90 795 error_at (d->loc, "NUL in alternative %d of operand %d",
796 which_alternative, start);
48ea5577 797 alternative_count_unsure = 1;
798 break;
799 }
800 else if (strchr (",#*", p[i]))
801 {
48bf1a90 802 error_at (d->loc, "'%c' in alternative %d of operand %d",
803 p[i], which_alternative, start);
48ea5577 804 alternative_count_unsure = 1;
805 }
806 }
b638f5c8 807 if (!alternative_count_unsure)
36deab5f 808 {
b638f5c8 809 if (n == 0)
810 n = d->operand[start].n_alternatives;
811 else if (n != d->operand[start].n_alternatives)
48bf1a90 812 error_at (d->loc, "wrong number of alternatives in operand %d",
813 start);
36deab5f 814 }
e1a1a29d 815 }
6357eaae 816
e1a1a29d 817 /* Record the insn's overall number of alternatives. */
818 d->n_alternatives = n;
819}
dd193d7c 820
821/* Verify that there are no gaps in operand numbers for INSNs. */
822
823static void
1a97be37 824validate_insn_operands (struct data *d)
dd193d7c 825{
826 int i;
827
828 for (i = 0; i < d->n_operands; ++i)
829 if (d->operand[i].seen == 0)
48bf1a90 830 error_at (d->loc, "missing operand %d", i);
dd193d7c 831}
cbb955b0 832
833static void
834validate_optab_operands (struct data *d)
835{
836 if (!d->name || d->name[0] == '\0' || d->name[0] == '*')
837 return;
838
839 /* Miscellaneous tests. */
840 if (strncmp (d->name, "cstore", 6) == 0
841 && d->name[strlen (d->name) - 1] == '4'
842 && d->operand[0].mode == VOIDmode)
843 {
48bf1a90 844 message_at (d->loc, "missing mode for operand 0 of cstore");
cbb955b0 845 have_error = 1;
846 }
847}
e1a1a29d 848\f
6357eaae 849/* Look at a define_insn just read. Assign its code number. Record
850 on idata the template and the number of arguments. If the insn has
851 a hairy output action, output a function for now. */
e1a1a29d 852
853static void
c04601c1 854gen_insn (md_rtx_info *info)
e1a1a29d 855{
cf85f835 856 struct pattern_stats stats;
c04601c1 857 rtx insn = info->def;
48bf1a90 858 data *d = new data;
19cb6b50 859 int i;
e1a1a29d 860
c04601c1 861 d->code_number = info->index;
862 d->loc = info->loc;
e1a1a29d 863 if (XSTR (insn, 0)[0])
864 d->name = XSTR (insn, 0);
865 else
866 d->name = 0;
867
868 /* Build up the list in the same order as the insns are seen
869 in the machine description. */
870 d->next = 0;
6357eaae 871 *idata_end = d;
872 idata_end = &d->next;
e1a1a29d 873
6357eaae 874 memset (d->operand, 0, sizeof (d->operand));
e1a1a29d 875
876 for (i = 0; i < XVECLEN (insn, 1); i++)
6357eaae 877 scan_operands (d, XVECEXP (insn, 1, i), 0, 0);
e1a1a29d 878
cf85f835 879 get_pattern_stats (&stats, XVEC (insn, 1));
880 d->n_generator_args = stats.num_generator_args;
881 d->n_operands = stats.num_insn_operands;
882 d->n_dups = stats.num_dups;
e1a1a29d 883
dd193d7c 884 validate_insn_operands (d);
e1a1a29d 885 validate_insn_alternatives (d);
cbb955b0 886 validate_optab_operands (d);
6357eaae 887 place_operands (d);
aa4c562d 888 process_template (d, XTMPL (insn, 3));
e1a1a29d 889}
890\f
891/* Look at a define_peephole just read. Assign its code number.
6357eaae 892 Record on idata the template and the number of arguments.
e1a1a29d 893 If the insn has a hairy output action, output it now. */
894
895static void
c04601c1 896gen_peephole (md_rtx_info *info)
e1a1a29d 897{
cf85f835 898 struct pattern_stats stats;
48bf1a90 899 data *d = new data;
19cb6b50 900 int i;
e1a1a29d 901
c04601c1 902 d->code_number = info->index;
903 d->loc = info->loc;
e1a1a29d 904 d->name = 0;
905
906 /* Build up the list in the same order as the insns are seen
907 in the machine description. */
908 d->next = 0;
6357eaae 909 *idata_end = d;
910 idata_end = &d->next;
e1a1a29d 911
6357eaae 912 memset (d->operand, 0, sizeof (d->operand));
913
914 /* Get the number of operands by scanning all the patterns of the
915 peephole optimizer. But ignore all the rest of the information
916 thus obtained. */
c04601c1 917 rtx peep = info->def;
e1a1a29d 918 for (i = 0; i < XVECLEN (peep, 0); i++)
6357eaae 919 scan_operands (d, XVECEXP (peep, 0, i), 0, 0);
e1a1a29d 920
cf85f835 921 get_pattern_stats (&stats, XVEC (peep, 0));
922 d->n_generator_args = 0;
923 d->n_operands = stats.num_insn_operands;
e1a1a29d 924 d->n_dups = 0;
925
e1a1a29d 926 validate_insn_alternatives (d);
6357eaae 927 place_operands (d);
aa4c562d 928 process_template (d, XTMPL (peep, 2));
e1a1a29d 929}
930\f
931/* Process a define_expand just read. Assign its code number,
932 only for the purposes of `insn_gen_function'. */
933
934static void
c04601c1 935gen_expand (md_rtx_info *info)
e1a1a29d 936{
cf85f835 937 struct pattern_stats stats;
c04601c1 938 rtx insn = info->def;
48bf1a90 939 data *d = new data;
19cb6b50 940 int i;
e1a1a29d 941
c04601c1 942 d->code_number = info->index;
943 d->loc = info->loc;
e1a1a29d 944 if (XSTR (insn, 0)[0])
945 d->name = XSTR (insn, 0);
946 else
947 d->name = 0;
948
949 /* Build up the list in the same order as the insns are seen
950 in the machine description. */
951 d->next = 0;
6357eaae 952 *idata_end = d;
953 idata_end = &d->next;
e1a1a29d 954
6357eaae 955 memset (d->operand, 0, sizeof (d->operand));
e1a1a29d 956
957 /* Scan the operands to get the specified predicates and modes,
958 since expand_binop needs to know them. */
959
e1a1a29d 960 if (XVEC (insn, 1))
961 for (i = 0; i < XVECLEN (insn, 1); i++)
6357eaae 962 scan_operands (d, XVECEXP (insn, 1, i), 0, 0);
e1a1a29d 963
cf85f835 964 get_pattern_stats (&stats, XVEC (insn, 1));
965 d->n_generator_args = stats.num_generator_args;
966 d->n_operands = stats.num_insn_operands;
967 d->n_dups = stats.num_dups;
2657a7d5 968 d->template_code = 0;
ae9660c8 969 d->output_format = INSN_OUTPUT_FORMAT_NONE;
6357eaae 970
e1a1a29d 971 validate_insn_alternatives (d);
cbb955b0 972 validate_optab_operands (d);
6357eaae 973 place_operands (d);
e1a1a29d 974}
975\f
5ab7f285 976static void
977init_insn_for_nothing (void)
978{
48bf1a90 979 idata = XCNEW (struct data);
980 new (idata) data ();
981 idata->name = "*placeholder_for_nothing";
982 idata->loc = file_location ("<internal>", 0);
983 idata_end = &idata->next;
5ab7f285 984}
985
1a97be37 986extern int main (int, char **);
947491b7 987
e1a1a29d 988int
1a97be37 989main (int argc, char **argv)
e1a1a29d 990{
05806416 991 progname = "genoutput";
992
5ab7f285 993 init_insn_for_nothing ();
994
77ba95d0 995 if (!init_rtx_reader_args (argc, argv))
c5ddd6b5 996 return (FATAL_EXIT_CODE);
e1a1a29d 997
e1a1a29d 998 output_prologue ();
e1a1a29d 999
1000 /* Read the machine description. */
1001
c04601c1 1002 md_rtx_info info;
1003 while (read_md_rtx (&info))
1004 switch (GET_CODE (info.def))
1005 {
1006 case DEFINE_INSN:
1007 gen_insn (&info);
e1a1a29d 1008 break;
e1a1a29d 1009
c04601c1 1010 case DEFINE_PEEPHOLE:
1011 gen_peephole (&info);
1012 break;
026d3868 1013
c04601c1 1014 case DEFINE_EXPAND:
1015 gen_expand (&info);
1016 break;
026d3868 1017
c04601c1 1018 case DEFINE_CONSTRAINT:
1019 case DEFINE_REGISTER_CONSTRAINT:
1020 case DEFINE_ADDRESS_CONSTRAINT:
1021 case DEFINE_MEMORY_CONSTRAINT:
1022 note_constraint (&info);
1023 break;
026d3868 1024
c04601c1 1025 default:
1026 break;
1027 }
e1a1a29d 1028
9af5ce0c 1029 printf ("\n\n");
6357eaae 1030 output_operand_data ();
1031 output_insn_data ();
1032 output_get_insn_name ();
e1a1a29d 1033
1034 fflush (stdout);
947491b7 1035 return (ferror (stdout) != 0 || have_error
72e9fcb2 1036 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
e1a1a29d 1037}
1038
5d844ba2 1039/* Return the number of occurrences of character C in string S or
1040 -1 if S is the null string. */
1041
e1a1a29d 1042static int
1a97be37 1043n_occurrences (int c, const char *s)
e1a1a29d 1044{
1045 int n = 0;
5d844ba2 1046
1047 if (s == 0 || *s == '\0')
1048 return -1;
1049
e1a1a29d 1050 while (*s)
1051 n += (*s++ == c);
5d844ba2 1052
e1a1a29d 1053 return n;
1054}
3f5cce54 1055
5d844ba2 1056/* Remove whitespace in `s' by moving up characters until the end.
1057 Return a new string. */
1058
1059static const char *
1a97be37 1060strip_whitespace (const char *s)
3f5cce54 1061{
5d844ba2 1062 char *p, *q;
1063 char ch;
1064
1065 if (s == 0)
1066 return 0;
3f5cce54 1067
4c36ffe6 1068 p = q = XNEWVEC (char, strlen (s) + 1);
3f5cce54 1069 while ((ch = *s++) != '\0')
1070 if (! ISSPACE (ch))
1071 *p++ = ch;
1072
1073 *p = '\0';
5d844ba2 1074 return q;
3f5cce54 1075}
48ea5577 1076
c04601c1 1077/* Record just enough information about the constraint in *INFO to allow
1078 checking of operand constraint strings above, in validate_insn_alternatives.
1079 Does not validate most properties of the constraint itself; does enforce
1080 no duplicate names, no overlap with MI constraints, and no prefixes. */
026d3868 1081static void
c04601c1 1082note_constraint (md_rtx_info *info)
026d3868 1083{
c04601c1 1084 rtx exp = info->def;
026d3868 1085 const char *name = XSTR (exp, 0);
2657a7d5 1086 struct constraint_data **iter, **slot, *new_cdata;
026d3868 1087
69449463 1088 if (strcmp (name, "TARGET_MEM_CONSTRAINT") == 0)
1089 name = general_mem;
1090 unsigned int namelen = strlen (name);
1091
1092 if (strchr (indep_constraints, name[0]))
026d3868 1093 {
1094 if (name[1] == '\0')
c04601c1 1095 error_at (info->loc, "constraint letter '%s' cannot be "
1096 "redefined by the machine description", name);
026d3868 1097 else
c04601c1 1098 error_at (info->loc, "constraint name '%s' cannot be defined by "
1099 "the machine description, as it begins with '%c'",
1100 name, name[0]);
026d3868 1101 return;
1102 }
1103
1104 slot = &constraints_by_letter_table[(unsigned int)name[0]];
1105 for (iter = slot; *iter; iter = &(*iter)->next_this_letter)
1106 {
1107 /* This causes slot to end up pointing to the
1108 next_this_letter field of the last constraint with a name
1109 of equal or greater length than the new constraint; hence
1110 the new constraint will be inserted after all previous
1111 constraints with names of the same length. */
1112 if ((*iter)->namelen >= namelen)
1113 slot = iter;
1114
1115 if (!strcmp ((*iter)->name, name))
1116 {
c04601c1 1117 error_at (info->loc, "redefinition of constraint '%s'", name);
48bf1a90 1118 message_at ((*iter)->loc, "previous definition is here");
026d3868 1119 return;
1120 }
1121 else if (!strncmp ((*iter)->name, name, (*iter)->namelen))
1122 {
c04601c1 1123 error_at (info->loc, "defining constraint '%s' here", name);
48bf1a90 1124 message_at ((*iter)->loc, "renders constraint '%s' "
1125 "(defined here) a prefix", (*iter)->name);
026d3868 1126 return;
1127 }
1128 else if (!strncmp ((*iter)->name, name, namelen))
1129 {
c04601c1 1130 error_at (info->loc, "constraint '%s' is a prefix", name);
48bf1a90 1131 message_at ((*iter)->loc, "of constraint '%s' "
1132 "(defined here)", (*iter)->name);
026d3868 1133 return;
1134 }
1135 }
48bf1a90 1136 new_cdata = XNEWVAR (struct constraint_data,
1137 sizeof (struct constraint_data) + namelen);
1138 new (new_cdata) constraint_data ();
9af5ce0c 1139 strcpy (CONST_CAST (char *, new_cdata->name), name);
2657a7d5 1140 new_cdata->namelen = namelen;
c04601c1 1141 new_cdata->loc = info->loc;
2657a7d5 1142 new_cdata->next_this_letter = *slot;
1143 *slot = new_cdata;
026d3868 1144}
1145
1146/* Return the length of the constraint name beginning at position S
1147 of an operand constraint string, or issue an error message if there
1148 is no such constraint. Does not expect to be called for generic
1149 constraints. */
1150static int
48bf1a90 1151mdep_constraint_len (const char *s, file_location loc, int opno)
026d3868 1152{
1153 struct constraint_data *p;
1154
1155 p = constraints_by_letter_table[(unsigned int)s[0]];
1156
1157 if (p)
1158 for (; p; p = p->next_this_letter)
1159 if (!strncmp (s, p->name, p->namelen))
1160 return p->namelen;
1161
48bf1a90 1162 error_at (loc, "error: undefined machine-specific constraint "
1163 "at this point: \"%s\"", s);
1164 message_at (loc, "note: in operand %d", opno);
026d3868 1165 return 1; /* safe */
1166}