X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fbearch_ia32.c;h=f7bbde804d260d12e8f70a9963e05c2005b7e9b9;hb=4b33054acaa27b6fca74713bb0e1e79e6af3d9c4;hp=2d79b093f4e912c4c2992a0969f804ec92d1195e;hpb=64723d1bd8ace74ca5f0018db8655f2a1f443532;p=libfirm diff --git a/ir/be/ia32/bearch_ia32.c b/ir/be/ia32/bearch_ia32.c index 2d79b093f..f7bbde804 100644 --- a/ir/be/ia32/bearch_ia32.c +++ b/ir/be/ia32/bearch_ia32.c @@ -42,6 +42,7 @@ #include "irgopt.h" #include "irbitset.h" #include "irgopt.h" +#include "irdump.h" #include "pdeq.h" #include "pset.h" #include "debug.h" @@ -132,7 +133,7 @@ static inline ir_node *create_const(ia32_code_gen_t *cg, ir_node **place, { ir_node *block, *res; - if(*place != NULL) + if (*place != NULL) return *place; block = get_irg_start_block(cg->irg); @@ -162,24 +163,6 @@ ir_node *ia32_new_NoReg_xmm(ia32_code_gen_t *cg) &ia32_xmm_regs[REG_XMM_NOREG]); } -ir_node *ia32_new_Unknown_gp(ia32_code_gen_t *cg) -{ - return create_const(cg, &cg->unknown_gp, new_bd_ia32_Unknown_GP, - &ia32_gp_regs[REG_GP_UKNWN]); -} - -ir_node *ia32_new_Unknown_vfp(ia32_code_gen_t *cg) -{ - return create_const(cg, &cg->unknown_vfp, new_bd_ia32_Unknown_VFP, - &ia32_vfp_regs[REG_VFP_UKNWN]); -} - -ir_node *ia32_new_Unknown_xmm(ia32_code_gen_t *cg) -{ - return create_const(cg, &cg->unknown_xmm, new_bd_ia32_Unknown_XMM, - &ia32_xmm_regs[REG_XMM_UKNWN]); -} - ir_node *ia32_new_Fpu_truncate(ia32_code_gen_t *cg) { return create_const(cg, &cg->fpu_trunc_mode, new_bd_ia32_ChangeCW, @@ -205,16 +188,6 @@ static ir_node *ia32_get_admissible_noreg(ia32_code_gen_t *cg, ir_node *irn, int } } -/************************************************** - * _ _ _ __ - * | | | (_)/ _| - * _ __ ___ __ _ __ _| | | ___ ___ _| |_ - * | '__/ _ \/ _` | / _` | | |/ _ \ / __| | | _| - * | | | __/ (_| | | (_| | | | (_) | (__ | | | - * |_| \___|\__, | \__,_|_|_|\___/ \___| |_|_| - * __/ | - * |___/ - **************************************************/ static const arch_register_req_t *get_ia32_SwitchJmp_out_req( const ir_node *node, int pos) @@ -267,9 +240,9 @@ static void ia32_set_frame_offset(ir_node *irn, int bias) return; if (is_ia32_Pop(irn) || is_ia32_PopMem(irn)) { - ia32_code_gen_t *cg = ia32_current_cg; - int omit_fp = be_abi_omit_fp(cg->birg->abi); - if (omit_fp) { + ir_graph *irg = get_irn_irg(irn); + be_stack_layout_t *layout = be_get_irg_stack_layout(irg); + if (layout->sp_relative) { /* Pop nodes modify the stack pointer before calculating the * destination address, so fix this here */ @@ -325,8 +298,8 @@ 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); - curr_sp = new_r_Proj(bl, push, get_irn_mode(curr_sp), pn_ia32_Push_stack); - *mem = new_r_Proj(bl, push, mode_M, pn_ia32_Push_M); + 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); /* the push must have SP out register */ arch_set_irn_register(curr_sp, arch_env->sp); @@ -381,8 +354,8 @@ static void ia32_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_ /* leave */ leave = new_bd_ia32_Leave(NULL, bl, curr_bp); - curr_bp = new_r_Proj(bl, leave, mode_bp, pn_ia32_Leave_frame); - curr_sp = new_r_Proj(bl, leave, get_irn_mode(curr_sp), pn_ia32_Leave_stack); + 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); } else { ir_node *pop; @@ -398,10 +371,10 @@ static void ia32_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_ /* pop ebp */ pop = new_bd_ia32_PopEbp(NULL, bl, *mem, curr_sp); - curr_bp = new_r_Proj(bl, pop, mode_bp, pn_ia32_Pop_res); - curr_sp = new_r_Proj(bl, pop, get_irn_mode(curr_sp), pn_ia32_Pop_stack); + 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); - *mem = new_r_Proj(bl, pop, mode_M, pn_ia32_Pop_M); + *mem = new_r_Proj(pop, mode_M, pn_ia32_Pop_M); } arch_set_irn_register(curr_sp, arch_env->sp); arch_set_irn_register(curr_bp, arch_env->bp); @@ -558,6 +531,13 @@ static int ia32_get_op_estimated_cost(const ir_node *irn) */ static arch_inverse_t *ia32_get_inverse(const ir_node *irn, int i, arch_inverse_t *inverse, struct obstack *obst) { + (void) irn; + (void) i; + (void) inverse; + (void) obst; + return NULL; + +#if 0 ir_mode *mode; ir_mode *irn_mode; ir_node *block, *noreg, *nomem; @@ -670,11 +650,12 @@ static arch_inverse_t *ia32_get_inverse(const ir_node *irn, int i, arch_inverse_ } return inverse; +#endif } static ir_mode *get_spill_mode_mode(const ir_mode *mode) { - if(mode_is_float(mode)) + if (mode_is_float(mode)) return mode_D; return mode_Iu; @@ -838,16 +819,6 @@ static const arch_irn_ops_t ia32_SwitchJmp_irn_ops = { ia32_perform_memory_operand, }; -/************************************************** - * _ _ __ - * | | (_)/ _| - * ___ ___ __| | ___ __ _ ___ _ __ _| |_ - * / __/ _ \ / _` |/ _ \/ _` |/ _ \ '_ \ | | _| - * | (_| (_) | (_| | __/ (_| | __/ | | | | | | - * \___\___/ \__,_|\___|\__, |\___|_| |_| |_|_| - * __/ | - * |___/ - **************************************************/ static ir_entity *mcount = NULL; @@ -864,7 +835,7 @@ static void ia32_before_abi(void *self) ir_lower_mode_b(cg->irg, &lower_mode_b_config); if (cg->dump) - be_dump(cg->irg, "-lower_modeb", dump_ir_block_graph_sched); + dump_ir_graph(cg->irg, "lower_modeb"); if (cg->gprof) { if (mcount == NULL) { @@ -886,29 +857,31 @@ static void ia32_prepare_graph(void *self) { ia32_code_gen_t *cg = self; +#ifdef FIRM_GRGEN_BE switch (be_transformer) { case TRANSFORMER_DEFAULT: /* transform remaining nodes into assembler instructions */ ia32_transform_graph(cg); break; -#ifdef FIRM_GRGEN_BE case TRANSFORMER_PBQP: case TRANSFORMER_RAND: /* transform nodes into assembler instructions by PBQP magic */ ia32_transform_graph_by_pbqp(cg); break; -#endif default: panic("invalid transformer"); } +#else + ia32_transform_graph(cg); +#endif /* do local optimizations (mainly CSE) */ optimize_graph_df(cg->irg); if (cg->dump) - be_dump(cg->irg, "-transformed", dump_ir_block_graph_sched); + dump_ir_graph(cg->irg, "transformed"); /* optimize address mode */ ia32_optimize_graph(cg); @@ -917,7 +890,7 @@ static void ia32_prepare_graph(void *self) place_code(cg->irg); if (cg->dump) - be_dump(cg->irg, "-place", dump_ir_block_graph_sched); + dump_ir_graph(cg->irg, "place"); } ir_node *turn_back_am(ir_node *node) @@ -930,7 +903,7 @@ ir_node *turn_back_am(ir_node *node) ir_node *noreg; ir_node *load = new_bd_ia32_Load(dbgi, block, base, index, mem); - ir_node *load_res = new_rd_Proj(dbgi, block, load, mode_Iu, pn_ia32_Load_res); + ir_node *load_res = new_rd_Proj(dbgi, load, mode_Iu, pn_ia32_Load_res); ia32_copy_am_attrs(load, node); if (is_ia32_is_reload(node)) @@ -1026,7 +999,7 @@ static void ia32_before_ra(void *self) ia32_setup_fpu_mode(cg); /* fixup flags */ - be_sched_fix_flags(cg->birg, &ia32_reg_classes[CLASS_ia32_flags], + be_sched_fix_flags(cg->irg, &ia32_reg_classes[CLASS_ia32_flags], &flags_remat); ia32_add_missing_keeps(cg); @@ -1076,7 +1049,7 @@ static void transform_to_Load(ia32_code_gen_t *cg, ir_node *node) DBG_OPT_RELOAD2LD(node, new_op); - proj = new_rd_Proj(dbg, block, new_op, mode, pn_ia32_Load_res); + proj = new_rd_Proj(dbg, new_op, mode, pn_ia32_Load_res); if (sched_point) { sched_add_after(sched_point, new_op); @@ -1114,18 +1087,6 @@ static void transform_to_Store(ia32_code_gen_t *cg, ir_node *node) sched_point = sched_prev(node); } - /* No need to spill unknown values... */ - if(is_ia32_Unknown_GP(val) || - is_ia32_Unknown_VFP(val) || - is_ia32_Unknown_XMM(val)) { - store = nomem; - if(sched_point) - sched_remove(node); - - exchange(node, store); - return; - } - if (mode_is_float(mode)) { if (ia32_cg_config.use_sse2) store = new_bd_ia32_xStore(dbg, block, ptr, noreg, nomem, val); @@ -1200,12 +1161,11 @@ static ir_node *create_pop(ia32_code_gen_t *cg, ir_node *node, ir_node *schedpoi static ir_node* create_spproj(ir_node *node, ir_node *pred, int pos) { dbg_info *dbg = get_irn_dbg_info(node); - ir_node *block = get_nodes_block(node); ir_mode *spmode = mode_Iu; const arch_register_t *spreg = &ia32_gp_regs[REG_ESP]; ir_node *sp; - sp = new_rd_Proj(dbg, block, pred, spmode, pos); + sp = new_rd_Proj(dbg, pred, spmode, pos); arch_set_irn_register(sp, spreg); return sp; @@ -1219,7 +1179,7 @@ static ir_node* create_spproj(ir_node *node, ir_node *pred, int pos) static void transform_MemPerm(ia32_code_gen_t *cg, ir_node *node) { ir_node *block = get_nodes_block(node); - ir_node *sp = be_abi_get_ignore_irn(cg->birg->abi, &ia32_gp_regs[REG_ESP]); + ir_node *sp = be_abi_get_ignore_irn(be_get_irg_abi(cg->irg), &ia32_gp_regs[REG_ESP]); int arity = be_get_MemPerm_entity_arity(node); ir_node **pops = ALLOCAN(ir_node*, arity); ir_node *in[1]; @@ -1229,7 +1189,7 @@ static void transform_MemPerm(ia32_code_gen_t *cg, ir_node *node) const ir_edge_t *next; /* create Pushs */ - for(i = 0; i < arity; ++i) { + for (i = 0; i < arity; ++i) { ir_entity *inent = be_get_MemPerm_in_entity(node, i); ir_entity *outent = be_get_MemPerm_out_entity(node, i); ir_type *enttype = get_entity_type(inent); @@ -1239,13 +1199,13 @@ static void transform_MemPerm(ia32_code_gen_t *cg, ir_node *node) ir_node *push; /* work around cases where entities have different sizes */ - if(entsize2 < entsize) + if (entsize2 < entsize) entsize = entsize2; assert( (entsize == 4 || entsize == 8) && "spillslot on x86 should be 32 or 64 bit"); push = create_push(cg, node, node, sp, mem, inent); sp = create_spproj(node, push, pn_ia32_Push_stack); - if(entsize == 8) { + if (entsize == 8) { /* add another push after the first one */ push = create_push(cg, node, node, sp, mem, inent); add_ia32_am_offs_int(push, 4); @@ -1256,7 +1216,7 @@ static void transform_MemPerm(ia32_code_gen_t *cg, ir_node *node) } /* create pops */ - for(i = arity - 1; i >= 0; --i) { + for (i = arity - 1; i >= 0; --i) { ir_entity *inent = be_get_MemPerm_in_entity(node, i); ir_entity *outent = be_get_MemPerm_out_entity(node, i); ir_type *enttype = get_entity_type(outent); @@ -1265,13 +1225,13 @@ static void transform_MemPerm(ia32_code_gen_t *cg, ir_node *node) ir_node *pop; /* work around cases where entities have different sizes */ - if(entsize2 < entsize) + if (entsize2 < entsize) entsize = entsize2; assert( (entsize == 4 || entsize == 8) && "spillslot on x86 should be 32 or 64 bit"); pop = create_pop(cg, node, node, sp, outent); sp = create_spproj(node, pop, pn_ia32_Pop_stack); - if(entsize == 8) { + if (entsize == 8) { add_ia32_am_offs_int(pop, 4); /* add another pop after the first one */ @@ -1299,7 +1259,7 @@ static void transform_MemPerm(ia32_code_gen_t *cg, ir_node *node) /* remove memperm */ arity = get_irn_arity(node); - for(i = 0; i < arity; ++i) { + for (i = 0; i < arity; ++i) { set_irn_n(node, i, new_Bad()); } sched_remove(node); @@ -1409,7 +1369,7 @@ static void ia32_after_ra(void *self) { ia32_code_gen_t *cg = self; ir_graph *irg = cg->irg; - be_fec_env_t *fec_env = be_new_frame_entity_coalescer(cg->birg); + be_fec_env_t *fec_env = be_new_frame_entity_coalescer(cg->irg); /* create and coalesce frame entities */ irg_walk_graph(irg, NULL, ia32_collect_frame_entity_nodes, fec_env); @@ -1433,7 +1393,7 @@ static void ia32_finish(void *self) /* we might have to rewrite x87 virtual registers */ if (cg->do_x87_sim) { - x87_simulate_graph(cg->birg); + x87_simulate_graph(cg->irg); } /* do peephole optimisations */ @@ -1441,7 +1401,7 @@ static void ia32_finish(void *self) /* create block schedule, this also removes empty blocks which might * produce critical edges */ - cg->blk_sched = be_create_block_schedule(irg, cg->birg->exec_freq); + cg->blk_sched = be_create_block_schedule(irg); } /** @@ -1488,7 +1448,7 @@ static ir_node *ia32_get_pic_base(void *self) return get_eip; } -static void *ia32_cg_init(be_irg_t *birg); +static void *ia32_cg_init(ir_graph *irg); static const arch_code_generator_if_t ia32_code_gen_if = { ia32_cg_init, @@ -1505,22 +1465,21 @@ static const arch_code_generator_if_t ia32_code_gen_if = { /** * Initializes a IA32 code generator. */ -static void *ia32_cg_init(be_irg_t *birg) +static void *ia32_cg_init(ir_graph *irg) { - ia32_isa_t *isa = (ia32_isa_t *)birg->main_env->arch_env; + ia32_isa_t *isa = (ia32_isa_t *)be_get_irg_arch_env(irg); ia32_code_gen_t *cg = XMALLOCZ(ia32_code_gen_t); cg->impl = &ia32_code_gen_if; - cg->irg = birg->irg; + cg->irg = irg; cg->isa = isa; - cg->birg = birg; cg->blk_sched = NULL; - cg->dump = (birg->main_env->options->dump_flags & DUMP_BE) ? 1 : 0; - cg->gprof = (birg->main_env->options->gprof) ? 1 : 0; + cg->dump = (be_get_irg_options(irg)->dump_flags & DUMP_BE) ? 1 : 0; + cg->gprof = (be_get_irg_options(irg)->gprof) ? 1 : 0; if (cg->gprof) { /* Linux gprof implementation needs base pointer */ - birg->main_env->options->omit_fp = 0; + be_get_irg_options(irg)->omit_fp = 0; } /* enter it */ @@ -1540,17 +1499,6 @@ static void *ia32_cg_init(be_irg_t *birg) } - -/***************************************************************** - * ____ _ _ _____ _____ - * | _ \ | | | | |_ _|/ ____| /\ - * | |_) | __ _ ___| | _____ _ __ __| | | | | (___ / \ - * | _ < / _` |/ __| |/ / _ \ '_ \ / _` | | | \___ \ / /\ \ - * | |_) | (_| | (__| < __/ | | | (_| | _| |_ ____) / ____ \ - * |____/ \__,_|\___|_|\_\___|_| |_|\__,_| |_____|_____/_/ \_\ - * - *****************************************************************/ - /** * Set output modes for GCC */ @@ -1593,6 +1541,7 @@ static ia32_isa_t ia32_isa_template = { NULL, /* main environment */ 7, /* costs for a spill instruction */ 5, /* costs for a reload instruction */ + false, /* no custom abi handling */ }, NULL, /* 16bit register names */ NULL, /* 8bit register names */ @@ -1671,7 +1620,7 @@ static arch_env_t *ia32_init(FILE *file_handle) isa = XMALLOC(ia32_isa_t); memcpy(isa, &ia32_isa_template, sizeof(*isa)); - if(mode_fpcw == NULL) { + if (mode_fpcw == NULL) { mode_fpcw = new_ir_mode("Fpcw", irms_int_number, 16, 0, irma_none, 0); } @@ -1710,7 +1659,7 @@ static arch_env_t *ia32_init(FILE *file_handle) /* needed for the debug support */ be_gas_emit_switch_section(GAS_SECTION_TEXT); - be_emit_cstring(".Ltext0:\n"); + be_emit_irprintf("%stext0:\n", be_gas_get_private_prefix()); be_emit_write_line(); return &isa->arch_env; @@ -1772,7 +1721,7 @@ static const arch_register_class_t *ia32_get_reg_class(unsigned i) * @param mode The mode in question. * @return A register class which can hold values of the given mode. */ -const arch_register_class_t *ia32_get_reg_class_for_mode(const ir_mode *mode) +static const arch_register_class_t *ia32_get_reg_class_for_mode(const ir_mode *mode) { if (mode_is_float(mode)) { return ia32_cg_config.use_sse2 ? &ia32_reg_classes[CLASS_ia32_xmm] : &ia32_reg_classes[CLASS_ia32_vfp]; @@ -1920,7 +1869,7 @@ static void ia32_get_call_abi(const void *self, ir_type *method_type, reg = ia32_get_RegParam_reg(cc, regnum, mode); } if (reg != NULL) { - be_abi_call_param_reg(abi, i, reg); + be_abi_call_param_reg(abi, i, reg, ABI_CONTEXT_BOTH); ++regnum; } else { /* Micro optimisation: if the mode is shorter than 4 bytes, load 4 bytes. @@ -1937,7 +1886,7 @@ static void ia32_get_call_abi(const void *self, ir_type *method_type, if (size < 4) load_mode = mode_Iu; } - be_abi_call_param_stack(abi, i, load_mode, 4, 0, 0); + be_abi_call_param_stack(abi, i, load_mode, 4, 0, 0, ABI_CONTEXT_BOTH); } } @@ -1960,8 +1909,8 @@ static void ia32_get_call_abi(const void *self, ir_type *method_type, assert(!mode_is_float(mode) && "mixed INT, FP results not supported"); - be_abi_call_res_reg(abi, 0, &ia32_gp_regs[REG_EAX]); - be_abi_call_res_reg(abi, 1, &ia32_gp_regs[REG_EDX]); + be_abi_call_res_reg(abi, 0, &ia32_gp_regs[REG_EAX], ABI_CONTEXT_BOTH); + be_abi_call_res_reg(abi, 1, &ia32_gp_regs[REG_EDX], ABI_CONTEXT_BOTH); } else if (n == 1) { const arch_register_t *reg; @@ -1972,22 +1921,20 @@ static void ia32_get_call_abi(const void *self, ir_type *method_type, reg = mode_is_float(mode) ? &ia32_vfp_regs[REG_VF0] : &ia32_gp_regs[REG_EAX]; - be_abi_call_res_reg(abi, 0, reg); + be_abi_call_res_reg(abi, 0, reg, ABI_CONTEXT_BOTH); } } -int ia32_to_appear_in_schedule(void *block_env, const ir_node *irn) +static int ia32_to_appear_in_schedule(void *block_env, const ir_node *irn) { (void) block_env; - if(!is_ia32_irn(irn)) { + if (!is_ia32_irn(irn)) { return -1; } - if(is_ia32_NoReg_GP(irn) || is_ia32_NoReg_VFP(irn) || is_ia32_NoReg_XMM(irn) - || is_ia32_Unknown_GP(irn) || is_ia32_Unknown_XMM(irn) - || is_ia32_Unknown_VFP(irn) || is_ia32_ChangeCW(irn) - || is_ia32_Immediate(irn)) + if (is_ia32_NoReg_GP(irn) || is_ia32_NoReg_VFP(irn) || is_ia32_NoReg_XMM(irn) + || is_ia32_ChangeCW(irn) || is_ia32_Immediate(irn)) return 0; return 1; @@ -2244,12 +2191,8 @@ static bool mux_is_set(ir_node *sel, ir_node *mux_true, ir_node *mux_false) && mode != mode_b) return false; - if (is_Const(mux_true) && is_Const_one(mux_true) - && is_Const(mux_false) && is_Const_null(mux_false)) { - return true; - } - if (is_Const(mux_true) && is_Const_null(mux_true) - && is_Const(mux_false) && is_Const_one(mux_false)) { + if (is_Const(mux_true) && is_Const(mux_false)) { + /* we can create a set plus up two 3 instructions for any combination of constants */ return true; } @@ -2393,17 +2336,17 @@ static ir_node *ia32_create_trampoline_fkt(ir_node *block, ir_node *mem, ir_node /* mov ecx, */ st = new_r_Store(block, mem, p, new_Const_long(mode_Bu, 0xb9), 0); - mem = new_r_Proj(block, st, mode_M, pn_Store_M); + mem = new_r_Proj(st, mode_M, pn_Store_M); p = new_r_Add(block, p, new_Const_long(mode_Iu, 1), mode); st = new_r_Store(block, mem, p, env, 0); - mem = new_r_Proj(block, st, mode_M, pn_Store_M); + mem = new_r_Proj(st, mode_M, pn_Store_M); p = new_r_Add(block, p, new_Const_long(mode_Iu, 4), mode); /* jmp */ st = new_r_Store(block, mem, p, new_Const_long(mode_Bu, 0xe9), 0); - mem = new_r_Proj(block, st, mode_M, pn_Store_M); + mem = new_r_Proj(st, mode_M, pn_Store_M); p = new_r_Add(block, p, new_Const_long(mode_Iu, 1), mode); st = new_r_Store(block, mem, p, callee, 0); - mem = new_r_Proj(block, st, mode_M, pn_Store_M); + mem = new_r_Proj(st, mode_M, pn_Store_M); p = new_r_Add(block, p, new_Const_long(mode_Iu, 4), mode); return mem; @@ -2510,6 +2453,7 @@ const arch_isa_if_t ia32_isa_if = { ia32_is_valid_clobber }; +BE_REGISTER_MODULE_CONSTRUCTOR(be_init_arch_ia32); void be_init_arch_ia32(void) { lc_opt_entry_t *be_grp = lc_opt_get_grp(firm_opt_get_root(), "be"); @@ -2527,5 +2471,3 @@ void be_init_arch_ia32(void) ia32_init_x87(); ia32_init_architecture(); } - -BE_REGISTER_MODULE_CONSTRUCTOR(be_init_arch_ia32);