Use backtracking in find_original_value() for the flags emitter.
[libfirm] / ir / be / ia32 / ia32_transform.c
index fe10f5f..7309ca2 100644 (file)
@@ -883,16 +883,16 @@ static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
        ir_node             *src_block  = get_nodes_block(node);
        ir_node             *op1        = get_irn_n(node, n_ia32_l_binop_left);
        ir_node             *op2        = get_irn_n(node, n_ia32_l_binop_right);
+       ir_node             *eflags     = get_irn_n(node, n_ia32_l_binop_eflags);
        dbg_info            *dbgi;
-       ir_node             *block, *new_node, *eflags, *new_eflags;
+       ir_node             *block, *new_node, *new_eflags;
        ia32_address_mode_t  am;
        ia32_address_t      *addr       = &am.addr;
 
-       match_arguments(&am, src_block, op1, op2, NULL, flags);
+       match_arguments(&am, src_block, op1, op2, eflags, flags);
 
        dbgi       = get_irn_dbg_info(node);
        block      = be_transform_node(src_block);
-       eflags     = get_irn_n(node, n_ia32_l_binop_eflags);
        new_eflags = be_transform_node(eflags);
        new_node   = func(dbgi, current_ir_graph, block, addr->base, addr->index,
                        addr->mem, am.new_op1, am.new_op2, new_eflags);
@@ -1974,30 +1974,49 @@ static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
 {
        ir_node *load;
 
-       if(!is_Proj(node))
+       if (!is_Proj(node))
                return 0;
 
        /* we only use address mode if we're the only user of the load */
-       if(get_irn_n_edges(node) > 1)
+       if (get_irn_n_edges(node) > 1)
                return 0;
 
        load = get_Proj_pred(node);
-       if(!is_Load(load))
+       if (!is_Load(load))
                return 0;
-       if(get_nodes_block(load) != block)
+       if (get_nodes_block(load) != block)
                return 0;
 
-       /* Store should be attached to the load */
-       if(!is_Proj(mem) || get_Proj_pred(mem) != load)
-               return 0;
        /* store should have the same pointer as the load */
-       if(get_Load_ptr(load) != ptr)
+       if (get_Load_ptr(load) != ptr)
                return 0;
 
        /* don't do AM if other node inputs depend on the load (via mem-proj) */
-       if(other != NULL && get_nodes_block(other) == block
-                       && heights_reachable_in_block(heights, other, load))
+       if (other != NULL                   &&
+           get_nodes_block(other) == block &&
+           heights_reachable_in_block(heights, other, load)) {
                return 0;
+       }
+
+       if (is_Sync(mem)) {
+               int i;
+
+               for (i = get_Sync_n_preds(mem) - 1; i >= 0; --i) {
+                       ir_node *const pred = get_Sync_pred(mem, i);
+
+                       if (is_Proj(pred) && get_Proj_pred(pred) == load)
+                               continue;
+
+                       if (get_nodes_block(pred) == block &&
+                           heights_reachable_in_block(heights, pred, load)) {
+                               return 0;
+                       }
+               }
+       } else {
+               /* Store should be attached to the load */
+               if (!is_Proj(mem) || get_Proj_pred(mem) != load)
+                       return 0;
+       }
 
        return 1;
 }
@@ -2204,9 +2223,8 @@ static ir_node *try_create_dest_am(ir_node *node) {
        case iro_Sub:
                op1      = get_Sub_left(val);
                op2      = get_Sub_right(val);
-               if(is_Const(op2)) {
-                       ir_fprintf(stderr, "Optimisation warning: not-normalize sub ,C"
-                                  "found\n");
+               if (is_Const(op2) && !mode_is_float(mode)) {
+                       ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
                }
                new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
                                         new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit,
@@ -2506,7 +2524,7 @@ static ir_node *gen_Store(ir_node *node)
        ir_mode  *mode = get_irn_mode(val);
 
        if (mode_is_float(mode) && is_Const(val)) {
-               int transform = 1;
+               int transform;
 
                /* we are storing a floating point constant */
                if (ia32_cg_config.use_sse2) {
@@ -3312,7 +3330,8 @@ static ir_node *gen_Conv(ir_node *node) {
                                        switch (get_mode_size_bits(tgt_mode)) {
                                                case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
                                                case 64: float_mantissa = 52 + 1; break;
-                                               case 80: float_mantissa = 64 + 1; break;
+                                               case 80:
+                                               case 96: float_mantissa = 64;     break;
                                                default: float_mantissa = 0;      break;
                                        }
                                        if (float_mantissa < int_mantissa) {