X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbeabi.c;h=0aeb25548ada8696ed567831da4aa024bb601fa6;hb=80a6158fdd766f42ee6c508a773bc114ff1b61f3;hp=2e06bc479baeb88cbb979142060f65582857bee7;hpb=eda38c30dfe82fcf21b4fbcb5eafd36b4b560e03;p=libfirm diff --git a/ir/be/beabi.c b/ir/be/beabi.c index 2e06bc479..0aeb25548 100644 --- a/ir/be/beabi.c +++ b/ir/be/beabi.c @@ -35,6 +35,7 @@ #include "benode_t.h" #include "belive_t.h" #include "besched_t.h" +#include "beirg.h" typedef struct _be_abi_call_arg_t { unsigned is_res : 1; /**< 1: the call argument is a return value. 0: it's a call parameter. */ @@ -43,23 +44,24 @@ typedef struct _be_abi_call_arg_t { int pos; const arch_register_t *reg; - entity *stack_ent; + ir_entity *stack_ent; unsigned alignment; unsigned space_before; unsigned space_after; } 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 { struct obstack obst; be_stack_layout_t *frame; /**< The stack frame model. */ - const be_irg_t *birg; /**< The back end IRG. */ + be_irg_t *birg; /**< The back end IRG. */ const arch_isa_t *isa; /**< The isa. */ survive_dce_t *dce_survivor; @@ -160,10 +162,18 @@ static INLINE be_abi_call_arg_t *get_call_arg(be_abi_call_t *call, int is_res, i /* 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); @@ -202,11 +212,14 @@ be_abi_call_flags_t be_abi_call_get_flags(const be_abi_call_t *call) 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; } @@ -236,10 +249,10 @@ static void be_abi_call_free(be_abi_call_t *call) and the spills. */ -static int get_stack_entity_offset(be_stack_layout_t *frame, entity *ent, int bias) +static int get_stack_entity_offset(be_stack_layout_t *frame, ir_entity *ent, int bias) { ir_type *t = get_entity_owner(ent); - int ofs = get_entity_offset_bytes(ent); + int ofs = get_entity_offset(ent); int i, index; @@ -265,13 +278,13 @@ static int get_stack_entity_offset(be_stack_layout_t *frame, entity *ent, int bi /** * Retrieve the entity with given offset from a frame type. */ -static entity *search_ent_with_offset(ir_type *t, int offset) +static ir_entity *search_ent_with_offset(ir_type *t, int offset) { int i, n; for(i = 0, n = get_compound_n_members(t); i < n; ++i) { - entity *ent = get_compound_member(t, i); - if(get_entity_offset_bytes(ent) == offset) + ir_entity *ent = get_compound_member(t, i); + if(get_entity_offset(ent) == offset) return ent; } @@ -280,10 +293,11 @@ static entity *search_ent_with_offset(ir_type *t, int offset) 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); + ir_type *base = frame->stack_dir < 0 ? frame->between_type : frame->frame_type; + ir_entity *ent = search_ent_with_offset(base, 0); + + frame->initial_offset = ent ? get_stack_entity_offset(frame, ent, 0) : 0; + return frame->initial_offset; } @@ -301,7 +315,7 @@ static int stack_frame_compute_initial_offset(be_stack_layout_t *frame) */ static be_stack_layout_t *stack_frame_init(be_stack_layout_t *frame, ir_type *args, ir_type *between, ir_type *locals, int stack_dir, - entity *param_map[]) + ir_entity *param_map[]) { frame->arg_type = args; frame->between_type = between; @@ -334,7 +348,7 @@ static void stack_layout_dump(FILE *file, be_stack_layout_t *frame) ir_fprintf(file, "type %d: %F size: %d\n", j, t, get_type_size_bytes(t)); for (i = 0, n = get_compound_n_members(t); i < n; ++i) { - entity *ent = get_compound_member(t, i); + ir_entity *ent = get_compound_member(t, i); ir_fprintf(file, "\t%F int ofs: %d glob ofs: %d\n", ent, get_entity_offset_bytes(ent), get_stack_entity_offset(frame, ent, 0)); } } @@ -622,11 +636,13 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp, i 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); + + /* Set input requirement for stack pointer. */ + be_node_set_reg_class(low_call, be_pos_Call_sp, arch_get_irn_reg_class(isa->main_env->arch_env, curr_sp, -1)); DBG((env->dbg, LEVEL_3, "\tcreated backend call %+F\n", low_call)); @@ -1083,7 +1099,7 @@ static void clearup_frame(be_abi_irg_t *env, ir_node *ret, pmap *reg_map, struct * * @return the stack argument layout type */ -static ir_type *compute_arg_type(be_abi_irg_t *env, be_abi_call_t *call, ir_type *method_type, entity ***param_map) +static ir_type *compute_arg_type(be_abi_irg_t *env, be_abi_call_t *call, ir_type *method_type, ir_entity ***param_map) { int dir = env->call->flags.bits.left_to_right ? 1 : -1; int inc = env->birg->main_env->arch_env->isa->stack_dir * dir; @@ -1096,9 +1112,9 @@ static ir_type *compute_arg_type(be_abi_irg_t *env, be_abi_call_t *call, ir_type int i; ir_type *val_param_tp = get_method_value_param_type(method_type); ident *id = get_entity_ident(get_irg_entity(env->birg->irg)); - entity **map; + ir_entity **map; - *param_map = map = obstack_alloc(&env->obst, n * sizeof(entity *)); + *param_map = map = obstack_alloc(&env->obst, n * sizeof(ir_entity *)); res = new_type_struct(mangle_u(id, new_id_from_chars("arg_type", 8))); for (i = 0; i < n; ++i, curr += inc) { ir_type *param_type = get_method_param_type(method_type, curr); @@ -1121,7 +1137,7 @@ static ir_type *compute_arg_type(be_abi_irg_t *env, be_abi_call_t *call, ir_type } ofs += arg->space_before; ofs = round_up2(ofs, arg->alignment); - set_entity_offset_bytes(arg->stack_ent, ofs); + set_entity_offset(arg->stack_ent, ofs); ofs += arg->space_after; ofs += get_type_size_bytes(param_type); map[i] = arg->stack_ent; @@ -1381,7 +1397,7 @@ static ir_node *create_be_return(be_abi_irg_t *env, ir_node *irn, ir_node *bl, i typedef struct lower_frame_sels_env_t { be_abi_irg_t *env; - entity *value_param_list; /**< the list of all value param entities */ + ir_entity *value_param_list; /**< the list of all value param entities */ } lower_frame_sels_env_t; /** @@ -1400,7 +1416,7 @@ static void lower_frame_sels_walker(ir_node *irn, void *data) if (ptr == frame || ptr == param_base) { be_abi_irg_t *env = ctx->env; - entity *ent = get_Sel_entity(irn); + ir_entity *ent = get_Sel_entity(irn); ir_node *bl = get_nodes_block(irn); ir_node *nw; @@ -1427,10 +1443,10 @@ static void lower_frame_sels_walker(ir_node *irn, void *data) * In the default case we move the entity to the frame type and create * a backing store into the first block. */ -static void fix_address_of_parameter_access(be_abi_irg_t *env, entity *value_param_list) { +static void fix_address_of_parameter_access(be_abi_irg_t *env, ir_entity *value_param_list) { be_abi_call_t *call = env->call; ir_graph *irg = env->birg->irg; - entity *ent, *next_ent, *new_list; + ir_entity *ent, *next_ent, *new_list; ir_type *frame_tp; DEBUG_ONLY(firm_dbg_module_t *dbg = env->dbg;) @@ -1516,7 +1532,7 @@ static void fix_address_of_parameter_access(be_abi_irg_t *env, entity *value_par add_class_member(frame_tp, ent); /* must be automatic to set a fixed layout */ set_entity_allocation(ent, allocation_automatic); - set_entity_offset_bytes(ent, offset); + set_entity_offset(ent, offset); offset += get_type_size_bytes(tp); } set_type_size_bytes(frame_tp, offset); @@ -1551,7 +1567,7 @@ static void modify_irg(be_abi_irg_t *env) const ir_edge_t *edge; ir_type *arg_type, *bet_type; lower_frame_sels_env_t ctx; - entity **param_map; + ir_entity **param_map; bitset_t *used_proj_nr; DEBUG_ONLY(firm_dbg_module_t *dbg = env->dbg;) @@ -1624,6 +1640,7 @@ static void modify_irg(be_abi_irg_t *env) 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. @@ -1864,22 +1881,18 @@ static void collect_stack_nodes_walker(ir_node *irn, void *data) void be_abi_fix_stack_nodes(be_abi_irg_t *env, be_lv_t *lv) { - dom_front_info_t *df; pset *stack_nodes = pset_new_ptr(16); struct fix_stack_walker_info info; info.nodes = stack_nodes; info.aenv = env->birg->main_env->arch_env; - /* We need dominance frontiers for fix up */ - df = be_compute_dominance_frontiers(env->birg->irg); + be_assure_dom_front(env->birg); + irg_walk_graph(env->birg->irg, collect_stack_nodes_walker, NULL, &info); pset_insert_ptr(stack_nodes, env->init_sp); - be_ssa_constr_set_phis(df, lv, stack_nodes, env->stack_phis); + be_ssa_constr_set_phis(env->birg->dom_front, lv, stack_nodes, env->stack_phis); del_pset(stack_nodes); - - /* free these dominance frontiers */ - be_free_dominance_frontiers(df); } static int process_stack_bias(be_abi_irg_t *env, ir_node *bl, int bias) @@ -1895,7 +1908,7 @@ static int process_stack_bias(be_abi_irg_t *env, ir_node *bl, int bias) If so, set the true offset (including the bias) for that node. */ - entity *ent = arch_get_frame_entity(arch_env, irn); + ir_entity *ent = arch_get_frame_entity(arch_env, irn); if(ent) { int offset = get_stack_entity_offset(env->frame, ent, bias); arch_set_frame_offset(arch_env, irn, offset); @@ -2058,12 +2071,12 @@ static arch_irn_flags_t abi_get_flags(const void *_self, const ir_node *irn) return arch_irn_flags_ignore | arch_irn_flags_modify_sp; } -static entity *abi_get_frame_entity(const void *_self, const ir_node *irn) +static ir_entity *abi_get_frame_entity(const void *_self, const ir_node *irn) { return NULL; } -static void abi_set_frame_entity(const void *_self, ir_node *irn, entity *ent) +static void abi_set_frame_entity(const void *_self, ir_node *irn, ir_entity *ent) { }