+#include "read-md.h"
+#include "gensupport.h"
+
+/* One element in a singly-linked list of (integer, string) pairs. */
+struct map_value {
+ struct map_value *next;
+ int number;
+ const char *string;
+};
+
+/* Maps an iterator or attribute name to a list of (integer, string) pairs.
+ The integers are mode or code values; the strings are either C conditions
+ or attribute values. */
+struct mapping {
+ /* The name of the iterator or attribute. */
+ const char *name;
+
+ /* The group (modes or codes) to which the iterator or attribute belongs. */
+ struct iterator_group *group;
+
+ /* Gives a unique number to the attribute or iterator. Numbers are
+ allocated consecutively, starting at 0. */
+ int index;
+
+ /* The list of (integer, string) pairs. */
+ struct map_value *values;
+};
+
+/* A structure for abstracting the common parts of code and mode iterators. */
+struct iterator_group {
+ /* Tables of "mapping" structures, one for attributes and one for iterators. */
+ htab_t attrs, iterators;
+
+ /* The number of "real" modes or codes (and by extension, the first
+ number available for use as an iterator placeholder). */
+ int num_builtins;
+
+ /* Treat the given string as the name of a standard mode or code and
+ return its integer value. */
+ int (*find_builtin) (const char *);
+
+ /* Return true if the given rtx uses the given mode or code. */
+ bool (*uses_iterator_p) (rtx, int);
+
+ /* Make the given rtx use the given mode or code. */
+ void (*apply_iterator) (rtx, int);
+};
+
+/* A structure used to pass data from read_rtx to apply_iterator_traverse
+ via htab_traverse. */
+struct iterator_traverse_data {
+ /* Instruction queue. */
+ rtx queue;
+ /* Attributes seen for modes. */
+ struct map_value *mode_maps;
+ /* The last unknown attribute used as a mode. */
+ const char *unknown_mode_attr;
+};
+
+/* If CODE is the number of a code iterator, return a real rtx code that
+ has the same format. Return CODE otherwise. */
+#define BELLWETHER_CODE(CODE) \
+ ((CODE) < NUM_RTX_CODE ? CODE : bellwether_codes[CODE - NUM_RTX_CODE])
+
+static int find_mode (const char *);
+static bool uses_mode_iterator_p (rtx, int);
+static void apply_mode_iterator (rtx, int);
+static int find_code (const char *);
+static bool uses_code_iterator_p (rtx, int);
+static void apply_code_iterator (rtx, int);
+static const char *apply_iterator_to_string (const char *, struct mapping *, int);
+static rtx apply_iterator_to_rtx (rtx, struct mapping *, int,
+ struct map_value *, const char **);
+static bool uses_iterator_p (rtx, struct mapping *);
+static const char *add_condition_to_string (const char *, const char *);
+static void add_condition_to_rtx (rtx, const char *);
+static int apply_iterator_traverse (void **, void *);
+static struct mapping *add_mapping (struct iterator_group *, htab_t t,
+ const char *);
+static struct map_value **add_map_value (struct map_value **,
+ int, const char *);
+static void initialize_iterators (void);
+static void read_conditions (void);
+static void validate_const_int (const char *);
+static int find_iterator (struct iterator_group *, const char *);
+static struct mapping *read_mapping (struct iterator_group *, htab_t);
+static void check_code_iterator (struct mapping *);
+static rtx read_rtx_code (const char *, struct map_value **);
+static rtx read_nested_rtx (struct map_value **);
+static rtx read_rtx_variadic (struct map_value **, rtx);
+
+/* The mode and code iterator structures. */
+static struct iterator_group modes, codes;
+
+/* Index I is the value of BELLWETHER_CODE (I + NUM_RTX_CODE). */
+static enum rtx_code *bellwether_codes;
+
+/* Implementations of the iterator_group callbacks for modes. */