typedef struct ir_exec_freq ir_exec_freq, *ir_exec_freq_ptr;
typedef struct ir_cdep ir_cdep, *ir_cdep_ptr;
typedef struct sn_entry *seqno_t;
+typedef struct arch_irn_ops_t arch_irn_ops_t;
typedef union ir_initializer_t ir_initializer_t, *ir_initializer_ptr;
iro_Pin,
iro_ASM,
iro_Anchor,
- /* last middleend node number */
- iro_Last,
+ /* first not middleend node number */
+ iro_Last = iro_Anchor,
/* first backend node number */
- beo_First = iro_Last,
+ beo_First,
/* backend specific nodes */
beo_Spill = beo_First,
beo_Reload,
beo_Barrier,
beo_Unwind,
/* last backend node number */
- beo_Last,
- /* last fixed number. Dynamic node numbers start here */
- iro_MaxOpcode = beo_Last
+ beo_Last = beo_Unwind,
+ /* first unfixed number. Dynamic node numbers start here */
+ iro_MaxOpcode
} ir_opcode;
extern ir_op *op_Block; ir_op *get_op_Block (void);
verify_proj_node_func verify_proj_node; /**< Verify the Proj node. */
dump_node_func dump_node; /**< Dump a node. */
op_func generic; /**< A generic function pointer. */
+ const arch_irn_ops_t *be_ops; /**< callbacks used by the backend. */
} ir_op_ops;
/**
/* fill register allocator interface */
-static const arch_irn_ops_if_t TEMPLATE_irn_ops_if = {
+static const arch_irn_ops_t TEMPLATE_irn_ops = {
TEMPLATE_get_irn_reg_req,
TEMPLATE_set_irn_reg,
TEMPLATE_get_irn_reg,
NULL, /* perform_memory_operand */
};
-TEMPLATE_irn_ops_t TEMPLATE_irn_ops = {
- &TEMPLATE_irn_ops_if,
- NULL
-};
-
-
-
/**************************************************
* _ _ __
* | | (_)/ _|
cur_reg_set = cg->reg_set;
- TEMPLATE_irn_ops.cg = cg;
-
return (arch_code_generator_t *)cg;
}
be_emit_init(outfile);
TEMPLATE_register_init();
- TEMPLATE_create_opcodes();
+ TEMPLATE_create_opcodes(&TEMPLATE_irn_ops);
return isa;
}
}
}
-static const void *TEMPLATE_get_irn_ops(const ir_node *irn)
-{
- (void) irn;
- return &TEMPLATE_irn_ops;
-}
-
-arch_get_irn_ops_t *TEMPLATE_get_irn_handler(const void *self)
-{
- (void) self;
- return &TEMPLATE_get_irn_ops;
-}
-
int TEMPLATE_to_appear_in_schedule(void *block_env, const ir_node *irn)
{
(void) block_env;
TEMPLATE_get_reg_class,
TEMPLATE_get_reg_class_for_mode,
TEMPLATE_get_call_abi,
- TEMPLATE_get_irn_handler,
TEMPLATE_get_code_generator_if,
TEMPLATE_get_list_sched_selector,
TEMPLATE_get_ilp_sched_selector,
typedef struct TEMPLATE_isa_t TEMPLATE_isa_t;
typedef struct TEMPLATE_code_gen_t TEMPLATE_code_gen_t;
-typedef struct TEMPLATE_irn_ops_t TEMPLATE_irn_ops_t;
typedef struct TEMPLATE_transform_env_t TEMPLATE_transform_env_t;
struct TEMPLATE_code_gen_t {
arch_isa_t arch_isa; /**< must be derived from arch_isa */
};
-struct TEMPLATE_irn_ops_t {
- const arch_irn_ops_if_t *impl;
- TEMPLATE_code_gen_t *cg;
-};
-
/**
* this is a struct to minimize the number of parameters
* for transformation walker
/* fill register allocator interface */
-static const arch_irn_ops_if_t arm_irn_ops_if = {
+static const arch_irn_ops_t arm_irn_ops = {
arm_get_irn_reg_req,
arm_set_irn_reg,
arm_get_irn_reg,
NULL, /* perform_memory_operand */
};
-arm_irn_ops_t arm_irn_ops = {
- &arm_irn_ops_if,
- NULL
-};
-
-
-
/**************************************************
* _ _ __
* | | (_)/ _|
cur_reg_set = cg->reg_set;
- arm_irn_ops.cg = cg;
-
/* enter the current code generator */
isa->cg = cg;
isa->cg = NULL;
be_emit_init(file_handle);
- arm_create_opcodes();
+ arm_create_opcodes(&arm_irn_ops);
arm_handle_intrinsics();
/* we mark referenced global entities, so we can only emit those which
}
}
-static const void *arm_get_irn_ops(const ir_node *irn) {
- (void) irn;
- return &arm_irn_ops;
-}
-
-arch_get_irn_ops_t *arm_get_irn_handler(const void *self) {
- (void) self;
- return &arm_get_irn_ops;
-}
-
int arm_to_appear_in_schedule(void *block_env, const ir_node *irn) {
(void) block_env;
if(!is_arm_irn(irn))
arm_get_reg_class,
arm_get_reg_class_for_mode,
arm_get_call_abi,
- arm_get_irn_handler,
arm_get_code_generator_if,
arm_get_list_sched_selector,
arm_get_ilp_sched_selector,
arm_code_gen_t *cg; /**< current code generator */
};
-
-typedef struct _arm_irn_ops_t {
- const arch_irn_ops_if_t *impl;
- arm_code_gen_t *cg;
-} arm_irn_ops_t;
-
-
#endif
char filtev[128]; /**< filter mask for stat events (regex is supported) */
};
-typedef struct {
- arch_irn_ops_t irn_ops;
- const arch_env_t *arch_env;
- pmap *phi_attrs;
-} phi_handler_t;
-
struct be_main_env_t {
arch_env_t arch_env;
be_options_t *options; /**< backend options */
ir_type *pic_trampolines_type; /**< Class type containing all trampolines */
pmap *ent_pic_symbol_map;
ir_type *pic_symbols_type;
- phi_handler_t phi_handler;
};
/**
return env;
}
-void arch_env_set_irn_handler(arch_env_t *env, arch_get_irn_ops_t *handler)
-{
- env->arch_handler = handler;
-}
-
-static const arch_irn_ops_t *fallback_irn_ops = NULL;
-
int arch_register_class_put(const arch_register_class_t *cls, bitset_t *bs)
{
if(bs) {
static INLINE const arch_irn_ops_t *
get_irn_ops(const arch_env_t *env, const ir_node *irn)
{
- const arch_irn_ops_t *ops = be_node_get_irn_ops(irn);
+ const ir_op *ops;
+ const arch_irn_ops_t *be_ops;
+ (void) env;
+
+ if (is_Proj(irn)) {
+ irn = get_Proj_pred(irn);
+ assert(!is_Proj(irn));
+ }
- if (ops)
- return ops;
- ops = env->arch_handler(irn);
+ ops = get_irn_op(irn);
+ be_ops = get_op_ops(ops)->be_ops;
- return ops != NULL ? ops : fallback_irn_ops;
+ assert(be_ops);
+ return be_ops;
}
const arch_irn_ops_t *arch_get_irn_ops(const arch_env_t *env, const ir_node *irn) {
const ir_node *irn, int pos)
{
const arch_irn_ops_t *ops = get_irn_ops(env, irn);
- return ops->impl->get_irn_reg_req(ops, irn, pos);
+ return ops->get_irn_reg_req(ops, irn, pos);
}
void arch_set_frame_offset(const arch_env_t *env, ir_node *irn, int offset)
{
const arch_irn_ops_t *ops = get_irn_ops(env, irn);
- ops->impl->set_frame_offset(ops, irn, offset);
+ ops->set_frame_offset(ops, irn, offset);
}
ir_entity *arch_get_frame_entity(const arch_env_t *env, const ir_node *irn)
{
const arch_irn_ops_t *ops = get_irn_ops(env, irn);
- return ops->impl->get_frame_entity(ops, irn);
+ return ops->get_frame_entity(ops, irn);
}
void arch_set_frame_entity(const arch_env_t *env, ir_node *irn, ir_entity *ent)
{
const arch_irn_ops_t *ops = get_irn_ops(env, irn);
- ops->impl->set_frame_entity(ops, irn, ent);
+ ops->set_frame_entity(ops, irn, ent);
}
int arch_get_sp_bias(const arch_env_t *env, ir_node *irn)
{
const arch_irn_ops_t *ops = get_irn_ops(env, irn);
- return ops->impl->get_sp_bias(ops, irn);
+ return ops->get_sp_bias(ops, irn);
}
arch_inverse_t *arch_get_inverse(const arch_env_t *env, const ir_node *irn, int i, arch_inverse_t *inverse, struct obstack *obstack)
{
const arch_irn_ops_t *ops = get_irn_ops(env, irn);
- if(ops->impl->get_inverse) {
- return ops->impl->get_inverse(ops, irn, i, inverse, obstack);
+ if(ops->get_inverse) {
+ return ops->get_inverse(ops, irn, i, inverse, obstack);
} else {
return NULL;
}
int arch_possible_memory_operand(const arch_env_t *env, const ir_node *irn, unsigned int i) {
const arch_irn_ops_t *ops = get_irn_ops(env, irn);
- if(ops->impl->possible_memory_operand) {
- return ops->impl->possible_memory_operand(ops, irn, i);
+ if(ops->possible_memory_operand) {
+ return ops->possible_memory_operand(ops, irn, i);
} else {
return 0;
}
void arch_perform_memory_operand(const arch_env_t *env, ir_node *irn, ir_node *spill, unsigned int i) {
const arch_irn_ops_t *ops = get_irn_ops(env, irn);
- if(ops->impl->perform_memory_operand) {
- ops->impl->perform_memory_operand(ops, irn, spill, i);
+ if(ops->perform_memory_operand) {
+ ops->perform_memory_operand(ops, irn, spill, i);
} else {
return;
}
{
const arch_irn_ops_t *ops = get_irn_ops(env, irn);
- if(ops->impl->get_op_estimated_cost) {
- return ops->impl->get_op_estimated_cost(ops, irn);
+ if(ops->get_op_estimated_cost) {
+ return ops->get_op_estimated_cost(ops, irn);
} else {
return 1;
}
{
const arch_irn_ops_t *ops = get_irn_ops(env, irn);
- if(ops->impl->possible_memory_operand) {
- return ops->impl->possible_memory_operand(ops, irn, i);
+ if(ops->possible_memory_operand) {
+ return ops->possible_memory_operand(ops, irn, i);
} else {
return 0;
}
int arch_get_allocatable_regs(const arch_env_t *env, const ir_node *irn, int pos, bitset_t *bs)
{
const arch_irn_ops_t *ops = get_irn_ops(env, irn);
- const arch_register_req_t *req = ops->impl->get_irn_reg_req(ops, irn, pos);
+ const arch_register_req_t *req = ops->get_irn_reg_req(ops, irn, pos);
if(req->type == arch_register_req_type_none) {
bitset_clear_all(bs);
const ir_node *irn, int pos)
{
const arch_irn_ops_t *ops = get_irn_ops(env, irn);
- const arch_register_req_t *req = ops->impl->get_irn_reg_req(ops, irn, pos);
+ const arch_register_req_t *req = ops->get_irn_reg_req(ops, irn, pos);
return req != NULL;
}
arch_get_irn_reg_class(const arch_env_t *env, const ir_node *irn, int pos)
{
const arch_irn_ops_t *ops = get_irn_ops(env, irn);
- const arch_register_req_t *req = ops->impl->get_irn_reg_req(ops, irn, pos);
+ const arch_register_req_t *req = ops->get_irn_reg_req(ops, irn, pos);
assert(req->type != arch_register_req_type_none || req->cls == NULL);
arch_get_irn_register(const arch_env_t *env, const ir_node *irn)
{
const arch_irn_ops_t *ops = get_irn_ops(env, irn);
- return ops->impl->get_irn_reg(ops, irn);
+ return ops->get_irn_reg(ops, irn);
}
extern void arch_set_irn_register(const arch_env_t *env,
ir_node *irn, const arch_register_t *reg)
{
const arch_irn_ops_t *ops = get_irn_ops(env, irn);
- ops->impl->set_irn_reg(ops, irn, reg);
+ ops->set_irn_reg(ops, irn, reg);
}
extern arch_irn_class_t arch_irn_classify(const arch_env_t *env, const ir_node *irn)
{
const arch_irn_ops_t *ops = get_irn_ops(env, irn);
- return ops->impl->classify(ops, irn);
+ return ops->classify(ops, irn);
}
extern arch_irn_flags_t arch_irn_get_flags(const arch_env_t *env, const ir_node *irn)
{
const arch_irn_ops_t *ops = get_irn_ops(env, irn);
- return ops->impl->get_flags(ops, irn);
+ return ops->get_flags(ops, irn);
}
extern const char *arch_irn_flag_str(arch_irn_flags_t fl)
typedef struct arch_isa_if_t arch_isa_if_t;
typedef struct arch_isa_t arch_isa_t;
typedef struct arch_env_t arch_env_t;
-typedef struct arch_irn_ops_if_t arch_irn_ops_if_t;
-typedef struct arch_irn_ops_t arch_irn_ops_t;
typedef struct arch_code_generator_t arch_code_generator_t;
typedef struct arch_code_generator_if_t arch_code_generator_if_t;
extern arch_env_t *arch_env_init(arch_env_t *env, const arch_isa_if_t *isa,
FILE *file_handle, be_main_env_t *main_env);
-/**
- * Set the architectural node handler to the environment.
- * @param env The environment.
- * @param handler The node handler for the selected architecture.
- * @return The environment itself.
- */
-extern void arch_env_set_irn_handler(arch_env_t *env, arch_get_irn_ops_t *handler);
-
/**
* Register an instruction set architecture
*/
ir_node **nodes;
};
-struct arch_irn_ops_if_t {
+struct arch_irn_ops_t {
/**
* Get the register requirements for a given operand.
void (*perform_memory_operand)(const void *self, ir_node *irn, ir_node *spill, unsigned int i);
};
-/**
- * irn_ops base class.
- */
-struct arch_irn_ops_t {
- const arch_irn_ops_if_t *impl;
-};
-
/**
* The code generator interface.
*/
*/
void (*get_call_abi)(const void *self, ir_type *call_type, be_abi_call_t *abi);
- /**
- * The irn handler for this architecture.
- * The irn handler is registered by the Firm back end
- * when the architecture is initialized.
- */
- arch_get_irn_ops_t *(*get_irn_handler)(const void *self);
-
/**
* Get the code generator interface.
* @param self The this pointer.
#define arch_isa_get_n_reg_class(isa) ((isa)->impl->get_n_reg_class(isa))
#define arch_isa_get_reg_class(isa,i) ((isa)->impl->get_reg_class(isa, i))
-#define arch_isa_get_irn_handler(isa) ((isa)->impl->get_irn_handler(isa))
#define arch_isa_get_call_abi(isa,tp,abi) ((isa)->impl->get_call_abi((isa), (tp), (abi)))
#define arch_isa_get_reg_class_for_mode(isa,mode) ((isa)->impl->get_reg_class_for_mode((isa), (mode)))
#define arch_isa_make_code_generator(isa,irg) ((isa)->impl->make_code_generator((isa), (irg)))
*/
struct arch_env_t {
arch_isa_t *isa; /**< The isa about which everything is. */
-
- arch_get_irn_ops_t *arch_handler; /**< The get_irn_ops handler for the selected architecture. */
};
/**
switch (bytes) {
case 1:
be_emit_irprintf("0x%02x", get_tarval_sub_bits(tv, 0));
- break;
+ return;
case 2:
be_emit_irprintf("0x%02x%02x", get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
- break;
+ return;
case 4:
be_emit_irprintf("0x%02x%02x%02x%02x",
get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2), get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
- break;
+ return;
case 8:
be_emit_irprintf("0x%02x%02x%02x%02x%02x%02x%02x%02x",
get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6), get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2), get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
- break;
+ return;
- case 10:
case 12:
- break;
+ be_emit_irprintf("0x%02x%02x%02x%02x%02x%02x%02x%02x"
+ "%02x%02x%02x%02x", get_tarval_sub_bits(tv, 11),
+ get_tarval_sub_bits(tv, 10), get_tarval_sub_bits(tv, 9),
+ get_tarval_sub_bits(tv, 8), get_tarval_sub_bits(tv, 7),
+ get_tarval_sub_bits(tv, 6), get_tarval_sub_bits(tv, 5),
+ get_tarval_sub_bits(tv, 4), get_tarval_sub_bits(tv, 3),
+ get_tarval_sub_bits(tv, 2), get_tarval_sub_bits(tv, 1),
+ get_tarval_sub_bits(tv, 0));
+ return;
case 16:
be_emit_irprintf("0x%02x%02x%02x%02x%02x%02x%02x%02x"
get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2),
get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
- break;
-
-
- default:
- fprintf(stderr, "Try to dump an tarval with %d bytes\n", bytes);
- assert(0);
+ return;
}
+
+ panic("Can't dump a tarval with %d bytes\n", bytes);
}
/**
*/
static be_main_env_t *be_init_env(be_main_env_t *env, FILE *file_handle)
{
- arch_get_irn_ops_t *handler;
-
memset(env, 0, sizeof(*env));
env->options = &be_options;
env->ent_trampoline_map = pmap_create();
arch_env_init(&env->arch_env, isa_if, file_handle, env);
- /* Register the irn handler of the architecture */
- handler = arch_isa_get_irn_handler(env->arch_env.isa);
- arch_env_set_irn_handler(&env->arch_env, handler);
-
be_phi_handler_new(env);
be_dbg_open();
{
env->arch_env.isa->impl->done(env->arch_env.isa);
be_dbg_close();
- be_phi_handler_free(env);
+ be_phi_handler_free();
pmap_destroy(env->ent_trampoline_map);
pmap_destroy(env->ent_pic_symbol_map);
be_sched_init_phase(irg);
/* reset the phi handler. */
- be_phi_handler_reset(&env);
+ be_phi_handler_reset();
stat_ev_ctx_push_fobj("bemain_irg", irg);
stat_ev_ctx_pop("bemain_phase");
/* reset the phi handler. */
- be_phi_handler_reset(&env);
+ be_phi_handler_reset();
be_do_stat_nodes(irg, "03 Prepare");
#define get_irn_attr(irn) get_irn_generic_attr(irn)
#define get_irn_attr_const(irn) get_irn_generic_attr_const(irn)
-static unsigned be_node_tag = FOURCC('B', 'E', 'N', 'O');
-
-/** The current phi handler */
-static const phi_handler_t *curr_phi_handler;
-
typedef struct {
arch_register_req_t req;
arch_irn_flags_t flags;
return &bereq->req;
}
-void be_node_init(void) {
- static int inited = 0;
-
- if(inited)
- return;
-
- inited = 1;
-
- /* Acquire all needed opcodes. */
- op_be_Spill = new_ir_op(beo_Spill, "be_Spill", op_pin_state_pinned, N, oparity_unary, 0, sizeof(be_frame_attr_t), &be_node_op_ops);
- op_be_Reload = new_ir_op(beo_Reload, "be_Reload", op_pin_state_pinned, N, oparity_zero, 0, sizeof(be_frame_attr_t), &be_node_op_ops);
- op_be_Perm = new_ir_op(beo_Perm, "be_Perm", op_pin_state_pinned, N, oparity_variable, 0, sizeof(be_node_attr_t), &be_node_op_ops);
- op_be_MemPerm = new_ir_op(beo_MemPerm, "be_MemPerm", op_pin_state_pinned, N, oparity_variable, 0, sizeof(be_memperm_attr_t), &be_node_op_ops);
- op_be_Copy = new_ir_op(beo_Copy, "be_Copy", op_pin_state_floats, N, oparity_unary, 0, sizeof(be_node_attr_t), &be_node_op_ops);
- op_be_Keep = new_ir_op(beo_Keep, "be_Keep", op_pin_state_pinned, K, oparity_dynamic, 0, sizeof(be_node_attr_t), &be_node_op_ops);
- op_be_CopyKeep = new_ir_op(beo_CopyKeep, "be_CopyKeep", op_pin_state_pinned, K, oparity_variable, 0, sizeof(be_node_attr_t), &be_node_op_ops);
- op_be_Call = new_ir_op(beo_Call, "be_Call", op_pin_state_pinned, F|M, oparity_variable, 0, sizeof(be_call_attr_t), &be_node_op_ops);
- op_be_Return = new_ir_op(beo_Return, "be_Return", op_pin_state_pinned, X, oparity_dynamic, 0, sizeof(be_return_attr_t), &be_node_op_ops);
- op_be_AddSP = new_ir_op(beo_AddSP, "be_AddSP", op_pin_state_pinned, N, oparity_unary, 0, sizeof(be_node_attr_t), &be_node_op_ops);
- op_be_SubSP = new_ir_op(beo_SubSP, "be_SubSP", op_pin_state_pinned, N, oparity_unary, 0, sizeof(be_node_attr_t), &be_node_op_ops);
- op_be_IncSP = new_ir_op(beo_IncSP, "be_IncSP", op_pin_state_pinned, N, oparity_unary, 0, sizeof(be_incsp_attr_t), &be_node_op_ops);
- op_be_RegParams = new_ir_op(beo_RegParams, "be_RegParams", op_pin_state_pinned, N, oparity_zero, 0, sizeof(be_node_attr_t), &be_node_op_ops);
- op_be_FrameAddr = new_ir_op(beo_FrameAddr, "be_FrameAddr", op_pin_state_floats, N, oparity_unary, 0, sizeof(be_frame_attr_t), &be_node_op_ops);
- op_be_Barrier = new_ir_op(beo_Barrier, "be_Barrier", op_pin_state_pinned, N, oparity_dynamic, 0, sizeof(be_node_attr_t), &be_node_op_ops);
- op_be_Unwind = new_ir_op(beo_Unwind, "be_Unwind", op_pin_state_pinned, X, oparity_zero, 0, sizeof(be_node_attr_t), &be_node_op_ops);
-
- set_op_tag(op_be_Spill, &be_node_tag);
- op_be_Spill->ops.node_cmp_attr = FrameAddr_cmp_attr;
- set_op_tag(op_be_Reload, &be_node_tag);
- op_be_Reload->ops.node_cmp_attr = FrameAddr_cmp_attr;
- set_op_tag(op_be_Perm, &be_node_tag);
- op_be_Perm->ops.node_cmp_attr = node_cmp_attr;
- set_op_tag(op_be_MemPerm, &be_node_tag);
- op_be_MemPerm->ops.node_cmp_attr = node_cmp_attr;
- set_op_tag(op_be_Copy, &be_node_tag);
- op_be_Copy->ops.node_cmp_attr = node_cmp_attr;
- set_op_tag(op_be_Keep, &be_node_tag);
- op_be_Keep->ops.node_cmp_attr = node_cmp_attr;
- set_op_tag(op_be_CopyKeep, &be_node_tag);
- op_be_CopyKeep->ops.node_cmp_attr = node_cmp_attr;
- set_op_tag(op_be_Call, &be_node_tag);
- op_be_Call->ops.node_cmp_attr = Call_cmp_attr;
- set_op_tag(op_be_Return, &be_node_tag);
- op_be_Return->ops.node_cmp_attr = Return_cmp_attr;
- set_op_tag(op_be_AddSP, &be_node_tag);
- op_be_AddSP->ops.node_cmp_attr = node_cmp_attr;
- set_op_tag(op_be_SubSP, &be_node_tag);
- op_be_SubSP->ops.node_cmp_attr = node_cmp_attr;
- set_op_tag(op_be_IncSP, &be_node_tag);
- op_be_IncSP->ops.node_cmp_attr = IncSP_cmp_attr;
- set_op_tag(op_be_RegParams, &be_node_tag);
- op_be_RegParams->ops.node_cmp_attr = node_cmp_attr;
- set_op_tag(op_be_FrameAddr, &be_node_tag);
- op_be_FrameAddr->ops.node_cmp_attr = FrameAddr_cmp_attr;
- set_op_tag(op_be_Barrier, &be_node_tag);
- op_be_Barrier->ops.node_cmp_attr = node_cmp_attr;
- set_op_tag(op_be_Unwind, &be_node_tag);
- op_be_Unwind->ops.node_cmp_attr = node_cmp_attr;
-}
-
/**
* Initializes the generic attribute of all be nodes and return ir.
*/
ARR_APP1(be_reg_data_t, a->reg_data, regreq);
}
-int is_be_node(const ir_node *irn)
-{
- return get_op_tag(get_irn_op(irn)) == &be_node_tag;
-}
-
/**
* Skip Proj nodes and return their Proj numbers.
*
*/
-static const arch_irn_ops_if_t be_node_irn_ops_if = {
+static const arch_irn_ops_t be_node_irn_ops = {
be_node_get_irn_reg_req,
be_node_set_irn_reg,
be_node_get_irn_reg,
NULL, /* perform_memory_operand */
};
-static const arch_irn_ops_t be_node_irn_ops = {
- &be_node_irn_ops_if
-};
-
-/* * irn handler for common be nodes and Phi's. */
-const void *be_node_get_irn_ops(const ir_node *irn)
-{
- if (is_Phi(irn)) {
- if (mode_is_datab(get_irn_mode(irn)))
- return &curr_phi_handler->irn_ops;
- return NULL;
- }
-
- if (is_Proj(irn)) {
- irn = get_Proj_pred(irn);
- if (is_Proj(irn)) {
- assert(get_irn_mode(irn) == mode_T);
- irn = get_Proj_pred(irn);
- }
- }
- return is_be_node(irn) ? &be_node_irn_ops : NULL;
-}
-
/*
____ _ _ ___ ____ _ _ _ _ _ _
| _ \| |__ (_) |_ _| _ \| \ | | | | | | __ _ _ __ __| | | ___ _ __
arch_irn_flags_t flags;
} phi_attr_t;
+struct {
+ arch_env_t *arch_env;
+ pmap *phi_attrs;
+} phi_handler;
+
#define get_phi_handler_from_ops(h) container_of(h, phi_handler_t, irn_ops)
static INLINE
-phi_attr_t *get_Phi_attr(const phi_handler_t *handler, const ir_node *phi)
+phi_attr_t *get_Phi_attr(const ir_node *phi)
{
- phi_attr_t *attr = pmap_get(handler->phi_attrs, (void*) phi);
+ phi_attr_t *attr = pmap_get(phi_handler.phi_attrs, (void*) phi);
if(attr == NULL) {
ir_graph *irg = get_irn_irg(phi);
struct obstack *obst = get_irg_obstack(irg);
attr = obstack_alloc(obst, sizeof(attr[0]));
memset(attr, 0, sizeof(attr[0]));
- pmap_insert(handler->phi_attrs, phi, attr);
+ pmap_insert(phi_handler.phi_attrs, phi, attr);
}
return attr;
* Get register class of a Phi.
*/
static
-const arch_register_req_t *get_Phi_reg_req_recursive(const phi_handler_t *h,
- const ir_node *phi,
+const arch_register_req_t *get_Phi_reg_req_recursive(const ir_node *phi,
pset **visited)
{
int n = get_irn_arity(phi);
/* Matze: don't we unnecessary constraint our phis with this?
* we only need to take the regclass IMO*/
if(!is_Phi(op))
- return arch_get_register_req(h->arch_env, op, BE_OUT_POS(0));
+ return arch_get_register_req(phi_handler.arch_env, op, BE_OUT_POS(0));
}
/*
for(i = 0; i < n; ++i) {
const arch_register_req_t *req;
op = get_irn_n(phi, i);
- req = get_Phi_reg_req_recursive(h, op, visited);
+ req = get_Phi_reg_req_recursive(op, visited);
if(req != NULL)
return req;
}
const arch_register_req_t *phi_get_irn_reg_req(const void *self,
const ir_node *irn, int pos)
{
- phi_handler_t *phi_handler = get_phi_handler_from_ops(self);
phi_attr_t *attr;
(void) self;
(void) pos;
if(!mode_is_datab(get_irn_mode(irn)))
return arch_no_register_req;
- attr = get_Phi_attr(phi_handler, irn);
+ attr = get_Phi_attr(irn);
if(attr->req.type == arch_register_req_type_none) {
pset *visited = NULL;
const arch_register_req_t *req;
- req = get_Phi_reg_req_recursive(phi_handler, irn, &visited);
+ req = get_Phi_reg_req_recursive(irn, &visited);
memcpy(&attr->req, req, sizeof(req[0]));
assert(attr->req.cls != NULL);
void be_set_phi_reg_req(const arch_env_t *arch_env, ir_node *node,
const arch_register_req_t *req)
{
- const arch_irn_ops_t *ops = arch_get_irn_ops(arch_env, node);
- const phi_handler_t *handler = get_phi_handler_from_ops(ops);
phi_attr_t *attr;
+ (void) arch_env;
assert(mode_is_datab(get_irn_mode(node)));
- attr = get_Phi_attr(handler, node);
+ attr = get_Phi_attr(node);
memcpy(&attr->req, req, sizeof(req[0]));
}
void be_set_phi_flags(const arch_env_t *arch_env, ir_node *node,
arch_irn_flags_t flags)
{
- const arch_irn_ops_t *ops = arch_get_irn_ops(arch_env, node);
- const phi_handler_t *handler = get_phi_handler_from_ops(ops);
phi_attr_t *attr;
+ (void) arch_env;
assert(mode_is_datab(get_irn_mode(node)));
- attr = get_Phi_attr(handler, node);
+ attr = get_Phi_attr(node);
attr->flags = flags;
}
static
void phi_set_irn_reg(const void *self, ir_node *irn, const arch_register_t *reg)
{
- phi_handler_t *h = get_phi_handler_from_ops(self);
- phi_attr_t *attr = get_Phi_attr(h, irn);
+ phi_attr_t *attr = get_Phi_attr(irn);
+ (void) self;
attr->reg = reg;
}
static
const arch_register_t *phi_get_irn_reg(const void *self, const ir_node *irn)
{
- phi_handler_t *h = get_phi_handler_from_ops(self);
- phi_attr_t *attr = get_Phi_attr(h, irn);
+ phi_attr_t *attr = get_Phi_attr(irn);
+ (void) self;
return attr->reg;
}
static
arch_irn_flags_t phi_get_flags(const void *self, const ir_node *irn)
{
- phi_handler_t *h = get_phi_handler_from_ops(self);
- phi_attr_t *attr = get_Phi_attr(h, irn);
+ phi_attr_t *attr = get_Phi_attr(irn);
(void) self;
return attr->flags;
}
return 0;
}
-static
-const arch_irn_ops_if_t phi_irn_ops = {
+static const arch_irn_ops_t phi_irn_ops = {
phi_get_irn_reg_req,
phi_set_irn_reg,
phi_get_irn_reg,
void be_phi_handler_new(be_main_env_t *env)
{
- phi_handler_t *h = &env->phi_handler;
- h->irn_ops.impl = &phi_irn_ops;
- h->arch_env = &env->arch_env;
- h->phi_attrs = pmap_create();
- curr_phi_handler = h;
+ phi_handler.arch_env = &env->arch_env;
+ phi_handler.phi_attrs = pmap_create();
+ op_Phi->ops.be_ops = &phi_irn_ops;
}
-void be_phi_handler_free(be_main_env_t *env)
+void be_phi_handler_free(void)
{
- phi_handler_t *h = &env->phi_handler;
- pmap_destroy(h->phi_attrs);
- h->phi_attrs = NULL;
- curr_phi_handler = NULL;
+ pmap_destroy(phi_handler.phi_attrs);
+ phi_handler.phi_attrs = NULL;
+ op_Phi->ops.be_ops = NULL;
}
-void be_phi_handler_reset(be_main_env_t *env)
+void be_phi_handler_reset(void)
{
- phi_handler_t *h = &env->phi_handler;
- if(h->phi_attrs)
- pmap_destroy(h->phi_attrs);
- h->phi_attrs = pmap_create();
+ if(phi_handler.phi_attrs)
+ pmap_destroy(phi_handler.phi_attrs);
+ phi_handler.phi_attrs = pmap_create();
}
/*
NULL,
NULL,
dump_node,
- NULL
+ NULL,
+ &be_node_irn_ops
};
+
+int is_be_node(const ir_node *irn)
+{
+ return get_op_ops(get_irn_op(irn))->be_ops == &be_node_irn_ops;
+}
+
+void be_node_init(void) {
+ static int inited = 0;
+
+ if(inited)
+ return;
+
+ inited = 1;
+
+ /* Acquire all needed opcodes. */
+ op_be_Spill = new_ir_op(beo_Spill, "be_Spill", op_pin_state_pinned, N, oparity_unary, 0, sizeof(be_frame_attr_t), &be_node_op_ops);
+ op_be_Reload = new_ir_op(beo_Reload, "be_Reload", op_pin_state_pinned, N, oparity_zero, 0, sizeof(be_frame_attr_t), &be_node_op_ops);
+ op_be_Perm = new_ir_op(beo_Perm, "be_Perm", op_pin_state_pinned, N, oparity_variable, 0, sizeof(be_node_attr_t), &be_node_op_ops);
+ op_be_MemPerm = new_ir_op(beo_MemPerm, "be_MemPerm", op_pin_state_pinned, N, oparity_variable, 0, sizeof(be_memperm_attr_t), &be_node_op_ops);
+ op_be_Copy = new_ir_op(beo_Copy, "be_Copy", op_pin_state_floats, N, oparity_unary, 0, sizeof(be_node_attr_t), &be_node_op_ops);
+ op_be_Keep = new_ir_op(beo_Keep, "be_Keep", op_pin_state_pinned, K, oparity_dynamic, 0, sizeof(be_node_attr_t), &be_node_op_ops);
+ op_be_CopyKeep = new_ir_op(beo_CopyKeep, "be_CopyKeep", op_pin_state_pinned, K, oparity_variable, 0, sizeof(be_node_attr_t), &be_node_op_ops);
+ op_be_Call = new_ir_op(beo_Call, "be_Call", op_pin_state_pinned, F|M, oparity_variable, 0, sizeof(be_call_attr_t), &be_node_op_ops);
+ op_be_Return = new_ir_op(beo_Return, "be_Return", op_pin_state_pinned, X, oparity_dynamic, 0, sizeof(be_return_attr_t), &be_node_op_ops);
+ op_be_AddSP = new_ir_op(beo_AddSP, "be_AddSP", op_pin_state_pinned, N, oparity_unary, 0, sizeof(be_node_attr_t), &be_node_op_ops);
+ op_be_SubSP = new_ir_op(beo_SubSP, "be_SubSP", op_pin_state_pinned, N, oparity_unary, 0, sizeof(be_node_attr_t), &be_node_op_ops);
+ op_be_IncSP = new_ir_op(beo_IncSP, "be_IncSP", op_pin_state_pinned, N, oparity_unary, 0, sizeof(be_incsp_attr_t), &be_node_op_ops);
+ op_be_RegParams = new_ir_op(beo_RegParams, "be_RegParams", op_pin_state_pinned, N, oparity_zero, 0, sizeof(be_node_attr_t), &be_node_op_ops);
+ op_be_FrameAddr = new_ir_op(beo_FrameAddr, "be_FrameAddr", op_pin_state_floats, N, oparity_unary, 0, sizeof(be_frame_attr_t), &be_node_op_ops);
+ op_be_Barrier = new_ir_op(beo_Barrier, "be_Barrier", op_pin_state_pinned, N, oparity_dynamic, 0, sizeof(be_node_attr_t), &be_node_op_ops);
+ op_be_Unwind = new_ir_op(beo_Unwind, "be_Unwind", op_pin_state_pinned, X, oparity_zero, 0, sizeof(be_node_attr_t), &be_node_op_ops);
+
+ op_be_Spill->ops.node_cmp_attr = FrameAddr_cmp_attr;
+ op_be_Reload->ops.node_cmp_attr = FrameAddr_cmp_attr;
+ op_be_Perm->ops.node_cmp_attr = node_cmp_attr;
+ op_be_MemPerm->ops.node_cmp_attr = node_cmp_attr;
+ op_be_Copy->ops.node_cmp_attr = node_cmp_attr;
+ op_be_Keep->ops.node_cmp_attr = node_cmp_attr;
+ op_be_CopyKeep->ops.node_cmp_attr = node_cmp_attr;
+ op_be_Call->ops.node_cmp_attr = Call_cmp_attr;
+ op_be_Return->ops.node_cmp_attr = Return_cmp_attr;
+ op_be_AddSP->ops.node_cmp_attr = node_cmp_attr;
+ op_be_SubSP->ops.node_cmp_attr = node_cmp_attr;
+ op_be_IncSP->ops.node_cmp_attr = IncSP_cmp_attr;
+ op_be_RegParams->ops.node_cmp_attr = node_cmp_attr;
+ op_be_FrameAddr->ops.node_cmp_attr = FrameAddr_cmp_attr;
+ op_be_Barrier->ops.node_cmp_attr = node_cmp_attr;
+ op_be_Unwind->ops.node_cmp_attr = node_cmp_attr;
+}
/**
* Destroy the Phi handler.
- * @param env The be_main environment.
*/
-void be_phi_handler_free(be_main_env_t *env);
+void be_phi_handler_free(void);
/**
* Reset the register data in the Phi handler.
* This should be called on each new graph and deletes the register information of the current graph.
*/
-void be_phi_handler_reset(be_main_env_t *env);
+void be_phi_handler_reset(void);
/**
* Set the register requirements for a phi node.
static void ia32_set_frame_offset(const void *self, ir_node *irn, int bias)
{
- const ia32_irn_ops_t *ops = self;
+ (void) self;
if (get_ia32_frame_ent(irn) == NULL)
return;
if (is_ia32_Pop(irn) || is_ia32_PopMem(irn)) {
- int omit_fp = be_abi_omit_fp(ops->cg->birg->abi);
+ ia32_code_gen_t *cg = ia32_current_cg;
+ int omit_fp = be_abi_omit_fp(cg->birg->abi);
if (omit_fp) {
/* Pop nodes modify the stack pointer before calculating the
* destination address, so fix this here
static void ia32_perform_memory_operand(const void *self, ir_node *irn,
ir_node *spill, unsigned int i)
{
- const ia32_irn_ops_t *ops = self;
+ ia32_code_gen_t *cg = ia32_current_cg;
+ (void) self;
assert(ia32_possible_memory_operand(self, irn, i) && "Cannot perform memory operand change");
set_ia32_need_stackent(irn);
set_irn_n(irn, n_ia32_base, get_irg_frame(get_irn_irg(irn)));
- set_irn_n(irn, n_ia32_binary_right, ia32_get_admissible_noreg(ops->cg, irn, n_ia32_binary_right));
+ set_irn_n(irn, n_ia32_binary_right, ia32_get_admissible_noreg(cg, irn, n_ia32_binary_right));
set_irn_n(irn, n_ia32_mem, spill);
/* immediates are only allowed on the right side */
/* fill register allocator interface */
-static const arch_irn_ops_if_t ia32_irn_ops_if = {
+static const arch_irn_ops_t ia32_irn_ops = {
ia32_get_irn_reg_req,
ia32_set_irn_reg,
ia32_get_irn_reg,
ia32_perform_memory_operand,
};
-static ia32_irn_ops_t ia32_irn_ops = {
- &ia32_irn_ops_if,
- NULL
-};
-
-
-
/**************************************************
* _ _ __
* | | (_)/ _|
cur_reg_set = cg->reg_set;
- ia32_irn_ops.cg = cg;
-
assert(ia32_current_cg == NULL);
ia32_current_cg = cg;
}
ia32_register_init();
- ia32_create_opcodes();
+ ia32_create_opcodes(&ia32_irn_ops);
be_emit_init(file_handle);
isa->regs_16bit = pmap_create();
}
}
-
-static const void *ia32_get_irn_ops(const ir_node *irn)
-{
- (void) irn;
- return &ia32_irn_ops;
-}
-
-arch_get_irn_ops_t *ia32_get_irn_handler(const void *self)
-{
- (void) self;
- return &ia32_get_irn_ops;
-}
-
int ia32_to_appear_in_schedule(void *block_env, const ir_node *irn)
{
(void) block_env;
ia32_get_reg_class,
ia32_get_reg_class_for_mode,
ia32_get_call_abi,
- ia32_get_irn_handler,
ia32_get_code_generator_if,
ia32_get_list_sched_selector,
ia32_get_ilp_sched_selector,
#endif /* NDEBUG */
};
-struct ia32_irn_ops_t {
- const arch_irn_ops_if_t *impl;
- ia32_code_gen_t *cg;
-};
-
/**
* A helper type collecting needed info for IA32 intrinsic lowering.
*/
/* fill register allocator interface */
-static const arch_irn_ops_if_t mips_irn_ops_if = {
+static const arch_irn_ops_t mips_irn_ops = {
mips_get_irn_reg_req,
mips_set_irn_reg,
mips_get_irn_reg,
NULL, /* perform_memory_operand */
};
-mips_irn_ops_t mips_irn_ops = {
- &mips_irn_ops_if,
- NULL
-};
-
-
-
/**************************************************
* _ _ __
* | | (_)/ _|
cur_reg_set = cg->reg_set;
- mips_irn_ops.cg = cg;
-
isa->cg = cg;
return (arch_code_generator_t *)cg;
be_emit_init(file_handle);
mips_register_init();
- mips_create_opcodes();
+ mips_create_opcodes(&mips_irn_ops);
// mips_init_opcode_transforms();
/* we mark referenced global entities, so we can only emit those which
}
}
-static const void *mips_get_irn_ops(const ir_node *irn)
-{
- (void) irn;
- return &mips_irn_ops;
-}
-
-arch_get_irn_ops_t *mips_get_irn_handler(const void *self)
-{
- (void) self;
- return &mips_get_irn_ops;
-}
-
/**
* Initializes the code generator interface.
*/
mips_get_reg_class,
mips_get_reg_class_for_mode,
mips_get_call_abi,
- mips_get_irn_handler,
mips_get_code_generator_if,
mips_get_list_sched_selector,
mips_get_ilp_sched_selector,
#include "set.h"
typedef struct mips_isa_t mips_isa_t;
-typedef struct mips_irn_ops_t mips_irn_ops_t;
typedef struct mips_transform_env_t mips_transform_env_t;
struct mips_code_gen_t {
mips_code_gen_t *cg;
};
-struct mips_irn_ops_t {
- const arch_irn_ops_if_t *impl;
- mips_code_gen_t *cg;
-};
-
/**
* this is a struct to minimize the number of parameters
/* fill register allocator interface */
-static const arch_irn_ops_if_t ppc32_irn_ops_if = {
+static const arch_irn_ops_t ppc32_irn_ops = {
ppc32_get_irn_reg_req,
ppc32_set_irn_reg,
ppc32_get_irn_reg,
NULL, /* perform_memory_operand */
};
-ppc32_irn_ops_t ppc32_irn_ops = {
- &ppc32_irn_ops_if,
- NULL
-};
-
-
-
/**************************************************
* _ _ __
* | | (_)/ _|
FIRM_DBG_REGISTER(cg->mod, "firm.be.ppc.cg");
cur_reg_set = cg->reg_set;
- ppc32_irn_ops.cg = cg;
return (arch_code_generator_t *)cg;
}
be_emit_init(file_handle);
ppc32_register_init();
- ppc32_create_opcodes();
+ ppc32_create_opcodes(&ppc32_irn_ops);
inited = 1;
}
}
-static const void *ppc32_get_irn_ops(const ir_node *irn) {
- (void) irn;
- return &ppc32_irn_ops;
-}
-
-arch_get_irn_ops_t *ppc32_get_irn_handler(const void *self) {
- (void) self;
- return &ppc32_get_irn_ops;
-}
-
int ppc32_to_appear_in_schedule(void *block_env, const ir_node *irn) {
(void) block_env;
if(!is_ppc32_irn(irn))
ppc32_get_reg_class,
ppc32_get_reg_class_for_mode,
ppc32_get_call_abi,
- ppc32_get_irn_handler,
ppc32_get_code_generator_if,
ppc32_get_list_sched_selector,
ppc32_get_ilp_sched_selector,
};
-typedef struct _ppc32_irn_ops_t {
- const arch_irn_ops_if_t *impl;
- ppc32_code_gen_t *cg;
-} ppc32_irn_ops_t;
-
-
/** this is a struct to minimize the number of parameters
for transformation walker */
typedef struct _ppc32_transform_env_t {
# for registering additional opcodes
$n_opcodes += $additional_opcodes if (defined($additional_opcodes));
-push(@obst_header, "void ".$arch."_create_opcodes(void);\n");
+push(@obst_header, "void ".$arch."_create_opcodes(const arch_irn_ops_t *be_ops);\n");
push(@obst_enum_op, "typedef enum _$arch\_opcodes {\n");
foreach my $op (keys(%nodes)) {
push(@obst_new_irop, "\n\tmemset(&ops, 0, sizeof(ops));\n");
+ push(@obst_new_irop, "\tops.be_ops = be_ops;\n");
push(@obst_new_irop, "\tops.dump_node = $arch\_dump_node;\n");
if (defined($cmp_attr_func)) {
* Creates the $arch specific Firm machine operations
* needed for the assembler irgs.
*/
-void $arch\_create_opcodes(void) {
+void $arch\_create_opcodes(const arch_irn_ops_t *be_ops) {
#define N irop_flag_none
#define L irop_flag_labeled
#define C irop_flag_commutative
ir_op_ops ops;
int cur_opcode;
static int run_once = 0;
+ int i;
+
+ /* we handle all middleend nodes as well */
+ for (i = 0; i <= iro_Last; ++i) {
+ ir_op *op = get_irp_opcode(i);
+ op->ops.be_ops = be_ops;
+ }
ENDOFMAIN
if(defined($default_op_attr_type)) {