X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbeabi.c;h=f2c3b01d5b70daa266b81e076b30f4d983b0536c;hb=505d3662efed6efbca2c43eea2fe23b87816b285;hp=ab7732de455ad4c67321a825f909b4b83b3c4172;hpb=816e7e0779021990465292820aa997d2af768c72;p=libfirm diff --git a/ir/be/beabi.c b/ir/be/beabi.c index ab7732de4..f2c3b01d5 100644 --- a/ir/be/beabi.c +++ b/ir/be/beabi.c @@ -83,7 +83,7 @@ struct _be_abi_irg_t { struct obstack obst; be_stack_layout_t *frame; /**< The stack frame model. */ be_irg_t *birg; /**< The back end IRG. */ - const arch_isa_t *isa; /**< The isa. */ + const arch_env_t *arch_env; survive_dce_t *dce_survivor; be_abi_call_t *call; /**< The ABI call information. */ @@ -113,9 +113,11 @@ struct _be_abi_irg_t { static heights_t *ir_heights; -/* Flag: if set, try to omit the frame pointer if called by the backend */ +/** Flag: if set, try to omit the frame pointer in all routines. */ static int be_omit_fp = 1; -static int be_pic = 0; + +/** Flag: if set, try to omit the frame pointer in leaf routines only. */ +static int be_omit_leaf_fp = 1; /* _ ____ ___ ____ _ _ _ _ @@ -240,7 +242,7 @@ static be_abi_call_t *be_abi_call_new(const arch_register_class_t *cls_addr) call->cb = NULL; call->cls_addr = cls_addr; - call->flags.bits.try_omit_fp = be_omit_fp; + call->flags.bits.try_omit_fp = be_omit_fp | be_omit_leaf_fp; return call; } @@ -411,7 +413,6 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp) { ir_graph *irg = env->birg->irg; const arch_env_t *arch_env = env->birg->main_env->arch_env; - const arch_isa_t *isa = arch_env->isa; ir_type *call_tp = get_Call_type(irn); ir_node *call_ptr = get_Call_ptr(irn); int n_params = get_method_n_params(call_tp); @@ -421,8 +422,8 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp) pset *caller_save = pset_new_ptr(8); pset *states = pset_new_ptr(2); int stack_size = 0; - int stack_dir = arch_isa_stack_dir(isa); - const arch_register_t *sp = arch_isa_sp(isa); + int stack_dir = arch_env_stack_dir(arch_env); + const arch_register_t *sp = arch_env_sp(arch_env); be_abi_call_t *call = be_abi_call_new(sp->reg_class); ir_mode *mach_mode = sp->reg_class->mode; struct obstack *obst = &env->obst; @@ -446,7 +447,7 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp) int i, n; /* Let the isa fill out the abi description for that call node. */ - arch_isa_get_call_abi(isa, call_tp, call); + arch_env_get_call_abi(arch_env, call_tp, call); /* Insert code to put the stack arguments on the stack. */ assert(get_Call_n_params(irn) == n_params); @@ -584,9 +585,9 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp) } /* Collect caller save registers */ - for (i = 0, n = arch_isa_get_n_reg_class(isa); i < n; ++i) { + for (i = 0, n = arch_env_get_n_reg_class(arch_env); i < n; ++i) { unsigned j; - const arch_register_class_t *cls = arch_isa_get_reg_class(isa, i); + const arch_register_class_t *cls = arch_env_get_reg_class(arch_env, i); for (j = 0; j < cls->n_regs; ++j) { const arch_register_t *reg = arch_register_for_index(cls, j); if (arch_register_type_is(reg, caller_save)) { @@ -627,7 +628,7 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp) } /** TODO: this is not correct for cases where return values are passed - * on the stack, but no known ABI does this currentl... + * on the stack, but no known ABI does this currently... */ n_reg_results = n_res; @@ -735,7 +736,7 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp) /* kill the ProjT node */ if (res_proj != NULL) { - be_kill_node(res_proj); + kill_node(res_proj); } /* Make additional projs for the caller save registers @@ -839,11 +840,15 @@ static ir_node *adjust_alloc_size(unsigned stack_alignment, ir_node *size, ir_graph *irg, ir_node *block, dbg_info *dbg) { if (stack_alignment > 1) { + ir_mode *mode; + tarval *tv; + ir_node *mask; + assert(is_po2(stack_alignment)); - ir_mode *mode = get_irn_mode(size); - tarval *tv = new_tarval_from_long(stack_alignment-1, mode); - ir_node *mask = new_r_Const(irg, block, mode, tv); + mode = get_irn_mode(size); + tv = new_tarval_from_long(stack_alignment-1, mode); + mask = new_r_Const(irg, block, mode, tv); size = new_rd_Add(dbg, irg, block, size, mask, mode); tv = new_tarval_from_long(-(long)stack_alignment, mode); @@ -869,10 +874,7 @@ static ir_node *adjust_alloc(be_abi_irg_t *env, ir_node *alloc, ir_node *curr_sp ir_node *new_alloc, *size, *addr, *ins[2]; unsigned stack_alignment; - if (get_Alloc_where(alloc) != stack_alloc) { - assert(0); - return alloc; - } + assert(get_Alloc_where(alloc) == stack_alloc); block = get_nodes_block(alloc); irg = get_irn_irg(block); @@ -884,7 +886,7 @@ static ir_node *adjust_alloc(be_abi_irg_t *env, ir_node *alloc, ir_node *curr_sp ir_node *irn = get_edge_src_irn(edge); assert(is_Proj(irn)); - switch(get_Proj_proj(irn)) { + switch (get_Proj_proj(irn)) { case pn_Alloc_M: alloc_mem = irn; break; @@ -907,7 +909,7 @@ static ir_node *adjust_alloc(be_abi_irg_t *env, ir_node *alloc, ir_node *curr_sp dbg = get_irn_dbg_info(alloc); /* we might need to multiply the size with the element size */ - if(type != get_unknown_type() && get_type_size_bytes(type) != 1) { + if (type != firm_unknown_type && get_type_size_bytes(type) != 1) { tarval *tv = new_tarval_from_long(get_type_size_bytes(type), mode_Iu); ir_node *cnst = new_rd_Const(dbg, irg, block, mode_Iu, tv); @@ -922,9 +924,9 @@ static ir_node *adjust_alloc(be_abi_irg_t *env, ir_node *alloc, ir_node *curr_sp We cannot omit it. */ env->call->flags.bits.try_omit_fp = 0; - stack_alignment = env->isa->stack_alignment; + stack_alignment = 1 << env->arch_env->stack_alignment; size = adjust_alloc_size(stack_alignment, size, irg, block, dbg); - new_alloc = be_new_AddSP(env->isa->sp, irg, block, curr_sp, size); + new_alloc = be_new_AddSP(env->arch_env->sp, irg, block, curr_sp, size); set_irn_dbg_info(new_alloc, dbg); if(alloc_mem != NULL) { @@ -969,19 +971,16 @@ static ir_node *adjust_free(be_abi_irg_t *env, ir_node *free, ir_node *curr_sp) unsigned stack_alignment; dbg_info *dbg; - if (get_Free_where(free) != stack_alloc) { - assert(0); - return free; - } + assert(get_Free_where(free) == stack_alloc); block = get_nodes_block(free); irg = get_irn_irg(block); type = get_Free_type(free); - sp_mode = env->isa->sp->reg_class->mode; + sp_mode = env->arch_env->sp->reg_class->mode; dbg = get_irn_dbg_info(free); /* we might need to multiply the size with the element size */ - if(type != get_unknown_type() && get_type_size_bytes(type) != 1) { + if (type != firm_unknown_type && get_type_size_bytes(type) != 1) { tarval *tv = new_tarval_from_long(get_type_size_bytes(type), mode_Iu); ir_node *cnst = new_rd_Const(dbg, irg, block, mode_Iu, tv); ir_node *mul = new_rd_Mul(dbg, irg, block, get_Free_size(free), @@ -991,13 +990,13 @@ static ir_node *adjust_free(be_abi_irg_t *env, ir_node *free, ir_node *curr_sp) size = get_Free_size(free); } - stack_alignment = env->isa->stack_alignment; + stack_alignment = 1 << env->arch_env->stack_alignment; size = adjust_alloc_size(stack_alignment, size, irg, block, dbg); /* The stack pointer will be modified in an unknown manner. We cannot omit it. */ env->call->flags.bits.try_omit_fp = 0; - subsp = be_new_SubSP(env->isa->sp, irg, block, curr_sp, size); + subsp = be_new_SubSP(env->arch_env->sp, irg, block, curr_sp, size); set_irn_dbg_info(subsp, dbg); mem = new_r_Proj(irg, block, subsp, mode_M, pn_be_SubSP_M); @@ -1083,15 +1082,16 @@ static int cmp_call_dependency(const void *c1, const void *c2) } /** - * Walker: links all Call/alloc/Free nodes to the Block they are contained. + * Walker: links all Call/Alloc/Free nodes to the Block they are contained. + * Clears the irg_is_leaf flag if a Call is detected. */ -static void link_calls_in_block_walker(ir_node *irn, void *data) +static void link_ops_in_block_walker(ir_node *irn, void *data) { ir_opcode code = get_irn_opcode(irn); if (code == iro_Call || - (code == iro_Alloc && get_Alloc_where(irn) == stack_alloc) || - (code == iro_Free && get_Free_where(irn) == stack_alloc)) { + (code == iro_Alloc && get_Alloc_where(irn) == stack_alloc) || + (code == iro_Free && get_Free_where(irn) == stack_alloc)) { be_abi_irg_t *env = data; ir_node *bl = get_nodes_block(irn); void *save = get_irn_link(bl); @@ -1106,23 +1106,23 @@ static void link_calls_in_block_walker(ir_node *irn, void *data) /** * Block-walker: - * Process all Call nodes inside a basic block. + * Process all Call/Alloc/Free nodes inside a basic block. * Note that the link field of the block must contain a linked list of all * Call nodes inside the Block. We first order this list according to data dependency * and that connect the calls together. */ -static void process_calls_in_block(ir_node *bl, void *data) +static void process_ops_in_block(ir_node *bl, void *data) { be_abi_irg_t *env = data; ir_node *curr_sp = env->init_sp; ir_node *irn; int n; - for(irn = get_irn_link(bl), n = 0; irn; irn = get_irn_link(irn), ++n) + for (irn = get_irn_link(bl), n = 0; irn; irn = get_irn_link(irn), ++n) obstack_ptr_grow(&env->obst, irn); /* If there were call nodes in the block. */ - if(n > 0) { + if (n > 0) { ir_node *keep; ir_node **nodes; int i; @@ -1132,19 +1132,25 @@ static void process_calls_in_block(ir_node *bl, void *data) /* order the call nodes according to data dependency */ qsort(nodes, n, sizeof(nodes[0]), cmp_call_dependency); - for(i = n - 1; i >= 0; --i) { + for (i = n - 1; i >= 0; --i) { ir_node *irn = nodes[i]; DBG((env->dbg, LEVEL_3, "\tprocessing call %+F\n", irn)); - switch(get_irn_opcode(irn)) { + switch (get_irn_opcode(irn)) { case iro_Call: + if (! be_omit_fp) { + /* The stack pointer will be modified due to a call. */ + env->call->flags.bits.try_omit_fp = 0; + } curr_sp = adjust_call(env, irn, curr_sp); break; case iro_Alloc: - curr_sp = adjust_alloc(env, irn, curr_sp); + if (get_Alloc_where(irn) == stack_alloc) + curr_sp = adjust_alloc(env, irn, curr_sp); break; case iro_Free: - curr_sp = adjust_free(env, irn, curr_sp); + if (get_Free_where(irn) == stack_alloc) + curr_sp = adjust_free(env, irn, curr_sp); break; default: panic("invalid call"); @@ -1156,11 +1162,11 @@ static void process_calls_in_block(ir_node *bl, void *data) /* Keep the last stack state in the block by tying it to Keep node, * the proj from calls is already kept */ - if(curr_sp != env->init_sp - && !(is_Proj(curr_sp) && be_is_Call(get_Proj_pred(curr_sp)))) { + if (curr_sp != env->init_sp && + !(is_Proj(curr_sp) && be_is_Call(get_Proj_pred(curr_sp)))) { nodes[0] = curr_sp; - keep = be_new_Keep(env->isa->sp->reg_class, get_irn_irg(bl), - bl, 1, nodes); + keep = be_new_Keep(env->arch_env->sp->reg_class, + get_irn_irg(bl), bl, 1, nodes); pmap_insert(env->keep_map, bl, keep); } } @@ -1176,10 +1182,10 @@ static void process_calls(be_abi_irg_t *env) ir_graph *irg = env->birg->irg; env->call->flags.bits.irg_is_leaf = 1; - irg_walk_graph(irg, firm_clear_link, link_calls_in_block_walker, env); + irg_walk_graph(irg, firm_clear_link, link_ops_in_block_walker, env); ir_heights = heights_new(env->birg->irg); - irg_block_walk_graph(irg, NULL, process_calls_in_block, env); + irg_block_walk_graph(irg, NULL, process_ops_in_block, env); heights_free(ir_heights); } @@ -1198,7 +1204,7 @@ static void process_calls(be_abi_irg_t *env) 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; + int inc = env->birg->main_env->arch_env->stack_dir * dir; int n = get_method_n_params(method_type); int curr = inc > 0 ? 0 : n - 1; int ofs = 0; @@ -1393,8 +1399,8 @@ static ir_node *create_barrier(be_abi_irg_t *env, ir_node *bl, ir_node **mem, pm static ir_node *create_be_return(be_abi_irg_t *env, ir_node *irn, ir_node *bl, ir_node *mem, int n_res) { - be_abi_call_t *call = env->call; - const arch_isa_t *isa = env->birg->main_env->arch_env->isa; + be_abi_call_t *call = env->call; + const arch_env_t *arch_env = env->birg->main_env->arch_env; dbg_info *dbgi; pmap *reg_map = pmap_create(); ir_node *keep = pmap_get(env->keep_map, bl); @@ -1414,10 +1420,10 @@ static ir_node *create_be_return(be_abi_irg_t *env, ir_node *irn, ir_node *bl, it then. Else we use the stack from the start block and let the ssa construction fix the usage. */ - stack = be_abi_reg_map_get(env->regs, isa->sp); + stack = be_abi_reg_map_get(env->regs, arch_env->sp); if (keep) { stack = get_irn_n(keep, 0); - be_kill_node(keep); + kill_node(keep); remove_End_keepalive(get_irg_end(env->birg->irg), keep); } @@ -1436,7 +1442,7 @@ static ir_node *create_be_return(be_abi_irg_t *env, ir_node *irn, ir_node *bl, pmap_insert(reg_map, ent->key, ent->value); } - be_abi_reg_map_set(reg_map, isa->sp, stack); + be_abi_reg_map_set(reg_map, arch_env->sp, stack); /* Make the Epilogue node and call the arch's epilogue maker. */ create_barrier(env, bl, &mem, reg_map, 1); @@ -1452,13 +1458,13 @@ static ir_node *create_be_return(be_abi_irg_t *env, ir_node *irn, ir_node *bl, regs = obstack_alloc(&env->obst, in_max * sizeof(regs[0])); in[0] = mem; - in[1] = be_abi_reg_map_get(reg_map, isa->sp); + in[1] = be_abi_reg_map_get(reg_map, arch_env->sp); regs[0] = NULL; - regs[1] = isa->sp; + regs[1] = arch_env->sp; n = 2; /* clear SP entry, since it has already been grown. */ - pmap_insert(reg_map, (void *) isa->sp, NULL); + pmap_insert(reg_map, (void *) arch_env->sp, NULL); for(i = 0; i < n_res; ++i) { be_abi_call_arg_t *arg = get_call_arg(call, 1, i); @@ -1525,7 +1531,7 @@ static void lower_frame_sels_walker(ir_node *irn, void *data) { ir_node *bl = get_nodes_block(irn); ir_node *nw; - nw = be_new_FrameAddr(env->isa->sp->reg_class, irg, bl, frame, ent); + nw = be_new_FrameAddr(env->arch_env->sp->reg_class, irg, bl, frame, ent); exchange(irn, nw); /* check, if it's a param sel and if have not seen this entity before */ @@ -1614,7 +1620,7 @@ static void fix_address_of_parameter_access(be_abi_irg_t *env, ir_entity *value_ ir_node *addr; /* address for the backing store */ - addr = be_new_FrameAddr(env->isa->sp->reg_class, irg, first_bl, frame, ent); + addr = be_new_FrameAddr(env->arch_env->sp->reg_class, irg, first_bl, frame, ent); if (store) mem = new_r_Proj(irg, first_bl, store, mode_M, pn_Store_M); @@ -1692,8 +1698,8 @@ static void fix_start_block(ir_node *block, void *env) { static void modify_irg(be_abi_irg_t *env) { be_abi_call_t *call = env->call; - const arch_isa_t *isa = env->birg->main_env->arch_env->isa; - const arch_register_t *sp = arch_isa_sp(isa); + const arch_env_t *arch_env= env->birg->main_env->arch_env; + const arch_register_t *sp = arch_env_sp(arch_env); ir_graph *irg = env->birg->irg; ir_node *bl = get_irg_start_block(irg); ir_node *end = get_irg_end_block(irg); @@ -1740,7 +1746,7 @@ static void modify_irg(be_abi_irg_t *env) /* value_param_base anchor is not needed anymore now */ value_param_base = get_irg_value_param_base(irg); - be_kill_node(value_param_base); + kill_node(value_param_base); set_irg_value_param_base(irg, new_r_Bad(irg)); env->frame = obstack_alloc(&env->obst, sizeof(env->frame[0])); @@ -1776,7 +1782,7 @@ static void modify_irg(be_abi_irg_t *env) arg_type = compute_arg_type(env, call, method_type, ¶m_map); bet_type = call->cb->get_between_type(env->cb); - stack_frame_init(env->frame, arg_type, bet_type, get_irg_frame_type(irg), isa->stack_dir, param_map); + stack_frame_init(env->frame, arg_type, bet_type, get_irg_frame_type(irg), arch_env->stack_dir, param_map); /* Count the register params and add them to the number of Projs for the RegParams node */ for(i = 0; i < n_params; ++i) { @@ -1793,8 +1799,8 @@ static void modify_irg(be_abi_irg_t *env) } /* Collect all callee-save registers */ - for(i = 0, n = arch_isa_get_n_reg_class(isa); i < n; ++i) { - const arch_register_class_t *cls = arch_isa_get_reg_class(isa, i); + for(i = 0, n = arch_env_get_n_reg_class(arch_env); i < n; ++i) { + const arch_register_class_t *cls = arch_env_get_reg_class(arch_env, i); for(j = 0; j < cls->n_regs; ++j) { const arch_register_t *reg = &cls->regs[j]; if(arch_register_type_is(reg, callee_save) || @@ -1805,7 +1811,7 @@ static void modify_irg(be_abi_irg_t *env) } pmap_insert(env->regs, (void *) sp, NULL); - pmap_insert(env->regs, (void *) isa->bp, NULL); + pmap_insert(env->regs, (void *) arch_env->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)); @@ -1936,7 +1942,7 @@ static void modify_irg(be_abi_irg_t *env) /* the arg proj is not needed anymore now and should be only used by the anchor */ assert(get_irn_n_edges(arg_tuple) == 1); - be_kill_node(arg_tuple); + kill_node(arg_tuple); set_irg_args(irg, new_rd_Bad(irg)); /* All Return nodes hang on the End node, so look for them there. */ @@ -1965,15 +1971,15 @@ static void modify_irg(be_abi_irg_t *env) static void fix_call_state_inputs(be_abi_irg_t *env) { - const arch_isa_t *isa = env->isa; + const arch_env_t *arch_env = env->arch_env; int i, n, n_states; arch_register_t **stateregs = NEW_ARR_F(arch_register_t*, 0); /* Collect caller save registers */ - n = arch_isa_get_n_reg_class(isa); + n = arch_env_get_n_reg_class(arch_env); for(i = 0; i < n; ++i) { unsigned j; - const arch_register_class_t *cls = arch_isa_get_reg_class(isa, i); + const arch_register_class_t *cls = arch_env_get_reg_class(arch_env, i); for(j = 0; j < cls->n_regs; ++j) { const arch_register_t *reg = arch_register_for_index(cls, j); if(arch_register_type_is(reg, state)) { @@ -1990,7 +1996,7 @@ void fix_call_state_inputs(be_abi_irg_t *env) arity = get_irn_arity(call); - /* the statereg inputs are the last n inputs of the calls */ + /* the state reg inputs are the last n inputs of the calls */ for(s = 0; s < n_states; ++s) { int inp = arity - n_states + s; const arch_register_t *reg = stateregs[s]; @@ -1999,8 +2005,13 @@ void fix_call_state_inputs(be_abi_irg_t *env) set_irn_n(call, inp, regnode); } } + + DEL_ARR_F(stateregs); } +/** + * Create a trampoline entity for the given method. + */ static ir_entity *create_trampoline(be_main_env_t *be, ir_entity *method) { ir_type *type = get_entity_type(method); @@ -2015,6 +2026,9 @@ static ir_entity *create_trampoline(be_main_env_t *be, ir_entity *method) return ent; } +/** + * Returns the trampoline entity for the given method. + */ static ir_entity *get_trampoline(be_main_env_t *env, ir_entity *method) { ir_entity *result = pmap_get(env->ent_trampoline_map, method); @@ -2026,6 +2040,9 @@ static ir_entity *get_trampoline(be_main_env_t *env, ir_entity *method) return result; } +/** + * Returns non-zero if a given entity can be accessed using a relative address. + */ static int can_address_relative(ir_entity *entity) { return get_entity_variability(entity) == variability_initialized @@ -2112,15 +2129,15 @@ be_abi_irg_t *be_abi_introduce(be_irg_t *birg) optimization_state_t state; unsigned *limited_bitset; - be_omit_fp = birg->main_env->options->omit_fp; - be_pic = birg->main_env->options->pic; + be_omit_fp = birg->main_env->options->omit_fp; + be_omit_leaf_fp = birg->main_env->options->omit_leaf_fp; obstack_init(&env->obst); - env->isa = birg->main_env->arch_env->isa; + env->arch_env = birg->main_env->arch_env; env->method_type = get_entity_type(get_irg_entity(irg)); - env->call = be_abi_call_new(env->isa->sp->reg_class); - arch_isa_get_call_abi(env->isa, env->method_type, env->call); + env->call = be_abi_call_new(env->arch_env->sp->reg_class); + arch_env_get_call_abi(env->arch_env, env->method_type, env->call); env->ignore_regs = pset_new_ptr_default(); env->keep_map = pmap_create(); @@ -2128,25 +2145,25 @@ be_abi_irg_t *be_abi_introduce(be_irg_t *birg) env->birg = birg; env->sp_req.type = arch_register_req_type_limited; - env->sp_req.cls = arch_register_get_class(env->isa->sp); + env->sp_req.cls = arch_register_get_class(env->arch_env->sp); limited_bitset = rbitset_obstack_alloc(&env->obst, env->sp_req.cls->n_regs); - rbitset_set(limited_bitset, arch_register_get_index(env->isa->sp)); + rbitset_set(limited_bitset, arch_register_get_index(env->arch_env->sp)); env->sp_req.limited = limited_bitset; env->sp_cls_req.type = arch_register_req_type_normal; - env->sp_cls_req.cls = arch_register_get_class(env->isa->sp); + env->sp_cls_req.cls = arch_register_get_class(env->arch_env->sp); /* Beware: later we replace this node by the real one, ensure it is not CSE'd to another Unknown or the stack pointer gets used */ save_optimization_state(&state); set_optimize(0); - env->init_sp = dummy = new_r_Unknown(irg, env->isa->sp->reg_class->mode); + env->init_sp = dummy = new_r_Unknown(irg, env->arch_env->sp->reg_class->mode); restore_optimization_state(&state); FIRM_DBG_REGISTER(env->dbg, "firm.be.abi"); env->calls = NEW_ARR_F(ir_node*, 0); - if (be_pic) { + if (birg->main_env->options->pic) { irg_walk_graph(irg, fix_pic_symconsts, NULL, env); } @@ -2207,6 +2224,27 @@ void be_abi_put_ignore_regs(be_abi_irg_t *abi, const arch_register_class_t *cls, bitset_set(bs, reg->index); } +void be_abi_set_non_ignore_regs(be_abi_irg_t *abi, const arch_register_class_t *cls, unsigned *raw_bitset) +{ + unsigned i; + arch_register_t *reg; + + for (i = 0; i < cls->n_regs; ++i) { + if (arch_register_type_is(&cls->regs[i], ignore)) + continue; + + rbitset_set(raw_bitset, i); + } + + for (reg = pset_first(abi->ignore_regs); reg != NULL; + reg = pset_next(abi->ignore_regs)) { + if (reg->reg_class != cls) + continue; + + rbitset_clear(raw_bitset, reg->index); + } +} + /* Returns the stack layout from a abi environment. */ const be_stack_layout_t *be_abi_get_stack_layout(const be_abi_irg_t *abi) { return abi->frame; @@ -2250,11 +2288,9 @@ void be_abi_fix_stack_nodes(be_abi_irg_t *env) be_irg_t *birg = env->birg; be_lv_t *lv = be_get_birg_liveness(birg); fix_stack_walker_env_t walker_env; - arch_isa_t *isa; walker_env.sp_nodes = NEW_ARR_F(ir_node*, 0); walker_env.arch_env = birg->main_env->arch_env; - isa = walker_env.arch_env->isa; irg_walk_graph(birg->irg, collect_stack_nodes_walker, NULL, &walker_env); @@ -2290,7 +2326,7 @@ void be_abi_fix_stack_nodes(be_abi_irg_t *env) ir_node *phi = phis[i]; be_set_phi_reg_req(walker_env.arch_env, phi, &env->sp_req); be_set_phi_flags(walker_env.arch_env, phi, arch_irn_flags_ignore | arch_irn_flags_modify_sp); - arch_set_irn_register(walker_env.arch_env, phi, env->isa->sp); + arch_set_irn_register(walker_env.arch_env, phi, env->arch_env->sp); } be_ssa_construction_destroy(&senv); @@ -2342,8 +2378,8 @@ static int process_stack_bias(be_abi_irg_t *env, ir_node *bl, int real_bias) /* patch IncSP to produce an aligned stack pointer */ ir_type *between_type = env->frame->between_type; int between_size = get_type_size_bytes(between_type); - int alignment = env->isa->stack_alignment; - int delta = (real_bias + ofs + between_size) % env->isa->stack_alignment; + int alignment = 1 << env->arch_env->stack_alignment; + int delta = (real_bias + ofs + between_size) & (alignment - 1); assert(ofs >= 0); if (delta > 0) { be_set_IncSP_offset(irn, ofs + alignment - delta);