Use backtracking in find_original_value() for the flags emitter.
[libfirm] / ir / be / ia32 / bearch_ia32.c
index 4410ce6..5923ae9 100644 (file)
@@ -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;
@@ -927,14 +927,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 +970,7 @@ static void ia32_prepare_graph(void *self) {
                        break;
 #endif
 
-               default: panic("Invalid tansformer");
+               default: panic("invalid transformer");
        }
 
        /* do local optimizations (mainly CSE) */
@@ -1864,7 +1857,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 +1867,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 +1877,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 +1887,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 +1907,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);