+static inline const arch_register_class_t *_arch_register_get_class(const arch_register_t *reg)
+{
+ return reg->reg_class;
+}
+
+static inline unsigned _arch_register_get_index(const arch_register_t *reg)
+{
+ return reg->index;
+}
+
+static inline const char *_arch_register_get_name(const arch_register_t *reg)
+{
+ return reg->name;
+}
+
+#define arch_register_get_class(reg) _arch_register_get_class(reg)
+#define arch_register_get_index(reg) _arch_register_get_index(reg)
+#define arch_register_get_name(reg) _arch_register_get_name(reg)
+
+/**
+ * Convenience macro to check for register type.
+ * @param req A pointer to register.
+ * @param kind The kind of type to check for (see arch_register_type_t).
+ * @return 1, If register is of given kind, 0 if not.
+ */
+#define arch_register_type_is(reg, kind) \
+ (((reg)->type & arch_register_type_ ## kind) != 0)
+
+/**
+ * A class of registers.
+ * Like general purpose or floating point.
+ */
+struct arch_register_class_t {
+ unsigned index; /**< index of this register class */
+ const char *name; /**< The name of the register class.*/
+ unsigned n_regs; /**< Number of registers in this
+ class. */
+ ir_mode *mode; /**< The mode of the register class.*/
+ const arch_register_t *regs; /**< The array of registers. */
+ arch_register_class_flags_t flags; /**< register class flags. */
+ const arch_register_req_t *class_req;
+};
+
+/** return the number of registers in this register class */
+#define arch_register_class_n_regs(cls) ((cls)->n_regs)
+
+/** return the largest mode of this register class */
+#define arch_register_class_mode(cls) ((cls)->mode)
+
+/** return the name of this register class */
+#define arch_register_class_name(cls) ((cls)->name)
+
+/** return the index of this register class */
+#define arch_register_class_index(cls) ((cls)->index)
+
+/** return the register class flags */
+#define arch_register_class_flags(cls) ((cls)->flags)
+
+static inline const arch_register_t *_arch_register_for_index(const arch_register_class_t *cls, unsigned idx)
+{
+ assert(idx < cls->n_regs);
+ return &cls->regs[idx];
+}
+
+#define arch_register_for_index(cls, idx) _arch_register_for_index(cls, idx)
+
+/**
+ * Convenience macro to check for set constraints.
+ * @param req A pointer to register requirements.
+ * @param kind The kind of constraint to check for (see arch_register_req_type_t).
+ * @return 1, If the kind of constraint is present, 0 if not.
+ */
+#define arch_register_req_is(req, kind) \
+ (((req)->type & (arch_register_req_type_ ## kind)) != 0)
+
+/**
+ * Expresses requirements to register allocation for an operand.
+ */
+struct arch_register_req_t {
+ arch_register_req_type_t type; /**< The type of the constraint. */
+ const arch_register_class_t *cls; /**< The register class this constraint belongs to. */
+
+ const unsigned *limited; /**< allowed register bitset */
+
+ unsigned other_same; /**< Bitmask of ins which should use the
+ same register (should_be_same). */
+ unsigned other_different; /**< Bitmask of ins which shall use a
+ different register
+ (must_be_different) */
+};
+
+static inline int reg_reqs_equal(const arch_register_req_t *req1,
+ const arch_register_req_t *req2)
+{
+ if (req1 == req2)
+ return 1;
+
+ if (req1->type != req2->type
+ || req1->cls != req2->cls
+ || req1->other_same != req2->other_same
+ || req1->other_different != req2->other_different)
+ return 0;
+
+ if (req1->limited != NULL) {
+ size_t n_regs;
+
+ if (req2->limited == NULL)
+ return 0;
+
+ n_regs = arch_register_class_n_regs(req1->cls);
+ if (!rbitsets_equal(req1->limited, req2->limited, n_regs))
+ return 0;
+ }
+
+ return 1;
+}
+