+struct arch_register_t {
+ const char *name; /**< The name of the register. */
+ const arch_register_class_t *reg_class; /**< The class the register belongs to. */
+ unsigned index; /**< The index of the register in the class. */
+ arch_register_type_t type; /**< The type of the register. */
+ const arch_register_req_t *single_req;
+};
+
+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 (!rbitset_equal(req1->limited, req2->limited, n_regs))
+ return 0;
+ }
+
+ return 1;
+}
+
+/**
+ * An inverse operation returned by the backend
+ */
+struct arch_inverse_t {
+ int n; /**< count of nodes returned in nodes array */
+ int costs; /**< costs of this remat */
+
+ /**< nodes for this inverse operation. shall be in
+ * schedule order. last element is the target value
+ */
+ ir_node **nodes;
+};
+
+struct arch_irn_ops_t {
+
+ /**
+ * Get the register requirements for a given operand.
+ * @param irn The node.
+ * @param pos The operand's position
+ * @return The register requirements for the selected operand.
+ * The pointer returned is never NULL.
+ */
+ const arch_register_req_t *(*get_irn_reg_req_in)(const ir_node *irn, int pos);
+
+ /**
+ * Classify the node.
+ * @param irn The node.
+ * @return A classification.
+ */
+ arch_irn_class_t (*classify)(const ir_node *irn);
+
+ /**
+ * Get the entity on the stack frame this node depends on.
+ * @param irn The node in question.
+ * @return The entity on the stack frame or NULL, if the node does not have a
+ * stack frame entity.
+ */
+ ir_entity *(*get_frame_entity)(const ir_node *irn);
+
+ /**
+ * Set the entity on the stack frame this node depends on.
+ * @param irn The node in question.
+ * @param ent The entity to set
+ */
+ void (*set_frame_entity)(ir_node *irn, ir_entity *ent);
+
+ /**
+ * Set the offset of a node carrying an entity on the stack frame.
+ * @param irn The node.
+ * @param offset The offset of the node's stack frame entity.
+ */
+ void (*set_frame_offset)(ir_node *irn, int offset);
+
+ /**
+ * Returns the delta of the stackpointer for nodes that increment or
+ * decrement the stackpointer with a constant value. (push, pop
+ * nodes on most architectures).
+ * A positive value stands for an expanding stack area, a negative value for
+ * a shrinking one.
+ *
+ * @param irn The node
+ * @return 0 if the stackpointer is not modified with a constant
+ * value, otherwise the increment/decrement value
+ */
+ int (*get_sp_bias)(const ir_node *irn);
+
+ /**
+ * Returns an inverse operation which yields the i-th argument
+ * of the given node as result.
+ *
+ * @param irn The original operation
+ * @param i Index of the argument we want the inverse operation to yield
+ * @param inverse struct to be filled with the resulting inverse op
+ * @param obstack The obstack to use for allocation of the returned nodes array
+ * @return The inverse operation or NULL if operation invertible
+ */
+ arch_inverse_t *(*get_inverse)(const ir_node *irn, int i, arch_inverse_t *inverse, struct obstack *obstack);
+
+ /**
+ * Get the estimated cycle count for @p irn.
+ *
+ * @param irn The node.
+ *
+ * @return The estimated cycle count for this operation
+ */
+ int (*get_op_estimated_cost)(const ir_node *irn);
+
+ /**
+ * Asks the backend whether operand @p i of @p irn can be loaded form memory internally
+ *
+ * @param irn The node.
+ * @param i Index of the argument we would like to know whether @p irn can load it form memory internally
+ *
+ * @return nonzero if argument can be loaded or zero otherwise
+ */
+ int (*possible_memory_operand)(const ir_node *irn, unsigned int i);
+
+ /**
+ * Ask the backend to assimilate @p reload of operand @p i into @p irn.
+ *
+ * @param irn The node.
+ * @param spill The spill.
+ * @param i The position of the reload.
+ */
+ void (*perform_memory_operand)(ir_node *irn, ir_node *spill, unsigned int i);