Merge ia32_am_type_t and ia32_am_arity_t, because (type == ia32_am_None) == (arity...
[libfirm] / ir / be / ia32 / ia32_transform.c
index 2396a3b..6c33567 100644 (file)
@@ -433,44 +433,6 @@ ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct) {
        return ent_cache[kct];
 }
 
-static int prevents_AM(ir_node *const block, ir_node *const am_candidate,
-                       ir_node *const other)
-{
-       if (get_nodes_block(other) != block)
-               return 0;
-
-       if (is_Sync(other)) {
-               int i;
-
-               for (i = get_Sync_n_preds(other) - 1; i >= 0; --i) {
-                       ir_node *const pred = get_Sync_pred(other, i);
-
-                       if (get_nodes_block(pred) != block)
-                               continue;
-
-                       /* Do not block ourselves from getting eaten */
-                       if (is_Proj(pred) && get_Proj_pred(pred) == am_candidate)
-                               continue;
-
-                       if (!heights_reachable_in_block(heights, pred, am_candidate))
-                               continue;
-
-                       return 1;
-               }
-
-               return 0;
-       } else {
-               /* Do not block ourselves from getting eaten */
-               if (is_Proj(other) && get_Proj_pred(other) == am_candidate)
-                       return 0;
-
-               if (!heights_reachable_in_block(heights, other, am_candidate))
-                       return 0;
-
-               return 1;
-       }
-}
-
 /**
  * return true if the node is a Proj(Load) and could be used in source address
  * mode for another node. Will return only true if the @p other node is not
@@ -775,20 +737,19 @@ static void match_arguments(ia32_address_mode_t *am, ir_node *block,
                }
                am->op_type = ia32_AddrModeS;
        } else {
+               am->op_type = ia32_Normal;
+
                if (flags & match_try_am) {
                        am->new_op1 = NULL;
                        am->new_op2 = NULL;
-                       am->op_type = ia32_Normal;
                        return;
                }
 
                new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
                if (new_op2 == NULL)
                        new_op2 = be_transform_node(op2);
-               am->op_type = ia32_Normal;
-               am->ls_mode = get_irn_mode(op2);
-               if (flags & match_mode_neutral)
-                       am->ls_mode = mode_Iu;
+               am->ls_mode =
+                       (flags & match_mode_neutral ? mode_Iu : get_irn_mode(op2));
        }
        if (addr->base == NULL)
                addr->base = noreg_gp;
@@ -858,7 +819,7 @@ static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
        set_am_attributes(new_node, &am);
        /* we can't use source address mode anymore when using immediates */
        if (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
-               set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
+               set_ia32_am_support(new_node, ia32_am_none);
        SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
 
        new_node = fix_mem_proj(new_node, &am);
@@ -908,7 +869,7 @@ static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
        set_am_attributes(new_node, &am);
        /* we can't use source address mode anymore when using immediates */
        if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
-               set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
+               set_ia32_am_support(new_node, ia32_am_none);
        SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
 
        new_node = fix_mem_proj(new_node, &am);
@@ -1248,7 +1209,7 @@ static ir_node *gen_Mulh(ir_node *node)
        set_am_attributes(new_node, &am);
        /* we can't use source address mode anymore when using immediates */
        if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
-               set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
+               set_ia32_am_support(new_node, ia32_am_none);
        SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
 
        assert(get_irn_mode(new_node) == mode_T);
@@ -2738,6 +2699,9 @@ static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
        if (get_mode_size_bits(mode) >= 32)
                return true;
 
+       if (is_Proj(transformed_node))
+               return upper_bits_clean(get_Proj_pred(transformed_node), mode);
+
        if (is_ia32_Conv_I2I(transformed_node)
                        || is_ia32_Conv_I2I8Bit(transformed_node)) {
                ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
@@ -2759,6 +2723,7 @@ static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
                                return true;
                        }
                }
+               return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
        }
 
        if (is_ia32_And(transformed_node) && !mode_is_signed(mode)) {
@@ -2772,8 +2737,11 @@ static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
                                return true;
                        }
                }
+               /* TODO recurse? */
        }
 
+       /* TODO recurse on Or, Xor, ... if appropriate? */
+
        if (is_ia32_Immediate(transformed_node)
                        || is_ia32_Const(transformed_node)) {
                const ia32_immediate_attr_t *attr
@@ -2843,8 +2811,8 @@ static ir_node *gen_Cmp(ir_node *node)
                                                                                match_8bit | match_16bit);
 
                /* use 32bit compare mode if possible since the opcode is smaller */
-               if (upper_bits_clean(am.new_op1, cmp_mode)
-                               && upper_bits_clean(am.new_op2, cmp_mode)) {
+               if (upper_bits_clean(am.new_op1, cmp_mode) &&
+                   upper_bits_clean(am.new_op2, cmp_mode)) {
                        cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
                }
 
@@ -2866,8 +2834,8 @@ static ir_node *gen_Cmp(ir_node *node)
                                match_16bit_am | match_am_and_immediates |
                                match_immediate | match_8bit | match_16bit);
                /* use 32bit compare mode if possible since the opcode is smaller */
-               if (upper_bits_clean(am.new_op1, cmp_mode)
-                               && upper_bits_clean(am.new_op2, cmp_mode)) {
+               if (upper_bits_clean(am.new_op1, cmp_mode) &&
+                   upper_bits_clean(am.new_op2, cmp_mode)) {
                        cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
                }