]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/gensupport.c
driver-i386.c (detect_caches_amd, [...]): Fix -Wc++-compat and/or -Wcast-qual warnings.
[thirdparty/gcc.git] / gcc / gensupport.c
CommitLineData
3916d6d8 1/* Support routines for the various generation passes.
9dcd6f09 2 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
3d7aafde 3 Free Software Foundation, Inc.
c88c0d42 4
1322177d 5 This file is part of GCC.
c88c0d42 6
1322177d
LB
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9dcd6f09 9 the Free Software Foundation; either version 3, or (at your option)
c88c0d42
CP
10 any later version.
11
1322177d
LB
12 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
c88c0d42
CP
16
17 You should have received a copy of the GNU General Public License
9dcd6f09
NC
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
c88c0d42 20
4977bab6 21#include "bconfig.h"
c88c0d42 22#include "system.h"
4977bab6
ZW
23#include "coretypes.h"
24#include "tm.h"
c88c0d42 25#include "rtl.h"
3916d6d8 26#include "obstack.h"
c88c0d42 27#include "errors.h"
2199e5fa 28#include "hashtab.h"
c88c0d42
CP
29#include "gensupport.h"
30
3916d6d8 31
c8cf201f
RK
32/* In case some macros used by files we include need it, define this here. */
33int target_flags;
34
2199e5fa
ZW
35int insn_elision = 1;
36
e543e219
ZW
37const char *in_fname;
38
26be549a
RH
39/* This callback will be invoked whenever an rtl include directive is
40 processed. To be used for creation of the dependency file. */
41void (*include_callback) (const char *);
42
3916d6d8
RH
43static struct obstack obstack;
44struct obstack *rtl_obstack = &obstack;
45
c88c0d42 46static int sequence_num;
3262c1f5
RH
47static int errors;
48
49static int predicable_default;
50static const char *predicable_true;
51static const char *predicable_false;
52
2199e5fa
ZW
53static htab_t condition_table;
54
04d8aa70
AM
55static char *base_dir = NULL;
56
3262c1f5
RH
57/* We initially queue all patterns, process the define_insn and
58 define_cond_exec patterns, then return them one at a time. */
c88c0d42 59
3262c1f5
RH
60struct queue_elem
61{
62 rtx data;
821e35ba 63 const char *filename;
3262c1f5
RH
64 int lineno;
65 struct queue_elem *next;
a406f566
MM
66 /* In a DEFINE_INSN that came from a DEFINE_INSN_AND_SPLIT, SPLIT
67 points to the generated DEFINE_SPLIT. */
68 struct queue_elem *split;
c88c0d42
CP
69};
70
3262c1f5
RH
71static struct queue_elem *define_attr_queue;
72static struct queue_elem **define_attr_tail = &define_attr_queue;
e543e219
ZW
73static struct queue_elem *define_pred_queue;
74static struct queue_elem **define_pred_tail = &define_pred_queue;
3262c1f5
RH
75static struct queue_elem *define_insn_queue;
76static struct queue_elem **define_insn_tail = &define_insn_queue;
77static struct queue_elem *define_cond_exec_queue;
78static struct queue_elem **define_cond_exec_tail = &define_cond_exec_queue;
79static struct queue_elem *other_queue;
80static struct queue_elem **other_tail = &other_queue;
c88c0d42 81
a406f566
MM
82static struct queue_elem *queue_pattern (rtx, struct queue_elem ***,
83 const char *, int);
04d8aa70
AM
84
85/* Current maximum length of directory names in the search path
86 for include files. (Altered as we get more of them.) */
87
88size_t max_include_len;
89
90struct file_name_list
91 {
92 struct file_name_list *next;
93 const char *fname;
94 };
95
4ec59de2 96struct file_name_list *first_dir_md_include = 0; /* First dir to search */
04d8aa70
AM
97 /* First dir to search for <file> */
98struct file_name_list *first_bracket_include = 0;
4ec59de2 99struct file_name_list *last_dir_md_include = 0; /* Last in chain */
04d8aa70 100
3d7aafde
AJ
101static void remove_constraints (rtx);
102static void process_rtx (rtx, int);
103
104static int is_predicable (struct queue_elem *);
105static void identify_predicable_attribute (void);
106static int n_alternatives (const char *);
107static void collect_insn_data (rtx, int *, int *);
108static rtx alter_predicate_for_insn (rtx, int, int, int);
109static const char *alter_test_for_insn (struct queue_elem *,
110 struct queue_elem *);
111static char *shift_output_template (char *, const char *, int);
112static const char *alter_output_for_insn (struct queue_elem *,
113 struct queue_elem *,
114 int, int);
115static void process_one_cond_exec (struct queue_elem *);
116static void process_define_cond_exec (void);
117static void process_include (rtx, int);
118static char *save_string (const char *, int);
e543e219 119static void init_predicate_table (void);
0458fe77 120static void record_insn_name (int, const char *);
3916d6d8
RH
121\f
122void
e34d07f2 123message_with_line (int lineno, const char *msg, ...)
3916d6d8 124{
e34d07f2 125 va_list ap;
3d7aafde 126
e34d07f2 127 va_start (ap, msg);
36244024 128
3916d6d8
RH
129 fprintf (stderr, "%s:%d: ", read_rtx_filename, lineno);
130 vfprintf (stderr, msg, ap);
131 fputc ('\n', stderr);
132
e34d07f2 133 va_end (ap);
3916d6d8 134}
10b76d73
RK
135
136/* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
137 the gensupport programs. */
138
139rtx
e18476eb 140gen_rtx_CONST_INT (enum machine_mode ARG_UNUSED (mode),
3d7aafde 141 HOST_WIDE_INT arg)
10b76d73
RK
142{
143 rtx rt = rtx_alloc (CONST_INT);
144
145 XWINT (rt, 0) = arg;
146 return rt;
147}
3916d6d8 148\f
a406f566
MM
149/* Queue PATTERN on LIST_TAIL. Return the address of the new queue
150 element. */
3262c1f5 151
a406f566 152static struct queue_elem *
3d7aafde
AJ
153queue_pattern (rtx pattern, struct queue_elem ***list_tail,
154 const char *filename, int lineno)
3262c1f5 155{
5d038c4c 156 struct queue_elem *e = XNEW(struct queue_elem);
3262c1f5 157 e->data = pattern;
821e35ba 158 e->filename = filename;
3262c1f5
RH
159 e->lineno = lineno;
160 e->next = NULL;
a406f566 161 e->split = NULL;
3262c1f5
RH
162 **list_tail = e;
163 *list_tail = &e->next;
a406f566 164 return e;
3262c1f5
RH
165}
166
c88c0d42
CP
167/* Recursively remove constraints from an rtx. */
168
169static void
3d7aafde 170remove_constraints (rtx part)
c88c0d42 171{
b3694847
SS
172 int i, j;
173 const char *format_ptr;
c88c0d42
CP
174
175 if (part == 0)
176 return;
177
178 if (GET_CODE (part) == MATCH_OPERAND)
179 XSTR (part, 2) = "";
180 else if (GET_CODE (part) == MATCH_SCRATCH)
181 XSTR (part, 1) = "";
182
183 format_ptr = GET_RTX_FORMAT (GET_CODE (part));
184
185 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
186 switch (*format_ptr++)
187 {
188 case 'e':
189 case 'u':
190 remove_constraints (XEXP (part, i));
191 break;
192 case 'E':
193 if (XVEC (part, i) != NULL)
194 for (j = 0; j < XVECLEN (part, i); j++)
195 remove_constraints (XVECEXP (part, i, j));
196 break;
197 }
198}
199
3d7aafde 200/* Process an include file assuming that it lives in gcc/config/{target}/
80815706 201 if the include looks like (include "file"). */
174cc7d1
RH
202
203static void
3d7aafde 204process_include (rtx desc, int lineno)
04d8aa70
AM
205{
206 const char *filename = XSTR (desc, 0);
174cc7d1
RH
207 const char *old_filename;
208 int old_lineno;
209 char *pathname;
04d8aa70 210 FILE *input_file;
04d8aa70 211
174cc7d1 212 /* If specified file name is absolute, skip the include stack. */
3dce1408 213 if (! IS_ABSOLUTE_PATH (filename))
04d8aa70 214 {
174cc7d1
RH
215 struct file_name_list *stackp;
216
217 /* Search directory path, trying to open the file. */
218 for (stackp = first_dir_md_include; stackp; stackp = stackp->next)
04d8aa70 219 {
174cc7d1
RH
220 static const char sep[2] = { DIR_SEPARATOR, '\0' };
221
222 pathname = concat (stackp->fname, sep, filename, NULL);
223 input_file = fopen (pathname, "r");
3d7aafde 224 if (input_file != NULL)
174cc7d1
RH
225 goto success;
226 free (pathname);
04d8aa70
AM
227 }
228 }
04d8aa70 229
174cc7d1
RH
230 if (base_dir)
231 pathname = concat (base_dir, filename, NULL);
232 else
233 pathname = xstrdup (filename);
234 input_file = fopen (pathname, "r");
235 if (input_file == NULL)
236 {
237 free (pathname);
238 message_with_line (lineno, "include file `%s' not found", filename);
239 errors = 1;
240 return;
241 }
242 success:
04d8aa70 243
174cc7d1
RH
244 /* Save old cursor; setup new for the new file. Note that "lineno" the
245 argument to this function is the beginning of the include statement,
246 while read_rtx_lineno has already been advanced. */
247 old_filename = read_rtx_filename;
248 old_lineno = read_rtx_lineno;
249 read_rtx_filename = pathname;
250 read_rtx_lineno = 1;
04d8aa70 251
26be549a
RH
252 if (include_callback)
253 include_callback (pathname);
254
174cc7d1 255 /* Read the entire file. */
57406c63
RS
256 while (read_rtx (input_file, &desc, &lineno))
257 process_rtx (desc, lineno);
04d8aa70 258
821e35ba
RH
259 /* Do not free pathname. It is attached to the various rtx queue
260 elements. */
261
174cc7d1
RH
262 read_rtx_filename = old_filename;
263 read_rtx_lineno = old_lineno;
04d8aa70 264
174cc7d1 265 fclose (input_file);
04d8aa70
AM
266}
267
d91edf86 268/* Process a top level rtx in some way, queuing as appropriate. */
c88c0d42
CP
269
270static void
3d7aafde 271process_rtx (rtx desc, int lineno)
3262c1f5
RH
272{
273 switch (GET_CODE (desc))
274 {
275 case DEFINE_INSN:
821e35ba 276 queue_pattern (desc, &define_insn_tail, read_rtx_filename, lineno);
3262c1f5
RH
277 break;
278
279 case DEFINE_COND_EXEC:
821e35ba 280 queue_pattern (desc, &define_cond_exec_tail, read_rtx_filename, lineno);
3262c1f5
RH
281 break;
282
283 case DEFINE_ATTR:
821e35ba 284 queue_pattern (desc, &define_attr_tail, read_rtx_filename, lineno);
3262c1f5
RH
285 break;
286
e543e219
ZW
287 case DEFINE_PREDICATE:
288 case DEFINE_SPECIAL_PREDICATE:
f38840db
ZW
289 case DEFINE_CONSTRAINT:
290 case DEFINE_REGISTER_CONSTRAINT:
291 case DEFINE_MEMORY_CONSTRAINT:
292 case DEFINE_ADDRESS_CONSTRAINT:
e543e219
ZW
293 queue_pattern (desc, &define_pred_tail, read_rtx_filename, lineno);
294 break;
295
04d8aa70 296 case INCLUDE:
174cc7d1 297 process_include (desc, lineno);
04d8aa70
AM
298 break;
299
3262c1f5
RH
300 case DEFINE_INSN_AND_SPLIT:
301 {
302 const char *split_cond;
20217ac1
KG
303 rtx split;
304 rtvec attr;
de4bfbcb 305 int i;
a406f566
MM
306 struct queue_elem *insn_elem;
307 struct queue_elem *split_elem;
3262c1f5 308
dc297297 309 /* Create a split with values from the insn_and_split. */
3262c1f5 310 split = rtx_alloc (DEFINE_SPLIT);
de4bfbcb
RH
311
312 i = XVECLEN (desc, 1);
fbd40359 313 XVEC (split, 0) = rtvec_alloc (i);
de4bfbcb
RH
314 while (--i >= 0)
315 {
316 XVECEXP (split, 0, i) = copy_rtx (XVECEXP (desc, 1, i));
317 remove_constraints (XVECEXP (split, 0, i));
318 }
3262c1f5
RH
319
320 /* If the split condition starts with "&&", append it to the
321 insn condition to create the new split condition. */
322 split_cond = XSTR (desc, 4);
323 if (split_cond[0] == '&' && split_cond[1] == '&')
7445392c
RS
324 {
325 copy_rtx_ptr_loc (split_cond + 2, split_cond);
326 split_cond = join_c_conditions (XSTR (desc, 2), split_cond + 2);
327 }
3262c1f5
RH
328 XSTR (split, 1) = split_cond;
329 XVEC (split, 2) = XVEC (desc, 5);
330 XSTR (split, 3) = XSTR (desc, 6);
331
332 /* Fix up the DEFINE_INSN. */
ee138cf8 333 attr = XVEC (desc, 7);
3262c1f5 334 PUT_CODE (desc, DEFINE_INSN);
ee138cf8 335 XVEC (desc, 4) = attr;
3262c1f5
RH
336
337 /* Queue them. */
a406f566
MM
338 insn_elem
339 = queue_pattern (desc, &define_insn_tail, read_rtx_filename,
340 lineno);
341 split_elem
342 = queue_pattern (split, &other_tail, read_rtx_filename, lineno);
343 insn_elem->split = split_elem;
3262c1f5
RH
344 break;
345 }
346
347 default:
821e35ba 348 queue_pattern (desc, &other_tail, read_rtx_filename, lineno);
3262c1f5 349 break;
c88c0d42
CP
350 }
351}
3916d6d8 352\f
3262c1f5
RH
353/* Return true if attribute PREDICABLE is true for ELEM, which holds
354 a DEFINE_INSN. */
355
356static int
3d7aafde 357is_predicable (struct queue_elem *elem)
3262c1f5
RH
358{
359 rtvec vec = XVEC (elem->data, 4);
360 const char *value;
361 int i;
362
363 if (! vec)
364 return predicable_default;
365
366 for (i = GET_NUM_ELEM (vec) - 1; i >= 0; --i)
367 {
368 rtx sub = RTVEC_ELT (vec, i);
369 switch (GET_CODE (sub))
370 {
371 case SET_ATTR:
372 if (strcmp (XSTR (sub, 0), "predicable") == 0)
373 {
374 value = XSTR (sub, 1);
375 goto found;
376 }
377 break;
378
379 case SET_ATTR_ALTERNATIVE:
380 if (strcmp (XSTR (sub, 0), "predicable") == 0)
381 {
382 message_with_line (elem->lineno,
383 "multiple alternatives for `predicable'");
384 errors = 1;
385 return 0;
386 }
387 break;
388
389 case SET:
390 if (GET_CODE (SET_DEST (sub)) != ATTR
391 || strcmp (XSTR (SET_DEST (sub), 0), "predicable") != 0)
392 break;
393 sub = SET_SRC (sub);
394 if (GET_CODE (sub) == CONST_STRING)
395 {
396 value = XSTR (sub, 0);
397 goto found;
398 }
399
400 /* ??? It would be possible to handle this if we really tried.
401 It's not easy though, and I'm not going to bother until it
402 really proves necessary. */
403 message_with_line (elem->lineno,
404 "non-constant value for `predicable'");
405 errors = 1;
406 return 0;
407
408 default:
b2d59f6f 409 gcc_unreachable ();
3262c1f5
RH
410 }
411 }
412
413 return predicable_default;
414
415 found:
416 /* Verify that predicability does not vary on the alternative. */
417 /* ??? It should be possible to handle this by simply eliminating
418 the non-predicable alternatives from the insn. FRV would like
419 to do this. Delay this until we've got the basics solid. */
420 if (strchr (value, ',') != NULL)
421 {
422 message_with_line (elem->lineno,
423 "multiple alternatives for `predicable'");
424 errors = 1;
425 return 0;
426 }
427
428 /* Find out which value we're looking at. */
429 if (strcmp (value, predicable_true) == 0)
430 return 1;
431 if (strcmp (value, predicable_false) == 0)
432 return 0;
433
434 message_with_line (elem->lineno,
1f978f5f 435 "unknown value `%s' for `predicable' attribute",
3262c1f5
RH
436 value);
437 errors = 1;
438 return 0;
439}
440
441/* Examine the attribute "predicable"; discover its boolean values
442 and its default. */
443
444static void
3d7aafde 445identify_predicable_attribute (void)
3262c1f5
RH
446{
447 struct queue_elem *elem;
d6edb99e 448 char *p_true, *p_false;
3262c1f5 449 const char *value;
3262c1f5
RH
450
451 /* Look for the DEFINE_ATTR for `predicable', which must exist. */
452 for (elem = define_attr_queue; elem ; elem = elem->next)
453 if (strcmp (XSTR (elem->data, 0), "predicable") == 0)
454 goto found;
455
456 message_with_line (define_cond_exec_queue->lineno,
1f978f5f 457 "attribute `predicable' not defined");
3262c1f5
RH
458 errors = 1;
459 return;
460
461 found:
462 value = XSTR (elem->data, 1);
1dcd444b 463 p_false = xstrdup (value);
d6edb99e
ZW
464 p_true = strchr (p_false, ',');
465 if (p_true == NULL || strchr (++p_true, ',') != NULL)
3262c1f5
RH
466 {
467 message_with_line (elem->lineno,
1f978f5f 468 "attribute `predicable' is not a boolean");
3262c1f5 469 errors = 1;
a14df7da
UP
470 if (p_false)
471 free (p_false);
3262c1f5
RH
472 return;
473 }
d6edb99e 474 p_true[-1] = '\0';
3262c1f5 475
d6edb99e
ZW
476 predicable_true = p_true;
477 predicable_false = p_false;
3262c1f5
RH
478
479 switch (GET_CODE (XEXP (elem->data, 2)))
480 {
481 case CONST_STRING:
482 value = XSTR (XEXP (elem->data, 2), 0);
483 break;
484
485 case CONST:
486 message_with_line (elem->lineno,
1f978f5f 487 "attribute `predicable' cannot be const");
3262c1f5 488 errors = 1;
a14df7da
UP
489 if (p_false)
490 free (p_false);
3262c1f5
RH
491 return;
492
493 default:
494 message_with_line (elem->lineno,
1f978f5f 495 "attribute `predicable' must have a constant default");
3262c1f5 496 errors = 1;
a14df7da
UP
497 if (p_false)
498 free (p_false);
3262c1f5
RH
499 return;
500 }
501
d6edb99e 502 if (strcmp (value, p_true) == 0)
3262c1f5 503 predicable_default = 1;
d6edb99e 504 else if (strcmp (value, p_false) == 0)
3262c1f5
RH
505 predicable_default = 0;
506 else
507 {
508 message_with_line (elem->lineno,
1f978f5f 509 "unknown value `%s' for `predicable' attribute",
3262c1f5
RH
510 value);
511 errors = 1;
c0fa4721
AS
512 if (p_false)
513 free (p_false);
3262c1f5
RH
514 }
515}
516
517/* Return the number of alternatives in constraint S. */
518
519static int
3d7aafde 520n_alternatives (const char *s)
3262c1f5
RH
521{
522 int n = 1;
523
524 if (s)
525 while (*s)
526 n += (*s++ == ',');
527
528 return n;
529}
530
531/* Determine how many alternatives there are in INSN, and how many
532 operands. */
533
534static void
3d7aafde 535collect_insn_data (rtx pattern, int *palt, int *pmax)
3262c1f5
RH
536{
537 const char *fmt;
538 enum rtx_code code;
539 int i, j, len;
540
541 code = GET_CODE (pattern);
542 switch (code)
543 {
544 case MATCH_OPERAND:
892ecf92
RH
545 i = n_alternatives (XSTR (pattern, 2));
546 *palt = (i > *palt ? i : *palt);
5d3cc252 547 /* Fall through. */
3262c1f5
RH
548
549 case MATCH_OPERATOR:
550 case MATCH_SCRATCH:
551 case MATCH_PARALLEL:
3262c1f5
RH
552 i = XINT (pattern, 0);
553 if (i > *pmax)
554 *pmax = i;
555 break;
556
557 default:
558 break;
559 }
560
561 fmt = GET_RTX_FORMAT (code);
562 len = GET_RTX_LENGTH (code);
563 for (i = 0; i < len; i++)
564 {
565 switch (fmt[i])
566 {
567 case 'e': case 'u':
568 collect_insn_data (XEXP (pattern, i), palt, pmax);
569 break;
570
571 case 'V':
572 if (XVEC (pattern, i) == NULL)
573 break;
5d3cc252 574 /* Fall through. */
3262c1f5
RH
575 case 'E':
576 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
577 collect_insn_data (XVECEXP (pattern, i, j), palt, pmax);
578 break;
579
3b324340 580 case 'i': case 'w': case '0': case 's': case 'S': case 'T':
3262c1f5
RH
581 break;
582
583 default:
b2d59f6f 584 gcc_unreachable ();
3262c1f5
RH
585 }
586 }
587}
588
589static rtx
3d7aafde 590alter_predicate_for_insn (rtx pattern, int alt, int max_op, int lineno)
3262c1f5
RH
591{
592 const char *fmt;
593 enum rtx_code code;
594 int i, j, len;
595
596 code = GET_CODE (pattern);
597 switch (code)
598 {
599 case MATCH_OPERAND:
600 {
601 const char *c = XSTR (pattern, 2);
602
603 if (n_alternatives (c) != 1)
604 {
605 message_with_line (lineno,
1f978f5f 606 "too many alternatives for operand %d",
3262c1f5
RH
607 XINT (pattern, 0));
608 errors = 1;
609 return NULL;
610 }
611
612 /* Replicate C as needed to fill out ALT alternatives. */
613 if (c && *c && alt > 1)
614 {
615 size_t c_len = strlen (c);
616 size_t len = alt * (c_len + 1);
5d038c4c 617 char *new_c = XNEWVEC(char, len);
3262c1f5
RH
618
619 memcpy (new_c, c, c_len);
620 for (i = 1; i < alt; ++i)
621 {
622 new_c[i * (c_len + 1) - 1] = ',';
623 memcpy (&new_c[i * (c_len + 1)], c, c_len);
624 }
625 new_c[len - 1] = '\0';
626 XSTR (pattern, 2) = new_c;
627 }
628 }
5d3cc252 629 /* Fall through. */
3262c1f5
RH
630
631 case MATCH_OPERATOR:
632 case MATCH_SCRATCH:
633 case MATCH_PARALLEL:
3262c1f5
RH
634 XINT (pattern, 0) += max_op;
635 break;
636
637 default:
638 break;
639 }
640
641 fmt = GET_RTX_FORMAT (code);
642 len = GET_RTX_LENGTH (code);
643 for (i = 0; i < len; i++)
644 {
645 rtx r;
646
647 switch (fmt[i])
648 {
649 case 'e': case 'u':
650 r = alter_predicate_for_insn (XEXP (pattern, i), alt,
651 max_op, lineno);
652 if (r == NULL)
653 return r;
654 break;
655
656 case 'E':
657 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
658 {
659 r = alter_predicate_for_insn (XVECEXP (pattern, i, j),
660 alt, max_op, lineno);
661 if (r == NULL)
662 return r;
663 }
664 break;
665
666 case 'i': case 'w': case '0': case 's':
667 break;
668
669 default:
b2d59f6f 670 gcc_unreachable ();
3262c1f5
RH
671 }
672 }
673
674 return pattern;
675}
676
677static const char *
3d7aafde
AJ
678alter_test_for_insn (struct queue_elem *ce_elem,
679 struct queue_elem *insn_elem)
3262c1f5 680{
7445392c
RS
681 return join_c_conditions (XSTR (ce_elem->data, 1),
682 XSTR (insn_elem->data, 2));
3262c1f5
RH
683}
684
1ad463f4 685/* Adjust all of the operand numbers in SRC to match the shift they'll
3262c1f5
RH
686 get from an operand displacement of DISP. Return a pointer after the
687 adjusted string. */
688
689static char *
1ad463f4 690shift_output_template (char *dest, const char *src, int disp)
3262c1f5 691{
1ad463f4 692 while (*src)
3262c1f5 693 {
1ad463f4 694 char c = *src++;
53ed1a12 695 *dest++ = c;
3262c1f5
RH
696 if (c == '%')
697 {
1ad463f4 698 c = *src++;
3262c1f5
RH
699 if (ISDIGIT ((unsigned char) c))
700 c += disp;
0df6c2c7 701 else if (ISALPHA (c))
3262c1f5 702 {
53ed1a12 703 *dest++ = c;
1ad463f4 704 c = *src++ + disp;
3262c1f5 705 }
53ed1a12 706 *dest++ = c;
3262c1f5
RH
707 }
708 }
709
53ed1a12 710 return dest;
3262c1f5
RH
711}
712
713static const char *
3d7aafde
AJ
714alter_output_for_insn (struct queue_elem *ce_elem,
715 struct queue_elem *insn_elem,
716 int alt, int max_op)
3262c1f5
RH
717{
718 const char *ce_out, *insn_out;
53ed1a12 719 char *result, *p;
3262c1f5
RH
720 size_t len, ce_len, insn_len;
721
722 /* ??? Could coordinate with genoutput to not duplicate code here. */
723
724 ce_out = XSTR (ce_elem->data, 2);
66621f9e 725 insn_out = XTMPL (insn_elem->data, 3);
3262c1f5
RH
726 if (!ce_out || *ce_out == '\0')
727 return insn_out;
728
729 ce_len = strlen (ce_out);
730 insn_len = strlen (insn_out);
731
732 if (*insn_out == '*')
733 /* You must take care of the predicate yourself. */
734 return insn_out;
735
736 if (*insn_out == '@')
737 {
738 len = (ce_len + 1) * alt + insn_len + 1;
53ed1a12 739 p = result = XNEWVEC(char, len);
3262c1f5
RH
740
741 do
742 {
743 do
744 *p++ = *insn_out++;
745 while (ISSPACE ((unsigned char) *insn_out));
746
747 if (*insn_out != '#')
748 {
749 p = shift_output_template (p, ce_out, max_op);
750 *p++ = ' ';
751 }
752
753 do
754 *p++ = *insn_out++;
755 while (*insn_out && *insn_out != '\n');
756 }
757 while (*insn_out);
758 *p = '\0';
759 }
760 else
761 {
762 len = ce_len + 1 + insn_len + 1;
53ed1a12 763 result = XNEWVEC (char, len);
3262c1f5 764
53ed1a12 765 p = shift_output_template (result, ce_out, max_op);
3262c1f5
RH
766 *p++ = ' ';
767 memcpy (p, insn_out, insn_len + 1);
768 }
769
53ed1a12 770 return result;
3262c1f5
RH
771}
772
773/* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */
774
775static void
3d7aafde 776process_one_cond_exec (struct queue_elem *ce_elem)
3262c1f5
RH
777{
778 struct queue_elem *insn_elem;
779 for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
780 {
781 int alternatives, max_operand;
a406f566
MM
782 rtx pred, insn, pattern, split;
783 int i;
3262c1f5
RH
784
785 if (! is_predicable (insn_elem))
786 continue;
787
788 alternatives = 1;
789 max_operand = -1;
790 collect_insn_data (insn_elem->data, &alternatives, &max_operand);
791 max_operand += 1;
792
793 if (XVECLEN (ce_elem->data, 0) != 1)
794 {
795 message_with_line (ce_elem->lineno,
796 "too many patterns in predicate");
797 errors = 1;
798 return;
799 }
800
801 pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0));
802 pred = alter_predicate_for_insn (pred, alternatives, max_operand,
803 ce_elem->lineno);
804 if (pred == NULL)
805 return;
806
807 /* Construct a new pattern for the new insn. */
808 insn = copy_rtx (insn_elem->data);
809 XSTR (insn, 0) = "";
810 pattern = rtx_alloc (COND_EXEC);
811 XEXP (pattern, 0) = pred;
812 if (XVECLEN (insn, 1) == 1)
813 {
814 XEXP (pattern, 1) = XVECEXP (insn, 1, 0);
815 XVECEXP (insn, 1, 0) = pattern;
816 PUT_NUM_ELEM (XVEC (insn, 1), 1);
817 }
818 else
819 {
820 XEXP (pattern, 1) = rtx_alloc (PARALLEL);
821 XVEC (XEXP (pattern, 1), 0) = XVEC (insn, 1);
822 XVEC (insn, 1) = rtvec_alloc (1);
823 XVECEXP (insn, 1, 0) = pattern;
824 }
825
826 XSTR (insn, 2) = alter_test_for_insn (ce_elem, insn_elem);
66621f9e 827 XTMPL (insn, 3) = alter_output_for_insn (ce_elem, insn_elem,
3262c1f5
RH
828 alternatives, max_operand);
829
830 /* ??? Set `predicable' to false. Not crucial since it's really
831 only used here, and we won't reprocess this new pattern. */
832
833 /* Put the new pattern on the `other' list so that it
834 (a) is not reprocessed by other define_cond_exec patterns
835 (b) appears after all normal define_insn patterns.
836
837 ??? B is debatable. If one has normal insns that match
838 cond_exec patterns, they will be preferred over these
839 generated patterns. Whether this matters in practice, or if
840 it's a good thing, or whether we should thread these new
841 patterns into the define_insn chain just after their generator
842 is something we'll have to experiment with. */
843
821e35ba
RH
844 queue_pattern (insn, &other_tail, insn_elem->filename,
845 insn_elem->lineno);
a406f566
MM
846
847 if (!insn_elem->split)
848 continue;
849
850 /* If the original insn came from a define_insn_and_split,
9cf737f8 851 generate a new split to handle the predicated insn. */
a406f566
MM
852 split = copy_rtx (insn_elem->split->data);
853 /* Predicate the pattern matched by the split. */
854 pattern = rtx_alloc (COND_EXEC);
855 XEXP (pattern, 0) = pred;
856 if (XVECLEN (split, 0) == 1)
857 {
858 XEXP (pattern, 1) = XVECEXP (split, 0, 0);
859 XVECEXP (split, 0, 0) = pattern;
860 PUT_NUM_ELEM (XVEC (split, 0), 1);
861 }
862 else
863 {
864 XEXP (pattern, 1) = rtx_alloc (PARALLEL);
865 XVEC (XEXP (pattern, 1), 0) = XVEC (split, 0);
866 XVEC (split, 0) = rtvec_alloc (1);
867 XVECEXP (split, 0, 0) = pattern;
868 }
869 /* Predicate all of the insns generated by the split. */
870 for (i = 0; i < XVECLEN (split, 2); i++)
871 {
872 pattern = rtx_alloc (COND_EXEC);
873 XEXP (pattern, 0) = pred;
874 XEXP (pattern, 1) = XVECEXP (split, 2, i);
875 XVECEXP (split, 2, i) = pattern;
876 }
877 /* Add the new split to the queue. */
878 queue_pattern (split, &other_tail, read_rtx_filename,
879 insn_elem->split->lineno);
3262c1f5
RH
880 }
881}
882
883/* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
884 patterns appropriately. */
885
886static void
3d7aafde 887process_define_cond_exec (void)
3262c1f5
RH
888{
889 struct queue_elem *elem;
890
891 identify_predicable_attribute ();
892 if (errors)
893 return;
894
895 for (elem = define_cond_exec_queue; elem ; elem = elem->next)
896 process_one_cond_exec (elem);
897}
04d8aa70
AM
898
899static char *
3d7aafde 900save_string (const char *s, int len)
04d8aa70 901{
5d038c4c 902 char *result = XNEWVEC (char, len + 1);
04d8aa70
AM
903
904 memcpy (result, s, len);
905 result[len] = 0;
906 return result;
907}
908
909\f
910/* The entry point for initializing the reader. */
911
912int
f9942f4e 913init_md_reader_args_cb (int argc, char **argv, bool (*parse_opt)(const char *))
04d8aa70 914{
f9942f4e 915 FILE *input_file;
1c7352cd 916 int c, i, lineno;
f9942f4e 917 char *lastsl;
57406c63 918 rtx desc;
1c7352cd
ZW
919 bool no_more_options;
920 bool already_read_stdin;
04d8aa70 921
98a3dad4 922 /* Unlock the stdio streams. */
2653bb0c 923 unlock_std_streams ();
98a3dad4 924
1c7352cd 925 /* First we loop over all the options. */
04d8aa70
AM
926 for (i = 1; i < argc; i++)
927 {
928 if (argv[i][0] != '-')
1c7352cd
ZW
929 continue;
930
931 c = argv[i][1];
932 switch (c)
04d8aa70 933 {
1c7352cd
ZW
934 case 'I': /* Add directory to path for includes. */
935 {
936 struct file_name_list *dirtmp;
937
938 dirtmp = XNEW (struct file_name_list);
939 dirtmp->next = 0; /* New one goes on the end */
940 if (first_dir_md_include == 0)
941 first_dir_md_include = dirtmp;
942 else
943 last_dir_md_include->next = dirtmp;
944 last_dir_md_include = dirtmp; /* Tail follows the last one */
945 if (argv[i][1] == 'I' && argv[i][2] != 0)
946 dirtmp->fname = argv[i] + 2;
947 else if (i + 1 == argc)
948 fatal ("directory name missing after -I option");
949 else
950 dirtmp->fname = argv[++i];
951 if (strlen (dirtmp->fname) > max_include_len)
952 max_include_len = strlen (dirtmp->fname);
953 }
954 break;
f9942f4e 955
1c7352cd
ZW
956 case '\0':
957 /* An argument consisting of exactly one dash is a request to
958 read stdin. This will be handled in the second loop. */
959 continue;
c88c0d42 960
1c7352cd
ZW
961 case '-':
962 /* An argument consisting of just two dashes causes option
963 parsing to cease. */
964 if (argv[i][2] == '\0')
965 goto stop_parsing_options;
04d8aa70 966
1c7352cd
ZW
967 default:
968 /* The program may have provided a callback so it can
969 accept its own options. */
970 if (parse_opt && parse_opt (argv[i]))
971 break;
3262c1f5 972
1c7352cd
ZW
973 fatal ("invalid option `%s'", argv[i]);
974 }
c88c0d42
CP
975 }
976
1c7352cd 977 stop_parsing_options:
2199e5fa 978
1c7352cd
ZW
979 /* Prepare to read input. */
980 condition_table = htab_create (500, hash_c_test, cmp_c_test, NULL);
e543e219 981 init_predicate_table ();
3916d6d8 982 obstack_init (rtl_obstack);
3262c1f5 983 errors = 0;
c88c0d42 984 sequence_num = 0;
1c7352cd
ZW
985 no_more_options = false;
986 already_read_stdin = false;
c88c0d42 987
1c7352cd
ZW
988
989 /* Now loop over all input files. */
990 for (i = 1; i < argc; i++)
991 {
992 if (argv[i][0] == '-')
993 {
994 if (argv[i][1] == '\0')
995 {
996 /* Read stdin. */
997 if (already_read_stdin)
998 fatal ("cannot read standard input twice");
999
1000 base_dir = NULL;
1001 read_rtx_filename = in_fname = "<stdin>";
1002 read_rtx_lineno = 1;
1003 input_file = stdin;
1004 already_read_stdin = true;
1005
1006 while (read_rtx (input_file, &desc, &lineno))
1007 process_rtx (desc, lineno);
1008 fclose (input_file);
1009 continue;
1010 }
1011 else if (argv[i][1] == '-' && argv[i][2] == '\0')
1012 {
1013 /* No further arguments are to be treated as options. */
1014 no_more_options = true;
1015 continue;
1016 }
1017 else if (!no_more_options)
1018 continue;
1019 }
1020
1021 /* If we get here we are looking at a non-option argument, i.e.
1022 a file to be processed. */
1023
1024 in_fname = argv[i];
1025 lastsl = strrchr (in_fname, '/');
1026 if (lastsl != NULL)
1027 base_dir = save_string (in_fname, lastsl - in_fname + 1 );
1028 else
1029 base_dir = NULL;
1030
1031 read_rtx_filename = in_fname;
1032 read_rtx_lineno = 1;
1033 input_file = fopen (in_fname, "r");
1034 if (input_file == 0)
1035 {
1036 perror (in_fname);
1037 return FATAL_EXIT_CODE;
1038 }
1039
1040 while (read_rtx (input_file, &desc, &lineno))
1041 process_rtx (desc, lineno);
1042 fclose (input_file);
1043 }
1044
1045 /* If we get to this point without having seen any files to process,
1046 read standard input now. */
1047 if (!in_fname)
1048 {
1049 base_dir = NULL;
1050 read_rtx_filename = in_fname = "<stdin>";
1051 read_rtx_lineno = 1;
1052 input_file = stdin;
1053
1054 while (read_rtx (input_file, &desc, &lineno))
1055 process_rtx (desc, lineno);
1056 fclose (input_file);
1057 }
3262c1f5
RH
1058
1059 /* Process define_cond_exec patterns. */
1060 if (define_cond_exec_queue != NULL)
1061 process_define_cond_exec ();
1062
1063 return errors ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
1064}
1065
f9942f4e
ZW
1066/* Programs that don't have their own options can use this entry point
1067 instead. */
1068int
1069init_md_reader_args (int argc, char **argv)
1070{
1071 return init_md_reader_args_cb (argc, argv, 0);
1072}
1073\f
3262c1f5
RH
1074/* The entry point for reading a single rtx from an md file. */
1075
1076rtx
3d7aafde 1077read_md_rtx (int *lineno, int *seqnr)
3262c1f5
RH
1078{
1079 struct queue_elem **queue, *elem;
1080 rtx desc;
1081
2199e5fa
ZW
1082 discard:
1083
3262c1f5
RH
1084 /* Read all patterns from a given queue before moving on to the next. */
1085 if (define_attr_queue != NULL)
1086 queue = &define_attr_queue;
e543e219
ZW
1087 else if (define_pred_queue != NULL)
1088 queue = &define_pred_queue;
3262c1f5
RH
1089 else if (define_insn_queue != NULL)
1090 queue = &define_insn_queue;
1091 else if (other_queue != NULL)
1092 queue = &other_queue;
1093 else
1094 return NULL_RTX;
1095
1096 elem = *queue;
1097 *queue = elem->next;
1098 desc = elem->data;
821e35ba 1099 read_rtx_filename = elem->filename;
3262c1f5 1100 *lineno = elem->lineno;
c88c0d42 1101 *seqnr = sequence_num;
3262c1f5
RH
1102
1103 free (elem);
1104
2199e5fa
ZW
1105 /* Discard insn patterns which we know can never match (because
1106 their C test is provably always false). If insn_elision is
1107 false, our caller needs to see all the patterns. Note that the
1108 elided patterns are never counted by the sequence numbering; it
1109 it is the caller's responsibility, when insn_elision is false, not
1110 to use elided pattern numbers for anything. */
c88c0d42
CP
1111 switch (GET_CODE (desc))
1112 {
3262c1f5
RH
1113 case DEFINE_INSN:
1114 case DEFINE_EXPAND:
2199e5fa
ZW
1115 if (maybe_eval_c_test (XSTR (desc, 2)) != 0)
1116 sequence_num++;
1117 else if (insn_elision)
1118 goto discard;
0458fe77
ZW
1119
1120 /* *seqnr is used here so the name table will match caller's
1121 idea of insn numbering, whether or not elision is active. */
1122 record_insn_name (*seqnr, XSTR (desc, 0));
2199e5fa
ZW
1123 break;
1124
3262c1f5
RH
1125 case DEFINE_SPLIT:
1126 case DEFINE_PEEPHOLE:
1127 case DEFINE_PEEPHOLE2:
2199e5fa
ZW
1128 if (maybe_eval_c_test (XSTR (desc, 1)) != 0)
1129 sequence_num++;
1130 else if (insn_elision)
1131 goto discard;
3262c1f5
RH
1132 break;
1133
1134 default:
1135 break;
c88c0d42
CP
1136 }
1137
1138 return desc;
1139}
9a5834ae 1140
2199e5fa
ZW
1141/* Helper functions for insn elision. */
1142
1143/* Compute a hash function of a c_test structure, which is keyed
1144 by its ->expr field. */
1145hashval_t
3d7aafde 1146hash_c_test (const void *x)
2199e5fa
ZW
1147{
1148 const struct c_test *a = (const struct c_test *) x;
1149 const unsigned char *base, *s = (const unsigned char *) a->expr;
1150 hashval_t hash;
1151 unsigned char c;
1152 unsigned int len;
1153
1154 base = s;
1155 hash = 0;
1156
1157 while ((c = *s++) != '\0')
1158 {
1159 hash += c + (c << 17);
1160 hash ^= hash >> 2;
1161 }
1162
1163 len = s - base;
1164 hash += len + (len << 17);
1165 hash ^= hash >> 2;
1166
1167 return hash;
1168}
1169
1170/* Compare two c_test expression structures. */
1171int
3d7aafde 1172cmp_c_test (const void *x, const void *y)
2199e5fa
ZW
1173{
1174 const struct c_test *a = (const struct c_test *) x;
1175 const struct c_test *b = (const struct c_test *) y;
1176
1177 return !strcmp (a->expr, b->expr);
1178}
1179
1180/* Given a string representing a C test expression, look it up in the
1181 condition_table and report whether or not its value is known
1182 at compile time. Returns a tristate: 1 for known true, 0 for
1183 known false, -1 for unknown. */
1184int
3d7aafde 1185maybe_eval_c_test (const char *expr)
2199e5fa
ZW
1186{
1187 const struct c_test *test;
1188 struct c_test dummy;
1189
1190 if (expr[0] == 0)
1191 return 1;
1192
2199e5fa 1193 dummy.expr = expr;
5d038c4c 1194 test = (const struct c_test *)htab_find (condition_table, &dummy);
1c7352cd
ZW
1195 if (!test)
1196 return -1;
2199e5fa
ZW
1197 return test->value;
1198}
1199
1c7352cd
ZW
1200/* Record the C test expression EXPR in the condition_table, with
1201 value VAL. Duplicates clobber previous entries. */
1202
1203void
1204add_c_test (const char *expr, int value)
1205{
1206 struct c_test *test;
1207
1208 if (expr[0] == 0)
1209 return;
1210
1211 test = XNEW (struct c_test);
1212 test->expr = expr;
1213 test->value = value;
1214
1215 *(htab_find_slot (condition_table, test, INSERT)) = test;
1216}
1217
1218/* For every C test, call CALLBACK with two arguments: a pointer to
1219 the condition structure and INFO. Stops when CALLBACK returns zero. */
1220void
1221traverse_c_tests (htab_trav callback, void *info)
1222{
1223 if (condition_table)
1224 htab_traverse (condition_table, callback, info);
1225}
1226
1227
9a5834ae
ZW
1228/* Given a string, return the number of comma-separated elements in it.
1229 Return 0 for the null string. */
1230int
3d7aafde 1231n_comma_elts (const char *s)
9a5834ae
ZW
1232{
1233 int n;
1234
1235 if (*s == '\0')
1236 return 0;
1237
1238 for (n = 1; *s; s++)
1239 if (*s == ',')
1240 n++;
1241
1242 return n;
1243}
1244
1245/* Given a pointer to a (char *), return a pointer to the beginning of the
1246 next comma-separated element in the string. Advance the pointer given
1247 to the end of that element. Return NULL if at end of string. Caller
1248 is responsible for copying the string if necessary. White space between
1249 a comma and an element is ignored. */
1250
1251const char *
3d7aafde 1252scan_comma_elt (const char **pstr)
9a5834ae
ZW
1253{
1254 const char *start;
1255 const char *p = *pstr;
1256
1257 if (*p == ',')
1258 p++;
1259 while (ISSPACE(*p))
1260 p++;
1261
1262 if (*p == '\0')
1263 return NULL;
1264
1265 start = p;
1266
1267 while (*p != ',' && *p != '\0')
1268 p++;
1269
1270 *pstr = p;
1271 return start;
1272}
e543e219
ZW
1273
1274/* Helper functions for define_predicate and define_special_predicate
1275 processing. Shared between genrecog.c and genpreds.c. */
1276
1277static htab_t predicate_table;
1278struct pred_data *first_predicate;
1279static struct pred_data **last_predicate = &first_predicate;
1280
1281static hashval_t
1282hash_struct_pred_data (const void *ptr)
1283{
1284 return htab_hash_string (((const struct pred_data *)ptr)->name);
1285}
1286
1287static int
1288eq_struct_pred_data (const void *a, const void *b)
1289{
1290 return !strcmp (((const struct pred_data *)a)->name,
1291 ((const struct pred_data *)b)->name);
1292}
1293
1294struct pred_data *
1295lookup_predicate (const char *name)
1296{
1297 struct pred_data key;
1298 key.name = name;
cceb1885 1299 return (struct pred_data *) htab_find (predicate_table, &key);
e543e219
ZW
1300}
1301
e663da80
RS
1302/* Record that predicate PRED can accept CODE. */
1303
1304void
1305add_predicate_code (struct pred_data *pred, enum rtx_code code)
1306{
1307 if (!pred->codes[code])
1308 {
1309 pred->num_codes++;
1310 pred->codes[code] = true;
1311
1312 if (GET_RTX_CLASS (code) != RTX_CONST_OBJ)
1313 pred->allows_non_const = true;
1314
1315 if (code != REG
1316 && code != SUBREG
1317 && code != MEM
1318 && code != CONCAT
1319 && code != PARALLEL
1320 && code != STRICT_LOW_PART)
1321 pred->allows_non_lvalue = true;
1322
1323 if (pred->num_codes == 1)
1324 pred->singleton = code;
1325 else if (pred->num_codes == 2)
1326 pred->singleton = UNKNOWN;
1327 }
1328}
1329
e543e219
ZW
1330void
1331add_predicate (struct pred_data *pred)
1332{
1333 void **slot = htab_find_slot (predicate_table, pred, INSERT);
1334 if (*slot)
1335 {
1336 error ("duplicate predicate definition for '%s'", pred->name);
1337 return;
1338 }
1339 *slot = pred;
1340 *last_predicate = pred;
1341 last_predicate = &pred->next;
1342}
1343
1344/* This array gives the initial content of the predicate table. It
c2acaf06 1345 has entries for all predicates defined in recog.c. */
e543e219 1346
ebce9df7 1347struct std_pred_table
e543e219
ZW
1348{
1349 const char *name;
ebce9df7 1350 bool special;
e663da80 1351 bool allows_const_p;
e543e219
ZW
1352 RTX_CODE codes[NUM_RTX_CODE];
1353};
1354
ebce9df7 1355static const struct std_pred_table std_preds[] = {
e663da80
RS
1356 {"general_operand", false, true, {SUBREG, REG, MEM}},
1357 {"address_operand", true, true, {SUBREG, REG, MEM, PLUS, MINUS, MULT}},
1358 {"register_operand", false, false, {SUBREG, REG}},
1359 {"pmode_register_operand", true, false, {SUBREG, REG}},
1360 {"scratch_operand", false, false, {SCRATCH, REG}},
1361 {"immediate_operand", false, true, {0}},
1362 {"const_int_operand", false, false, {CONST_INT}},
1363 {"const_double_operand", false, false, {CONST_INT, CONST_DOUBLE}},
1364 {"nonimmediate_operand", false, false, {SUBREG, REG, MEM}},
1365 {"nonmemory_operand", false, true, {SUBREG, REG}},
1366 {"push_operand", false, false, {MEM}},
1367 {"pop_operand", false, false, {MEM}},
1368 {"memory_operand", false, false, {SUBREG, MEM}},
1369 {"indirect_operand", false, false, {SUBREG, MEM}},
1370 {"comparison_operator", false, false, {EQ, NE,
1371 LE, LT, GE, GT,
1372 LEU, LTU, GEU, GTU,
1373 UNORDERED, ORDERED,
1374 UNEQ, UNGE, UNGT,
1375 UNLE, UNLT, LTGT}}
e543e219 1376};
ebce9df7 1377#define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)
e543e219
ZW
1378
1379/* Initialize the table of predicate definitions, starting with
c2acaf06 1380 the information we have on generic predicates. */
e543e219
ZW
1381
1382static void
1383init_predicate_table (void)
1384{
1385 size_t i, j;
1386 struct pred_data *pred;
1387
1388 predicate_table = htab_create_alloc (37, hash_struct_pred_data,
1389 eq_struct_pred_data, 0,
1390 xcalloc, free);
1391
ebce9df7 1392 for (i = 0; i < NUM_KNOWN_STD_PREDS; i++)
e543e219 1393 {
cceb1885 1394 pred = XCNEW (struct pred_data);
ebce9df7
PB
1395 pred->name = std_preds[i].name;
1396 pred->special = std_preds[i].special;
e543e219 1397
ebce9df7 1398 for (j = 0; std_preds[i].codes[j] != 0; j++)
e663da80
RS
1399 add_predicate_code (pred, std_preds[i].codes[j]);
1400
1401 if (std_preds[i].allows_const_p)
1402 for (j = 0; j < NUM_RTX_CODE; j++)
1403 if (GET_RTX_CLASS (j) == RTX_CONST_OBJ)
1404 add_predicate_code (pred, j);
e543e219
ZW
1405
1406 add_predicate (pred);
1407 }
e543e219 1408}
0458fe77
ZW
1409\f
1410/* These functions allow linkage with print-rtl.c. Also, some generators
1411 like to annotate their output with insn names. */
1412
1413/* Holds an array of names indexed by insn_code_number. */
1414static char **insn_name_ptr = 0;
1415static int insn_name_ptr_size = 0;
1416
1417const char *
1418get_insn_name (int code)
1419{
1420 if (code < insn_name_ptr_size)
1421 return insn_name_ptr[code];
1422 else
1423 return NULL;
1424}
1425
1426static void
1427record_insn_name (int code, const char *name)
1428{
1429 static const char *last_real_name = "insn";
1430 static int last_real_code = 0;
1431 char *new;
1432
1433 if (insn_name_ptr_size <= code)
1434 {
1435 int new_size;
1436 new_size = (insn_name_ptr_size ? insn_name_ptr_size * 2 : 512);
1437 insn_name_ptr = xrealloc (insn_name_ptr, sizeof(char *) * new_size);
1438 memset (insn_name_ptr + insn_name_ptr_size, 0,
1439 sizeof(char *) * (new_size - insn_name_ptr_size));
1440 insn_name_ptr_size = new_size;
1441 }
1442
1443 if (!name || name[0] == '\0')
1444 {
1445 new = xmalloc (strlen (last_real_name) + 10);
1446 sprintf (new, "%s+%d", last_real_name, code - last_real_code);
1447 }
1448 else
1449 {
1450 last_real_name = new = xstrdup (name);
1451 last_real_code = code;
1452 }
1453
1454 insn_name_ptr[code] = new;
1455}