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