]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/genoutput.c
* doc/md.texi: Document vec_shl_<mode> pattern.
[thirdparty/gcc.git] / gcc / genoutput.c
CommitLineData
e1a1a29d 1/* Generate code from to output assembler insns as recognized from rtl.
fbd26352 2 Copyright (C) 1987-2019 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{
1e0295b9 130 0, 0, "", "", E_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
785790dc 206 printf ("#define IN_TARGET_CODE 1\n");
e1a1a29d 207 printf ("#include \"config.h\"\n");
9aaa1fcc 208 printf ("#include \"system.h\"\n");
805e22b2 209 printf ("#include \"coretypes.h\"\n");
9ef16211 210 printf ("#include \"backend.h\"\n");
d040a5b0 211 printf ("#include \"predict.h\"\n");
9ef16211 212 printf ("#include \"tree.h\"\n");
213 printf ("#include \"rtl.h\"\n");
3ef9782d 214 printf ("#include \"flags.h\"\n");
b20a8bb4 215 printf ("#include \"alias.h\"\n");
9ed99284 216 printf ("#include \"varasm.h\"\n");
217 printf ("#include \"stor-layout.h\"\n");
218 printf ("#include \"calls.h\"\n");
d53441c8 219 printf ("#include \"insn-config.h\"\n");
220 printf ("#include \"expmed.h\"\n");
221 printf ("#include \"dojump.h\"\n");
222 printf ("#include \"explow.h\"\n");
ad7b10a2 223 printf ("#include \"memmodel.h\"\n");
d53441c8 224 printf ("#include \"emit-rtl.h\"\n");
225 printf ("#include \"stmt.h\"\n");
9ff0b0fd 226 printf ("#include \"expr.h\"\n");
d8fc4d0b 227 printf ("#include \"insn-codes.h\"\n");
7953c610 228 printf ("#include \"tm_p.h\"\n");
e1a1a29d 229 printf ("#include \"regs.h\"\n");
e1a1a29d 230 printf ("#include \"conditions.h\"\n");
e1a1a29d 231 printf ("#include \"insn-attr.h\"\n\n");
e1a1a29d 232 printf ("#include \"recog.h\"\n\n");
c18cb818 233 printf ("#include \"diagnostic-core.h\"\n");
e1a1a29d 234 printf ("#include \"output.h\"\n");
805e22b2 235 printf ("#include \"target.h\"\n");
a014ec0f 236 printf ("#include \"tm-constrs.h\"\n");
e1a1a29d 237}
238
6357eaae 239static void
1a97be37 240output_operand_data (void)
6357eaae 241{
19cb6b50 242 struct operand_data *d;
6357eaae 243
244 printf ("\nstatic const struct insn_operand_data operand_data[] = \n{\n");
245
246 for (d = odata; d; d = d->next)
e1a1a29d 247 {
48eb616d 248 struct pred_data *pred;
249
6357eaae 250 printf (" {\n");
251
252 printf (" %s,\n",
253 d->predicate && d->predicate[0] ? d->predicate : "0");
254
15b50aec 255 printf (" \"%s\",\n", d->constraint ? d->constraint : "");
e1a1a29d 256
1e0295b9 257 printf (" E_%smode,\n", GET_MODE_NAME (d->mode));
6357eaae 258
6b21946f 259 printf (" %d,\n", d->strict_low);
260
a67a82ef 261 printf (" %d,\n", d->constraint == NULL ? 1 : 0);
262
48eb616d 263 printf (" %d,\n", d->eliminable);
264
265 pred = NULL;
266 if (d->predicate)
267 pred = lookup_predicate (d->predicate);
268 printf (" %d\n", pred && pred->codes[MEM]);
6357eaae 269
9af5ce0c 270 printf (" },\n");
6357eaae 271 }
9af5ce0c 272 printf ("};\n\n\n");
6357eaae 273}
274
275static void
1a97be37 276output_insn_data (void)
6357eaae 277{
19cb6b50 278 struct data *d;
6357eaae 279 int name_offset = 0;
280 int next_name_offset;
281 const char * last_name = 0;
282 const char * next_name = 0;
19cb6b50 283 struct data *n;
6357eaae 284
285 for (n = idata, next_name_offset = 1; n; n = n->next, next_name_offset++)
286 if (n->name)
e1a1a29d 287 {
6357eaae 288 next_name = n->name;
289 break;
e1a1a29d 290 }
e1a1a29d 291
48b3d385 292 printf ("#if GCC_VERSION >= 2007\n__extension__\n#endif\n");
f2956fc5 293 printf ("\nconst struct insn_data_d insn_data[] = \n{\n");
e1a1a29d 294
6357eaae 295 for (d = idata; d; d = d->next)
e1a1a29d 296 {
48bf1a90 297 printf (" /* %s:%d */\n", d->loc.filename, d->loc.lineno);
6357eaae 298 printf (" {\n");
299
300 if (d->name)
e1a1a29d 301 {
6357eaae 302 printf (" \"%s\",\n", d->name);
303 name_offset = 0;
304 last_name = d->name;
305 next_name = 0;
306 for (n = d->next, next_name_offset = 1; n;
307 n = n->next, next_name_offset++)
e1a1a29d 308 {
6357eaae 309 if (n->name)
310 {
311 next_name = n->name;
312 break;
313 }
e1a1a29d 314 }
e1a1a29d 315 }
6357eaae 316 else
e1a1a29d 317 {
6357eaae 318 name_offset++;
319 if (next_name && (last_name == 0
320 || name_offset > next_name_offset / 2))
321 printf (" \"%s-%d\",\n", next_name,
322 next_name_offset - name_offset);
323 else
324 printf (" \"%s+%d\",\n", last_name, name_offset);
e1a1a29d 325 }
e1a1a29d 326
ae9660c8 327 switch (d->output_format)
328 {
329 case INSN_OUTPUT_FORMAT_NONE:
a88d399f 330 printf ("#if HAVE_DESIGNATED_UNION_INITIALIZERS\n");
48b3d385 331 printf (" { 0 },\n");
332 printf ("#else\n");
333 printf (" { 0, 0, 0 },\n");
334 printf ("#endif\n");
ae9660c8 335 break;
336 case INSN_OUTPUT_FORMAT_SINGLE:
4062b755 337 {
2657a7d5 338 const char *p = d->template_code;
4062b755 339 char prev = 0;
1a97be37 340
a88d399f 341 printf ("#if HAVE_DESIGNATED_UNION_INITIALIZERS\n");
48b3d385 342 printf (" { .single =\n");
343 printf ("#else\n");
344 printf (" {\n");
345 printf ("#endif\n");
4062b755 346 printf (" \"");
347 while (*p)
348 {
337057dd 349 if (IS_VSPACE (*p) && prev != '\\')
350 {
351 /* Preserve two consecutive \n's or \r's, but treat \r\n
352 as a single newline. */
353 if (*p == '\n' && prev != '\r')
354 printf ("\\n\\\n");
355 }
4062b755 356 else
357 putchar (*p);
358 prev = *p;
359 ++p;
360 }
361 printf ("\",\n");
a88d399f 362 printf ("#if HAVE_DESIGNATED_UNION_INITIALIZERS\n");
48b3d385 363 printf (" },\n");
364 printf ("#else\n");
365 printf (" 0, 0 },\n");
366 printf ("#endif\n");
4062b755 367 }
ae9660c8 368 break;
369 case INSN_OUTPUT_FORMAT_MULTI:
a88d399f 370 printf ("#if HAVE_DESIGNATED_UNION_INITIALIZERS\n");
48b3d385 371 printf (" { .multi = output_%d },\n", d->code_number);
372 printf ("#else\n");
373 printf (" { 0, output_%d, 0 },\n", d->code_number);
374 printf ("#endif\n");
375 break;
ae9660c8 376 case INSN_OUTPUT_FORMAT_FUNCTION:
a88d399f 377 printf ("#if HAVE_DESIGNATED_UNION_INITIALIZERS\n");
48b3d385 378 printf (" { .function = output_%d },\n", d->code_number);
379 printf ("#else\n");
380 printf (" { 0, 0, output_%d },\n", d->code_number);
381 printf ("#endif\n");
ae9660c8 382 break;
383 default:
e0a4c0c2 384 gcc_unreachable ();
ae9660c8 385 }
6357eaae 386
387 if (d->name && d->name[0] != '*')
3d953cb1 388 printf (" { (insn_gen_fn::stored_funcptr) gen_%s },\n", d->name);
6357eaae 389 else
3d953cb1 390 printf (" { 0 },\n");
6357eaae 391
392 printf (" &operand_data[%d],\n", d->operand_number);
cf85f835 393 printf (" %d,\n", d->n_generator_args);
6357eaae 394 printf (" %d,\n", d->n_operands);
395 printf (" %d,\n", d->n_dups);
ae9660c8 396 printf (" %d,\n", d->n_alternatives);
397 printf (" %d\n", d->output_format);
6357eaae 398
9af5ce0c 399 printf (" },\n");
e1a1a29d 400 }
6357eaae 401 printf ("};\n\n\n");
402}
e1a1a29d 403
6357eaae 404static void
1a97be37 405output_get_insn_name (void)
6357eaae 406{
407 printf ("const char *\n");
69dc4d00 408 printf ("get_insn_name (int code)\n");
6357eaae 409 printf ("{\n");
4951824a 410 printf (" if (code == NOOP_MOVE_INSN_CODE)\n");
411 printf (" return \"NOOP_MOVE\";\n");
412 printf (" else\n");
413 printf (" return insn_data[code].name;\n");
6357eaae 414 printf ("}\n");
e1a1a29d 415}
6357eaae 416
e1a1a29d 417\f
cf85f835 418/* Stores the operand data into `d->operand[i]'.
e1a1a29d 419
420 THIS_ADDRESS_P is nonzero if the containing rtx was an ADDRESS.
421 THIS_STRICT_LOW is nonzero if the containing rtx was a STRICT_LOW_PART. */
422
e1a1a29d 423static void
1a97be37 424scan_operands (struct data *d, rtx part, int this_address_p,
425 int this_strict_low)
e1a1a29d 426{
19cb6b50 427 int i, j;
428 const char *format_ptr;
e1a1a29d 429 int opno;
430
431 if (part == 0)
432 return;
433
434 switch (GET_CODE (part))
435 {
436 case MATCH_OPERAND:
437 opno = XINT (part, 0);
cf85f835 438 if (opno >= MAX_MAX_OPERANDS)
a29c013c 439 {
48bf1a90 440 error_at (d->loc, "maximum number of operands exceeded");
a29c013c 441 return;
442 }
6357eaae 443 if (d->operand[opno].seen)
48bf1a90 444 error_at (d->loc, "repeated operand number %d\n", opno);
36deab5f 445
6357eaae 446 d->operand[opno].seen = 1;
447 d->operand[opno].mode = GET_MODE (part);
448 d->operand[opno].strict_low = this_strict_low;
449 d->operand[opno].predicate = XSTR (part, 1);
5d844ba2 450 d->operand[opno].constraint = strip_whitespace (XSTR (part, 2));
451 d->operand[opno].n_alternatives
452 = n_occurrences (',', d->operand[opno].constraint) + 1;
6357eaae 453 d->operand[opno].address_p = this_address_p;
6b21946f 454 d->operand[opno].eliminable = 1;
e1a1a29d 455 return;
456
457 case MATCH_SCRATCH:
458 opno = XINT (part, 0);
cf85f835 459 if (opno >= MAX_MAX_OPERANDS)
a29c013c 460 {
48bf1a90 461 error_at (d->loc, "maximum number of operands exceeded");
a29c013c 462 return;
463 }
6357eaae 464 if (d->operand[opno].seen)
48bf1a90 465 error_at (d->loc, "repeated operand number %d\n", opno);
36deab5f 466
6357eaae 467 d->operand[opno].seen = 1;
468 d->operand[opno].mode = GET_MODE (part);
469 d->operand[opno].strict_low = 0;
470 d->operand[opno].predicate = "scratch_operand";
5d844ba2 471 d->operand[opno].constraint = strip_whitespace (XSTR (part, 1));
472 d->operand[opno].n_alternatives
473 = n_occurrences (',', d->operand[opno].constraint) + 1;
6357eaae 474 d->operand[opno].address_p = 0;
6b21946f 475 d->operand[opno].eliminable = 0;
e1a1a29d 476 return;
477
478 case MATCH_OPERATOR:
479 case MATCH_PARALLEL:
480 opno = XINT (part, 0);
cf85f835 481 if (opno >= MAX_MAX_OPERANDS)
a29c013c 482 {
48bf1a90 483 error_at (d->loc, "maximum number of operands exceeded");
a29c013c 484 return;
485 }
6357eaae 486 if (d->operand[opno].seen)
48bf1a90 487 error_at (d->loc, "repeated operand number %d\n", opno);
36deab5f 488
6357eaae 489 d->operand[opno].seen = 1;
490 d->operand[opno].mode = GET_MODE (part);
491 d->operand[opno].strict_low = 0;
492 d->operand[opno].predicate = XSTR (part, 1);
493 d->operand[opno].constraint = 0;
494 d->operand[opno].address_p = 0;
6b21946f 495 d->operand[opno].eliminable = 0;
e1a1a29d 496 for (i = 0; i < XVECLEN (part, 2); i++)
6357eaae 497 scan_operands (d, XVECEXP (part, 2, i), 0, 0);
e1a1a29d 498 return;
499
e1a1a29d 500 case STRICT_LOW_PART:
6357eaae 501 scan_operands (d, XEXP (part, 0), 0, 1);
e1a1a29d 502 return;
1a97be37 503
3ef9782d 504 default:
505 break;
e1a1a29d 506 }
507
508 format_ptr = GET_RTX_FORMAT (GET_CODE (part));
509
510 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
511 switch (*format_ptr++)
512 {
513 case 'e':
3ef9782d 514 case 'u':
6357eaae 515 scan_operands (d, XEXP (part, i), 0, 0);
e1a1a29d 516 break;
517 case 'E':
518 if (XVEC (part, i) != NULL)
519 for (j = 0; j < XVECLEN (part, i); j++)
6357eaae 520 scan_operands (d, XVECEXP (part, i, j), 0, 0);
e1a1a29d 521 break;
522 }
523}
6357eaae 524
525/* Compare two operands for content equality. */
526
527static int
1a97be37 528compare_operands (struct operand_data *d0, struct operand_data *d1)
6357eaae 529{
947491b7 530 const char *p0, *p1;
6357eaae 531
532 p0 = d0->predicate;
533 if (!p0)
534 p0 = "";
535 p1 = d1->predicate;
536 if (!p1)
537 p1 = "";
538 if (strcmp (p0, p1) != 0)
539 return 0;
540
15b50aec 541 p0 = d0->constraint;
542 if (!p0)
543 p0 = "";
544 p1 = d1->constraint;
545 if (!p1)
546 p1 = "";
547 if (strcmp (p0, p1) != 0)
548 return 0;
6357eaae 549
550 if (d0->mode != d1->mode)
551 return 0;
552
6357eaae 553 if (d0->strict_low != d1->strict_low)
554 return 0;
555
6b21946f 556 if (d0->eliminable != d1->eliminable)
557 return 0;
558
6357eaae 559 return 1;
560}
561
562/* Scan the list of operands we've already committed to output and either
563 find a subsequence that is the same, or allocate a new one at the end. */
564
565static void
1a97be37 566place_operands (struct data *d)
6357eaae 567{
568 struct operand_data *od, *od2;
569 int i;
570
571 if (d->n_operands == 0)
572 {
573 d->operand_number = 0;
574 return;
575 }
576
577 /* Brute force substring search. */
578 for (od = odata, i = 0; od; od = od->next, i = 0)
579 if (compare_operands (od, &d->operand[0]))
580 {
581 od2 = od->next;
582 i = 1;
583 while (1)
584 {
585 if (i == d->n_operands)
586 goto full_match;
587 if (od2 == NULL)
588 goto partial_match;
589 if (! compare_operands (od2, &d->operand[i]))
590 break;
591 ++i, od2 = od2->next;
592 }
593 }
594
595 /* Either partial match at the end of the list, or no match. In either
596 case, we tack on what operands are remaining to the end of the list. */
597 partial_match:
598 d->operand_number = next_operand_number - i;
599 for (; i < d->n_operands; ++i)
600 {
601 od2 = &d->operand[i];
602 *odata_end = od2;
603 odata_end = &od2->next;
604 od2->index = next_operand_number++;
605 }
606 *odata_end = NULL;
607 return;
608
609 full_match:
610 d->operand_number = od->index;
611 return;
612}
613
e1a1a29d 614\f
615/* Process an assembler template from a define_insn or a define_peephole.
616 It is either the assembler code template, a list of assembler code
617 templates, or C code to generate the assembler code template. */
618
619static void
2657a7d5 620process_template (struct data *d, const char *template_code)
e1a1a29d 621{
19cb6b50 622 const char *cp;
623 int i;
e1a1a29d 624
ae9660c8 625 /* Templates starting with * contain straight code to be run. */
2657a7d5 626 if (template_code[0] == '*')
e1a1a29d 627 {
2657a7d5 628 d->template_code = 0;
ae9660c8 629 d->output_format = INSN_OUTPUT_FORMAT_FUNCTION;
e1a1a29d 630
ae9660c8 631 puts ("\nstatic const char *");
bf59a32d 632 printf ("output_%d (rtx *operands ATTRIBUTE_UNUSED, rtx_insn *insn ATTRIBUTE_UNUSED)\n",
69dc4d00 633 d->code_number);
ae9660c8 634 puts ("{");
e1e9159b 635 rtx_reader_ptr->print_md_ptr_loc (template_code);
2657a7d5 636 puts (template_code + 1);
ae9660c8 637 puts ("}");
638 }
e1a1a29d 639
640 /* If the assembler code template starts with a @ it is a newline-separated
ae9660c8 641 list of assembler code templates, one for each alternative. */
2657a7d5 642 else if (template_code[0] == '@')
e1a1a29d 643 {
66799bd7 644 int found_star = 0;
e1a1a29d 645
66799bd7 646 for (cp = &template_code[1]; *cp; )
647 {
648 while (ISSPACE (*cp))
649 cp++;
650 if (*cp == '*')
651 found_star = 1;
652 while (!IS_VSPACE (*cp) && *cp != '\0')
653 ++cp;
654 }
655 d->template_code = 0;
656 if (found_star)
657 {
658 d->output_format = INSN_OUTPUT_FORMAT_FUNCTION;
659 puts ("\nstatic const char *");
660 printf ("output_%d (rtx *operands ATTRIBUTE_UNUSED, "
bf59a32d 661 "rtx_insn *insn ATTRIBUTE_UNUSED)\n", d->code_number);
66799bd7 662 puts ("{");
663 puts (" switch (which_alternative)\n {");
664 }
665 else
666 {
667 d->output_format = INSN_OUTPUT_FORMAT_MULTI;
668 printf ("\nstatic const char * const output_%d[] = {\n",
669 d->code_number);
670 }
e1a1a29d 671
2657a7d5 672 for (i = 0, cp = &template_code[1]; *cp; )
e1a1a29d 673 {
66799bd7 674 const char *ep, *sp, *bp;
742e47a0 675
337057dd 676 while (ISSPACE (*cp))
e1a1a29d 677 cp++;
678
66799bd7 679 bp = cp;
680 if (found_star)
681 {
682 printf (" case %d:", i);
683 if (*cp == '*')
684 {
685 printf ("\n ");
686 cp++;
687 }
688 else
689 printf (" return \"");
690 }
691 else
692 printf (" \"");
742e47a0 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)
48bf1a90 699 message_at (d->loc, "trailing whitespace in output template");
742e47a0 700
701 while (cp < sp)
534fd0c8 702 {
703 putchar (*cp);
704 cp++;
705 }
e1a1a29d 706
66799bd7 707 if (!found_star)
708 puts ("\",");
709 else if (*bp != '*')
710 puts ("\";");
711 else
712 {
713 /* The usual action will end with a return.
714 If there is neither break or return at the end, this is
715 assumed to be intentional; this allows to have multiple
716 consecutive alternatives share some code. */
717 puts ("");
718 }
e1a1a29d 719 i++;
720 }
c21cb186 721 if (i == 1)
48bf1a90 722 message_at (d->loc, "'@' is redundant for output template with"
723 " single alternative");
c21cb186 724 if (i != d->n_alternatives)
48bf1a90 725 error_at (d->loc, "wrong number of alternatives in the output"
726 " template");
e1a1a29d 727
66799bd7 728 if (found_star)
729 puts (" default: gcc_unreachable ();\n }\n}");
730 else
731 printf ("};\n");
e1a1a29d 732 }
733 else
734 {
2657a7d5 735 d->template_code = template_code;
ae9660c8 736 d->output_format = INSN_OUTPUT_FORMAT_SINGLE;
e1a1a29d 737 }
e1a1a29d 738}
739\f
740/* Check insn D for consistency in number of constraint alternatives. */
741
742static void
1a97be37 743validate_insn_alternatives (struct data *d)
e1a1a29d 744{
19cb6b50 745 int n = 0, start;
6357eaae 746
747 /* Make sure all the operands have the same number of alternatives
748 in their constraints. Let N be that number. */
e1a1a29d 749 for (start = 0; start < d->n_operands; start++)
6357eaae 750 if (d->operand[start].n_alternatives > 0)
e1a1a29d 751 {
48ea5577 752 int len, i;
753 const char *p;
754 char c;
755 int which_alternative = 0;
756 int alternative_count_unsure = 0;
ffcd6b16 757 bool seen_write = false;
48ea5577 758
759 for (p = d->operand[start].constraint; (c = *p); p += len)
760 {
205c3b0a 761 if ((c == '%' || c == '=' || c == '+')
762 && p != d->operand[start].constraint)
48bf1a90 763 error_at (d->loc, "character '%c' can only be used at the"
764 " beginning of a constraint string", c);
ffcd6b16 765
766 if (c == '=' || c == '+')
767 seen_write = true;
768
769 /* Earlyclobber operands must always be marked write-only
770 or read/write. */
771 if (!seen_write && c == '&')
48bf1a90 772 error_at (d->loc, "earlyclobber operands may not be"
773 " read-only in alternative %d", which_alternative);
ffcd6b16 774
026d3868 775 if (ISSPACE (c) || strchr (indep_constraints, c))
776 len = 1;
777 else if (ISDIGIT (c))
778 {
779 const char *q = p;
780 do
781 q++;
782 while (ISDIGIT (*q));
783 len = q - p;
784 }
785 else
48bf1a90 786 len = mdep_constraint_len (p, d->loc, start);
48ea5577 787
788 if (c == ',')
789 {
790 which_alternative++;
791 continue;
792 }
793
794 for (i = 1; i < len; i++)
795 if (p[i] == '\0')
796 {
48bf1a90 797 error_at (d->loc, "NUL in alternative %d of operand %d",
798 which_alternative, start);
48ea5577 799 alternative_count_unsure = 1;
800 break;
801 }
802 else if (strchr (",#*", p[i]))
803 {
48bf1a90 804 error_at (d->loc, "'%c' in alternative %d of operand %d",
805 p[i], which_alternative, start);
48ea5577 806 alternative_count_unsure = 1;
807 }
808 }
b638f5c8 809 if (!alternative_count_unsure)
36deab5f 810 {
b638f5c8 811 if (n == 0)
812 n = d->operand[start].n_alternatives;
813 else if (n != d->operand[start].n_alternatives)
48bf1a90 814 error_at (d->loc, "wrong number of alternatives in operand %d",
815 start);
36deab5f 816 }
e1a1a29d 817 }
6357eaae 818
e1a1a29d 819 /* Record the insn's overall number of alternatives. */
820 d->n_alternatives = n;
821}
dd193d7c 822
823/* Verify that there are no gaps in operand numbers for INSNs. */
824
825static void
1a97be37 826validate_insn_operands (struct data *d)
dd193d7c 827{
828 int i;
829
830 for (i = 0; i < d->n_operands; ++i)
831 if (d->operand[i].seen == 0)
48bf1a90 832 error_at (d->loc, "missing operand %d", i);
dd193d7c 833}
cbb955b0 834
835static void
836validate_optab_operands (struct data *d)
837{
838 if (!d->name || d->name[0] == '\0' || d->name[0] == '*')
839 return;
840
841 /* Miscellaneous tests. */
842 if (strncmp (d->name, "cstore", 6) == 0
843 && d->name[strlen (d->name) - 1] == '4'
844 && d->operand[0].mode == VOIDmode)
845 {
48bf1a90 846 message_at (d->loc, "missing mode for operand 0 of cstore");
cbb955b0 847 have_error = 1;
848 }
849}
e1a1a29d 850\f
6357eaae 851/* Look at a define_insn just read. Assign its code number. Record
852 on idata the template and the number of arguments. If the insn has
853 a hairy output action, output a function for now. */
e1a1a29d 854
855static void
c04601c1 856gen_insn (md_rtx_info *info)
e1a1a29d 857{
cf85f835 858 struct pattern_stats stats;
c04601c1 859 rtx insn = info->def;
48bf1a90 860 data *d = new data;
19cb6b50 861 int i;
e1a1a29d 862
c04601c1 863 d->code_number = info->index;
864 d->loc = info->loc;
e1a1a29d 865 if (XSTR (insn, 0)[0])
866 d->name = XSTR (insn, 0);
867 else
868 d->name = 0;
869
870 /* Build up the list in the same order as the insns are seen
871 in the machine description. */
872 d->next = 0;
6357eaae 873 *idata_end = d;
874 idata_end = &d->next;
e1a1a29d 875
6357eaae 876 memset (d->operand, 0, sizeof (d->operand));
e1a1a29d 877
878 for (i = 0; i < XVECLEN (insn, 1); i++)
6357eaae 879 scan_operands (d, XVECEXP (insn, 1, i), 0, 0);
e1a1a29d 880
cf85f835 881 get_pattern_stats (&stats, XVEC (insn, 1));
882 d->n_generator_args = stats.num_generator_args;
883 d->n_operands = stats.num_insn_operands;
884 d->n_dups = stats.num_dups;
e1a1a29d 885
dd193d7c 886 validate_insn_operands (d);
e1a1a29d 887 validate_insn_alternatives (d);
cbb955b0 888 validate_optab_operands (d);
6357eaae 889 place_operands (d);
aa4c562d 890 process_template (d, XTMPL (insn, 3));
e1a1a29d 891}
892\f
893/* Look at a define_peephole just read. Assign its code number.
6357eaae 894 Record on idata the template and the number of arguments.
e1a1a29d 895 If the insn has a hairy output action, output it now. */
896
897static void
c04601c1 898gen_peephole (md_rtx_info *info)
e1a1a29d 899{
cf85f835 900 struct pattern_stats stats;
48bf1a90 901 data *d = new data;
19cb6b50 902 int i;
e1a1a29d 903
c04601c1 904 d->code_number = info->index;
905 d->loc = info->loc;
e1a1a29d 906 d->name = 0;
907
908 /* Build up the list in the same order as the insns are seen
909 in the machine description. */
910 d->next = 0;
6357eaae 911 *idata_end = d;
912 idata_end = &d->next;
e1a1a29d 913
6357eaae 914 memset (d->operand, 0, sizeof (d->operand));
915
916 /* Get the number of operands by scanning all the patterns of the
917 peephole optimizer. But ignore all the rest of the information
918 thus obtained. */
c04601c1 919 rtx peep = info->def;
e1a1a29d 920 for (i = 0; i < XVECLEN (peep, 0); i++)
6357eaae 921 scan_operands (d, XVECEXP (peep, 0, i), 0, 0);
e1a1a29d 922
cf85f835 923 get_pattern_stats (&stats, XVEC (peep, 0));
924 d->n_generator_args = 0;
925 d->n_operands = stats.num_insn_operands;
e1a1a29d 926 d->n_dups = 0;
927
e1a1a29d 928 validate_insn_alternatives (d);
6357eaae 929 place_operands (d);
aa4c562d 930 process_template (d, XTMPL (peep, 2));
e1a1a29d 931}
932\f
933/* Process a define_expand just read. Assign its code number,
934 only for the purposes of `insn_gen_function'. */
935
936static void
c04601c1 937gen_expand (md_rtx_info *info)
e1a1a29d 938{
cf85f835 939 struct pattern_stats stats;
c04601c1 940 rtx insn = info->def;
48bf1a90 941 data *d = new data;
19cb6b50 942 int i;
e1a1a29d 943
c04601c1 944 d->code_number = info->index;
945 d->loc = info->loc;
e1a1a29d 946 if (XSTR (insn, 0)[0])
947 d->name = XSTR (insn, 0);
948 else
949 d->name = 0;
950
951 /* Build up the list in the same order as the insns are seen
952 in the machine description. */
953 d->next = 0;
6357eaae 954 *idata_end = d;
955 idata_end = &d->next;
e1a1a29d 956
6357eaae 957 memset (d->operand, 0, sizeof (d->operand));
e1a1a29d 958
959 /* Scan the operands to get the specified predicates and modes,
960 since expand_binop needs to know them. */
961
e1a1a29d 962 if (XVEC (insn, 1))
963 for (i = 0; i < XVECLEN (insn, 1); i++)
6357eaae 964 scan_operands (d, XVECEXP (insn, 1, i), 0, 0);
e1a1a29d 965
cf85f835 966 get_pattern_stats (&stats, XVEC (insn, 1));
967 d->n_generator_args = stats.num_generator_args;
968 d->n_operands = stats.num_insn_operands;
969 d->n_dups = stats.num_dups;
2657a7d5 970 d->template_code = 0;
ae9660c8 971 d->output_format = INSN_OUTPUT_FORMAT_NONE;
6357eaae 972
e1a1a29d 973 validate_insn_alternatives (d);
cbb955b0 974 validate_optab_operands (d);
6357eaae 975 place_operands (d);
e1a1a29d 976}
977\f
5ab7f285 978static void
979init_insn_for_nothing (void)
980{
48bf1a90 981 idata = XCNEW (struct data);
982 new (idata) data ();
983 idata->name = "*placeholder_for_nothing";
2a340d63 984 idata->loc = file_location ("<internal>", 0, 0);
48bf1a90 985 idata_end = &idata->next;
5ab7f285 986}
987
16570c04 988extern int main (int, const char **);
947491b7 989
e1a1a29d 990int
16570c04 991main (int argc, const char **argv)
e1a1a29d 992{
05806416 993 progname = "genoutput";
994
5ab7f285 995 init_insn_for_nothing ();
996
77ba95d0 997 if (!init_rtx_reader_args (argc, argv))
c5ddd6b5 998 return (FATAL_EXIT_CODE);
e1a1a29d 999
e1a1a29d 1000 output_prologue ();
e1a1a29d 1001
1002 /* Read the machine description. */
1003
c04601c1 1004 md_rtx_info info;
1005 while (read_md_rtx (&info))
1006 switch (GET_CODE (info.def))
1007 {
1008 case DEFINE_INSN:
1009 gen_insn (&info);
e1a1a29d 1010 break;
e1a1a29d 1011
c04601c1 1012 case DEFINE_PEEPHOLE:
1013 gen_peephole (&info);
1014 break;
026d3868 1015
c04601c1 1016 case DEFINE_EXPAND:
1017 gen_expand (&info);
1018 break;
026d3868 1019
c04601c1 1020 case DEFINE_CONSTRAINT:
1021 case DEFINE_REGISTER_CONSTRAINT:
1022 case DEFINE_ADDRESS_CONSTRAINT:
1023 case DEFINE_MEMORY_CONSTRAINT:
6b3b345a 1024 case DEFINE_SPECIAL_MEMORY_CONSTRAINT:
c04601c1 1025 note_constraint (&info);
1026 break;
026d3868 1027
c04601c1 1028 default:
1029 break;
1030 }
e1a1a29d 1031
9af5ce0c 1032 printf ("\n\n");
6357eaae 1033 output_operand_data ();
1034 output_insn_data ();
1035 output_get_insn_name ();
e1a1a29d 1036
1037 fflush (stdout);
947491b7 1038 return (ferror (stdout) != 0 || have_error
72e9fcb2 1039 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
e1a1a29d 1040}
1041
5d844ba2 1042/* Return the number of occurrences of character C in string S or
1043 -1 if S is the null string. */
1044
e1a1a29d 1045static int
1a97be37 1046n_occurrences (int c, const char *s)
e1a1a29d 1047{
1048 int n = 0;
5d844ba2 1049
1050 if (s == 0 || *s == '\0')
1051 return -1;
1052
e1a1a29d 1053 while (*s)
1054 n += (*s++ == c);
5d844ba2 1055
e1a1a29d 1056 return n;
1057}
3f5cce54 1058
5d844ba2 1059/* Remove whitespace in `s' by moving up characters until the end.
1060 Return a new string. */
1061
1062static const char *
1a97be37 1063strip_whitespace (const char *s)
3f5cce54 1064{
5d844ba2 1065 char *p, *q;
1066 char ch;
1067
1068 if (s == 0)
1069 return 0;
3f5cce54 1070
4c36ffe6 1071 p = q = XNEWVEC (char, strlen (s) + 1);
3f5cce54 1072 while ((ch = *s++) != '\0')
1073 if (! ISSPACE (ch))
1074 *p++ = ch;
1075
1076 *p = '\0';
5d844ba2 1077 return q;
3f5cce54 1078}
48ea5577 1079
c04601c1 1080/* Record just enough information about the constraint in *INFO to allow
1081 checking of operand constraint strings above, in validate_insn_alternatives.
1082 Does not validate most properties of the constraint itself; does enforce
1083 no duplicate names, no overlap with MI constraints, and no prefixes. */
026d3868 1084static void
c04601c1 1085note_constraint (md_rtx_info *info)
026d3868 1086{
c04601c1 1087 rtx exp = info->def;
026d3868 1088 const char *name = XSTR (exp, 0);
2657a7d5 1089 struct constraint_data **iter, **slot, *new_cdata;
026d3868 1090
69449463 1091 if (strcmp (name, "TARGET_MEM_CONSTRAINT") == 0)
1092 name = general_mem;
1093 unsigned int namelen = strlen (name);
1094
1095 if (strchr (indep_constraints, name[0]))
026d3868 1096 {
1097 if (name[1] == '\0')
c04601c1 1098 error_at (info->loc, "constraint letter '%s' cannot be "
1099 "redefined by the machine description", name);
026d3868 1100 else
c04601c1 1101 error_at (info->loc, "constraint name '%s' cannot be defined by "
1102 "the machine description, as it begins with '%c'",
1103 name, name[0]);
026d3868 1104 return;
1105 }
1106
1107 slot = &constraints_by_letter_table[(unsigned int)name[0]];
1108 for (iter = slot; *iter; iter = &(*iter)->next_this_letter)
1109 {
1110 /* This causes slot to end up pointing to the
1111 next_this_letter field of the last constraint with a name
1112 of equal or greater length than the new constraint; hence
1113 the new constraint will be inserted after all previous
1114 constraints with names of the same length. */
1115 if ((*iter)->namelen >= namelen)
1116 slot = iter;
1117
1118 if (!strcmp ((*iter)->name, name))
1119 {
c04601c1 1120 error_at (info->loc, "redefinition of constraint '%s'", name);
48bf1a90 1121 message_at ((*iter)->loc, "previous definition is here");
026d3868 1122 return;
1123 }
1124 else if (!strncmp ((*iter)->name, name, (*iter)->namelen))
1125 {
c04601c1 1126 error_at (info->loc, "defining constraint '%s' here", name);
48bf1a90 1127 message_at ((*iter)->loc, "renders constraint '%s' "
1128 "(defined here) a prefix", (*iter)->name);
026d3868 1129 return;
1130 }
1131 else if (!strncmp ((*iter)->name, name, namelen))
1132 {
c04601c1 1133 error_at (info->loc, "constraint '%s' is a prefix", name);
48bf1a90 1134 message_at ((*iter)->loc, "of constraint '%s' "
1135 "(defined here)", (*iter)->name);
026d3868 1136 return;
1137 }
1138 }
48bf1a90 1139 new_cdata = XNEWVAR (struct constraint_data,
1140 sizeof (struct constraint_data) + namelen);
1141 new (new_cdata) constraint_data ();
9af5ce0c 1142 strcpy (CONST_CAST (char *, new_cdata->name), name);
2657a7d5 1143 new_cdata->namelen = namelen;
c04601c1 1144 new_cdata->loc = info->loc;
2657a7d5 1145 new_cdata->next_this_letter = *slot;
1146 *slot = new_cdata;
026d3868 1147}
1148
1149/* Return the length of the constraint name beginning at position S
1150 of an operand constraint string, or issue an error message if there
1151 is no such constraint. Does not expect to be called for generic
1152 constraints. */
1153static int
48bf1a90 1154mdep_constraint_len (const char *s, file_location loc, int opno)
026d3868 1155{
1156 struct constraint_data *p;
1157
1158 p = constraints_by_letter_table[(unsigned int)s[0]];
1159
1160 if (p)
1161 for (; p; p = p->next_this_letter)
1162 if (!strncmp (s, p->name, p->namelen))
1163 return p->namelen;
1164
48bf1a90 1165 error_at (loc, "error: undefined machine-specific constraint "
1166 "at this point: \"%s\"", s);
1167 message_at (loc, "note: in operand %d", opno);
026d3868 1168 return 1; /* safe */
1169}