]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/genoutput.c
bootstrap-ubsan.mk (POSTSTAGE1_LDFLAGS): Add -ldl.
[thirdparty/gcc.git] / gcc / genoutput.c
CommitLineData
9db4e0ec 1/* Generate code from to output assembler insns as recognized from rtl.
d1e082c2 2 Copyright (C) 1987-2013 Free Software Foundation, Inc.
9db4e0ec 3
1322177d 4This file is part of GCC.
9db4e0ec 5
1322177d
LB
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
9dcd6f09 8Software Foundation; either version 3, or (at your option) any later
1322177d 9version.
9db4e0ec 10
1322177d
LB
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.
9db4e0ec
RK
15
16You should have received a copy of the GNU General Public License
9dcd6f09
NC
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
9db4e0ec
RK
19
20
21/* This program reads the machine description for the compiler target machine
22 and produces a file containing these things:
23
f12c802a 24 1. An array of `struct insn_data_d', which is indexed by insn code number,
a995e389 25 which contains:
9db4e0ec 26
a995e389
RH
27 a. `name' is the name for that pattern. Nameless patterns are
28 given a name.
29
4bbf910e
RH
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,
a995e389
RH
34 given operands as arguments.
35
4bbf910e 36 d. `n_operands' is the number of distinct operands in the pattern
a995e389 37 for that insn,
9db4e0ec 38
4bbf910e 39 e. `n_dups' is the number of match_dup's that appear in the insn's
a995e389
RH
40 pattern. This says how many elements of `recog_data.dup_loc' are
41 significant after an insn has been recognized.
9db4e0ec 42
4bbf910e 43 f. `n_alternatives' is the number of alternatives in the constraints
a995e389 44 of each pattern.
9db4e0ec 45
4bbf910e
RH
46 g. `output_format' tells what type of thing `output' is.
47
a995e389 48 h. `operand' is the base of an array of operand data for the insn.
9db4e0ec 49
a995e389 50 2. An array of `struct insn_operand data', used by `operand' above.
9db4e0ec 51
a995e389
RH
52 a. `predicate', an int-valued function, is the match_operand predicate
53 for this operand.
9db4e0ec 54
f38840db 55 b. `constraint' is the constraint for this operand.
9db4e0ec 56
a995e389 57 c. `address_p' indicates that the operand appears within ADDRESS
f38840db 58 rtx's.
9db4e0ec 59
a995e389 60 d. `mode' is the machine mode that that operand is supposed to have.
9db4e0ec 61
a995e389 62 e. `strict_low', is nonzero for operands contained in a STRICT_LOW_PART.
9db4e0ec 63
dfac187e
BS
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
4fd3a105
RS
68 g. `allows_mem', is true for operands that accept MEM rtxes.
69
a995e389
RH
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.
9db4e0ec 73
a995e389 74 Thus, the following entry in the machine description
9db4e0ec
RK
75
76 (define_insn "clrdf"
77 [(set (match_operand:DF 0 "general_operand" "")
78 (const_int 0))]
79 ""
80 "clrd %0")
81
a995e389
RH
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. */
9db4e0ec 85\f
4977bab6 86#include "bconfig.h"
0b93b64e 87#include "system.h"
4977bab6
ZW
88#include "coretypes.h"
89#include "tm.h"
9db4e0ec 90#include "rtl.h"
d80eb1e1 91#include "errors.h"
10692477 92#include "read-md.h"
c88c0d42 93#include "gensupport.h"
9db4e0ec 94
a995e389
RH
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? */
9db4e0ec
RK
98
99#define MAX_MAX_OPERANDS 40
100
3d7aafde
AJ
101static int n_occurrences (int, const char *);
102static const char *strip_whitespace (const char *);
9db4e0ec
RK
103
104/* insns in the machine description are assigned sequential code numbers
105 that are used by insn-recog.c (produced by genrecog) to communicate
106 to insn-output.c (produced by this program). */
107
108static int next_code_number;
109
110/* This counts all definitions in the md file,
111 for the sake of error messages. */
112
113static int next_index_number;
114
a995e389
RH
115/* This counts all operands used in the md file. The first is null. */
116
117static int next_operand_number = 1;
118
119/* Record in this chain all information about the operands we will output. */
120
121struct operand_data
122{
123 struct operand_data *next;
124 int index;
c1b59dce
KG
125 const char *predicate;
126 const char *constraint;
a995e389
RH
127 enum machine_mode mode;
128 unsigned char n_alternatives;
129 char address_p;
130 char strict_low;
dfac187e 131 char eliminable;
a995e389
RH
132 char seen;
133};
134
135/* Begin with a null operand at index 0. */
136
137static struct operand_data null_operand =
138{
f4e2ed09 139 0, 0, "", "", VOIDmode, 0, 0, 0, 0, 0
a995e389
RH
140};
141
142static struct operand_data *odata = &null_operand;
143static struct operand_data **odata_end = &null_operand.next;
144
4bbf910e
RH
145/* Must match the constants in recog.h. */
146
147#define INSN_OUTPUT_FORMAT_NONE 0 /* abort */
148#define INSN_OUTPUT_FORMAT_SINGLE 1 /* const char * */
149#define INSN_OUTPUT_FORMAT_MULTI 2 /* const char * const * */
150#define INSN_OUTPUT_FORMAT_FUNCTION 3 /* const char * (*)(...) */
151
9db4e0ec
RK
152/* Record in this chain all information that we will output,
153 associated with the code number of the insn. */
154
155struct data
156{
a995e389 157 struct data *next;
c1b59dce 158 const char *name;
8ad97cfc 159 const char *template_code;
a995e389
RH
160 int code_number;
161 int index_number;
1e9c8405 162 const char *filename;
d96a2fcd 163 int lineno;
b29387ee 164 int n_generator_args; /* Number of arguments passed to generator */
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
e714561a
SB
173/* A dummy insn, for CODE_FOR_nothing. */
174static struct data nothing;
175
a995e389 176/* This variable points to the first link in the insn chain. */
e714561a
SB
177static struct data *idata = &nothing;
178
179/* This variable points to the end of the insn chain. This is where
180 everything relevant from the machien description is appended to. */
181static struct data **idata_end = &nothing.next;
9db4e0ec 182
9db4e0ec 183\f
3d7aafde 184static void output_prologue (void);
3d7aafde
AJ
185static void output_operand_data (void);
186static void output_insn_data (void);
187static void output_get_insn_name (void);
188static void scan_operands (struct data *, rtx, int, int);
189static int compare_operands (struct operand_data *,
190 struct operand_data *);
191static void place_operands (struct data *);
192static void process_template (struct data *, const char *);
193static void validate_insn_alternatives (struct data *);
194static void validate_insn_operands (struct data *);
195static void gen_insn (rtx, int);
196static void gen_peephole (rtx, int);
197static void gen_expand (rtx, int);
198static void gen_split (rtx, int);
f38840db
ZW
199
200#ifdef USE_MD_CONSTRAINTS
201
202struct constraint_data
203{
204 struct constraint_data *next_this_letter;
205 int lineno;
206 unsigned int namelen;
207 const char name[1];
208};
209
210/* This is a complete list (unlike the one in genpreds.c) of constraint
211 letters and modifiers with machine-independent meaning. The only
212 omission is digits, as these are handled specially. */
213static const char indep_constraints[] = ",=+%*?!#&<>EFVXgimnoprs";
214
215static struct constraint_data *
216constraints_by_letter_table[1 << CHAR_BIT];
217
218static int mdep_constraint_len (const char *, int, int);
219static void note_constraint (rtx, int);
220
221#else /* !USE_MD_CONSTRAINTS */
222
3d7aafde
AJ
223static void check_constraint_len (void);
224static int constraint_len (const char *, int);
f38840db
ZW
225
226#endif /* !USE_MD_CONSTRAINTS */
227
56c0e996 228\f
9db4e0ec 229static void
3d7aafde 230output_prologue (void)
9db4e0ec 231{
9db4e0ec 232 printf ("/* Generated automatically by the program `genoutput'\n\
d96a2fcd 233 from the machine description file `md'. */\n\n");
9db4e0ec
RK
234
235 printf ("#include \"config.h\"\n");
729da3f5 236 printf ("#include \"system.h\"\n");
4977bab6
ZW
237 printf ("#include \"coretypes.h\"\n");
238 printf ("#include \"tm.h\"\n");
ccd043a9 239 printf ("#include \"flags.h\"\n");
3bc9f12b 240 printf ("#include \"ggc.h\"\n");
4d648807 241 printf ("#include \"tree.h\"\n");
9db4e0ec 242 printf ("#include \"rtl.h\"\n");
f3a8030a 243 printf ("#include \"expr.h\"\n");
e78d8e51 244 printf ("#include \"insn-codes.h\"\n");
6baf1cc8 245 printf ("#include \"tm_p.h\"\n");
49ad7cfa 246 printf ("#include \"function.h\"\n");
9db4e0ec
RK
247 printf ("#include \"regs.h\"\n");
248 printf ("#include \"hard-reg-set.h\"\n");
9db4e0ec
RK
249 printf ("#include \"insn-config.h\"\n\n");
250 printf ("#include \"conditions.h\"\n");
9db4e0ec 251 printf ("#include \"insn-attr.h\"\n\n");
9db4e0ec 252 printf ("#include \"recog.h\"\n\n");
79a3f089 253 printf ("#include \"diagnostic-core.h\"\n");
9db4e0ec 254 printf ("#include \"output.h\"\n");
4977bab6 255 printf ("#include \"target.h\"\n");
279bb624 256 printf ("#include \"tm-constrs.h\"\n");
9db4e0ec
RK
257}
258
a995e389 259static void
3d7aafde 260output_operand_data (void)
a995e389 261{
b3694847 262 struct operand_data *d;
a995e389
RH
263
264 printf ("\nstatic const struct insn_operand_data operand_data[] = \n{\n");
265
266 for (d = odata; d; d = d->next)
9db4e0ec 267 {
4fd3a105
RS
268 struct pred_data *pred;
269
a995e389
RH
270 printf (" {\n");
271
272 printf (" %s,\n",
273 d->predicate && d->predicate[0] ? d->predicate : "0");
274
19af6455 275 printf (" \"%s\",\n", d->constraint ? d->constraint : "");
9db4e0ec 276
a995e389
RH
277 printf (" %smode,\n", GET_MODE_NAME (d->mode));
278
dfac187e
BS
279 printf (" %d,\n", d->strict_low);
280
6ddfdb0f
BS
281 printf (" %d,\n", d->constraint == NULL ? 1 : 0);
282
4fd3a105
RS
283 printf (" %d,\n", d->eliminable);
284
285 pred = NULL;
286 if (d->predicate)
287 pred = lookup_predicate (d->predicate);
288 printf (" %d\n", pred && pred->codes[MEM]);
a995e389 289
c3284718 290 printf (" },\n");
a995e389 291 }
c3284718 292 printf ("};\n\n\n");
a995e389
RH
293}
294
295static void
3d7aafde 296output_insn_data (void)
a995e389 297{
b3694847 298 struct data *d;
a995e389
RH
299 int name_offset = 0;
300 int next_name_offset;
301 const char * last_name = 0;
302 const char * next_name = 0;
b3694847 303 struct data *n;
a995e389
RH
304
305 for (n = idata, next_name_offset = 1; n; n = n->next, next_name_offset++)
306 if (n->name)
9db4e0ec 307 {
a995e389
RH
308 next_name = n->name;
309 break;
9db4e0ec 310 }
9db4e0ec 311
3897f229 312 printf ("#if GCC_VERSION >= 2007\n__extension__\n#endif\n");
f12c802a 313 printf ("\nconst struct insn_data_d insn_data[] = \n{\n");
9db4e0ec 314
a995e389 315 for (d = idata; d; d = d->next)
9db4e0ec 316 {
1e9c8405 317 printf (" /* %s:%d */\n", d->filename, d->lineno);
a995e389
RH
318 printf (" {\n");
319
320 if (d->name)
9db4e0ec 321 {
a995e389
RH
322 printf (" \"%s\",\n", d->name);
323 name_offset = 0;
324 last_name = d->name;
325 next_name = 0;
326 for (n = d->next, next_name_offset = 1; n;
327 n = n->next, next_name_offset++)
9db4e0ec 328 {
a995e389
RH
329 if (n->name)
330 {
331 next_name = n->name;
332 break;
333 }
9db4e0ec 334 }
9db4e0ec 335 }
a995e389 336 else
9db4e0ec 337 {
a995e389
RH
338 name_offset++;
339 if (next_name && (last_name == 0
340 || name_offset > next_name_offset / 2))
341 printf (" \"%s-%d\",\n", next_name,
342 next_name_offset - name_offset);
343 else
344 printf (" \"%s+%d\",\n", last_name, name_offset);
9db4e0ec 345 }
9db4e0ec 346
4bbf910e
RH
347 switch (d->output_format)
348 {
349 case INSN_OUTPUT_FORMAT_NONE:
9ca1483b 350 printf ("#if HAVE_DESIGNATED_UNION_INITIALIZERS\n");
3897f229
JM
351 printf (" { 0 },\n");
352 printf ("#else\n");
353 printf (" { 0, 0, 0 },\n");
354 printf ("#endif\n");
4bbf910e
RH
355 break;
356 case INSN_OUTPUT_FORMAT_SINGLE:
212d447c 357 {
8ad97cfc 358 const char *p = d->template_code;
212d447c 359 char prev = 0;
3d7aafde 360
9ca1483b 361 printf ("#if HAVE_DESIGNATED_UNION_INITIALIZERS\n");
3897f229
JM
362 printf (" { .single =\n");
363 printf ("#else\n");
364 printf (" {\n");
365 printf ("#endif\n");
212d447c
DC
366 printf (" \"");
367 while (*p)
368 {
6b8b9d7b
CM
369 if (IS_VSPACE (*p) && prev != '\\')
370 {
371 /* Preserve two consecutive \n's or \r's, but treat \r\n
372 as a single newline. */
373 if (*p == '\n' && prev != '\r')
374 printf ("\\n\\\n");
375 }
212d447c
DC
376 else
377 putchar (*p);
378 prev = *p;
379 ++p;
380 }
381 printf ("\",\n");
9ca1483b 382 printf ("#if HAVE_DESIGNATED_UNION_INITIALIZERS\n");
3897f229
JM
383 printf (" },\n");
384 printf ("#else\n");
385 printf (" 0, 0 },\n");
386 printf ("#endif\n");
212d447c 387 }
4bbf910e
RH
388 break;
389 case INSN_OUTPUT_FORMAT_MULTI:
9ca1483b 390 printf ("#if HAVE_DESIGNATED_UNION_INITIALIZERS\n");
3897f229
JM
391 printf (" { .multi = output_%d },\n", d->code_number);
392 printf ("#else\n");
393 printf (" { 0, output_%d, 0 },\n", d->code_number);
394 printf ("#endif\n");
395 break;
4bbf910e 396 case INSN_OUTPUT_FORMAT_FUNCTION:
9ca1483b 397 printf ("#if HAVE_DESIGNATED_UNION_INITIALIZERS\n");
3897f229
JM
398 printf (" { .function = output_%d },\n", d->code_number);
399 printf ("#else\n");
400 printf (" { 0, 0, output_%d },\n", d->code_number);
401 printf ("#endif\n");
4bbf910e
RH
402 break;
403 default:
b2d59f6f 404 gcc_unreachable ();
4bbf910e 405 }
a995e389
RH
406
407 if (d->name && d->name[0] != '*')
eb923e54 408 printf (" { (insn_gen_fn::stored_funcptr) gen_%s },\n", d->name);
a995e389 409 else
eb923e54 410 printf (" { 0 },\n");
a995e389
RH
411
412 printf (" &operand_data[%d],\n", d->operand_number);
b29387ee 413 printf (" %d,\n", d->n_generator_args);
a995e389
RH
414 printf (" %d,\n", d->n_operands);
415 printf (" %d,\n", d->n_dups);
4bbf910e
RH
416 printf (" %d,\n", d->n_alternatives);
417 printf (" %d\n", d->output_format);
a995e389 418
c3284718 419 printf (" },\n");
9db4e0ec 420 }
a995e389
RH
421 printf ("};\n\n\n");
422}
9db4e0ec 423
a995e389 424static void
3d7aafde 425output_get_insn_name (void)
a995e389
RH
426{
427 printf ("const char *\n");
6906ba40 428 printf ("get_insn_name (int code)\n");
a995e389 429 printf ("{\n");
a0f0e963
SB
430 printf (" if (code == NOOP_MOVE_INSN_CODE)\n");
431 printf (" return \"NOOP_MOVE\";\n");
432 printf (" else\n");
433 printf (" return insn_data[code].name;\n");
a995e389 434 printf ("}\n");
9db4e0ec 435}
a995e389 436
9db4e0ec 437\f
b29387ee 438/* Stores the operand data into `d->operand[i]'.
9db4e0ec
RK
439
440 THIS_ADDRESS_P is nonzero if the containing rtx was an ADDRESS.
441 THIS_STRICT_LOW is nonzero if the containing rtx was a STRICT_LOW_PART. */
442
9db4e0ec 443static void
3d7aafde
AJ
444scan_operands (struct data *d, rtx part, int this_address_p,
445 int this_strict_low)
9db4e0ec 446{
b3694847
SS
447 int i, j;
448 const char *format_ptr;
9db4e0ec
RK
449 int opno;
450
451 if (part == 0)
452 return;
453
454 switch (GET_CODE (part))
455 {
456 case MATCH_OPERAND:
457 opno = XINT (part, 0);
b29387ee 458 if (opno >= MAX_MAX_OPERANDS)
5a806d65 459 {
bb933490 460 error_with_line (d->lineno, "maximum number of operands exceeded");
5a806d65
RK
461 return;
462 }
a995e389 463 if (d->operand[opno].seen)
bb933490 464 error_with_line (d->lineno, "repeated operand number %d\n", opno);
d96a2fcd 465
a995e389
RH
466 d->operand[opno].seen = 1;
467 d->operand[opno].mode = GET_MODE (part);
468 d->operand[opno].strict_low = this_strict_low;
469 d->operand[opno].predicate = XSTR (part, 1);
665f2503
RK
470 d->operand[opno].constraint = strip_whitespace (XSTR (part, 2));
471 d->operand[opno].n_alternatives
472 = n_occurrences (',', d->operand[opno].constraint) + 1;
a995e389 473 d->operand[opno].address_p = this_address_p;
dfac187e 474 d->operand[opno].eliminable = 1;
9db4e0ec
RK
475 return;
476
477 case MATCH_SCRATCH:
478 opno = XINT (part, 0);
b29387ee 479 if (opno >= MAX_MAX_OPERANDS)
5a806d65 480 {
bb933490 481 error_with_line (d->lineno, "maximum number of operands exceeded");
5a806d65
RK
482 return;
483 }
a995e389 484 if (d->operand[opno].seen)
bb933490 485 error_with_line (d->lineno, "repeated operand number %d\n", opno);
d96a2fcd 486
a995e389
RH
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 = "scratch_operand";
665f2503
RK
491 d->operand[opno].constraint = strip_whitespace (XSTR (part, 1));
492 d->operand[opno].n_alternatives
493 = n_occurrences (',', d->operand[opno].constraint) + 1;
a995e389 494 d->operand[opno].address_p = 0;
dfac187e 495 d->operand[opno].eliminable = 0;
9db4e0ec
RK
496 return;
497
498 case MATCH_OPERATOR:
499 case MATCH_PARALLEL:
500 opno = XINT (part, 0);
b29387ee 501 if (opno >= MAX_MAX_OPERANDS)
5a806d65 502 {
bb933490 503 error_with_line (d->lineno, "maximum number of operands exceeded");
5a806d65
RK
504 return;
505 }
a995e389 506 if (d->operand[opno].seen)
bb933490 507 error_with_line (d->lineno, "repeated operand number %d\n", opno);
d96a2fcd 508
a995e389
RH
509 d->operand[opno].seen = 1;
510 d->operand[opno].mode = GET_MODE (part);
511 d->operand[opno].strict_low = 0;
512 d->operand[opno].predicate = XSTR (part, 1);
513 d->operand[opno].constraint = 0;
514 d->operand[opno].address_p = 0;
dfac187e 515 d->operand[opno].eliminable = 0;
9db4e0ec 516 for (i = 0; i < XVECLEN (part, 2); i++)
a995e389 517 scan_operands (d, XVECEXP (part, 2, i), 0, 0);
9db4e0ec
RK
518 return;
519
9db4e0ec 520 case STRICT_LOW_PART:
a995e389 521 scan_operands (d, XEXP (part, 0), 0, 1);
9db4e0ec 522 return;
3d7aafde 523
ccd043a9
RL
524 default:
525 break;
9db4e0ec
RK
526 }
527
528 format_ptr = GET_RTX_FORMAT (GET_CODE (part));
529
530 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
531 switch (*format_ptr++)
532 {
533 case 'e':
ccd043a9 534 case 'u':
a995e389 535 scan_operands (d, XEXP (part, i), 0, 0);
9db4e0ec
RK
536 break;
537 case 'E':
538 if (XVEC (part, i) != NULL)
539 for (j = 0; j < XVECLEN (part, i); j++)
a995e389 540 scan_operands (d, XVECEXP (part, i, j), 0, 0);
9db4e0ec
RK
541 break;
542 }
543}
a995e389
RH
544
545/* Compare two operands for content equality. */
546
547static int
3d7aafde 548compare_operands (struct operand_data *d0, struct operand_data *d1)
a995e389 549{
c1b59dce 550 const char *p0, *p1;
a995e389
RH
551
552 p0 = d0->predicate;
553 if (!p0)
554 p0 = "";
555 p1 = d1->predicate;
556 if (!p1)
557 p1 = "";
558 if (strcmp (p0, p1) != 0)
559 return 0;
560
19af6455
BS
561 p0 = d0->constraint;
562 if (!p0)
563 p0 = "";
564 p1 = d1->constraint;
565 if (!p1)
566 p1 = "";
567 if (strcmp (p0, p1) != 0)
568 return 0;
a995e389
RH
569
570 if (d0->mode != d1->mode)
571 return 0;
572
a995e389
RH
573 if (d0->strict_low != d1->strict_low)
574 return 0;
575
dfac187e
BS
576 if (d0->eliminable != d1->eliminable)
577 return 0;
578
a995e389
RH
579 return 1;
580}
581
582/* Scan the list of operands we've already committed to output and either
583 find a subsequence that is the same, or allocate a new one at the end. */
584
585static void
3d7aafde 586place_operands (struct data *d)
a995e389
RH
587{
588 struct operand_data *od, *od2;
589 int i;
590
591 if (d->n_operands == 0)
592 {
593 d->operand_number = 0;
594 return;
595 }
596
597 /* Brute force substring search. */
598 for (od = odata, i = 0; od; od = od->next, i = 0)
599 if (compare_operands (od, &d->operand[0]))
600 {
601 od2 = od->next;
602 i = 1;
603 while (1)
604 {
605 if (i == d->n_operands)
606 goto full_match;
607 if (od2 == NULL)
608 goto partial_match;
609 if (! compare_operands (od2, &d->operand[i]))
610 break;
611 ++i, od2 = od2->next;
612 }
613 }
614
615 /* Either partial match at the end of the list, or no match. In either
616 case, we tack on what operands are remaining to the end of the list. */
617 partial_match:
618 d->operand_number = next_operand_number - i;
619 for (; i < d->n_operands; ++i)
620 {
621 od2 = &d->operand[i];
622 *odata_end = od2;
623 odata_end = &od2->next;
624 od2->index = next_operand_number++;
625 }
626 *odata_end = NULL;
627 return;
628
629 full_match:
630 d->operand_number = od->index;
631 return;
632}
633
9db4e0ec
RK
634\f
635/* Process an assembler template from a define_insn or a define_peephole.
636 It is either the assembler code template, a list of assembler code
637 templates, or C code to generate the assembler code template. */
638
639static void
8ad97cfc 640process_template (struct data *d, const char *template_code)
9db4e0ec 641{
b3694847
SS
642 const char *cp;
643 int i;
9db4e0ec 644
4bbf910e 645 /* Templates starting with * contain straight code to be run. */
8ad97cfc 646 if (template_code[0] == '*')
9db4e0ec 647 {
8ad97cfc 648 d->template_code = 0;
4bbf910e 649 d->output_format = INSN_OUTPUT_FORMAT_FUNCTION;
9db4e0ec 650
4bbf910e 651 puts ("\nstatic const char *");
6906ba40
KG
652 printf ("output_%d (rtx *operands ATTRIBUTE_UNUSED, rtx insn ATTRIBUTE_UNUSED)\n",
653 d->code_number);
4bbf910e 654 puts ("{");
d2a3ce4e 655 print_md_ptr_loc (template_code);
8ad97cfc 656 puts (template_code + 1);
4bbf910e
RH
657 puts ("}");
658 }
9db4e0ec
RK
659
660 /* If the assembler code template starts with a @ it is a newline-separated
4bbf910e 661 list of assembler code templates, one for each alternative. */
8ad97cfc 662 else if (template_code[0] == '@')
9db4e0ec 663 {
94c765ab 664 int found_star = 0;
9db4e0ec 665
94c765ab
R
666 for (cp = &template_code[1]; *cp; )
667 {
668 while (ISSPACE (*cp))
669 cp++;
670 if (*cp == '*')
671 found_star = 1;
672 while (!IS_VSPACE (*cp) && *cp != '\0')
673 ++cp;
674 }
675 d->template_code = 0;
676 if (found_star)
677 {
678 d->output_format = INSN_OUTPUT_FORMAT_FUNCTION;
679 puts ("\nstatic const char *");
680 printf ("output_%d (rtx *operands ATTRIBUTE_UNUSED, "
681 "rtx insn ATTRIBUTE_UNUSED)\n", d->code_number);
682 puts ("{");
683 puts (" switch (which_alternative)\n {");
684 }
685 else
686 {
687 d->output_format = INSN_OUTPUT_FORMAT_MULTI;
688 printf ("\nstatic const char * const output_%d[] = {\n",
689 d->code_number);
690 }
9db4e0ec 691
8ad97cfc 692 for (i = 0, cp = &template_code[1]; *cp; )
9db4e0ec 693 {
94c765ab 694 const char *ep, *sp, *bp;
4112be4a 695
6b8b9d7b 696 while (ISSPACE (*cp))
9db4e0ec
RK
697 cp++;
698
94c765ab
R
699 bp = cp;
700 if (found_star)
701 {
702 printf (" case %d:", i);
703 if (*cp == '*')
704 {
705 printf ("\n ");
706 cp++;
707 }
708 else
709 printf (" return \"");
710 }
711 else
712 printf (" \"");
4112be4a
JJ
713
714 for (ep = sp = cp; !IS_VSPACE (*ep) && *ep != '\0'; ++ep)
715 if (!ISSPACE (*ep))
716 sp = ep + 1;
717
718 if (sp != ep)
719 message_with_line (d->lineno,
720 "trailing whitespace in output template");
721
722 while (cp < sp)
2f013c71
RK
723 {
724 putchar (*cp);
725 cp++;
726 }
9db4e0ec 727
94c765ab
R
728 if (!found_star)
729 puts ("\",");
730 else if (*bp != '*')
731 puts ("\";");
732 else
733 {
734 /* The usual action will end with a return.
735 If there is neither break or return at the end, this is
736 assumed to be intentional; this allows to have multiple
737 consecutive alternatives share some code. */
738 puts ("");
739 }
9db4e0ec
RK
740 i++;
741 }
c6d79bee
JH
742 if (i == 1)
743 message_with_line (d->lineno,
744 "'@' is redundant for output template with single alternative");
745 if (i != d->n_alternatives)
bb933490
RS
746 error_with_line (d->lineno,
747 "wrong number of alternatives in the output template");
9db4e0ec 748
94c765ab
R
749 if (found_star)
750 puts (" default: gcc_unreachable ();\n }\n}");
751 else
752 printf ("};\n");
9db4e0ec
RK
753 }
754 else
755 {
8ad97cfc 756 d->template_code = template_code;
4bbf910e 757 d->output_format = INSN_OUTPUT_FORMAT_SINGLE;
9db4e0ec 758 }
9db4e0ec
RK
759}
760\f
761/* Check insn D for consistency in number of constraint alternatives. */
762
763static void
3d7aafde 764validate_insn_alternatives (struct data *d)
9db4e0ec 765{
b3694847 766 int n = 0, start;
a995e389
RH
767
768 /* Make sure all the operands have the same number of alternatives
769 in their constraints. Let N be that number. */
9db4e0ec 770 for (start = 0; start < d->n_operands; start++)
a995e389 771 if (d->operand[start].n_alternatives > 0)
9db4e0ec 772 {
97488870
R
773 int len, i;
774 const char *p;
775 char c;
776 int which_alternative = 0;
777 int alternative_count_unsure = 0;
778
779 for (p = d->operand[start].constraint; (c = *p); p += len)
780 {
f38840db
ZW
781#ifdef USE_MD_CONSTRAINTS
782 if (ISSPACE (c) || strchr (indep_constraints, c))
783 len = 1;
784 else if (ISDIGIT (c))
785 {
786 const char *q = p;
787 do
788 q++;
789 while (ISDIGIT (*q));
790 len = q - p;
791 }
792 else
793 len = mdep_constraint_len (p, d->lineno, start);
794#else
97488870
R
795 len = CONSTRAINT_LEN (c, p);
796
797 if (len < 1 || (len > 1 && strchr (",#*+=&%!0123456789", c)))
798 {
bb933490
RS
799 error_with_line (d->lineno,
800 "invalid length %d for char '%c' in"
801 " alternative %d of operand %d",
802 len, c, which_alternative, start);
97488870 803 len = 1;
97488870 804 }
f38840db 805#endif
97488870
R
806
807 if (c == ',')
808 {
809 which_alternative++;
810 continue;
811 }
812
813 for (i = 1; i < len; i++)
814 if (p[i] == '\0')
815 {
bb933490
RS
816 error_with_line (d->lineno,
817 "NUL in alternative %d of operand %d",
818 which_alternative, start);
97488870
R
819 alternative_count_unsure = 1;
820 break;
821 }
822 else if (strchr (",#*", p[i]))
823 {
bb933490
RS
824 error_with_line (d->lineno,
825 "'%c' in alternative %d of operand %d",
826 p[i], which_alternative, start);
97488870
R
827 alternative_count_unsure = 1;
828 }
829 }
bb933490 830 if (!alternative_count_unsure)
d96a2fcd 831 {
bb933490
RS
832 if (n == 0)
833 n = d->operand[start].n_alternatives;
834 else if (n != d->operand[start].n_alternatives)
835 error_with_line (d->lineno,
d96a2fcd
RH
836 "wrong number of alternatives in operand %d",
837 start);
d96a2fcd 838 }
9db4e0ec 839 }
a995e389 840
9db4e0ec
RK
841 /* Record the insn's overall number of alternatives. */
842 d->n_alternatives = n;
843}
c77e04ae
RH
844
845/* Verify that there are no gaps in operand numbers for INSNs. */
846
847static void
3d7aafde 848validate_insn_operands (struct data *d)
c77e04ae
RH
849{
850 int i;
851
852 for (i = 0; i < d->n_operands; ++i)
853 if (d->operand[i].seen == 0)
bb933490 854 error_with_line (d->lineno, "missing operand %d", i);
c77e04ae 855}
7ddf71e3
PB
856
857static void
858validate_optab_operands (struct data *d)
859{
860 if (!d->name || d->name[0] == '\0' || d->name[0] == '*')
861 return;
862
863 /* Miscellaneous tests. */
864 if (strncmp (d->name, "cstore", 6) == 0
865 && d->name[strlen (d->name) - 1] == '4'
866 && d->operand[0].mode == VOIDmode)
867 {
868 message_with_line (d->lineno, "missing mode for operand 0 of cstore");
869 have_error = 1;
870 }
871}
9db4e0ec 872\f
a995e389
RH
873/* Look at a define_insn just read. Assign its code number. Record
874 on idata the template and the number of arguments. If the insn has
875 a hairy output action, output a function for now. */
9db4e0ec
RK
876
877static void
3d7aafde 878gen_insn (rtx insn, int lineno)
9db4e0ec 879{
b29387ee 880 struct pattern_stats stats;
5ed6ace5 881 struct data *d = XNEW (struct data);
b3694847 882 int i;
9db4e0ec 883
c88c0d42 884 d->code_number = next_code_number;
9db4e0ec 885 d->index_number = next_index_number;
d2a3ce4e 886 d->filename = read_md_filename;
d96a2fcd 887 d->lineno = lineno;
9db4e0ec
RK
888 if (XSTR (insn, 0)[0])
889 d->name = XSTR (insn, 0);
890 else
891 d->name = 0;
892
893 /* Build up the list in the same order as the insns are seen
894 in the machine description. */
895 d->next = 0;
a995e389
RH
896 *idata_end = d;
897 idata_end = &d->next;
9db4e0ec 898
a995e389 899 memset (d->operand, 0, sizeof (d->operand));
9db4e0ec
RK
900
901 for (i = 0; i < XVECLEN (insn, 1); i++)
a995e389 902 scan_operands (d, XVECEXP (insn, 1, i), 0, 0);
9db4e0ec 903
b29387ee
RS
904 get_pattern_stats (&stats, XVEC (insn, 1));
905 d->n_generator_args = stats.num_generator_args;
906 d->n_operands = stats.num_insn_operands;
907 d->n_dups = stats.num_dups;
9db4e0ec 908
f38840db 909#ifndef USE_MD_CONSTRAINTS
97488870 910 check_constraint_len ();
f38840db 911#endif
c77e04ae 912 validate_insn_operands (d);
9db4e0ec 913 validate_insn_alternatives (d);
7ddf71e3 914 validate_optab_operands (d);
a995e389 915 place_operands (d);
1f3b37a3 916 process_template (d, XTMPL (insn, 3));
9db4e0ec
RK
917}
918\f
919/* Look at a define_peephole just read. Assign its code number.
a995e389 920 Record on idata the template and the number of arguments.
9db4e0ec
RK
921 If the insn has a hairy output action, output it now. */
922
923static void
3d7aafde 924gen_peephole (rtx peep, int lineno)
9db4e0ec 925{
b29387ee 926 struct pattern_stats stats;
5ed6ace5 927 struct data *d = XNEW (struct data);
b3694847 928 int i;
9db4e0ec 929
c88c0d42 930 d->code_number = next_code_number;
9db4e0ec 931 d->index_number = next_index_number;
d2a3ce4e 932 d->filename = read_md_filename;
d96a2fcd 933 d->lineno = lineno;
9db4e0ec
RK
934 d->name = 0;
935
936 /* Build up the list in the same order as the insns are seen
937 in the machine description. */
938 d->next = 0;
a995e389
RH
939 *idata_end = d;
940 idata_end = &d->next;
9db4e0ec 941
a995e389
RH
942 memset (d->operand, 0, sizeof (d->operand));
943
944 /* Get the number of operands by scanning all the patterns of the
945 peephole optimizer. But ignore all the rest of the information
946 thus obtained. */
9db4e0ec 947 for (i = 0; i < XVECLEN (peep, 0); i++)
a995e389 948 scan_operands (d, XVECEXP (peep, 0, i), 0, 0);
9db4e0ec 949
b29387ee
RS
950 get_pattern_stats (&stats, XVEC (peep, 0));
951 d->n_generator_args = 0;
952 d->n_operands = stats.num_insn_operands;
9db4e0ec
RK
953 d->n_dups = 0;
954
9db4e0ec 955 validate_insn_alternatives (d);
a995e389 956 place_operands (d);
1f3b37a3 957 process_template (d, XTMPL (peep, 2));
9db4e0ec
RK
958}
959\f
960/* Process a define_expand just read. Assign its code number,
961 only for the purposes of `insn_gen_function'. */
962
963static void
3d7aafde 964gen_expand (rtx insn, int lineno)
9db4e0ec 965{
b29387ee 966 struct pattern_stats stats;
5ed6ace5 967 struct data *d = XNEW (struct data);
b3694847 968 int i;
9db4e0ec 969
c88c0d42 970 d->code_number = next_code_number;
9db4e0ec 971 d->index_number = next_index_number;
d2a3ce4e 972 d->filename = read_md_filename;
d96a2fcd 973 d->lineno = lineno;
9db4e0ec
RK
974 if (XSTR (insn, 0)[0])
975 d->name = XSTR (insn, 0);
976 else
977 d->name = 0;
978
979 /* Build up the list in the same order as the insns are seen
980 in the machine description. */
981 d->next = 0;
a995e389
RH
982 *idata_end = d;
983 idata_end = &d->next;
9db4e0ec 984
a995e389 985 memset (d->operand, 0, sizeof (d->operand));
9db4e0ec
RK
986
987 /* Scan the operands to get the specified predicates and modes,
988 since expand_binop needs to know them. */
989
9db4e0ec
RK
990 if (XVEC (insn, 1))
991 for (i = 0; i < XVECLEN (insn, 1); i++)
a995e389 992 scan_operands (d, XVECEXP (insn, 1, i), 0, 0);
9db4e0ec 993
b29387ee
RS
994 get_pattern_stats (&stats, XVEC (insn, 1));
995 d->n_generator_args = stats.num_generator_args;
996 d->n_operands = stats.num_insn_operands;
997 d->n_dups = stats.num_dups;
8ad97cfc 998 d->template_code = 0;
4bbf910e 999 d->output_format = INSN_OUTPUT_FORMAT_NONE;
a995e389 1000
9db4e0ec 1001 validate_insn_alternatives (d);
7ddf71e3 1002 validate_optab_operands (d);
a995e389 1003 place_operands (d);
9db4e0ec
RK
1004}
1005\f
1006/* Process a define_split just read. Assign its code number,
1007 only for reasons of consistency and to simplify genrecog. */
1008
9db4e0ec 1009static void
3d7aafde 1010gen_split (rtx split, int lineno)
9db4e0ec 1011{
b29387ee 1012 struct pattern_stats stats;
5ed6ace5 1013 struct data *d = XNEW (struct data);
b3694847 1014 int i;
9db4e0ec 1015
c88c0d42 1016 d->code_number = next_code_number;
9db4e0ec 1017 d->index_number = next_index_number;
d2a3ce4e 1018 d->filename = read_md_filename;
d96a2fcd 1019 d->lineno = lineno;
9db4e0ec
RK
1020 d->name = 0;
1021
1022 /* Build up the list in the same order as the insns are seen
1023 in the machine description. */
1024 d->next = 0;
a995e389
RH
1025 *idata_end = d;
1026 idata_end = &d->next;
9db4e0ec 1027
a995e389 1028 memset (d->operand, 0, sizeof (d->operand));
9db4e0ec 1029
a995e389
RH
1030 /* Get the number of operands by scanning all the patterns of the
1031 split patterns. But ignore all the rest of the information thus
1032 obtained. */
9db4e0ec 1033 for (i = 0; i < XVECLEN (split, 0); i++)
a995e389 1034 scan_operands (d, XVECEXP (split, 0, i), 0, 0);
9db4e0ec 1035
b29387ee
RS
1036 get_pattern_stats (&stats, XVEC (split, 0));
1037 d->n_generator_args = 0;
1038 d->n_operands = stats.num_insn_operands;
9db4e0ec 1039 d->n_dups = 0;
42495ca0 1040 d->n_alternatives = 0;
8ad97cfc 1041 d->template_code = 0;
4bbf910e 1042 d->output_format = INSN_OUTPUT_FORMAT_NONE;
a995e389
RH
1043
1044 place_operands (d);
9db4e0ec 1045}
9db4e0ec 1046
e714561a
SB
1047static void
1048init_insn_for_nothing (void)
1049{
1050 memset (&nothing, 0, sizeof (nothing));
1051 nothing.name = "*placeholder_for_nothing";
1052 nothing.filename = "<internal>";
1053}
1054
3d7aafde 1055extern int main (int, char **);
c1b59dce 1056
9db4e0ec 1057int
3d7aafde 1058main (int argc, char **argv)
9db4e0ec
RK
1059{
1060 rtx desc;
9db4e0ec 1061
d80eb1e1
RH
1062 progname = "genoutput";
1063
e714561a
SB
1064 init_insn_for_nothing ();
1065
600ab3fc 1066 if (!init_rtx_reader_args (argc, argv))
c88c0d42 1067 return (FATAL_EXIT_CODE);
9db4e0ec 1068
9db4e0ec 1069 output_prologue ();
9db4e0ec 1070 next_index_number = 0;
9db4e0ec
RK
1071
1072 /* Read the machine description. */
1073
1074 while (1)
1075 {
c88c0d42
CP
1076 int line_no;
1077
1078 desc = read_md_rtx (&line_no, &next_code_number);
1079 if (desc == NULL)
9db4e0ec 1080 break;
9db4e0ec 1081
f38840db
ZW
1082 switch (GET_CODE (desc))
1083 {
1084 case DEFINE_INSN:
1085 gen_insn (desc, line_no);
1086 break;
1087
1088 case DEFINE_PEEPHOLE:
1089 gen_peephole (desc, line_no);
1090 break;
1091
1092 case DEFINE_EXPAND:
1093 gen_expand (desc, line_no);
1094 break;
1095
1096 case DEFINE_SPLIT:
1097 case DEFINE_PEEPHOLE2:
1098 gen_split (desc, line_no);
1099 break;
1100
1101#ifdef USE_MD_CONSTRAINTS
1102 case DEFINE_CONSTRAINT:
1103 case DEFINE_REGISTER_CONSTRAINT:
1104 case DEFINE_ADDRESS_CONSTRAINT:
1105 case DEFINE_MEMORY_CONSTRAINT:
1106 note_constraint (desc, line_no);
1107 break;
1108#endif
1109
1110 default:
1111 break;
1112 }
9db4e0ec
RK
1113 next_index_number++;
1114 }
1115
c3284718 1116 printf ("\n\n");
a995e389
RH
1117 output_operand_data ();
1118 output_insn_data ();
1119 output_get_insn_name ();
9db4e0ec
RK
1120
1121 fflush (stdout);
c1b59dce 1122 return (ferror (stdout) != 0 || have_error
6a270722 1123 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
9db4e0ec
RK
1124}
1125
665f2503
RK
1126/* Return the number of occurrences of character C in string S or
1127 -1 if S is the null string. */
1128
9db4e0ec 1129static int
3d7aafde 1130n_occurrences (int c, const char *s)
9db4e0ec
RK
1131{
1132 int n = 0;
665f2503
RK
1133
1134 if (s == 0 || *s == '\0')
1135 return -1;
1136
9db4e0ec
RK
1137 while (*s)
1138 n += (*s++ == c);
665f2503 1139
9db4e0ec
RK
1140 return n;
1141}
88a56c2e 1142
665f2503
RK
1143/* Remove whitespace in `s' by moving up characters until the end.
1144 Return a new string. */
1145
1146static const char *
3d7aafde 1147strip_whitespace (const char *s)
88a56c2e 1148{
665f2503
RK
1149 char *p, *q;
1150 char ch;
1151
1152 if (s == 0)
1153 return 0;
88a56c2e 1154
5ed6ace5 1155 p = q = XNEWVEC (char, strlen (s) + 1);
88a56c2e
HPN
1156 while ((ch = *s++) != '\0')
1157 if (! ISSPACE (ch))
1158 *p++ = ch;
1159
1160 *p = '\0';
665f2503 1161 return q;
88a56c2e 1162}
97488870 1163
f38840db
ZW
1164#ifdef USE_MD_CONSTRAINTS
1165
1166/* Record just enough information about a constraint to allow checking
1167 of operand constraint strings above, in validate_insn_alternatives.
1168 Does not validate most properties of the constraint itself; does
1169 enforce no duplicate names, no overlap with MI constraints, and no
1170 prefixes. EXP is the define_*constraint form, LINENO the line number
1171 reported by the reader. */
1172static void
1173note_constraint (rtx exp, int lineno)
1174{
1175 const char *name = XSTR (exp, 0);
1176 unsigned int namelen = strlen (name);
8ad97cfc 1177 struct constraint_data **iter, **slot, *new_cdata;
f38840db 1178
a4edaf83
AK
1179 /* The 'm' constraint is special here since that constraint letter
1180 can be overridden by the back end by defining the
1181 TARGET_MEM_CONSTRAINT macro. */
1182 if (strchr (indep_constraints, name[0]) && name[0] != 'm')
f38840db
ZW
1183 {
1184 if (name[1] == '\0')
bb933490
RS
1185 error_with_line (lineno, "constraint letter '%s' cannot be "
1186 "redefined by the machine description", name);
f38840db 1187 else
bb933490
RS
1188 error_with_line (lineno, "constraint name '%s' cannot be defined by "
1189 "the machine description, as it begins with '%c'",
1190 name, name[0]);
f38840db
ZW
1191 return;
1192 }
1193
1194 slot = &constraints_by_letter_table[(unsigned int)name[0]];
1195 for (iter = slot; *iter; iter = &(*iter)->next_this_letter)
1196 {
1197 /* This causes slot to end up pointing to the
1198 next_this_letter field of the last constraint with a name
1199 of equal or greater length than the new constraint; hence
1200 the new constraint will be inserted after all previous
1201 constraints with names of the same length. */
1202 if ((*iter)->namelen >= namelen)
1203 slot = iter;
1204
1205 if (!strcmp ((*iter)->name, name))
1206 {
bb933490 1207 error_with_line (lineno, "redefinition of constraint '%s'", name);
f38840db 1208 message_with_line ((*iter)->lineno, "previous definition is here");
f38840db
ZW
1209 return;
1210 }
1211 else if (!strncmp ((*iter)->name, name, (*iter)->namelen))
1212 {
bb933490 1213 error_with_line (lineno, "defining constraint '%s' here", name);
f38840db
ZW
1214 message_with_line ((*iter)->lineno, "renders constraint '%s' "
1215 "(defined here) a prefix", (*iter)->name);
f38840db
ZW
1216 return;
1217 }
1218 else if (!strncmp ((*iter)->name, name, namelen))
1219 {
bb933490 1220 error_with_line (lineno, "constraint '%s' is a prefix", name);
f38840db
ZW
1221 message_with_line ((*iter)->lineno, "of constraint '%s' "
1222 "(defined here)", (*iter)->name);
f38840db
ZW
1223 return;
1224 }
1225 }
8ad97cfc 1226 new_cdata = XNEWVAR (struct constraint_data, sizeof (struct constraint_data) + namelen);
c3284718 1227 strcpy (CONST_CAST (char *, new_cdata->name), name);
8ad97cfc
KG
1228 new_cdata->namelen = namelen;
1229 new_cdata->lineno = lineno;
1230 new_cdata->next_this_letter = *slot;
1231 *slot = new_cdata;
f38840db
ZW
1232}
1233
1234/* Return the length of the constraint name beginning at position S
1235 of an operand constraint string, or issue an error message if there
1236 is no such constraint. Does not expect to be called for generic
1237 constraints. */
1238static int
1239mdep_constraint_len (const char *s, int lineno, int opno)
1240{
1241 struct constraint_data *p;
1242
1243 p = constraints_by_letter_table[(unsigned int)s[0]];
1244
1245 if (p)
1246 for (; p; p = p->next_this_letter)
1247 if (!strncmp (s, p->name, p->namelen))
1248 return p->namelen;
1249
bb933490
RS
1250 error_with_line (lineno,
1251 "error: undefined machine-specific constraint "
1252 "at this point: \"%s\"", s);
f38840db 1253 message_with_line (lineno, "note: in operand %d", opno);
f38840db
ZW
1254 return 1; /* safe */
1255}
1256
1257#else
97488870
R
1258/* Verify that DEFAULT_CONSTRAINT_LEN is used properly and not
1259 tampered with. This isn't bullet-proof, but it should catch
1260 most genuine mistakes. */
1261static void
3d7aafde 1262check_constraint_len (void)
97488870
R
1263{
1264 const char *p;
1265 int d;
1266
1267 for (p = ",#*+=&%!1234567890"; *p; p++)
1268 for (d = -9; d < 9; d++)
b2d59f6f 1269 gcc_assert (constraint_len (p, d) == d);
97488870
R
1270}
1271
1272static int
3d7aafde 1273constraint_len (const char *p, int genoutput_default_constraint_len)
97488870
R
1274{
1275 /* Check that we still match defaults.h . First we do a generation-time
1276 check that fails if the value is not the expected one... */
b2d59f6f 1277 gcc_assert (DEFAULT_CONSTRAINT_LEN (*p, p) == 1);
2067c116 1278 /* And now a compile-time check that should give a diagnostic if the
97488870
R
1279 definition doesn't exactly match. */
1280#define DEFAULT_CONSTRAINT_LEN(C,STR) 1
1281 /* Now re-define DEFAULT_CONSTRAINT_LEN so that we can verify it is
1282 being used. */
1283#undef DEFAULT_CONSTRAINT_LEN
1284#define DEFAULT_CONSTRAINT_LEN(C,STR) \
1285 ((C) != *p || STR != p ? -1 : genoutput_default_constraint_len)
1286 return CONSTRAINT_LEN (*p, p);
1287 /* And set it back. */
1288#undef DEFAULT_CONSTRAINT_LEN
1289#define DEFAULT_CONSTRAINT_LEN(C,STR) 1
1290}
f38840db 1291#endif