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