X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fbearch_ia32.c;h=1db15bf5b0a66ff46c95b909ebf5f9d9d55b755b;hb=577e990a5c85673d69ff5eee46d438be2bf50f44;hp=c1461e1b104f1baf0a5ae21b1443ca5ff0e94353;hpb=920ea4afea0593c9f59091881774a3b1c6bc3336;p=libfirm diff --git a/ir/be/ia32/bearch_ia32.c b/ir/be/ia32/bearch_ia32.c index c1461e1b1..1db15bf5b 100644 --- a/ir/be/ia32/bearch_ia32.c +++ b/ir/be/ia32/bearch_ia32.c @@ -486,7 +486,6 @@ 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, irg, bl, curr_sp, BE_STACK_FRAME_SIZE_SHRINK, 0); - add_irn_dep(curr_sp, *mem); } else { ir_mode *mode_bp = arch_env->bp->reg_class->mode; @@ -630,9 +629,10 @@ static int ia32_get_op_estimated_cost(const ir_node *irn) (we assume they are in cache), other memory operations cost 20 cycles. */ - if(is_ia32_use_frame(irn) || - (is_ia32_NoReg_GP(get_irn_n(irn, 0)) && - is_ia32_NoReg_GP(get_irn_n(irn, 1)))) { + if (is_ia32_use_frame(irn) || ( + is_ia32_NoReg_GP(get_irn_n(irn, n_ia32_base)) && + is_ia32_NoReg_GP(get_irn_n(irn, n_ia32_index)) + )) { cost += 5; } else { cost += 20; @@ -839,6 +839,9 @@ static int ia32_possible_memory_operand(const ir_node *irn, unsigned int i) { static void ia32_perform_memory_operand(ir_node *irn, ir_node *spill, unsigned int i) { + ir_mode *load_mode; + ir_mode *dest_op_mode; + ia32_code_gen_t *cg = ia32_current_cg; assert(ia32_possible_memory_operand(irn, i) && "Cannot perform memory operand change"); @@ -848,13 +851,19 @@ static void ia32_perform_memory_operand(ir_node *irn, ir_node *spill, } set_ia32_op_type(irn, ia32_AddrModeS); - set_ia32_ls_mode(irn, get_irn_mode(get_irn_n(irn, i))); + + load_mode = get_irn_mode(get_irn_n(irn, i)); + dest_op_mode = get_ia32_ls_mode(irn); + if (get_mode_size_bits(load_mode) <= get_mode_size_bits(dest_op_mode)) { + set_ia32_ls_mode(irn, load_mode); + } set_ia32_use_frame(irn); set_ia32_need_stackent(irn); set_irn_n(irn, n_ia32_base, get_irg_frame(get_irn_irg(irn))); set_irn_n(irn, n_ia32_binary_right, ia32_get_admissible_noreg(cg, irn, n_ia32_binary_right)); set_irn_n(irn, n_ia32_mem, spill); + set_ia32_is_reload(irn); /* immediates are only allowed on the right side */ if (i == n_ia32_binary_left && is_ia32_Immediate(get_irn_n(irn, n_ia32_binary_left))) { @@ -927,14 +936,7 @@ static void ia32_before_abi(void *self) { } } -typedef enum transformer_t { - TRANSFORMER_DEFAULT, -#ifdef FIRM_GRGEN_BE - TRANSFORMER_PBQP -#endif -} transformer_t; - -static transformer_t be_transformer = TRANSFORMER_DEFAULT; +transformer_t be_transformer = TRANSFORMER_DEFAULT; /** * Transforms the standard firm graph into @@ -977,7 +979,7 @@ static void ia32_prepare_graph(void *self) { break; #endif - default: panic("Invalid transformer"); + default: panic("invalid transformer"); } /* do local optimizations (mainly CSE) */ @@ -1432,7 +1434,11 @@ static void ia32_collect_frame_entity_nodes(ir_node *node, void *data) if (is_ia32_need_stackent(node) || is_ia32_Load(node)) { const ir_mode *mode = get_ia32_ls_mode(node); const ia32_attr_t *attr = get_ia32_attr_const(node); - int align = get_mode_size_bytes(mode); + int align; + + if (is_ia32_is_reload(node)) { + mode = get_spill_mode_mode(mode); + } if(attr->data.need_64bit_stackent) { mode = mode_Ls; @@ -1440,6 +1446,7 @@ static void ia32_collect_frame_entity_nodes(ir_node *node, void *data) if(attr->data.need_32bit_stackent) { mode = mode_Is; } + align = get_mode_size_bytes(mode); be_node_needs_frame_entity(env, node, mode, align); } else if (is_ia32_vfild(node) || is_ia32_xLoad(node) || is_ia32_vfld(node)) { @@ -1864,7 +1871,9 @@ static void ia32_get_call_abi(const void *self, ir_type *method_type, ir_mode *mode; unsigned cc; int n, i, regnum; + int pop_amount = 0; be_abi_call_flags_t call_flags = be_abi_call_get_flags(abi); + (void) self; /* set abi flags for calls */ @@ -1872,7 +1881,7 @@ static void ia32_get_call_abi(const void *self, ir_type *method_type, call_flags.bits.store_args_sequential = 0; /* call_flags.bits.try_omit_fp not changed: can handle both settings */ call_flags.bits.fp_free = 0; /* the frame pointer is fixed in IA32 */ - call_flags.bits.call_has_imm = 1; /* IA32 calls can have immediate address */ + call_flags.bits.call_has_imm = 1; /* No call immediates, we handle this by ourselves */ /* set parameter passing style */ be_abi_call_set_flags(abi, call_flags, &ia32_abi_callbacks); @@ -1882,8 +1891,8 @@ static void ia32_get_call_abi(const void *self, ir_type *method_type, cc = cc_cdecl_set; } else { cc = get_method_calling_convention(method_type); - if (get_method_additional_properties(method_type) & mtp_property_private - && (ia32_cg_config.optimize_cc)) { + if (get_method_additional_properties(method_type) & mtp_property_private && + ia32_cg_config.optimize_cc) { /* set the calling conventions to register parameter */ cc = (cc & ~cc_bits) | cc_reg_param; } @@ -1892,7 +1901,7 @@ static void ia32_get_call_abi(const void *self, ir_type *method_type, /* we have to pop the shadow parameter ourself for compound calls */ if( (get_method_calling_convention(method_type) & cc_compound_ret) && !(cc & cc_reg_param)) { - be_abi_call_set_pop(abi, get_mode_size_bytes(mode_P_data)); + pop_amount += get_mode_size_bytes(mode_P_data); } n = get_method_n_params(method_type); @@ -1912,11 +1921,23 @@ static void ia32_get_call_abi(const void *self, ir_type *method_type, /* Micro optimisation: if the mode is shorter than 4 bytes, load 4 bytes. * movl has a shorter opcode than mov[sz][bw]l */ ir_mode *load_mode = mode; - if (mode != NULL && get_mode_size_bytes(mode) < 4) load_mode = mode_Iu; + + if (mode != NULL) { + unsigned size = get_mode_size_bytes(mode); + + if (cc & cc_callee_clear_stk) { + pop_amount += (size + 3U) & ~3U; + } + + if (size < 4) load_mode = mode_Iu; + } + be_abi_call_param_stack(abi, i, load_mode, 4, 0, 0); } } + be_abi_call_set_pop(abi, pop_amount); + /* set return registers */ n = get_method_n_ress(method_type);