typedef enum _arch_register_type_t {
arch_register_type_none = 0,
- arch_register_type_write_invariant,
arch_register_type_caller_saved, /**< The register must be saved by the caller
upon a function call. It thus can be overwritten
in the called function. */
arch_register_req_type_t type; /**< The type of the constraint. */
const arch_register_class_t *cls; /**< The register class this constraint belongs to. */
- void (*limited)(const ir_node *irn, int pos, bitset_t *bs);
+ void (*limited)(void *limited_env, bitset_t *bs);
/**< In case of the 'limited'
constraint, this function
must put all allowable
return the number of registers
in the bitset. */
+ void *limited_env; /**< This is passed to limited. */
+
ir_node *other; /**< In case of "should be equal"
or should be different, this gives
the node to whose register this
* Some flags describing a node in more detail.
*/
typedef enum _arch_irn_flags_t {
- arch_irn_flags_spillable = 1,
- arch_irn_flags_rematerializable = 2
+ arch_irn_flags_dont_spill = 1, /**< This must not be spilled. */
+ arch_irn_flags_rematerializable = 2, /**< This should be replicated instead of spilled/reloaded. */
+ arch_irn_flags_ignore = 4, /**< Do not consider the node during register allocation. */
} arch_irn_flags_t;
struct _arch_irn_ops_if_t {
* @param env The environment.
* @param irn The node.
* @param pos The postition of the node's operand.
- * @param cls The register class.
* @param bs The bitset all allocatable registers shall be put into.
* Note, that you can also pass NULL here. If you don't,
* make sure, the bitset is as large as the register class
* has registers.
* @return The amount of registers allocatable for that operand.
*/
-extern int arch_get_allocatable_regs(const arch_env_t *env, const ir_node *irn,
- int pos, const arch_register_class_t *cls, bitset_t *bs);
+extern int arch_get_allocatable_regs(const arch_env_t *env, const ir_node *irn, int pos, bitset_t *bs);
/**
* Check, if a register is assignable to an operand of a node.
*/
extern arch_irn_flags_t arch_irn_get_flags(const arch_env_t *env, const ir_node *irn);
+#define arch_irn_is_ignore(env, irn) 0
+ // ((arch_irn_get_flags(env, irn) & arch_irn_flags_ignore) != 0)
+
#define arch_irn_has_reg_class(env, irn, pos, cls) \
((cls) == arch_get_irn_reg_class(env, irn, pos))
+#define arch_irn_consider_in_reg_alloc(env, cls, irn) \
+ (arch_irn_has_reg_class(env, irn, -1, cls) && !arch_irn_is_ignore(env, irn))
+
/**
* Somebody who can be asked about nodes.
*/
/**
* Called after register allocation to lower Spills to Stores
+ * @param self The code generator
+ * @param spill The spill node to lower
+ * @return The new backend node which substitutes the spill
*/
ir_node *(*lower_spill)(void *self, ir_node *spill);
/**
* Called after register allocation to lower Reloads to Loads
+ * @param self The code generator
+ * @param reload The reload node to lower
+ * @return The new backend node which substitutes the reload
*/
ir_node *(*lower_reload)(void *self, ir_node *reload);
+ /**
+ * Called in lowering (e.g. alloca lowering) to set the
+ * correct stack register.
+ * @param self The code generator
+ * @return The stack register for the current irg
+ */
+ const arch_register_t *(*get_stack_register)(void *self);
+
/**
* Called after everything happened.
* The code generator must also be de-allocated here.
const list_sched_selector_t *(*get_list_sched_selector)(const void *self);
/**
- * Get the proj number assigned to the register.
- * @param self The isa object.
- * @param reg The register
- * @return The proj number assigned to this register
+ * Take a proj from a call, set the correct register and projnum for this proj
+ * @param self The isa object.
+ * @param proj The proj
+ * @param is_keep Non-zero if proj is a Keep argument
+ * @return The backend proj number assigned to this proj
*/
- long (*get_projnum_for_register)(const void *self, const arch_register_t *reg);
+ long (*handle_call_proj)(const void *self, ir_node *proj, int is_keep);
};
#define arch_isa_get_n_reg_class(isa) ((isa)->impl->get_n_reg_class(isa))