#include "beilpsched.h"
#include "bemachine.h"
#include "beirg.h"
+#include "beinfo.h"
#include "beabi.h"
#include "raw_bitset.h"
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. */
- void *data; /**< Custom data. */
};
-static INLINE const arch_register_class_t *
+static inline const arch_register_class_t *
_arch_register_get_class(const arch_register_t *reg)
{
return reg->reg_class;
}
-static INLINE
+static inline
unsigned _arch_register_get_index(const arch_register_t *reg)
{
return reg->index;
}
-static INLINE
+static inline
const char *_arch_register_get_name(const arch_register_t *reg)
{
return reg->name;
/** return the register class flags */
#define arch_register_class_flags(cls) ((cls)->flags)
-static INLINE const arch_register_t *
+static inline const arch_register_t *
_arch_register_for_index(const arch_register_class_t *cls, unsigned idx)
{
assert(idx < cls->n_regs);
(must_be_different) */
};
-static INLINE int reg_reqs_equal(const arch_register_req_t *req1,
+static inline int reg_reqs_equal(const arch_register_req_t *req1,
const arch_register_req_t *req2)
{
if (req1 == req2)
* Get the register requirements for a given operand.
* @param self The self pointer.
* @param irn The node.
- * @param pos The operand's position
- * (-1 for the result of the node, 0..n for the input operands).
+ * @param pos The operand's position (0..n for the input operands).
* @return The register requirements for the selected operand.
* The pointer returned is never NULL.
*/
const arch_register_req_t *(*get_irn_reg_req)(const ir_node *irn, int pos);
- /**
- * Set the register for an output operand.
- * @param irn The node.
- * @param reg The register allocated to that operand.
- * @note If the operand is not a register operand,
- * the call is ignored.
- */
- void (*set_irn_reg)(ir_node *irn, const arch_register_t *reg);
-
- /**
- * Get the register allocated for an output operand.
- * @param irn The node.
- * @return The register allocated at that operand. NULL, if
- * the operand was no register operand or
- * @c arch_register_invalid, if no register has yet been
- * allocated for this node.
- */
- const arch_register_t *(*get_irn_reg)(const ir_node *irn);
-
/**
* Classify the node.
* @param irn The node.
*/
arch_irn_class_t (*classify)(const ir_node *irn);
- /**
- * Get the flags of a node.
- * @param self The irn ops themselves.
- * @param irn The node.
- * @return A set of flags.
- */
- arch_irn_flags_t (*get_flags)(const ir_node *irn);
-
/**
* Get the entity on the stack frame this node depends on.
* @param self The this pointer.
*/
void (*spill)(void *self, be_irg_t *birg);
- /**
- * Called before scheduling.
- */
- void (*before_sched)(void *self);
-
/**
* Called before register allocation.
*/
#define arch_code_generator_before_abi(cg) _arch_cg_call(cg, before_abi)
#define arch_code_generator_prepare_graph(cg) _arch_cg_call(cg, prepare_graph)
-#define arch_code_generator_before_sched(cg) _arch_cg_call(cg, before_sched)
#define arch_code_generator_before_ra(cg) _arch_cg_call(cg, before_ra)
#define arch_code_generator_after_ra(cg) _arch_cg_call(cg, after_ra)
#define arch_code_generator_finish(cg) _arch_cg_call(cg, finish)
/**
* Initialize the isa interface.
* @param file_handle the file handle to write the output to
- * @param main_env the be main environment
* @return a new isa instance
*/
arch_env_t *(*init)(FILE *file_handle);
*/
void (*done)(void *self);
+ /**
+ * Called directly after initialization. Backend should handle all
+ * intrinsics here.
+ */
+ void (*handle_intrinsics)(void);
+
/**
* Get the the number of register classes in the isa.
* @return The number of register classes.
};
#define arch_env_done(env) ((env)->impl->done(env))
+#define arch_env_handle_intrinsics(env) \
+ do { if((env)->impl->handle_intrinsics != NULL) (env)->impl->handle_intrinsics(); } while(0)
#define arch_env_get_n_reg_class(env) ((env)->impl->get_n_reg_class(env))
#define arch_env_get_reg_class(env,i) ((env)->impl->get_reg_class(env, i))
#define arch_env_get_reg_class_for_mode(env,mode) ((env)->impl->get_reg_class_for_mode((env), (mode)))
*/
struct arch_env_t {
const arch_isa_if_t *impl;
- const arch_register_t *sp; /** The stack pointer register. */
- const arch_register_t *bp; /** The base pointer register. */
- int stack_dir; /** -1 for decreasing, 1 for increasing. */
- int stack_alignment; /** power of 2 stack alignment */
- const be_main_env_t *main_env; /** the be main environment */
- int spill_cost; /** cost for a be_Spill node */
- int reload_cost; /** cost for a be_Reload node */
+ const arch_register_t *sp; /** The stack pointer register. */
+ const arch_register_t *bp; /** The base pointer register. */
+ const arch_register_class_t *link_class; /** The static link pointer register class. */
+ int stack_dir; /** -1 for decreasing, 1 for increasing. */
+ int stack_alignment; /** power of 2 stack alignment */
+ const be_main_env_t *main_env; /** the be main environment */
+ int spill_cost; /** cost for a be_Spill node */
+ int reload_cost; /** cost for a be_Reload node */
};
-#define arch_env_stack_dir(env) ((env)->stack_dir)
-#define arch_env_sp(env) ((env)->sp)
-#define arch_env_bp(env) ((env)->bp)
+static inline unsigned arch_irn_get_n_outs(const ir_node *node)
+{
+ backend_info_t *info = be_get_info(node);
+ return ARR_LEN(info->out_infos);
+}
+
+static inline bool arch_irn_consider_in_reg_alloc(
+ const arch_register_class_t *cls, const ir_node *node)
+{
+ const arch_register_req_t *req = arch_get_register_req_out(node);
+ return
+ req->cls == cls &&
+ !(req->type & arch_register_req_type_ignore);
+}
+
+static inline bool arch_irn_is_ignore(const ir_node *irn)
+{
+ const arch_register_req_t *req = arch_get_register_req_out(irn);
+ return !!(req->type & arch_register_req_type_ignore);
+}
-#endif /* FIRM_BE_BEARCH_T_H */
+#endif