Fix fehler139: Pass eflags input of Adc/Sbb to AM matcher.
[libfirm] / ir / be / ia32 / ia32_transform.c
index a4c75c1..76ae7d3 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;
 }
@@ -2205,8 +2224,7 @@ static ir_node *try_create_dest_am(ir_node *node) {
                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");
+                       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,
@@ -2324,20 +2342,22 @@ static int is_float_to_int32_conv(const ir_node *node)
  */
 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
 {
-       ir_mode  *mode      = get_irn_mode(cns);
-       unsigned size       = get_mode_size_bytes(mode);
-       tarval   *tv        = get_Const_tarval(cns);
-       ir_node  *block     = get_nodes_block(node);
-       ir_node  *new_block = be_transform_node(block);
-       ir_node  *ptr       = get_Store_ptr(node);
-       ir_node  *mem       = get_Store_mem(node);
-       ir_graph *irg       = current_ir_graph;
-       dbg_info *dbgi      = get_irn_dbg_info(node);
-       int      ofs        = 0;
-       ir_node  *new_node;
-       ia32_address_t addr;
+       ir_mode        *mode      = get_irn_mode(cns);
+       unsigned        size      = get_mode_size_bytes(mode);
+       tarval         *tv        = get_Const_tarval(cns);
+       ir_node        *block     = get_nodes_block(node);
+       ir_node        *new_block = be_transform_node(block);
+       ir_node        *ptr       = get_Store_ptr(node);
+       ir_node        *mem       = get_Store_mem(node);
+       ir_graph       *irg       = current_ir_graph;
+       dbg_info       *dbgi      = get_irn_dbg_info(node);
+       int             ofs       = 0;
+       size_t          i         = 0;
+       ir_node        *ins[4];
+       ia32_address_t  addr;
 
-       assert(size % 4 == 0);
+       assert(size % 4 ==  0);
+       assert(size     <= 16);
 
        build_address_ptr(&addr, ptr, mem);
 
@@ -2349,7 +2369,7 @@ static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
                        (get_tarval_sub_bits(tv, ofs + 3) << 24);
                ir_node *imm = create_Immediate(NULL, 0, val);
 
-               new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
+               ir_node *new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
                        addr.index, addr.mem, imm);
 
                set_irn_pinned(new_node, get_irn_pinned(node));
@@ -2358,13 +2378,14 @@ static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
                set_address(new_node, &addr);
                SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
 
+               ins[i++] = new_node;
+
                size        -= 4;
                ofs         += 4;
                addr.offset += 4;
-               addr.mem     = new_node;
        } while (size != 0);
 
-       return new_node;
+       return i == 1 ? ins[0] : new_rd_Sync(dbgi, irg, new_block, i, ins);
 }
 
 /**
@@ -2503,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) {