} be_abi_call_arg_t;
struct _be_abi_call_t {
- be_abi_call_flags_t flags;
- const be_abi_callbacks_t *cb;
- ir_type *between_type;
- set *params;
+ be_abi_call_flags_t flags;
+ const be_abi_callbacks_t *cb;
+ ir_type *between_type;
+ set *params;
+ const arch_register_class_t *cls_addr;
};
struct _be_abi_irg_t {
ir_node *init_sp; /**< The node representing the stack pointer
at the start of the function. */
+ ir_node *start_barrier; /**< The barrier of the start block */
+
ir_node *reg_params; /**< The reg params node. */
pmap *regs; /**< A map of all callee-save and ignore regs to
their Projs to the RegParams node. */
/* Set the flags for a call. */
void be_abi_call_set_flags(be_abi_call_t *call, be_abi_call_flags_t flags, const be_abi_callbacks_t *cb)
{
- call->flags = flags;
- call->cb = cb;
+ call->flags = flags;
+ call->cb = cb;
+}
+
+
+/* Set register class for call address */
+void be_abi_call_set_call_address_reg_class(be_abi_call_t *call, const arch_register_class_t *cls)
+{
+ call->cls_addr = cls;
}
+
void be_abi_call_param_stack(be_abi_call_t *call, int arg_pos, unsigned alignment, unsigned space_before, unsigned space_after)
{
be_abi_call_arg_t *arg = get_or_set_call_arg(call, 0, arg_pos, 1);
static be_abi_call_t *be_abi_call_new(void)
{
be_abi_call_t *call = xmalloc(sizeof(call[0]));
+
call->flags.val = 0;
call->params = new_set(cmp_call_arg, 16);
call->cb = NULL;
+ call->cls_addr = NULL;
call->flags.bits.try_omit_fp = be_omit_fp;
+
return call;
}
static int stack_frame_compute_initial_offset(be_stack_layout_t *frame)
{
ir_type *base = frame->stack_dir < 0 ? frame->between_type : frame->frame_type;
- entity *ent = search_ent_with_offset(base, 0);
- frame->initial_offset = 0;
- frame->initial_offset = get_stack_entity_offset(frame, ent, 0);
+ entity *ent = search_ent_with_offset(base, 0);
+
+ frame->initial_offset = ent ? get_stack_entity_offset(frame, ent, 0) : 0;
+
return frame->initial_offset;
}
get_Call_type(irn));
/*
- TODO:
- Set the register class of the call address to the same as the stack pointer's.
- That' probably buggy for some architectures.
+ Set the register class of the call address to the same as the stack pointer's
+ if it's not set by the backend in the abi callback.
*/
- be_node_set_reg_class(low_call, be_pos_Call_ptr, sp->reg_class);
+ be_node_set_reg_class(low_call, be_pos_Call_ptr, call->cls_addr ? call->cls_addr : sp->reg_class);
DBG((env->dbg, LEVEL_3, "\tcreated backend call %+F\n", low_call));
nw = be_new_FrameAddr(env->isa->sp->reg_class, irg, bl, frame, ent);
exchange(irn, nw);
- if (ptr == param_base) {
+ /* check, if it's a param sel and if have not seen this entity immediatly before */
+ if (ptr == param_base && ctx->value_param_list != ent) {
set_entity_link(ent, ctx->value_param_list);
ctx->value_param_list = ent;
}
pmap_insert(env->regs, (void *) isa->bp, NULL);
reg_params_bl = get_irg_start_block(irg);
env->reg_params = be_new_RegParams(irg, reg_params_bl, pmap_count(env->regs));
+ add_irn_dep(env->reg_params, get_irg_start(irg));
/*
* make proj nodes for the callee save registers.
env->init_sp = be_new_IncSP(sp, irg, bl, env->init_sp, BE_STACK_FRAME_SIZE_EXPAND);
be_abi_reg_map_set(env->regs, sp, env->init_sp);
- barrier = create_barrier(env, bl, &mem, env->regs, 0);
+ env->start_barrier = barrier = create_barrier(env, bl, &mem, env->regs, 0);
env->init_sp = be_abi_reg_map_get(env->regs, sp);
arch_set_irn_register(env->birg->main_env->arch_env, env->init_sp, sp);
return pmap_get(abi->regs, (void *) reg);
}
+ir_node *be_abi_get_ignore_irn(be_abi_irg_t *abi, const arch_register_t *reg)
+{
+ assert(arch_register_type_is(reg, ignore));
+ assert(pmap_contains(abi->regs, (void *) reg));
+ return pmap_get(abi->regs, (void *) reg);
+}
+
+ir_node *be_abi_get_start_barrier(be_abi_irg_t *abi)
+{
+ return abi->start_barrier;
+}
+
/*
_____ _____ _ _ _ _ _ _
|_ _| __ \| \ | | | | | | | | |