X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fbearch_ia32.c;h=3d6973a2e0ede7d726d0008af84061459cd2a90e;hb=289f417b740633fd4caab706441b6e47bb8d19d1;hp=cacc36c4441860c23be1830dfcd720eb81a3d6e5;hpb=1e77e520bae91c00c143e190ece4bedab9049fd8;p=libfirm diff --git a/ir/be/ia32/bearch_ia32.c b/ir/be/ia32/bearch_ia32.c index cacc36c44..3d6973a2e 100644 --- a/ir/be/ia32/bearch_ia32.c +++ b/ir/be/ia32/bearch_ia32.c @@ -258,6 +258,11 @@ static int ia32_get_sp_bias(const ir_node *node) if (is_ia32_Pop(node) || is_ia32_PopMem(node)) return -4; + if (is_ia32_Leave(node) || (be_is_Copy(node) + && arch_get_irn_register(node) == &ia32_registers[REG_ESP])) { + return SP_BIAS_RESET; + } + return 0; } @@ -293,8 +298,10 @@ static const arch_register_t *ia32_abi_prologue(void *self, ir_node **mem, pmap /* push ebp */ push = new_bd_ia32_Push(NULL, bl, noreg, noreg, *mem, curr_bp, curr_sp); + arch_irn_add_flags(push, arch_irn_flags_prolog); curr_sp = new_r_Proj(push, get_irn_mode(curr_sp), pn_ia32_Push_stack); *mem = new_r_Proj(push, mode_M, pn_ia32_Push_M); + set_irn_pinned(push, op_pin_state_pinned); /* the push must have SP out register */ arch_set_irn_register(curr_sp, arch_env->sp); @@ -304,11 +311,14 @@ static const arch_register_t *ia32_abi_prologue(void *self, ir_node **mem, pmap /* move esp to ebp */ curr_bp = be_new_Copy(arch_env->bp->reg_class, bl, curr_sp); + arch_irn_add_flags(curr_bp, arch_irn_flags_prolog); be_set_constr_single_reg_out(curr_bp, 0, arch_env->bp, arch_register_req_type_ignore); + set_irn_pinned(curr_bp, op_pin_state_pinned); /* beware: the copy must be done before any other sp use */ curr_sp = be_new_CopyKeep_single(arch_env->sp->reg_class, bl, curr_sp, curr_bp, get_irn_mode(curr_sp)); + arch_irn_add_flags(curr_sp, arch_irn_flags_prolog); be_set_constr_single_reg_out(curr_sp, 0, arch_env->sp, arch_register_req_type_produces_sp); @@ -341,6 +351,8 @@ static void ia32_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_ if (env->flags.try_omit_fp) { /* simply remove the stack frame here */ curr_sp = be_new_IncSP(arch_env->sp, bl, curr_sp, BE_STACK_FRAME_SIZE_SHRINK, 0); + arch_irn_add_flags(curr_sp, arch_irn_flags_epilog); + set_irn_pinned(curr_sp, op_pin_state_pinned); } else { ir_mode *mode_bp = arch_env->bp->reg_class->mode; @@ -351,23 +363,25 @@ static void ia32_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_ leave = new_bd_ia32_Leave(NULL, bl, curr_bp); curr_bp = new_r_Proj(leave, mode_bp, pn_ia32_Leave_frame); curr_sp = new_r_Proj(leave, get_irn_mode(curr_sp), pn_ia32_Leave_stack); + arch_irn_add_flags(leave, arch_irn_flags_epilog); + set_irn_pinned(leave, op_pin_state_pinned); } else { ir_node *pop; - /* the old SP is not needed anymore (kill the proj) */ - assert(is_Proj(curr_sp)); - kill_node(curr_sp); - /* copy ebp to esp */ curr_sp = be_new_Copy(&ia32_reg_classes[CLASS_ia32_gp], bl, curr_bp); arch_set_irn_register(curr_sp, arch_env->sp); be_set_constr_single_reg_out(curr_sp, 0, arch_env->sp, arch_register_req_type_ignore); + arch_irn_add_flags(curr_sp, arch_irn_flags_epilog); + set_irn_pinned(curr_sp, op_pin_state_pinned); /* pop ebp */ pop = new_bd_ia32_PopEbp(NULL, bl, *mem, curr_sp); curr_bp = new_r_Proj(pop, mode_bp, pn_ia32_Pop_res); curr_sp = new_r_Proj(pop, get_irn_mode(curr_sp), pn_ia32_Pop_stack); + arch_irn_add_flags(pop, arch_irn_flags_epilog); + set_irn_pinned(pop, op_pin_state_pinned); *mem = new_r_Proj(pop, mode_M, pn_ia32_Pop_M); } @@ -790,10 +804,11 @@ static const arch_irn_ops_t ia32_irn_ops = { }; static ir_entity *mcount = NULL; +static int gprof = 0; static void ia32_before_abi(ir_graph *irg) { - if (be_get_irg_options(irg)->gprof) { + if (gprof) { if (mcount == NULL) { ir_type *tp = new_type_method(0, 0); ident *id = new_id_from_str("mcount"); @@ -1324,11 +1339,13 @@ need_stackent: */ static void ia32_after_ra(ir_graph *irg) { - be_fec_env_t *fec_env = be_new_frame_entity_coalescer(irg); + be_stack_layout_t *stack_layout = be_get_irg_stack_layout(irg); + bool at_begin = stack_layout->sp_relative ? true : false; + be_fec_env_t *fec_env = be_new_frame_entity_coalescer(irg); /* create and coalesce frame entities */ irg_walk_graph(irg, NULL, ia32_collect_frame_entity_nodes, fec_env); - be_assign_entities(fec_env, ia32_set_frame_entity); + be_assign_entities(fec_env, ia32_set_frame_entity, at_begin); be_free_frame_entity_coalescer(fec_env); irg_block_walk_graph(irg, NULL, ia32_after_ra_walker, NULL); @@ -1386,7 +1403,6 @@ static ir_node *ia32_get_pic_base(ir_graph *irg) get_eip = new_bd_ia32_GetEIP(NULL, block); irg_data->get_eip = get_eip; - be_dep_on_frame(get_eip); return get_eip; } @@ -1400,7 +1416,7 @@ static void ia32_init_graph(ir_graph *irg) irg_data->dump = (be_get_irg_options(irg)->dump_flags & DUMP_BE) ? 1 : 0; - if (be_get_irg_options(irg)->gprof) { + if (gprof) { /* Linux gprof implementation needs base pointer */ be_get_irg_options(irg)->omit_fp = 0; } @@ -1423,10 +1439,10 @@ static const tarval_mode_info mo_integer = { */ static void set_tarval_output_modes(void) { - int i; + size_t i; - for (i = get_irp_n_modes() - 1; i >= 0; --i) { - ir_mode *mode = get_irp_mode(i); + for (i = get_irp_n_modes(); i > 0;) { + ir_mode *mode = get_irp_mode(--i); if (mode_is_int(mode)) set_tarval_mode_output_option(mode, &mo_integer); @@ -1515,7 +1531,6 @@ static void init_asm_constraints(void) static arch_env_t *ia32_init(FILE *file_handle) { ia32_isa_t *isa = XMALLOC(ia32_isa_t); - int i, n; set_tarval_output_modes(); @@ -1536,19 +1551,6 @@ static arch_env_t *ia32_init(FILE *file_handle) /* enter the ISA object into the intrinsic environment */ intrinsic_env.isa = isa; - /* emit asm includes */ - n = get_irp_n_asms(); - for (i = 0; i < n; ++i) { - be_emit_cstring("#APP\n"); - be_emit_ident(get_irp_asm(i)); - be_emit_cstring("\n#NO_APP\n"); - } - - /* needed for the debug support */ - be_gas_emit_switch_section(GAS_SECTION_TEXT); - be_emit_irprintf("%stext0:\n", be_gas_get_private_prefix()); - be_emit_write_line(); - return &isa->base; } @@ -2030,8 +2032,7 @@ static ir_node *ia32_create_set(ir_node *cond) static void ia32_lower_for_target(void) { - int n_irgs = get_irp_n_irgs(); - int i; + size_t i, n_irgs = get_irp_n_irgs(); lower_mode_b_config_t lower_mode_b_config = { mode_Iu, /* lowered mode */ ia32_create_set, @@ -2045,9 +2046,6 @@ static void ia32_lower_for_target(void) NULL, /* ret_compound_in_regs */ }; - /* lower compound param handling */ - lower_calls_with_compounds(¶ms); - /* perform doubleword lowering */ lwrdw_param_t lower_dw_params = { 1, /* little endian */ @@ -2055,6 +2053,10 @@ static void ia32_lower_for_target(void) ia32_create_intrinsic_fkt, &intrinsic_env, }; + + /* lower compound param handling */ + lower_calls_with_compounds(¶ms); + lower_dw_ops(&lower_dw_params); for (i = 0; i < n_irgs; ++i) { @@ -2163,8 +2165,9 @@ static const lc_opt_table_entry_t ia32_options[] = { #ifdef FIRM_GRGEN_BE LC_OPT_ENT_ENUM_INT("transformer", "the transformer used for code selection", &transformer_var), #endif - LC_OPT_ENT_INT("stackalign", "set power of two stack alignment for calls", - &ia32_isa_template.base.stack_alignment), + LC_OPT_ENT_INT ("stackalign", "set power of two stack alignment for calls", + &ia32_isa_template.base.stack_alignment), + LC_OPT_ENT_BOOL("gprof", "create gprof profiling code", &gprof), LC_OPT_LAST };