typedef enum arch_register_class_flags_t {
arch_register_class_flag_none = 0,
/** don't do automatic register allocation for this class */
- arch_register_class_flag_manual_ra = 1U << 0,
+ arch_register_class_flag_manual_ra = 1U << 0,
/** the register models an abstract state (example: fpu rounding mode) */
arch_register_class_flag_state = 1U << 1
} arch_register_class_flags_t;
*/
typedef enum arch_register_req_type_t {
/** No register requirement. */
- arch_register_req_type_none = 0,
+ arch_register_req_type_none = 0,
/** All registers in the class are allowed. */
arch_register_req_type_normal = 1U << 0,
/** Only a real subset of the class is allowed. */
arch_register_req_type_should_be_same = 1U << 2,
/** The register must be unequal from some other at the node. */
arch_register_req_type_must_be_different = 1U << 3,
+ /** The registernumber should be aligned (in case of multiregister values)*/
+ arch_register_req_type_aligned = 1U << 4,
/** ignore while allocating registers */
- arch_register_req_type_ignore = 1U << 4,
+ arch_register_req_type_ignore = 1U << 5,
/** the output produces a new value for the stack pointer
* (this is not really a constraint but a marker to guide the stackpointer
* rewiring logic) */
- arch_register_req_type_produces_sp = 1U << 5,
+ arch_register_req_type_produces_sp = 1U << 6,
} arch_register_req_type_t;
extern const arch_register_req_t *arch_no_register_req;
void arch_set_frame_offset(ir_node *irn, int bias);
ir_entity *arch_get_frame_entity(const ir_node *irn);
-void arch_set_frame_entity(ir_node *irn, ir_entity *ent);
int arch_get_sp_bias(ir_node *irn);
int arch_get_op_estimated_cost(const ir_node *irn);
unsigned other_different; /**< Bitmask of ins which shall use a
different register
(must_be_different) */
+ unsigned char width; /**< specifies how many sequential
+ registers are required */
};
static inline int reg_reqs_equal(const arch_register_req_t *req1,
struct arch_irn_ops_t {
/**
- * Get the register requirements for a given operand.
+ * 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.
*/
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.
info->out_infos[pos].req = req;
}
+/**
+ * Iterate over all values defined by an instruction.
+ * Only looks at values in a certain register class where the requirements
+ * are not marked as ignore.
+ * Executes @p code for each definition.
+ */
+#define be_foreach_definition(node, cls, value, code) \
+ do { \
+ if (get_irn_mode(node) == mode_T) { \
+ const ir_edge_t *edge_; \
+ foreach_out_edge(node, edge_) { \
+ const arch_register_req_t *req_; \
+ value = get_edge_src_irn(edge_); \
+ req_ = arch_get_register_req_out(value); \
+ if (req_->cls != cls) \
+ continue; \
+ if (req_->type & arch_register_req_type_ignore) \
+ continue; \
+ code \
+ } \
+ } else { \
+ const arch_register_req_t *req_ = arch_get_register_req_out(node); \
+ value = node; \
+ if (req_->cls == cls \
+ && !(req_->type & arch_register_req_type_ignore)) { \
+ code \
+ } \
+ } \
+ } while (0)
+
#endif