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