@@ -11502,11 +11502,10 @@ The construct:
@end smallexample
defines a pseudo integer constant @var{name} that can be instantiated as
-@var{inti} if condition @var{condi} is true. Each @var{int} must have the
-same rtx format. @xref{RTL Classes}. Int iterators can appear in only
-those rtx fields that have 'i', 'n', 'w', or 'p' as the specifier. This
-means that each @var{int} has to be a constant defined using define_constant
-or define_c_enum.
+@var{inti} if condition @var{condi} is true. Int iterators can appear in
+only those rtx fields that have `i', `n', `w', or `p' as the specifier.
+This means that each @var{int} has to be a constant defined using
+@samp{define_constant} or @samp{define_c_enum}.
As with mode and code iterators, each pattern that uses @var{name} will be
expanded @var{n} times, once with all uses of @var{name} replaced by
@@ -11517,9 +11516,13 @@ It is possible to define attributes for ints as well as for codes and modes.
Attributes are defined using:
@smallexample
-(define_int_attr @var{name} [(@var{int1} "@var{value1}") @dots{} (@var{intn} "@var{valuen}")])
+(define_int_attr @var{attr_name} [(@var{int1} "@var{value1}") @dots{} (@var{intn} "@var{valuen}")])
@end smallexample
+In additon to these user-defined attributes, it is possible to use
+@samp{<@var{name}>} to refer to the current expansion of iterator
+@var{name} (such as @var{int1}, @var{int2}, and so on).
+
Here's an example of int iterators in action, taken from the ARM port:
@smallexample
@@ -80,6 +80,12 @@ struct iterator_group {
/* Return the C token for the given standard mode, code, etc. */
const char *(*get_c_token) (int);
+
+ /* True if each iterator name should be treated as an attribute that
+ maps to the C token produced by get_c_token. This means that for
+ an iterator ITER, <ITER> can be used in strings to refer to the
+ current value of ITER, as a C token. */
+ bool has_self_attr;
};
/* Records one use of an iterator. */
@@ -472,6 +478,25 @@ map_attr_string (file_location loc, const char *p, mapping **iterator_out = 0)
|| iterator->name[iterator_name_len] != 0))
continue;
+ if (iterator->group->has_self_attr
+ && strcmp (attr, iterator->name) == 0)
+ {
+ if (iterator_out)
+ *iterator_out = iterator;
+ int number = iterator->current_value->number;
+ const char *string = iterator->group->get_c_token (number);
+ if (res && strcmp (string, res->string) != 0)
+ {
+ error_at (loc, "ambiguous attribute '%s'; could be"
+ " '%s' (via '%s:%s') or '%s' (via '%s:%s')",
+ attr, res->string, prev->name, attr,
+ string, iterator->name, attr);
+ return res;
+ }
+ prev = iterator;
+ res = new map_value { nullptr, number, string };
+ }
+
/* Find the attribute specification. */
m = (struct mapping *) htab_find (iterator->group->attrs, &attr);
if (m)
@@ -1035,6 +1060,7 @@ initialize_iterators (void)
ints.find_builtin = find_int;
ints.apply_iterator = apply_int_iterator;
ints.get_c_token = get_int_token;
+ ints.has_self_attr = true;
substs.attrs = htab_create (13, leading_string_hash, leading_string_eq_p, 0);
substs.iterators = htab_create (13, leading_string_hash,