]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/read-rtl.c
Put the CL into the right dir.
[thirdparty/gcc.git] / gcc / read-rtl.c
CommitLineData
bccafa26 1/* RTL reader for GCC.
fbd26352 2 Copyright (C) 1987-2019 Free Software Foundation, Inc.
875d8740 3
f12b58b3 4This file is part of GCC.
875d8740 5
f12b58b3 6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8c4c00c1 8Software Foundation; either version 3, or (at your option) any later
f12b58b3 9version.
875d8740 10
f12b58b3 11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
875d8740 15
16You should have received a copy of the GNU General Public License
8c4c00c1 17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
875d8740 19
836c1c68 20/* This file is compiled twice: once for the generator programs
21 once for the compiler. */
22#ifdef GENERATOR_FILE
805e22b2 23#include "bconfig.h"
836c1c68 24#else
25#include "config.h"
26#endif
4f1159f8 27
fd781bb2 28/* Disable rtl checking; it conflicts with the iterator handling. */
4f1159f8 29#undef ENABLE_RTL_CHECKING
30
875d8740 31#include "system.h"
805e22b2 32#include "coretypes.h"
33#include "tm.h"
875d8740 34#include "rtl.h"
35#include "obstack.h"
960ebfe7 36#include "read-md.h"
af908c02 37#include "gensupport.h"
875d8740 38
836c1c68 39#ifndef GENERATOR_FILE
40#include "function.h"
41#include "memmodel.h"
42#include "emit-rtl.h"
43#endif
44
4a293229 45/* One element in a singly-linked list of (integer, string) pairs. */
46struct map_value {
47 struct map_value *next;
48 int number;
49 const char *string;
50};
51
fd781bb2 52/* Maps an iterator or attribute name to a list of (integer, string) pairs.
f5d566ff 53 The integers are iterator values; the strings are either C conditions
4a293229 54 or attribute values. */
55struct mapping {
fd781bb2 56 /* The name of the iterator or attribute. */
4a293229 57 const char *name;
58
fd781bb2 59 /* The group (modes or codes) to which the iterator or attribute belongs. */
60 struct iterator_group *group;
4a293229 61
4a293229 62 /* The list of (integer, string) pairs. */
63 struct map_value *values;
f5d566ff 64
65 /* For iterators, records the current value of the iterator. */
66 struct map_value *current_value;
4a293229 67};
68
f5d566ff 69/* A structure for abstracting the common parts of iterators. */
fd781bb2 70struct iterator_group {
f5d566ff 71 /* Tables of "mapping" structures, one for attributes and one for
72 iterators. */
fd781bb2 73 htab_t attrs, iterators;
4a293229 74
60eea7fb 75 /* The C++ type of the iterator, such as "machine_mode" for modes. */
76 const char *type;
77
f5d566ff 78 /* Treat the given string as the name of a standard mode, etc., and
b3453c30 79 return its integer value. */
80 int (*find_builtin) (const char *);
4a293229 81
0fdb6b5d 82 /* Make the given rtx use the iterator value given by the third argument.
83 If the iterator applies to operands, the second argument gives the
84 operand index, otherwise it is ignored. */
85 void (*apply_iterator) (rtx, unsigned int, int);
60eea7fb 86
87 /* Return the C token for the given standard mode, code, etc. */
88 const char *(*get_c_token) (int);
f5d566ff 89};
4a293229 90
f5d566ff 91/* Records one use of an iterator. */
92struct iterator_use {
93 /* The iterator itself. */
94 struct mapping *iterator;
95
0fdb6b5d 96 /* The location of the use, as passed to the apply_iterator callback.
97 The index is the number of the operand that used the iterator
98 if applicable, otherwise it is ignored. */
99 rtx x;
100 unsigned int index;
4a293229 101};
102
f5d566ff 103/* Records one use of an attribute (the "<[iterator:]attribute>" syntax)
104 in a non-string rtx field. */
105struct attribute_use {
106 /* The group that describes the use site. */
107 struct iterator_group *group;
108
48db11b0 109 /* The location at which the use occurs. */
110 file_location loc;
111
f5d566ff 112 /* The name of the attribute, possibly with an "iterator:" prefix. */
113 const char *value;
114
0fdb6b5d 115 /* The location of the use, as passed to GROUP's apply_iterator callback.
116 The index is the number of the operand that used the iterator
117 if applicable, otherwise it is ignored. */
118 rtx x;
119 unsigned int index;
e64e4ed9 120};
121
cbedf5a3 122/* This struct is used to link subst_attr named ATTR_NAME with
123 corresponding define_subst named ITER_NAME. */
124struct subst_attr_to_iter_mapping
125{
126 char *attr_name;
127 char *iter_name;
128};
129
130/* Hash-table to store links between subst-attributes and
131 define_substs. */
132htab_t subst_attr_to_iter_map = NULL;
133/* This global stores name of subst-iterator which is currently being
134 processed. */
135const char *current_iterator_name;
136
b3453c30 137static void validate_const_int (const char *);
836c1c68 138static void one_time_initialization (void);
4a293229 139
d3ab2953 140/* Global singleton. */
141rtx_reader *rtx_reader_ptr = NULL;
142
fd781bb2 143/* The mode and code iterator structures. */
cbedf5a3 144static struct iterator_group modes, codes, ints, substs;
4a293229 145
f5d566ff 146/* All iterators used in the current rtx. */
04009ada 147static vec<mapping *> current_iterators;
f5d566ff 148
149/* The list of all iterator uses in the current rtx. */
f1f41a6c 150static vec<iterator_use> iterator_uses;
f5d566ff 151
152/* The list of all attribute uses in the current rtx. */
f1f41a6c 153static vec<attribute_use> attribute_uses;
875d8740 154
fd781bb2 155/* Implementations of the iterator_group callbacks for modes. */
4a293229 156
157static int
b3453c30 158find_mode (const char *name)
4a293229 159{
160 int i;
161
162 for (i = 0; i < NUM_MACHINE_MODES; i++)
163 if (strcmp (GET_MODE_NAME (i), name) == 0)
164 return i;
165
b3453c30 166 fatal_with_file_and_line ("unknown mode `%s'", name);
4a293229 167}
168
4a293229 169static void
0fdb6b5d 170apply_mode_iterator (rtx x, unsigned int, int mode)
4a293229 171{
0fdb6b5d 172 PUT_MODE (x, (machine_mode) mode);
4a293229 173}
174
60eea7fb 175static const char *
176get_mode_token (int mode)
177{
178 return concat ("E_", GET_MODE_NAME (mode), "mode", NULL);
179}
180
836c1c68 181/* In compact dumps, the code of insns is prefixed with "c", giving "cinsn",
182 "cnote" etc, and CODE_LABEL is special-cased as "clabel". */
183
184struct compact_insn_name {
185 RTX_CODE code;
186 const char *name;
187};
188
189static const compact_insn_name compact_insn_names[] = {
190 { DEBUG_INSN, "cdebug_insn" },
191 { INSN, "cinsn" },
192 { JUMP_INSN, "cjump_insn" },
193 { CALL_INSN, "ccall_insn" },
194 { JUMP_TABLE_DATA, "cjump_table_data" },
195 { BARRIER, "cbarrier" },
196 { CODE_LABEL, "clabel" },
197 { NOTE, "cnote" }
198};
199
c08a1447 200/* Return the rtx code for NAME, or UNKNOWN if NAME isn't a valid rtx code. */
4a293229 201
c08a1447 202static rtx_code
203maybe_find_code (const char *name)
4a293229 204{
c08a1447 205 for (int i = 0; i < NUM_RTX_CODE; i++)
4a293229 206 if (strcmp (GET_RTX_NAME (i), name) == 0)
c08a1447 207 return (rtx_code) i;
4a293229 208
c08a1447 209 for (int i = 0; i < (signed)ARRAY_SIZE (compact_insn_names); i++)
836c1c68 210 if (strcmp (compact_insn_names[i].name, name) == 0)
211 return compact_insn_names[i].code;
212
c08a1447 213 return UNKNOWN;
214}
215
216/* Implementations of the iterator_group callbacks for codes. */
217
218static int
219find_code (const char *name)
220{
221 rtx_code code = maybe_find_code (name);
222 if (code == UNKNOWN)
223 fatal_with_file_and_line ("unknown rtx code `%s'", name);
224 return code;
4a293229 225}
226
4a293229 227static void
0fdb6b5d 228apply_code_iterator (rtx x, unsigned int, int code)
4a293229 229{
0fdb6b5d 230 PUT_CODE (x, (enum rtx_code) code);
4a293229 231}
232
60eea7fb 233static const char *
234get_code_token (int code)
235{
236 char *name = xstrdup (GET_RTX_NAME (code));
237 for (int i = 0; name[i]; ++i)
238 name[i] = TOUPPER (name[i]);
239 return name;
240}
241
65729bd0 242/* Implementations of the iterator_group callbacks for ints. */
243
244/* Since GCC does not construct a table of valid constants,
245 we have to accept any int as valid. No cross-checking can
246 be done. */
247
248static int
249find_int (const char *name)
250{
251 validate_const_int (name);
252 return atoi (name);
253}
254
255static void
0fdb6b5d 256apply_int_iterator (rtx x, unsigned int index, int value)
65729bd0 257{
9edf7ea8 258 if (GET_CODE (x) == SUBREG)
259 SUBREG_BYTE (x) = value;
260 else
261 XINT (x, index) = value;
65729bd0 262}
263
60eea7fb 264static const char *
265get_int_token (int value)
266{
267 char buffer[HOST_BITS_PER_INT + 1];
268 sprintf (buffer, "%d", value);
269 return xstrdup (buffer);
270}
271
836c1c68 272#ifdef GENERATOR_FILE
273
cbedf5a3 274/* This routine adds attribute or does nothing depending on VALUE. When
275 VALUE is 1, it does nothing - the first duplicate of original
276 template is kept untouched when it's subjected to a define_subst.
0fdb6b5d 277 When VALUE isn't 1, the routine modifies RTL-template RT, adding
cbedf5a3 278 attribute, named exactly as define_subst, which later will be
279 applied. If such attribute has already been added, then no the
280 routine has no effect. */
281static void
0fdb6b5d 282apply_subst_iterator (rtx rt, unsigned int, int value)
cbedf5a3 283{
cbedf5a3 284 rtx new_attr;
285 rtvec attrs_vec, new_attrs_vec;
286 int i;
2f9f8666 287 /* define_split has no attributes. */
288 if (value == 1 || GET_CODE (rt) == DEFINE_SPLIT)
cbedf5a3 289 return;
290 gcc_assert (GET_CODE (rt) == DEFINE_INSN
2f9f8666 291 || GET_CODE (rt) == DEFINE_INSN_AND_SPLIT
e8c17f8e 292 || GET_CODE (rt) == DEFINE_INSN_AND_REWRITE
cbedf5a3 293 || GET_CODE (rt) == DEFINE_EXPAND);
294
e8c17f8e 295 int attrs = (GET_CODE (rt) == DEFINE_INSN_AND_SPLIT ? 7
296 : GET_CODE (rt) == DEFINE_INSN_AND_REWRITE ? 6 : 4);
2f9f8666 297 attrs_vec = XVEC (rt, attrs);
cbedf5a3 298
299 /* If we've already added attribute 'current_iterator_name', then we
300 have nothing to do now. */
301 if (attrs_vec)
302 {
303 for (i = 0; i < GET_NUM_ELEM (attrs_vec); i++)
304 {
305 if (strcmp (XSTR (attrs_vec->elem[i], 0), current_iterator_name) == 0)
306 return;
307 }
308 }
309
310 /* Add attribute with subst name - it serves as a mark for
311 define_subst which later would be applied to this pattern. */
312 new_attr = rtx_alloc (SET_ATTR);
313 PUT_CODE (new_attr, SET_ATTR);
314 XSTR (new_attr, 0) = xstrdup (current_iterator_name);
315 XSTR (new_attr, 1) = xstrdup ("yes");
316
317 if (!attrs_vec)
318 {
319 new_attrs_vec = rtvec_alloc (1);
320 new_attrs_vec->elem[0] = new_attr;
321 }
322 else
323 {
324 new_attrs_vec = rtvec_alloc (GET_NUM_ELEM (attrs_vec) + 1);
325 memcpy (&new_attrs_vec->elem[0], &attrs_vec->elem[0],
326 GET_NUM_ELEM (attrs_vec) * sizeof (rtx));
327 new_attrs_vec->elem[GET_NUM_ELEM (attrs_vec)] = new_attr;
328 }
2f9f8666 329 XVEC (rt, attrs) = new_attrs_vec;
cbedf5a3 330}
331
332/* Map subst-attribute ATTR to subst iterator ITER. */
333
334static void
335bind_subst_iter_and_attr (const char *iter, const char *attr)
336{
337 struct subst_attr_to_iter_mapping *value;
338 void **slot;
339 if (!subst_attr_to_iter_map)
340 subst_attr_to_iter_map =
341 htab_create (1, leading_string_hash, leading_string_eq_p, 0);
342 value = XNEW (struct subst_attr_to_iter_mapping);
343 value->attr_name = xstrdup (attr);
344 value->iter_name = xstrdup (iter);
345 slot = htab_find_slot (subst_attr_to_iter_map, value, INSERT);
346 *slot = value;
347}
348
836c1c68 349#endif /* #ifdef GENERATOR_FILE */
350
cbedf5a3 351/* Return name of a subst-iterator, corresponding to subst-attribute ATTR. */
352
353static char*
354find_subst_iter_by_attr (const char *attr)
355{
356 char *iter_name = NULL;
357 struct subst_attr_to_iter_mapping *value;
358 value = (struct subst_attr_to_iter_mapping*)
359 htab_find (subst_attr_to_iter_map, &attr);
360 if (value)
361 iter_name = value->iter_name;
362 return iter_name;
363}
364
f5d566ff 365/* Map attribute string P to its current value. Return null if the attribute
60eea7fb 366 isn't known. If ITERATOR_OUT is nonnull, store the associated iterator
48db11b0 367 there. Report any errors against location LOC. */
e64e4ed9 368
369static struct map_value *
48db11b0 370map_attr_string (file_location loc, const char *p, mapping **iterator_out = 0)
e64e4ed9 371{
372 const char *attr;
f5d566ff 373 struct mapping *iterator;
374 unsigned int i;
e64e4ed9 375 struct mapping *m;
376 struct map_value *v;
f5d566ff 377 int iterator_name_len;
48db11b0 378 struct map_value *res = NULL;
379 struct mapping *prev = NULL;
e64e4ed9 380
f5d566ff 381 /* Peel off any "iterator:" prefix. Set ATTR to the start of the
382 attribute name. */
e64e4ed9 383 attr = strchr (p, ':');
384 if (attr == 0)
f5d566ff 385 {
386 iterator_name_len = -1;
387 attr = p;
388 }
e64e4ed9 389 else
390 {
f5d566ff 391 iterator_name_len = attr - p;
e64e4ed9 392 attr++;
393 }
394
f1f41a6c 395 FOR_EACH_VEC_ELT (current_iterators, i, iterator)
e64e4ed9 396 {
f5d566ff 397 /* If an iterator name was specified, check that it matches. */
398 if (iterator_name_len >= 0
399 && (strncmp (p, iterator->name, iterator_name_len) != 0
400 || iterator->name[iterator_name_len] != 0))
401 continue;
e64e4ed9 402
f5d566ff 403 /* Find the attribute specification. */
404 m = (struct mapping *) htab_find (iterator->group->attrs, &attr);
405 if (m)
cbedf5a3 406 {
407 /* In contrast to code/mode/int iterators, attributes of subst
408 iterators are linked to one specific subst-iterator. So, if
409 we are dealing with subst-iterator, we should check if it's
410 the one which linked with the given attribute. */
411 if (iterator->group == &substs)
412 {
413 char *iter_name = find_subst_iter_by_attr (attr);
414 if (strcmp (iter_name, iterator->name) != 0)
415 continue;
416 }
417 /* Find the attribute value associated with the current
418 iterator value. */
419 for (v = m->values; v; v = v->next)
420 if (v->number == iterator->current_value->number)
60eea7fb 421 {
48db11b0 422 if (res && strcmp (v->string, res->string) != 0)
423 {
424 error_at (loc, "ambiguous attribute '%s'; could be"
425 " '%s' (via '%s:%s') or '%s' (via '%s:%s')",
426 attr, res->string, prev->name, attr,
427 v->string, iterator->name, attr);
428 return v;
429 }
60eea7fb 430 if (iterator_out)
431 *iterator_out = iterator;
48db11b0 432 prev = iterator;
433 res = v;
60eea7fb 434 }
cbedf5a3 435 }
e64e4ed9 436 }
48db11b0 437 return res;
e64e4ed9 438}
439
f5d566ff 440/* Apply the current iterator values to STRING. Return the new string
441 if any changes were needed, otherwise return STRING itself. */
4a293229 442
e1e9159b 443const char *
d3ab2953 444md_reader::apply_iterator_to_string (const char *string)
4a293229 445{
e64e4ed9 446 char *base, *copy, *p, *start, *end;
4a293229 447 struct map_value *v;
448
48db11b0 449 if (string == 0 || string[0] == 0)
4a293229 450 return string;
451
48db11b0 452 file_location loc = get_md_ptr_loc (string)->loc;
4a293229 453 base = p = copy = ASTRDUP (string);
192342fa 454 while ((start = strchr (p, '<')) && (end = strchr (start, '>')))
4a293229 455 {
456 p = start + 1;
457
4a293229 458 *end = 0;
48db11b0 459 v = map_attr_string (loc, p);
4a293229 460 *end = '>';
4a293229 461 if (v == 0)
462 continue;
463
464 /* Add everything between the last copied byte and the '<',
465 then add in the attribute value. */
e1e9159b 466 obstack_grow (&m_string_obstack, base, start - base);
467 obstack_grow (&m_string_obstack, v->string, strlen (v->string));
4a293229 468 base = end + 1;
469 }
470 if (base != copy)
471 {
e1e9159b 472 obstack_grow (&m_string_obstack, base, strlen (base) + 1);
473 copy = XOBFINISH (&m_string_obstack, char *);
77c2564f 474 copy_md_ptr_loc (copy, string);
9e959634 475 return copy;
4a293229 476 }
477 return string;
478}
479
f5d566ff 480/* Return a deep copy of X, substituting the current iterator
481 values into any strings. */
4a293229 482
e1e9159b 483rtx
d3ab2953 484md_reader::copy_rtx_for_iterators (rtx original)
4a293229 485{
873bf3e1 486 const char *format_ptr, *p;
4a293229 487 int i, j;
488 rtx x;
4a293229 489
490 if (original == 0)
491 return original;
492
493 /* Create a shallow copy of ORIGINAL. */
f5d566ff 494 x = rtx_alloc (GET_CODE (original));
495 memcpy (x, original, RTX_CODE_SIZE (GET_CODE (original)));
e64e4ed9 496
4a293229 497 /* Change each string and recursively change each rtx. */
f5d566ff 498 format_ptr = GET_RTX_FORMAT (GET_CODE (original));
4a293229 499 for (i = 0; format_ptr[i] != 0; i++)
500 switch (format_ptr[i])
501 {
4a293229 502 case 'T':
873bf3e1 503 while (XTMPL (x, i) != (p = apply_iterator_to_string (XTMPL (x, i))))
504 XTMPL (x, i) = p;
4f1159f8 505 break;
506
507 case 'S':
4a293229 508 case 's':
873bf3e1 509 while (XSTR (x, i) != (p = apply_iterator_to_string (XSTR (x, i))))
510 XSTR (x, i) = p;
4a293229 511 break;
512
513 case 'e':
f5d566ff 514 XEXP (x, i) = copy_rtx_for_iterators (XEXP (x, i));
4a293229 515 break;
516
517 case 'V':
518 case 'E':
519 if (XVEC (original, i))
520 {
521 XVEC (x, i) = rtvec_alloc (XVECLEN (original, i));
522 for (j = 0; j < XVECLEN (x, i); j++)
f5d566ff 523 XVECEXP (x, i, j)
524 = copy_rtx_for_iterators (XVECEXP (original, i, j));
4a293229 525 }
526 break;
527
528 default:
529 break;
530 }
531 return x;
532}
533
836c1c68 534#ifdef GENERATOR_FILE
535
4a293229 536/* Return a condition that must satisfy both ORIGINAL and EXTRA. If ORIGINAL
537 has the form "&& ..." (as used in define_insn_and_splits), assume that
538 EXTRA is already satisfied. Empty strings are treated like "true". */
539
540static const char *
541add_condition_to_string (const char *original, const char *extra)
542{
9e959634 543 if (original != 0 && original[0] == '&' && original[1] == '&')
4a293229 544 return original;
e1e9159b 545 return rtx_reader_ptr->join_c_conditions (original, extra);
4a293229 546}
547
548/* Like add_condition, but applied to all conditions in rtx X. */
549
550static void
551add_condition_to_rtx (rtx x, const char *extra)
552{
553 switch (GET_CODE (x))
554 {
555 case DEFINE_INSN:
556 case DEFINE_EXPAND:
cbedf5a3 557 case DEFINE_SUBST:
4a293229 558 XSTR (x, 2) = add_condition_to_string (XSTR (x, 2), extra);
559 break;
560
561 case DEFINE_SPLIT:
562 case DEFINE_PEEPHOLE:
563 case DEFINE_PEEPHOLE2:
564 case DEFINE_COND_EXEC:
565 XSTR (x, 1) = add_condition_to_string (XSTR (x, 1), extra);
566 break;
567
568 case DEFINE_INSN_AND_SPLIT:
e8c17f8e 569 case DEFINE_INSN_AND_REWRITE:
4a293229 570 XSTR (x, 2) = add_condition_to_string (XSTR (x, 2), extra);
571 XSTR (x, 4) = add_condition_to_string (XSTR (x, 4), extra);
572 break;
573
574 default:
575 break;
576 }
577}
578
f5d566ff 579/* Apply the current iterator values to all attribute_uses. */
580
581static void
582apply_attribute_uses (void)
583{
584 struct map_value *v;
585 attribute_use *ause;
586 unsigned int i;
587
f1f41a6c 588 FOR_EACH_VEC_ELT (attribute_uses, i, ause)
f5d566ff 589 {
48db11b0 590 v = map_attr_string (ause->loc, ause->value);
f5d566ff 591 if (!v)
592 fatal_with_file_and_line ("unknown iterator value `%s'", ause->value);
0fdb6b5d 593 ause->group->apply_iterator (ause->x, ause->index,
f5d566ff 594 ause->group->find_builtin (v->string));
595 }
596}
597
598/* A htab_traverse callback for iterators. Add all used iterators
599 to current_iterators. */
4a293229 600
601static int
f5d566ff 602add_current_iterators (void **slot, void *data ATTRIBUTE_UNUSED)
4a293229 603{
fd781bb2 604 struct mapping *iterator;
4a293229 605
fd781bb2 606 iterator = (struct mapping *) *slot;
f5d566ff 607 if (iterator->current_value)
f1f41a6c 608 current_iterators.safe_push (iterator);
4a293229 609 return 1;
610}
611
60eea7fb 612/* Return a hash value for overloaded_name UNCAST_ONAME. There shouldn't
613 be many instances of two overloaded_names having the same name but
614 different arguments, so hashing on the name should be good enough in
615 practice. */
616
617static hashval_t
618overloaded_name_hash (const void *uncast_oname)
619{
620 const overloaded_name *oname = (const overloaded_name *) uncast_oname;
621 return htab_hash_string (oname->name);
622}
623
624/* Return true if two overloaded_names are similar enough to share
625 the same generated functions. */
626
627static int
628overloaded_name_eq_p (const void *uncast_oname1, const void *uncast_oname2)
629{
630 const overloaded_name *oname1 = (const overloaded_name *) uncast_oname1;
631 const overloaded_name *oname2 = (const overloaded_name *) uncast_oname2;
632 if (strcmp (oname1->name, oname2->name) != 0
633 || oname1->arg_types.length () != oname2->arg_types.length ())
634 return 0;
635
636 for (unsigned int i = 0; i < oname1->arg_types.length (); ++i)
637 if (strcmp (oname1->arg_types[i], oname2->arg_types[i]) != 0)
638 return 0;
639
640 return 1;
641}
642
643/* Return true if X has an instruction name in XSTR (X, 0). */
644
645static bool
646named_rtx_p (rtx x)
647{
648 switch (GET_CODE (x))
649 {
650 case DEFINE_EXPAND:
651 case DEFINE_INSN:
652 case DEFINE_INSN_AND_SPLIT:
e8c17f8e 653 case DEFINE_INSN_AND_REWRITE:
60eea7fb 654 return true;
655
656 default:
657 return false;
658 }
659}
660
661/* Check whether ORIGINAL is a named pattern whose name starts with '@'.
662 If so, return the associated overloaded_name and add the iterator for
663 each argument to ITERATORS. Return null otherwise. */
664
665overloaded_name *
666md_reader::handle_overloaded_name (rtx original, vec<mapping *> *iterators)
667{
668 /* Check for the leading '@'. */
669 if (!named_rtx_p (original) || XSTR (original, 0)[0] != '@')
670 return NULL;
671
672 /* Remove the '@', so that no other code needs to worry about it. */
673 const char *name = XSTR (original, 0);
48db11b0 674 file_location loc = get_md_ptr_loc (name)->loc;
60eea7fb 675 copy_md_ptr_loc (name + 1, name);
676 name += 1;
677 XSTR (original, 0) = name;
678
679 /* Build a copy of the name without the '<...>' attribute strings.
680 Add the iterator associated with each such attribute string to ITERATORS
681 and add an associated argument to TMP_ONAME. */
682 char *copy = ASTRDUP (name);
683 char *base = copy, *start, *end;
684 overloaded_name tmp_oname;
685 tmp_oname.arg_types.create (current_iterators.length ());
686 bool pending_underscore_p = false;
687 while ((start = strchr (base, '<')) && (end = strchr (start, '>')))
688 {
689 *end = 0;
690 mapping *iterator;
48db11b0 691 if (!map_attr_string (loc, start + 1, &iterator))
60eea7fb 692 fatal_with_file_and_line ("unknown iterator `%s'", start + 1);
693 *end = '>';
694
695 /* Remove a trailing underscore, so that we don't end a name
696 with "_" or turn "_<...>_" into "__". */
697 if (start != base && start[-1] == '_')
698 {
699 start -= 1;
700 pending_underscore_p = true;
701 }
702
703 /* Add the text between either the last '>' or the start of
704 the string and this '<'. */
705 obstack_grow (&m_string_obstack, base, start - base);
706 base = end + 1;
707
708 /* If there's a character we need to keep after the '>', check
709 whether we should prefix it with a previously-dropped '_'. */
710 if (base[0] != 0 && base[0] != '<')
711 {
712 if (pending_underscore_p && base[0] != '_')
713 obstack_1grow (&m_string_obstack, '_');
714 pending_underscore_p = false;
715 }
716
717 /* Record an argument for ITERATOR. */
718 iterators->safe_push (iterator);
719 tmp_oname.arg_types.safe_push (iterator->group->type);
720 }
721 if (base == copy)
722 fatal_with_file_and_line ("no iterator attributes in name `%s'", name);
723
724 size_t length = obstack_object_size (&m_string_obstack);
725 if (length == 0)
726 fatal_with_file_and_line ("`%s' only contains iterator attributes", name);
727
728 /* Get the completed name. */
729 obstack_grow (&m_string_obstack, base, strlen (base) + 1);
730 char *new_name = XOBFINISH (&m_string_obstack, char *);
731 tmp_oname.name = new_name;
732
733 if (!m_overloads_htab)
734 m_overloads_htab = htab_create (31, overloaded_name_hash,
735 overloaded_name_eq_p, NULL);
736
737 /* See whether another pattern had the same overload name and list
738 of argument types. Create a new permanent one if not. */
739 void **slot = htab_find_slot (m_overloads_htab, &tmp_oname, INSERT);
740 overloaded_name *oname = (overloaded_name *) *slot;
741 if (!oname)
742 {
743 *slot = oname = new overloaded_name;
744 oname->name = tmp_oname.name;
745 oname->arg_types = tmp_oname.arg_types;
746 oname->next = NULL;
747 oname->first_instance = NULL;
748 oname->next_instance_ptr = &oname->first_instance;
749
750 *m_next_overload_ptr = oname;
751 m_next_overload_ptr = &oname->next;
752 }
753 else
754 {
755 obstack_free (&m_string_obstack, new_name);
756 tmp_oname.arg_types.release ();
757 }
758
759 return oname;
760}
761
762/* Add an instance of ONAME for instruction pattern X. ITERATORS[I]
763 gives the iterator associated with argument I of ONAME. */
764
765static void
766add_overload_instance (overloaded_name *oname, vec<mapping *> iterators, rtx x)
767{
768 /* Create the instance. */
769 overloaded_instance *instance = new overloaded_instance;
770 instance->next = NULL;
771 instance->arg_values.create (oname->arg_types.length ());
772 for (unsigned int i = 0; i < iterators.length (); ++i)
773 {
774 int value = iterators[i]->current_value->number;
775 const char *name = iterators[i]->group->get_c_token (value);
776 instance->arg_values.quick_push (name);
777 }
778 instance->name = XSTR (x, 0);
779 instance->insn = x;
780
781 /* Chain it onto the end of ONAME's list. */
782 *oname->next_instance_ptr = instance;
783 oname->next_instance_ptr = &instance->next;
784}
785
f5d566ff 786/* Expand all iterators in the current rtx, which is given as ORIGINAL.
787 Build a list of expanded rtxes in the EXPR_LIST pointed to by QUEUE. */
788
789static void
b0e2a5e8 790apply_iterators (rtx original, vec<rtx> *queue)
f5d566ff 791{
792 unsigned int i;
793 const char *condition;
794 iterator_use *iuse;
795 struct mapping *iterator;
796 struct map_value *v;
797 rtx x;
798
f1f41a6c 799 if (iterator_uses.is_empty ())
f5d566ff 800 {
801 /* Raise an error if any attributes were used. */
802 apply_attribute_uses ();
60eea7fb 803
804 if (named_rtx_p (original) && XSTR (original, 0)[0] == '@')
805 fatal_with_file_and_line ("'@' used without iterators");
806
b0e2a5e8 807 queue->safe_push (original);
f5d566ff 808 return;
809 }
810
811 /* Clear out the iterators from the previous run. */
f1f41a6c 812 FOR_EACH_VEC_ELT (current_iterators, i, iterator)
f5d566ff 813 iterator->current_value = NULL;
f1f41a6c 814 current_iterators.truncate (0);
f5d566ff 815
816 /* Mark the iterators that we need this time. */
f1f41a6c 817 FOR_EACH_VEC_ELT (iterator_uses, i, iuse)
f5d566ff 818 iuse->iterator->current_value = iuse->iterator->values;
819
820 /* Get the list of iterators that are in use, preserving the
821 definition order within each group. */
822 htab_traverse (modes.iterators, add_current_iterators, NULL);
823 htab_traverse (codes.iterators, add_current_iterators, NULL);
65729bd0 824 htab_traverse (ints.iterators, add_current_iterators, NULL);
cbedf5a3 825 htab_traverse (substs.iterators, add_current_iterators, NULL);
f1f41a6c 826 gcc_assert (!current_iterators.is_empty ());
f5d566ff 827
60eea7fb 828 /* Check whether this is a '@' overloaded pattern. */
829 auto_vec<mapping *, 16> iterators;
830 overloaded_name *oname
831 = rtx_reader_ptr->handle_overloaded_name (original, &iterators);
832
f5d566ff 833 for (;;)
834 {
835 /* Apply the current iterator values. Accumulate a condition to
836 say when the resulting rtx can be used. */
4441642c 837 condition = "";
f1f41a6c 838 FOR_EACH_VEC_ELT (iterator_uses, i, iuse)
f5d566ff 839 {
cbedf5a3 840 if (iuse->iterator->group == &substs)
841 continue;
f5d566ff 842 v = iuse->iterator->current_value;
0fdb6b5d 843 iuse->iterator->group->apply_iterator (iuse->x, iuse->index,
844 v->number);
e1e9159b 845 condition = rtx_reader_ptr->join_c_conditions (condition, v->string);
f5d566ff 846 }
847 apply_attribute_uses ();
e1e9159b 848 x = rtx_reader_ptr->copy_rtx_for_iterators (original);
f5d566ff 849 add_condition_to_rtx (x, condition);
850
cbedf5a3 851 /* We apply subst iterator after RTL-template is copied, as during
852 subst-iterator processing, we could add an attribute to the
853 RTL-template, and we don't want to do it in the original one. */
854 FOR_EACH_VEC_ELT (iterator_uses, i, iuse)
855 {
856 v = iuse->iterator->current_value;
857 if (iuse->iterator->group == &substs)
858 {
0fdb6b5d 859 iuse->x = x;
860 iuse->index = 0;
cbedf5a3 861 current_iterator_name = iuse->iterator->name;
0fdb6b5d 862 iuse->iterator->group->apply_iterator (iuse->x, iuse->index,
863 v->number);
cbedf5a3 864 }
865 }
60eea7fb 866
867 if (oname)
868 add_overload_instance (oname, iterators, x);
869
f5d566ff 870 /* Add the new rtx to the end of the queue. */
b0e2a5e8 871 queue->safe_push (x);
f5d566ff 872
873 /* Lexicographically increment the iterator value sequence.
874 That is, cycle through iterator values, starting from the right,
875 and stopping when one of them doesn't wrap around. */
f1f41a6c 876 i = current_iterators.length ();
f5d566ff 877 for (;;)
878 {
879 if (i == 0)
880 return;
881 i--;
f1f41a6c 882 iterator = current_iterators[i];
f5d566ff 883 iterator->current_value = iterator->current_value->next;
884 if (iterator->current_value)
885 break;
886 iterator->current_value = iterator->values;
887 }
f5d566ff 888 }
889}
836c1c68 890#endif /* #ifdef GENERATOR_FILE */
f5d566ff 891
4a293229 892/* Add a new "mapping" structure to hashtable TABLE. NAME is the name
b3453c30 893 of the mapping and GROUP is the group to which it belongs. */
4a293229 894
895static struct mapping *
b3453c30 896add_mapping (struct iterator_group *group, htab_t table, const char *name)
4a293229 897{
898 struct mapping *m;
899 void **slot;
900
901 m = XNEW (struct mapping);
902 m->name = xstrdup (name);
903 m->group = group;
4a293229 904 m->values = 0;
f5d566ff 905 m->current_value = NULL;
4a293229 906
907 slot = htab_find_slot (table, m, INSERT);
908 if (*slot != 0)
b3453c30 909 fatal_with_file_and_line ("`%s' already defined", name);
4a293229 910
911 *slot = m;
912 return m;
913}
914
915/* Add the pair (NUMBER, STRING) to a list of map_value structures.
916 END_PTR points to the current null terminator for the list; return
917 a pointer the new null terminator. */
918
919static struct map_value **
920add_map_value (struct map_value **end_ptr, int number, const char *string)
921{
922 struct map_value *value;
923
924 value = XNEW (struct map_value);
925 value->next = 0;
926 value->number = number;
927 value->string = string;
928
929 *end_ptr = value;
930 return &value->next;
931}
932
933/* Do one-time initialization of the mode and code attributes. */
934
935static void
fd781bb2 936initialize_iterators (void)
4a293229 937{
938 struct mapping *lower, *upper;
939 struct map_value **lower_ptr, **upper_ptr;
940 char *copy, *p;
941 int i;
942
ac0640e5 943 modes.attrs = htab_create (13, leading_string_hash, leading_string_eq_p, 0);
944 modes.iterators = htab_create (13, leading_string_hash,
945 leading_string_eq_p, 0);
60eea7fb 946 modes.type = "machine_mode";
4a293229 947 modes.find_builtin = find_mode;
fd781bb2 948 modes.apply_iterator = apply_mode_iterator;
60eea7fb 949 modes.get_c_token = get_mode_token;
4a293229 950
ac0640e5 951 codes.attrs = htab_create (13, leading_string_hash, leading_string_eq_p, 0);
952 codes.iterators = htab_create (13, leading_string_hash,
953 leading_string_eq_p, 0);
60eea7fb 954 codes.type = "rtx_code";
4a293229 955 codes.find_builtin = find_code;
fd781bb2 956 codes.apply_iterator = apply_code_iterator;
60eea7fb 957 codes.get_c_token = get_code_token;
4a293229 958
65729bd0 959 ints.attrs = htab_create (13, leading_string_hash, leading_string_eq_p, 0);
960 ints.iterators = htab_create (13, leading_string_hash,
961 leading_string_eq_p, 0);
60eea7fb 962 ints.type = "int";
65729bd0 963 ints.find_builtin = find_int;
964 ints.apply_iterator = apply_int_iterator;
60eea7fb 965 ints.get_c_token = get_int_token;
65729bd0 966
cbedf5a3 967 substs.attrs = htab_create (13, leading_string_hash, leading_string_eq_p, 0);
968 substs.iterators = htab_create (13, leading_string_hash,
969 leading_string_eq_p, 0);
60eea7fb 970 substs.type = "int";
cbedf5a3 971 substs.find_builtin = find_int; /* We don't use it, anyway. */
836c1c68 972#ifdef GENERATOR_FILE
cbedf5a3 973 substs.apply_iterator = apply_subst_iterator;
836c1c68 974#endif
60eea7fb 975 substs.get_c_token = get_int_token;
cbedf5a3 976
b3453c30 977 lower = add_mapping (&modes, modes.attrs, "mode");
978 upper = add_mapping (&modes, modes.attrs, "MODE");
4a293229 979 lower_ptr = &lower->values;
980 upper_ptr = &upper->values;
981 for (i = 0; i < MAX_MACHINE_MODE; i++)
982 {
983 copy = xstrdup (GET_MODE_NAME (i));
984 for (p = copy; *p != 0; p++)
985 *p = TOLOWER (*p);
986
987 upper_ptr = add_map_value (upper_ptr, i, GET_MODE_NAME (i));
988 lower_ptr = add_map_value (lower_ptr, i, copy);
989 }
990
b3453c30 991 lower = add_mapping (&codes, codes.attrs, "code");
992 upper = add_mapping (&codes, codes.attrs, "CODE");
4a293229 993 lower_ptr = &lower->values;
994 upper_ptr = &upper->values;
995 for (i = 0; i < NUM_RTX_CODE; i++)
996 {
997 copy = xstrdup (GET_RTX_NAME (i));
998 for (p = copy; *p != 0; p++)
999 *p = TOUPPER (*p);
1000
1001 lower_ptr = add_map_value (lower_ptr, i, GET_RTX_NAME (i));
1002 upper_ptr = add_map_value (upper_ptr, i, copy);
1003 }
1004}
875d8740 1005\f
1006/* Provide a version of a function to read a long long if the system does
1007 not provide one. */
b5e563e4 1008#if HOST_BITS_PER_WIDE_INT > HOST_BITS_PER_LONG && !HAVE_DECL_ATOLL && !defined(HAVE_ATOQ)
3ad4992f 1009HOST_WIDE_INT atoll (const char *);
a92a1bb2 1010
875d8740 1011HOST_WIDE_INT
3ad4992f 1012atoll (const char *p)
875d8740 1013{
1014 int neg = 0;
1015 HOST_WIDE_INT tmp_wide;
1016
337d789b 1017 while (ISSPACE (*p))
875d8740 1018 p++;
1019 if (*p == '-')
1020 neg = 1, p++;
1021 else if (*p == '+')
1022 p++;
1023
1024 tmp_wide = 0;
337d789b 1025 while (ISDIGIT (*p))
875d8740 1026 {
1027 HOST_WIDE_INT new_wide = tmp_wide*10 + (*p - '0');
1028 if (new_wide < tmp_wide)
1029 {
1030 /* Return INT_MAX equiv on overflow. */
7097b942 1031 tmp_wide = HOST_WIDE_INT_M1U >> 1;
875d8740 1032 break;
1033 }
1034 tmp_wide = new_wide;
1035 p++;
1036 }
1037
1038 if (neg)
1039 tmp_wide = -tmp_wide;
1040 return tmp_wide;
1041}
1042#endif
af908c02 1043\f
836c1c68 1044
1045#ifdef GENERATOR_FILE
220dcf2f 1046/* Process a define_conditions directive, starting with the optional
1047 space after the "define_conditions". The directive looks like this:
af908c02 1048
1049 (define_conditions [
1050 (number "string")
1051 (number "string")
1052 ...
1053 ])
1054
1055 It's not intended to appear in machine descriptions. It is
1056 generated by (the program generated by) genconditions.c, and
1057 slipped in at the beginning of the sequence of MD files read by
1058 most of the other generators. */
e1e9159b 1059void
d3ab2953 1060md_reader::read_conditions ()
af908c02 1061{
1062 int c;
1063
3604118d 1064 require_char_ws ('[');
af908c02 1065
b3453c30 1066 while ( (c = read_skip_spaces ()) != ']')
af908c02 1067 {
220dcf2f 1068 struct md_name name;
af908c02 1069 char *expr;
1070 int value;
1071
1072 if (c != '(')
b3453c30 1073 fatal_expected_char ('(', c);
af908c02 1074
220dcf2f 1075 read_name (&name);
1076 validate_const_int (name.string);
1077 value = atoi (name.string);
af908c02 1078
3604118d 1079 require_char_ws ('"');
b3453c30 1080 expr = read_quoted_string ();
af908c02 1081
3604118d 1082 require_char_ws (')');
af908c02 1083
1084 add_c_test (expr, value);
1085 }
af908c02 1086}
836c1c68 1087#endif /* #ifdef GENERATOR_FILE */
875d8740 1088
bd7c2be3 1089static void
b3453c30 1090validate_const_int (const char *string)
bd7c2be3 1091{
1092 const char *cp;
1093 int valid = 1;
1094
1095 cp = string;
337d789b 1096 while (*cp && ISSPACE (*cp))
bd7c2be3 1097 cp++;
1098 if (*cp == '-' || *cp == '+')
1099 cp++;
1100 if (*cp == 0)
1101 valid = 0;
1102 for (; *cp; cp++)
1103 if (! ISDIGIT (*cp))
d13600bf 1104 {
1105 valid = 0;
1106 break;
1107 }
bd7c2be3 1108 if (!valid)
b3453c30 1109 fatal_with_file_and_line ("invalid decimal constant \"%s\"\n", string);
bd7c2be3 1110}
1111
e913b5cd 1112static void
1113validate_const_wide_int (const char *string)
1114{
1115 const char *cp;
1116 int valid = 1;
1117
1118 cp = string;
1119 while (*cp && ISSPACE (*cp))
1120 cp++;
1121 /* Skip the leading 0x. */
1122 if (cp[0] == '0' || cp[1] == 'x')
1123 cp += 2;
1124 else
1125 valid = 0;
1126 if (*cp == 0)
1127 valid = 0;
1128 for (; *cp; cp++)
1129 if (! ISXDIGIT (*cp))
1130 valid = 0;
1131 if (!valid)
1132 fatal_with_file_and_line ("invalid hex constant \"%s\"\n", string);
1133}
1134
0fdb6b5d 1135/* Record that X uses iterator ITERATOR. If the use is in an operand
1136 of X, INDEX is the index of that operand, otherwise it is ignored. */
4a293229 1137
f5d566ff 1138static void
0fdb6b5d 1139record_iterator_use (struct mapping *iterator, rtx x, unsigned int index)
f5d566ff 1140{
0fdb6b5d 1141 struct iterator_use iuse = {iterator, x, index};
f1f41a6c 1142 iterator_uses.safe_push (iuse);
f5d566ff 1143}
1144
48db11b0 1145/* Record that X uses attribute VALUE at location LOC, where VALUE must
1146 match a built-in value from group GROUP. If the use is in an operand
1147 of X, INDEX is the index of that operand, otherwise it is ignored. */
f5d566ff 1148
1149static void
48db11b0 1150record_attribute_use (struct iterator_group *group, file_location loc, rtx x,
0fdb6b5d 1151 unsigned int index, const char *value)
f5d566ff 1152{
48db11b0 1153 struct attribute_use ause = {group, loc, value, x, index};
f1f41a6c 1154 attribute_uses.safe_push (ause);
f5d566ff 1155}
1156
1157/* Interpret NAME as either a built-in value, iterator or attribute
0fdb6b5d 1158 for group GROUP. X and INDEX are the values to pass to GROUP's
48db11b0 1159 apply_iterator callback. LOC is the location of the use. */
f5d566ff 1160
e1e9159b 1161void
d3ab2953 1162md_reader::record_potential_iterator_use (struct iterator_group *group,
48db11b0 1163 file_location loc,
0fdb6b5d 1164 rtx x, unsigned int index,
1165 const char *name)
4a293229 1166{
1167 struct mapping *m;
f5d566ff 1168 size_t len;
4a293229 1169
f5d566ff 1170 len = strlen (name);
1171 if (name[0] == '<' && name[len - 1] == '>')
1172 {
1173 /* Copy the attribute string into permanent storage, without the
1174 angle brackets around it. */
e1e9159b 1175 obstack_grow0 (&m_string_obstack, name + 1, len - 2);
48db11b0 1176 record_attribute_use (group, loc, x, index,
0fdb6b5d 1177 XOBFINISH (&m_string_obstack, char *));
f5d566ff 1178 }
1179 else
1180 {
1181 m = (struct mapping *) htab_find (group->iterators, &name);
1182 if (m != 0)
0fdb6b5d 1183 record_iterator_use (m, x, index);
f5d566ff 1184 else
0fdb6b5d 1185 group->apply_iterator (x, index, group->find_builtin (name));
f5d566ff 1186 }
4a293229 1187}
1188
836c1c68 1189#ifdef GENERATOR_FILE
1190
4a293229 1191/* Finish reading a declaration of the form:
1192
1193 (define... <name> [<value1> ... <valuen>])
1194
b3453c30 1195 from the MD file, where each <valuei> is either a bare symbol name or a
4a293229 1196 "(<name> <string>)" pair. The "(define..." part has already been read.
1197
1198 Represent the declaration as a "mapping" structure; add it to TABLE
1199 (which belongs to GROUP) and return it. */
1200
e1e9159b 1201struct mapping *
d3ab2953 1202md_reader::read_mapping (struct iterator_group *group, htab_t table)
4a293229 1203{
220dcf2f 1204 struct md_name name;
4a293229 1205 struct mapping *m;
1206 struct map_value **end_ptr;
1207 const char *string;
1208 int number, c;
1209
1210 /* Read the mapping name and create a structure for it. */
220dcf2f 1211 read_name (&name);
1212 m = add_mapping (group, table, name.string);
4a293229 1213
3604118d 1214 require_char_ws ('[');
4a293229 1215
1216 /* Read each value. */
1217 end_ptr = &m->values;
b3453c30 1218 c = read_skip_spaces ();
4a293229 1219 do
1220 {
1221 if (c != '(')
1222 {
1223 /* A bare symbol name that is implicitly paired to an
1224 empty string. */
b3453c30 1225 unread_char (c);
220dcf2f 1226 read_name (&name);
4a293229 1227 string = "";
1228 }
1229 else
1230 {
1231 /* A "(name string)" pair. */
220dcf2f 1232 read_name (&name);
b3453c30 1233 string = read_string (false);
3604118d 1234 require_char_ws (')');
4a293229 1235 }
220dcf2f 1236 number = group->find_builtin (name.string);
4a293229 1237 end_ptr = add_map_value (end_ptr, number, string);
b3453c30 1238 c = read_skip_spaces ();
4a293229 1239 }
1240 while (c != ']');
1241
4a293229 1242 return m;
1243}
1244
cbedf5a3 1245/* For iterator with name ATTR_NAME generate define_attr with values
1246 'yes' and 'no'. This attribute is used to mark templates to which
1247 define_subst ATTR_NAME should be applied. This attribute is set and
1248 defined implicitly and automatically. */
1249static void
b0e2a5e8 1250add_define_attr_for_define_subst (const char *attr_name, vec<rtx> *queue)
cbedf5a3 1251{
1252 rtx const_str, return_rtx;
1253
1254 return_rtx = rtx_alloc (DEFINE_ATTR);
1255 PUT_CODE (return_rtx, DEFINE_ATTR);
1256
1257 const_str = rtx_alloc (CONST_STRING);
1258 PUT_CODE (const_str, CONST_STRING);
1259 XSTR (const_str, 0) = xstrdup ("no");
1260
1261 XSTR (return_rtx, 0) = xstrdup (attr_name);
1262 XSTR (return_rtx, 1) = xstrdup ("no,yes");
1263 XEXP (return_rtx, 2) = const_str;
1264
b0e2a5e8 1265 queue->safe_push (return_rtx);
cbedf5a3 1266}
1267
1268/* This routine generates DEFINE_SUBST_ATTR expression with operands
1269 ATTR_OPERANDS and places it to QUEUE. */
1270static void
b0e2a5e8 1271add_define_subst_attr (const char **attr_operands, vec<rtx> *queue)
cbedf5a3 1272{
1273 rtx return_rtx;
1274 int i;
1275
1276 return_rtx = rtx_alloc (DEFINE_SUBST_ATTR);
1277 PUT_CODE (return_rtx, DEFINE_SUBST_ATTR);
1278
1279 for (i = 0; i < 4; i++)
1280 XSTR (return_rtx, i) = xstrdup (attr_operands[i]);
1281
b0e2a5e8 1282 queue->safe_push (return_rtx);
cbedf5a3 1283}
1284
1285/* Read define_subst_attribute construction. It has next form:
1286 (define_subst_attribute <attribute_name> <iterator_name> <value1> <value2>)
1287 Attribute is substituted with value1 when no subst is applied and with
1288 value2 in the opposite case.
1289 Attributes are added to SUBST_ATTRS_TABLE.
1290 In case the iterator is encountered for the first time, it's added to
1291 SUBST_ITERS_TABLE. Also, implicit define_attr is generated. */
1292
1293static void
1294read_subst_mapping (htab_t subst_iters_table, htab_t subst_attrs_table,
b0e2a5e8 1295 vec<rtx> *queue)
cbedf5a3 1296{
1297 struct mapping *m;
1298 struct map_value **end_ptr;
1299 const char *attr_operands[4];
cbedf5a3 1300 int i;
1301
1302 for (i = 0; i < 4; i++)
e1e9159b 1303 attr_operands[i] = rtx_reader_ptr->read_string (false);
cbedf5a3 1304
b0e2a5e8 1305 add_define_subst_attr (attr_operands, queue);
cbedf5a3 1306
1307 bind_subst_iter_and_attr (attr_operands[1], attr_operands[0]);
1308
1309 m = (struct mapping *) htab_find (substs.iterators, &attr_operands[1]);
1310 if (!m)
1311 {
1312 m = add_mapping (&substs, subst_iters_table, attr_operands[1]);
1313 end_ptr = &m->values;
1314 end_ptr = add_map_value (end_ptr, 1, "");
22eb1ed5 1315 add_map_value (end_ptr, 2, "");
cbedf5a3 1316
b0e2a5e8 1317 add_define_attr_for_define_subst (attr_operands[1], queue);
cbedf5a3 1318 }
1319
1320 m = add_mapping (&substs, subst_attrs_table, attr_operands[0]);
1321 end_ptr = &m->values;
1322 end_ptr = add_map_value (end_ptr, 1, attr_operands[2]);
22eb1ed5 1323 add_map_value (end_ptr, 2, attr_operands[3]);
cbedf5a3 1324}
1325
fd781bb2 1326/* Check newly-created code iterator ITERATOR to see whether every code has the
f5d566ff 1327 same format. */
4a293229 1328
1329static void
b3453c30 1330check_code_iterator (struct mapping *iterator)
4a293229 1331{
1332 struct map_value *v;
1333 enum rtx_code bellwether;
1334
fd781bb2 1335 bellwether = (enum rtx_code) iterator->values->number;
1336 for (v = iterator->values->next; v != 0; v = v->next)
4a293229 1337 if (strcmp (GET_RTX_FORMAT (bellwether), GET_RTX_FORMAT (v->number)) != 0)
b3453c30 1338 fatal_with_file_and_line ("code iterator `%s' combines "
c08a1447 1339 "`%s' and `%s', which have different "
1340 "rtx formats", iterator->name,
1341 GET_RTX_NAME (bellwether),
1342 GET_RTX_NAME (v->number));
1343}
1344
1345/* Check that all values of attribute ATTR are rtx codes that have a
1346 consistent format. Return a representative code. */
1347
1348static rtx_code
1349check_code_attribute (mapping *attr)
1350{
1351 rtx_code bellwether = UNKNOWN;
1352 for (map_value *v = attr->values; v != 0; v = v->next)
1353 {
1354 rtx_code code = maybe_find_code (v->string);
1355 if (code == UNKNOWN)
1356 fatal_with_file_and_line ("code attribute `%s' contains "
1357 "unrecognized rtx code `%s'",
1358 attr->name, v->string);
1359 if (bellwether == UNKNOWN)
1360 bellwether = code;
1361 else if (strcmp (GET_RTX_FORMAT (bellwether),
1362 GET_RTX_FORMAT (code)) != 0)
1363 fatal_with_file_and_line ("code attribute `%s' combines "
1364 "`%s' and `%s', which have different "
1365 "rtx formats", attr->name,
1366 GET_RTX_NAME (bellwether),
1367 GET_RTX_NAME (code));
1368 }
1369 return bellwether;
4a293229 1370}
1371
77ba95d0 1372/* Read an rtx-related declaration from the MD file, given that it
1373 starts with directive name RTX_NAME. Return true if it expands to
1374 one or more rtxes (as defined by rtx.def). When returning true,
1375 store the list of rtxes as an EXPR_LIST in *X. */
875d8740 1376
fea520eb 1377bool
e1e9159b 1378rtx_reader::read_rtx (const char *rtx_name, vec<rtx> *rtxen)
875d8740 1379{
77ba95d0 1380 /* Handle various rtx-related declarations that aren't themselves
1381 encoded as rtxes. */
1382 if (strcmp (rtx_name, "define_conditions") == 0)
4a293229 1383 {
77ba95d0 1384 read_conditions ();
1385 return false;
4a293229 1386 }
77ba95d0 1387 if (strcmp (rtx_name, "define_mode_attr") == 0)
1388 {
1389 read_mapping (&modes, modes.attrs);
1390 return false;
1391 }
1392 if (strcmp (rtx_name, "define_mode_iterator") == 0)
1393 {
1394 read_mapping (&modes, modes.iterators);
1395 return false;
1396 }
1397 if (strcmp (rtx_name, "define_code_attr") == 0)
1398 {
1399 read_mapping (&codes, codes.attrs);
1400 return false;
1401 }
1402 if (strcmp (rtx_name, "define_code_iterator") == 0)
1403 {
1404 check_code_iterator (read_mapping (&codes, codes.iterators));
1405 return false;
1406 }
65729bd0 1407 if (strcmp (rtx_name, "define_int_attr") == 0)
1408 {
1409 read_mapping (&ints, ints.attrs);
1410 return false;
1411 }
1412 if (strcmp (rtx_name, "define_int_iterator") == 0)
1413 {
1414 read_mapping (&ints, ints.iterators);
1415 return false;
1416 }
cbedf5a3 1417 if (strcmp (rtx_name, "define_subst_attr") == 0)
1418 {
b0e2a5e8 1419 read_subst_mapping (substs.iterators, substs.attrs, rtxen);
cbedf5a3 1420
1421 /* READ_SUBST_MAPPING could generate a new DEFINE_ATTR. Return
1422 TRUE to process it. */
1423 return true;
1424 }
77ba95d0 1425
d3ab2953 1426 apply_iterators (rtx_reader_ptr->read_rtx_code (rtx_name), rtxen);
f1f41a6c 1427 iterator_uses.truncate (0);
1428 attribute_uses.truncate (0);
4a293229 1429
fea520eb 1430 return true;
4a293229 1431}
1432
836c1c68 1433#endif /* #ifdef GENERATOR_FILE */
1434
1435/* Do one-time initialization. */
1436
1437static void
1438one_time_initialization (void)
1439{
1440 static bool initialized = false;
1441
1442 if (!initialized)
1443 {
1444 initialize_iterators ();
1445 initialized = true;
1446 }
1447}
1448
1449/* Consume characters until encountering a character in TERMINATOR_CHARS,
1450 consuming the terminator character if CONSUME_TERMINATOR is true.
1451 Return all characters before the terminator as an allocated buffer. */
1452
1453char *
1454rtx_reader::read_until (const char *terminator_chars, bool consume_terminator)
1455{
1456 int ch = read_skip_spaces ();
1457 unread_char (ch);
1458 auto_vec<char> buf;
1459 while (1)
1460 {
1461 ch = read_char ();
1462 if (strchr (terminator_chars, ch))
1463 {
1464 if (!consume_terminator)
1465 unread_char (ch);
1466 break;
1467 }
1468 buf.safe_push (ch);
1469 }
1470 buf.safe_push ('\0');
1471 return xstrdup (buf.address ());
1472}
1473
1474/* Subroutine of read_rtx_code, for parsing zero or more flags. */
1475
1476static void
1477read_flags (rtx return_rtx)
1478{
1479 while (1)
1480 {
1481 int ch = read_char ();
1482 if (ch != '/')
1483 {
1484 unread_char (ch);
1485 break;
1486 }
1487
1488 int flag_char = read_char ();
1489 switch (flag_char)
1490 {
1491 case 's':
1492 RTX_FLAG (return_rtx, in_struct) = 1;
1493 break;
1494 case 'v':
1495 RTX_FLAG (return_rtx, volatil) = 1;
1496 break;
1497 case 'u':
1498 RTX_FLAG (return_rtx, unchanging) = 1;
1499 break;
1500 case 'f':
1501 RTX_FLAG (return_rtx, frame_related) = 1;
1502 break;
1503 case 'j':
1504 RTX_FLAG (return_rtx, jump) = 1;
1505 break;
1506 case 'c':
1507 RTX_FLAG (return_rtx, call) = 1;
1508 break;
1509 case 'i':
1510 RTX_FLAG (return_rtx, return_val) = 1;
1511 break;
1512 default:
1513 fatal_with_file_and_line ("unrecognized flag: `%c'", flag_char);
1514 }
1515 }
1516}
1517
1518/* Return the numeric value n for GET_REG_NOTE_NAME (n) for STRING,
1519 or fail if STRING isn't recognized. */
1520
1521static int
1522parse_reg_note_name (const char *string)
1523{
1524 for (int i = 0; i < REG_NOTE_MAX; i++)
c9281ef8 1525 if (strcmp (string, GET_REG_NOTE_NAME (i)) == 0)
836c1c68 1526 return i;
1527 fatal_with_file_and_line ("unrecognized REG_NOTE name: `%s'", string);
1528}
1529
c08a1447 1530/* Allocate an rtx for code NAME. If NAME is a code iterator or code
1531 attribute, record its use for later and use one of its possible
1532 values as an interim rtx code. */
1533
1534rtx
1535rtx_reader::rtx_alloc_for_name (const char *name)
1536{
1537#ifdef GENERATOR_FILE
1538 size_t len = strlen (name);
1539 if (name[0] == '<' && name[len - 1] == '>')
1540 {
1541 /* Copy the attribute string into permanent storage, without the
1542 angle brackets around it. */
1543 obstack *strings = get_string_obstack ();
1544 obstack_grow0 (strings, name + 1, len - 2);
1545 char *deferred_name = XOBFINISH (strings, char *);
1546
1547 /* Find the name of the attribute. */
1548 const char *attr = strchr (deferred_name, ':');
1549 if (!attr)
1550 attr = deferred_name;
1551
1552 /* Find the attribute itself. */
1553 mapping *m = (mapping *) htab_find (codes.attrs, &attr);
1554 if (!m)
1555 fatal_with_file_and_line ("unknown code attribute `%s'", attr);
1556
1557 /* Pick the first possible code for now, and record the attribute
1558 use for later. */
1559 rtx x = rtx_alloc (check_code_attribute (m));
48db11b0 1560 record_attribute_use (&codes, get_current_location (),
1561 x, 0, deferred_name);
c08a1447 1562 return x;
1563 }
1564
1565 mapping *iterator = (mapping *) htab_find (codes.iterators, &name);
1566 if (iterator != 0)
1567 {
1568 /* Pick the first possible code for now, and record the iterator
1569 use for later. */
1570 rtx x = rtx_alloc (rtx_code (iterator->values->number));
1571 record_iterator_use (iterator, x, 0);
1572 return x;
1573 }
1574#endif
1575
1576 return rtx_alloc (rtx_code (codes.find_builtin (name)));
1577}
1578
77ba95d0 1579/* Subroutine of read_rtx and read_nested_rtx. CODE_NAME is the name of
1580 either an rtx code or a code iterator. Parse the rest of the rtx and
f5d566ff 1581 return it. */
4a293229 1582
e1e9159b 1583rtx
1584rtx_reader::read_rtx_code (const char *code_name)
4a293229 1585{
f5d566ff 1586 RTX_CODE code;
19cb6b50 1587 const char *format_ptr;
220dcf2f 1588 struct md_name name;
875d8740 1589 rtx return_rtx;
19cb6b50 1590 int c;
836c1c68 1591 long reuse_id = -1;
875d8740 1592
875d8740 1593 /* Linked list structure for making RTXs: */
1594 struct rtx_list
1595 {
1596 struct rtx_list *next;
1597 rtx value; /* Value of this node. */
1598 };
1599
836c1c68 1600 /* Handle reuse_rtx ids e.g. "(0|scratch:DI)". */
1601 if (ISDIGIT (code_name[0]))
1602 {
1603 reuse_id = atoi (code_name);
1604 while (char ch = *code_name++)
1605 if (ch == '|')
1606 break;
1607 }
1608
1609 /* Handle "reuse_rtx". */
1610 if (strcmp (code_name, "reuse_rtx") == 0)
1611 {
1612 read_name (&name);
50079afd 1613 unsigned idx = atoi (name.string);
836c1c68 1614 /* Look it up by ID. */
1615 gcc_assert (idx < m_reuse_rtx_by_id.length ());
1616 return_rtx = m_reuse_rtx_by_id[idx];
1617 return return_rtx;
1618 }
1619
875d8740 1620 /* If we end up with an insn expression then we free this space below. */
c08a1447 1621 return_rtx = rtx_alloc_for_name (code_name);
1622 code = GET_CODE (return_rtx);
f5d566ff 1623 format_ptr = GET_RTX_FORMAT (code);
2975871c 1624 memset (return_rtx, 0, RTX_CODE_SIZE (code));
f5d566ff 1625 PUT_CODE (return_rtx, code);
1626
836c1c68 1627 if (reuse_id != -1)
1628 {
1629 /* Store away for later reuse. */
1630 m_reuse_rtx_by_id.safe_grow_cleared (reuse_id + 1);
1631 m_reuse_rtx_by_id[reuse_id] = return_rtx;
1632 }
1633
836c1c68 1634 /* Check for flags. */
1635 read_flags (return_rtx);
1636
1637 /* Read REG_NOTE names for EXPR_LIST and INSN_LIST. */
1638 if ((GET_CODE (return_rtx) == EXPR_LIST
1639 || GET_CODE (return_rtx) == INSN_LIST
1640 || GET_CODE (return_rtx) == INT_LIST)
1641 && !m_in_call_function_usage)
1642 {
1643 char ch = read_char ();
1644 if (ch == ':')
1645 {
1646 read_name (&name);
1647 PUT_MODE_RAW (return_rtx,
1648 (machine_mode)parse_reg_note_name (name.string));
1649 }
1650 else
1651 unread_char (ch);
1652 }
1653
875d8740 1654 /* If what follows is `: mode ', read it and
1655 store the mode in the rtx. */
1656
9b12e2dc 1657 c = read_skip_spaces ();
1658 if (c == ':')
875d8740 1659 {
48db11b0 1660 file_location loc = read_name (&name);
1661 record_potential_iterator_use (&modes, loc, return_rtx, 0, name.string);
875d8740 1662 }
1663 else
9b12e2dc 1664 unread_char (c);
875d8740 1665
836c1c68 1666 if (INSN_CHAIN_CODE_P (code))
1667 {
1668 read_name (&name);
1669 INSN_UID (return_rtx) = atoi (name.string);
1670 }
1671
1672 /* Use the format_ptr to parse the various operands of this rtx. */
9b12e2dc 1673 for (int idx = 0; format_ptr[idx] != 0; idx++)
836c1c68 1674 return_rtx = read_rtx_operand (return_rtx, idx);
1675
1676 /* Handle any additional information that after the regular fields
1677 (e.g. when parsing function dumps). */
1678 handle_any_trailing_information (return_rtx);
875d8740 1679
e913b5cd 1680 if (CONST_WIDE_INT_P (return_rtx))
1681 {
1682 read_name (&name);
1683 validate_const_wide_int (name.string);
1684 {
e913b5cd 1685 const char *s = name.string;
1686 int len;
1687 int index = 0;
1688 int gs = HOST_BITS_PER_WIDE_INT/4;
1689 int pos;
1690 char * buf = XALLOCAVEC (char, gs + 1);
1691 unsigned HOST_WIDE_INT wi;
1692 int wlen;
1693
1694 /* Skip the leading spaces. */
1695 while (*s && ISSPACE (*s))
1696 s++;
1697
1698 /* Skip the leading 0x. */
1699 gcc_assert (s[0] == '0');
1700 gcc_assert (s[1] == 'x');
1701 s += 2;
1702
1703 len = strlen (s);
1704 pos = len - gs;
1705 wlen = (len + gs - 1) / gs; /* Number of words needed */
1706
1707 return_rtx = const_wide_int_alloc (wlen);
1708
e913b5cd 1709 while (pos > 0)
1710 {
1711#if HOST_BITS_PER_WIDE_INT == 64
1712 sscanf (s + pos, "%16" HOST_WIDE_INT_PRINT "x", &wi);
1713#else
1714 sscanf (s + pos, "%8" HOST_WIDE_INT_PRINT "x", &wi);
1715#endif
05c25ee6 1716 CWI_ELT (return_rtx, index++) = wi;
e913b5cd 1717 pos -= gs;
1718 }
1719 strncpy (buf, s, gs - pos);
1720 buf [gs - pos] = 0;
1721 sscanf (buf, "%" HOST_WIDE_INT_PRINT "x", &wi);
05c25ee6 1722 CWI_ELT (return_rtx, index++) = wi;
e913b5cd 1723 /* TODO: After reading, do we want to canonicalize with:
1724 value = lookup_const_wide_int (value); ? */
1725 }
1726 }
1727
77ba95d0 1728 c = read_skip_spaces ();
1729 /* Syntactic sugar for AND and IOR, allowing Lisp-like
1730 arbitrary number of arguments for them. */
1731 if (c == '('
1732 && (GET_CODE (return_rtx) == AND
1733 || GET_CODE (return_rtx) == IOR))
f5d566ff 1734 return read_rtx_variadic (return_rtx);
77ba95d0 1735
1736 unread_char (c);
1737 return return_rtx;
1738}
1739
9b12e2dc 1740/* Subroutine of read_rtx_code. Parse operand IDX within RETURN_RTX,
1741 based on the corresponding format character within GET_RTX_FORMAT
836c1c68 1742 for the GET_CODE (RETURN_RTX), and return RETURN_RTX.
1743 This is a virtual function, so that function_reader can override
1744 some parsing, and potentially return a different rtx. */
9b12e2dc 1745
836c1c68 1746rtx
e1e9159b 1747rtx_reader::read_rtx_operand (rtx return_rtx, int idx)
9b12e2dc 1748{
1749 RTX_CODE code = GET_CODE (return_rtx);
1750 const char *format_ptr = GET_RTX_FORMAT (code);
1751 int c;
1752 struct md_name name;
1753
1754 switch (format_ptr[idx])
1755 {
1756 /* 0 means a field for internal use only.
1757 Don't expect it to be present in the input. */
1758 case '0':
1759 if (code == REG)
1760 ORIGINAL_REGNO (return_rtx) = REGNO (return_rtx);
1761 break;
1762
1763 case 'e':
836c1c68 1764 XEXP (return_rtx, idx) = read_nested_rtx ();
1765 break;
1766
9b12e2dc 1767 case 'u':
1768 XEXP (return_rtx, idx) = read_nested_rtx ();
1769 break;
1770
1771 case 'V':
1772 /* 'V' is an optional vector: if a closeparen follows,
1773 just store NULL for this element. */
1774 c = read_skip_spaces ();
1775 unread_char (c);
1776 if (c == ')')
1777 {
1778 XVEC (return_rtx, idx) = 0;
1779 break;
1780 }
1781 /* Now process the vector. */
1782 /* FALLTHRU */
1783
1784 case 'E':
1785 {
1786 /* Obstack to store scratch vector in. */
1787 struct obstack vector_stack;
1788 int list_counter = 0;
1789 rtvec return_vec = NULL_RTVEC;
c488a0b5 1790 rtx saved_rtx = NULL_RTX;
9b12e2dc 1791
1792 require_char_ws ('[');
1793
1794 /* Add expressions to a list, while keeping a count. */
1795 obstack_init (&vector_stack);
1796 while ((c = read_skip_spaces ()) && c != ']')
1797 {
1798 if (c == EOF)
1799 fatal_expected_char (']', c);
1800 unread_char (c);
c488a0b5 1801
1802 rtx value;
1803 int repeat_count = 1;
1804 if (c == 'r')
1805 {
1806 /* Process "repeated xN" directive. */
1807 read_name (&name);
1808 if (strcmp (name.string, "repeated"))
1809 fatal_with_file_and_line ("invalid directive \"%s\"\n",
1810 name.string);
1811 read_name (&name);
1812 if (!sscanf (name.string, "x%d", &repeat_count))
1813 fatal_with_file_and_line ("invalid repeat count \"%s\"\n",
1814 name.string);
1815
1816 /* We already saw one of the instances. */
1817 repeat_count--;
1818 value = saved_rtx;
1819 }
1820 else
1821 value = read_nested_rtx ();
1822
1823 for (; repeat_count > 0; repeat_count--)
1824 {
1825 list_counter++;
1826 obstack_ptr_grow (&vector_stack, value);
1827 }
1828 saved_rtx = value;
9b12e2dc 1829 }
1830 if (list_counter > 0)
1831 {
1832 return_vec = rtvec_alloc (list_counter);
1833 memcpy (&return_vec->elem[0], obstack_finish (&vector_stack),
1834 list_counter * sizeof (rtx));
1835 }
1836 else if (format_ptr[idx] == 'E')
1837 fatal_with_file_and_line ("vector must have at least one element");
1838 XVEC (return_rtx, idx) = return_vec;
1839 obstack_free (&vector_stack, NULL);
1840 /* close bracket gotten */
1841 }
1842 break;
1843
1844 case 'S':
1845 case 'T':
1846 case 's':
1847 {
1848 char *stringbuf;
1849 int star_if_braced;
1850
1851 c = read_skip_spaces ();
1852 unread_char (c);
1853 if (c == ')')
1854 {
1855 /* 'S' fields are optional and should be NULL if no string
1856 was given. Also allow normal 's' and 'T' strings to be
1857 omitted, treating them in the same way as empty strings. */
1858 XSTR (return_rtx, idx) = (format_ptr[idx] == 'S' ? NULL : "");
1859 break;
1860 }
1861
e8c17f8e 1862 /* The output template slot of a DEFINE_INSN, DEFINE_INSN_AND_SPLIT,
1863 DEFINE_INSN_AND_REWRITE or DEFINE_PEEPHOLE automatically
9b12e2dc 1864 gets a star inserted as its first character, if it is
1865 written with a brace block instead of a string constant. */
1866 star_if_braced = (format_ptr[idx] == 'T');
1867
1868 stringbuf = read_string (star_if_braced);
836c1c68 1869 if (!stringbuf)
1870 break;
9b12e2dc 1871
836c1c68 1872#ifdef GENERATOR_FILE
9b12e2dc 1873 /* For insn patterns, we want to provide a default name
1874 based on the file and line, like "*foo.md:12", if the
1875 given name is blank. These are only for define_insn and
1876 define_insn_and_split, to aid debugging. */
1877 if (*stringbuf == '\0'
1878 && idx == 0
1879 && (GET_CODE (return_rtx) == DEFINE_INSN
e8c17f8e 1880 || GET_CODE (return_rtx) == DEFINE_INSN_AND_SPLIT
1881 || GET_CODE (return_rtx) == DEFINE_INSN_AND_REWRITE))
9b12e2dc 1882 {
48db11b0 1883 const char *old_stringbuf = stringbuf;
836c1c68 1884 struct obstack *string_obstack = get_string_obstack ();
9b12e2dc 1885 char line_name[20];
e1e9159b 1886 const char *read_md_filename = get_filename ();
9b12e2dc 1887 const char *fn = (read_md_filename ? read_md_filename : "rtx");
1888 const char *slash;
1889 for (slash = fn; *slash; slash ++)
1890 if (*slash == '/' || *slash == '\\' || *slash == ':')
1891 fn = slash + 1;
d3ab2953 1892 obstack_1grow (string_obstack, '*');
1893 obstack_grow (string_obstack, fn, strlen (fn));
e1e9159b 1894 sprintf (line_name, ":%d", get_lineno ());
d3ab2953 1895 obstack_grow (string_obstack, line_name, strlen (line_name)+1);
1896 stringbuf = XOBFINISH (string_obstack, char *);
48db11b0 1897 copy_md_ptr_loc (stringbuf, old_stringbuf);
9b12e2dc 1898 }
1899
1900 /* Find attr-names in the string. */
1901 char *str;
1902 char *start, *end, *ptr;
1903 char tmpstr[256];
1904 ptr = &tmpstr[0];
1905 end = stringbuf;
1906 while ((start = strchr (end, '<')) && (end = strchr (start, '>')))
1907 {
1908 if ((end - start - 1 > 0)
1909 && (end - start - 1 < (int)sizeof (tmpstr)))
1910 {
1911 strncpy (tmpstr, start+1, end-start-1);
1912 tmpstr[end-start-1] = 0;
1913 end++;
1914 }
1915 else
1916 break;
1917 struct mapping *m
1918 = (struct mapping *) htab_find (substs.attrs, &ptr);
1919 if (m != 0)
1920 {
1921 /* Here we should find linked subst-iter. */
1922 str = find_subst_iter_by_attr (ptr);
1923 if (str)
1924 m = (struct mapping *) htab_find (substs.iterators, &str);
1925 else
1926 m = 0;
1927 }
1928 if (m != 0)
0fdb6b5d 1929 record_iterator_use (m, return_rtx, 0);
9b12e2dc 1930 }
836c1c68 1931#endif /* #ifdef GENERATOR_FILE */
1932
1933 const char *string_ptr = finalize_string (stringbuf);
9b12e2dc 1934
1935 if (star_if_braced)
836c1c68 1936 XTMPL (return_rtx, idx) = string_ptr;
9b12e2dc 1937 else
836c1c68 1938 XSTR (return_rtx, idx) = string_ptr;
9b12e2dc 1939 }
1940 break;
1941
1942 case 'w':
1943 {
1944 HOST_WIDE_INT tmp_wide;
1945 read_name (&name);
1946 validate_const_int (name.string);
1947#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
1948 tmp_wide = atoi (name.string);
1949#else
1950#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
1951 tmp_wide = atol (name.string);
1952#else
1953 /* Prefer atoll over atoq, since the former is in the ISO C99 standard.
1954 But prefer not to use our hand-rolled function above either. */
1955#if HAVE_DECL_ATOLL || !defined(HAVE_ATOQ)
1956 tmp_wide = atoll (name.string);
1957#else
1958 tmp_wide = atoq (name.string);
1959#endif
1960#endif
1961#endif
1962 XWINT (return_rtx, idx) = tmp_wide;
1963 }
1964 break;
1965
1966 case 'i':
1967 case 'n':
9edf7ea8 1968 case 'p':
48db11b0 1969 {
1970 /* Can be an iterator or an integer constant. */
1971 file_location loc = read_name (&name);
1972 record_potential_iterator_use (&ints, loc, return_rtx, idx,
1973 name.string);
1974 break;
1975 }
9b12e2dc 1976
1977 case 'r':
1978 read_name (&name);
1979 validate_const_int (name.string);
1980 set_regno_raw (return_rtx, atoi (name.string), 1);
1981 REG_ATTRS (return_rtx) = NULL;
1982 break;
1983
1984 default:
1985 gcc_unreachable ();
1986 }
836c1c68 1987
1988 return return_rtx;
9b12e2dc 1989}
1990
f5d566ff 1991/* Read a nested rtx construct from the MD file and return it. */
77ba95d0 1992
e1e9159b 1993rtx
1994rtx_reader::read_nested_rtx ()
77ba95d0 1995{
1996 struct md_name name;
77ba95d0 1997 rtx return_rtx;
1998
836c1c68 1999 /* In compact dumps, trailing "(nil)" values can be omitted.
2000 Handle such dumps. */
2001 if (peek_char () == ')')
2002 return NULL_RTX;
2003
3604118d 2004 require_char_ws ('(');
77ba95d0 2005
2006 read_name (&name);
2007 if (strcmp (name.string, "nil") == 0)
2008 return_rtx = NULL;
2009 else
f5d566ff 2010 return_rtx = read_rtx_code (name.string);
77ba95d0 2011
3604118d 2012 require_char_ws (')');
875d8740 2013
836c1c68 2014 return_rtx = postprocess (return_rtx);
2015
875d8740 2016 return return_rtx;
2017}
6c9ff279 2018
2019/* Mutually recursive subroutine of read_rtx which reads
2020 (thing x1 x2 x3 ...) and produces RTL as if
2021 (thing x1 (thing x2 (thing x3 ...))) had been written.
2022 When called, FORM is (thing x1 x2), and the file position
2023 is just past the leading parenthesis of x3. Only works
2024 for THINGs which are dyadic expressions, e.g. AND, IOR. */
e1e9159b 2025rtx
2026rtx_reader::read_rtx_variadic (rtx form)
6c9ff279 2027{
2028 char c = '(';
2029 rtx p = form, q;
2030
2031 do
2032 {
b3453c30 2033 unread_char (c);
6c9ff279 2034
2035 q = rtx_alloc (GET_CODE (p));
2036 PUT_MODE (q, GET_MODE (p));
2037
2038 XEXP (q, 0) = XEXP (p, 1);
f5d566ff 2039 XEXP (q, 1) = read_nested_rtx ();
48e1416a 2040
6c9ff279 2041 XEXP (p, 1) = q;
2042 p = q;
b3453c30 2043 c = read_skip_spaces ();
6c9ff279 2044 }
2045 while (c == '(');
77ba95d0 2046 unread_char (c);
6c9ff279 2047 return form;
2048}
d3ab2953 2049
2050/* Constructor for class rtx_reader. */
2051
836c1c68 2052rtx_reader::rtx_reader (bool compact)
2053: md_reader (compact),
2054 m_in_call_function_usage (false)
d3ab2953 2055{
2056 /* Set the global singleton pointer. */
2057 rtx_reader_ptr = this;
836c1c68 2058
2059 one_time_initialization ();
d3ab2953 2060}
2061
2062/* Destructor for class rtx_reader. */
2063
2064rtx_reader::~rtx_reader ()
2065{
2066 /* Clear the global singleton pointer. */
2067 rtx_reader_ptr = NULL;
2068}