sparc: Improve handling of MemPerm nodes.
[libfirm] / ir / be / ia32 / ia32_transform.c
index 803a4d3..a06ccd3 100644 (file)
@@ -225,7 +225,6 @@ static ir_node *gen_Const(ir_node *node)
        if (mode_is_float(mode)) {
                ir_node   *res   = NULL;
                ir_node   *load;
-               ir_node   *base;
                ir_entity *floatent;
 
                if (ia32_cg_config.use_sse2) {
@@ -260,6 +259,7 @@ static ir_node *gen_Const(ir_node *node)
                                set_ia32_ls_mode(load, mode);
                                res = load;
                        } else {
+                               ir_node *base;
 #ifdef CONSTRUCT_SSE_CONST
                                if (mode == mode_D) {
                                        unsigned val = get_tarval_sub_bits(tv, 0) |
@@ -292,7 +292,7 @@ static ir_node *gen_Const(ir_node *node)
                                                             mode);
                                set_ia32_op_type(load, ia32_AddrModeS);
                                set_ia32_am_sc(load, floatent);
-                               arch_irn_add_flags(load, arch_irn_flags_rematerializable);
+                               arch_add_irn_flags(load, arch_irn_flags_rematerializable);
                                res = new_r_Proj(load, mode_xmm, pn_ia32_xLoad_res);
                        }
                } else {
@@ -317,7 +317,7 @@ static ir_node *gen_Const(ir_node *node)
                                                            ls_mode);
                                set_ia32_op_type(load, ia32_AddrModeS);
                                set_ia32_am_sc(load, floatent);
-                               arch_irn_add_flags(load, arch_irn_flags_rematerializable);
+                               arch_add_irn_flags(load, arch_irn_flags_rematerializable);
                                res = new_r_Proj(load, mode_vfp, pn_ia32_vfld_res);
                        }
                }
@@ -881,7 +881,6 @@ static void match_arguments(ia32_address_mode_t *am, ir_node *block,
                }
                am->op_type = ia32_AddrModeS;
        } else {
-               ir_mode *mode;
                am->op_type = ia32_Normal;
 
                if (flags & match_try_am) {
@@ -1112,15 +1111,19 @@ static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
 {
        dbg_info *dbgi;
        ir_node  *block, *new_block, *new_op1, *new_op2, *new_node;
+       ir_mode  *mode = get_irn_mode(node);
 
-       assert(! mode_is_float(get_irn_mode(node)));
+       assert(! mode_is_float(mode));
        assert(flags & match_immediate);
        assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
 
+       if (get_mode_modulo_shift(mode) != 32)
+               panic("modulo shift!=32 not supported by ia32 backend");
+
        if (flags & match_mode_neutral) {
                op1     = ia32_skip_downconv(op1);
                new_op1 = be_transform_node(op1);
-       } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
+       } else if (get_mode_size_bits(mode) != 32) {
                new_op1 = create_upconv(op1, node);
        } else {
                new_op1 = be_transform_node(op1);
@@ -1190,7 +1193,9 @@ static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
                                         ia32_address_t *addr)
 {
-       ir_node *base, *index, *res;
+       ir_node *base;
+       ir_node *idx;
+       ir_node *res;
 
        base = addr->base;
        if (base == NULL) {
@@ -1199,11 +1204,11 @@ static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
                base = be_transform_node(base);
        }
 
-       index = addr->index;
-       if (index == NULL) {
-               index = noreg_GP;
+       idx = addr->index;
+       if (idx == NULL) {
+               idx = noreg_GP;
        } else {
-               index = be_transform_node(index);
+               idx = be_transform_node(idx);
        }
 
        /* segment overrides are ineffective for Leas :-( so we have to patch
@@ -1218,7 +1223,7 @@ static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
                addr->tls_segment = false;
        }
 
-       res = new_bd_ia32_Lea(dbgi, block, base, index);
+       res = new_bd_ia32_Lea(dbgi, block, base, idx);
        set_address(res, addr);
 
        return res;
@@ -1962,43 +1967,41 @@ static ir_node *gen_Not(ir_node *node)
        return gen_unop(node, op, new_bd_ia32_Not, match_mode_neutral);
 }
 
-static ir_node *create_abs(dbg_info *dbgi, ir_node *block, ir_node *op,
-                           bool negate, ir_node *node)
+static ir_node *create_float_abs(dbg_info *dbgi, ir_node *block, ir_node *op,
+                                 bool negate, ir_node *node)
 {
        ir_node   *new_block = be_transform_node(block);
        ir_mode   *mode      = get_irn_mode(op);
-       ir_node   *new_op;
+       ir_node   *new_op    = be_transform_node(op);
        ir_node   *new_node;
        int        size;
        ir_entity *ent;
 
-       if (mode_is_float(mode)) {
-               new_op = be_transform_node(op);
+       assert(mode_is_float(mode));
 
-               if (ia32_cg_config.use_sse2) {
-                       ir_node *noreg_fp = ia32_new_NoReg_xmm(current_ir_graph);
-                       new_node = new_bd_ia32_xAnd(dbgi, new_block, get_symconst_base(),
-                                                   noreg_GP, nomem, new_op, noreg_fp);
+       if (ia32_cg_config.use_sse2) {
+               ir_node *noreg_fp = ia32_new_NoReg_xmm(current_ir_graph);
+               new_node = new_bd_ia32_xAnd(dbgi, new_block, get_symconst_base(),
+                                                                       noreg_GP, nomem, new_op, noreg_fp);
 
-                       size = get_mode_size_bits(mode);
-                       ent  = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
+               size = get_mode_size_bits(mode);
+               ent  = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
 
-                       set_ia32_am_sc(new_node, ent);
+               set_ia32_am_sc(new_node, ent);
 
-                       SET_IA32_ORIG_NODE(new_node, node);
+               SET_IA32_ORIG_NODE(new_node, node);
 
-                       set_ia32_op_type(new_node, ia32_AddrModeS);
-                       set_ia32_ls_mode(new_node, mode);
+               set_ia32_op_type(new_node, ia32_AddrModeS);
+               set_ia32_ls_mode(new_node, mode);
 
-                       /* TODO, implement -Abs case */
-                       assert(!negate);
-               } else {
-                       new_node = new_bd_ia32_vfabs(dbgi, new_block, new_op);
+               /* TODO, implement -Abs case */
+               assert(!negate);
+       } else {
+               new_node = new_bd_ia32_vfabs(dbgi, new_block, new_op);
+               SET_IA32_ORIG_NODE(new_node, node);
+               if (negate) {
+                       new_node = new_bd_ia32_vfchs(dbgi, new_block, new_node);
                        SET_IA32_ORIG_NODE(new_node, node);
-                       if (negate) {
-                               new_node = new_bd_ia32_vfchs(dbgi, new_block, new_node);
-                               SET_IA32_ORIG_NODE(new_node, node);
-                       }
                }
        }
 
@@ -2095,17 +2098,6 @@ static ia32_condition_code_t relation_to_condition_code(ir_relation relation,
        }
 }
 
-static ir_node *get_flags_mode_b(ir_node *node, ia32_condition_code_t *cc_out)
-{
-       /* a mode_b value, we have to compare it against 0 */
-       dbg_info *dbgi      = get_irn_dbg_info(node);
-       ir_node  *new_block = be_transform_node(get_nodes_block(node));
-       ir_node  *new_op    = be_transform_node(node);
-       ir_node  *flags     = new_bd_ia32_Test(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_op, new_op, false);
-       *cc_out  = ia32_cc_not_equal;
-       return flags;
-}
-
 static ir_node *get_flags_node_cmp(ir_node *cmp, ia32_condition_code_t *cc_out)
 {
        /* must have a Cmp as input */
@@ -2167,10 +2159,8 @@ static ir_node *get_flags_node_cmp(ir_node *cmp, ia32_condition_code_t *cc_out)
  */
 static ir_node *get_flags_node(ir_node *node, ia32_condition_code_t *cc_out)
 {
-       if (is_Cmp(node))
-               return get_flags_node_cmp(node, cc_out);
-       assert(get_irn_mode(node) == mode_b);
-       return get_flags_mode_b(node, cc_out);
+       assert(is_Cmp(node));
+       return get_flags_node_cmp(node, cc_out);
 }
 
 /**
@@ -2189,15 +2179,15 @@ static ir_node *gen_Load(ir_node *node)
        ir_mode  *mode      = get_Load_mode(node);
        int       throws_exception = ir_throws_exception(node);
        ir_node  *base;
-       ir_node  *index;
+       ir_node  *idx;
        ir_node  *new_node;
        ia32_address_t addr;
 
        /* construct load address */
        memset(&addr, 0, sizeof(addr));
        ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
-       base  = addr.base;
-       index = addr.index;
+       base = addr.base;
+       idx  = addr.index;
 
        if (base == NULL) {
                base = noreg_GP;
@@ -2205,18 +2195,18 @@ static ir_node *gen_Load(ir_node *node)
                base = be_transform_node(base);
        }
 
-       if (index == NULL) {
-               index = noreg_GP;
+       if (idx == NULL) {
+               idx = noreg_GP;
        } else {
-               index = be_transform_node(index);
+               idx = be_transform_node(idx);
        }
 
        if (mode_is_float(mode)) {
                if (ia32_cg_config.use_sse2) {
-                       new_node = new_bd_ia32_xLoad(dbgi, block, base, index, new_mem,
+                       new_node = new_bd_ia32_xLoad(dbgi, block, base, idx, new_mem,
                                                     mode);
                } else {
-                       new_node = new_bd_ia32_vfld(dbgi, block, base, index, new_mem,
+                       new_node = new_bd_ia32_vfld(dbgi, block, base, idx, new_mem,
                                                    mode);
                }
        } else {
@@ -2224,10 +2214,10 @@ static ir_node *gen_Load(ir_node *node)
 
                /* create a conv node with address mode for smaller modes */
                if (get_mode_size_bits(mode) < 32) {
-                       new_node = new_bd_ia32_Conv_I2I(dbgi, block, base, index,
+                       new_node = new_bd_ia32_Conv_I2I(dbgi, block, base, idx,
                                                        new_mem, noreg_GP, mode);
                } else {
-                       new_node = new_bd_ia32_Load(dbgi, block, base, index, new_mem);
+                       new_node = new_bd_ia32_Load(dbgi, block, base, idx, new_mem);
                }
        }
        ir_set_throws_exception(new_node, throws_exception);
@@ -2241,7 +2231,7 @@ static ir_node *gen_Load(ir_node *node)
                assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
                                && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
                                && (int)pn_ia32_Load_res == (int)pn_ia32_res);
-               arch_irn_add_flags(new_node, arch_irn_flags_rematerializable);
+               arch_add_irn_flags(new_node, arch_irn_flags_rematerializable);
        }
 
        SET_IA32_ORIG_NODE(new_node, node);
@@ -2642,7 +2632,7 @@ static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
 
                ir_node *new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
                        addr.index, addr.mem, imm);
-               ir_node *mem      = new_r_Proj(new_node, mode_M, pn_ia32_Store_M);
+               ir_node *new_mem  = new_r_Proj(new_node, mode_M, pn_ia32_Store_M);
 
                ir_set_throws_exception(new_node, throws_exception);
                set_irn_pinned(new_node, get_irn_pinned(node));
@@ -2652,7 +2642,7 @@ static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
                SET_IA32_ORIG_NODE(new_node, node);
 
                assert(i < 4);
-               ins[i++] = mem;
+               ins[i++] = new_mem;
 
                size        -= 4;
                ofs         += 4;
@@ -2838,6 +2828,8 @@ static ir_node *create_Switch(ir_node *node)
        set_ia32_op_type(new_node, ia32_AddrModeS);
        set_ia32_ls_mode(new_node, mode_Iu);
        SET_IA32_ORIG_NODE(new_node, node);
+       // FIXME This seems wrong. GCC uses PIC for switch on OS X.
+       get_ia32_attr(new_node)->data.am_sc_no_pic_adjust = true;
 
        return new_node;
 }
@@ -3016,7 +3008,8 @@ static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
                                return shifted == 0 || shifted == -1;
                        } else {
                                unsigned long shifted = (unsigned long)attr->offset;
-                               shifted >>= get_mode_size_bits(mode);
+                               shifted >>= get_mode_size_bits(mode)-1;
+                               shifted >>= 1;
                                return shifted == 0;
                        }
                }
@@ -3404,11 +3397,11 @@ static void find_const_transform(ia32_condition_code_t cc,
                                ++step;
                                res->steps[step].transform = SETCC_TR_NEG;
                        } else {
-                               int v = get_tarval_lowest_bit(t);
-                               assert(v >= 0);
+                               int val = get_tarval_lowest_bit(t);
+                               assert(val >= 0);
 
                                res->steps[step].transform = SETCC_TR_SHL;
-                               res->steps[step].scale     = v;
+                               res->steps[step].scale     = val;
                        }
                }
                ++step;
@@ -3447,7 +3440,7 @@ static ir_node *gen_Mux(ir_node *node)
                                   node);
                } else {
                        ir_node *op = ir_get_abs_op(sel, mux_true, mux_false);
-                       return create_abs(dbgi, block, op, is_abs < 0, node);
+                       return create_float_abs(dbgi, block, op, is_abs < 0, node);
                }
        }
 
@@ -3649,6 +3642,18 @@ static ir_node *gen_Mux(ir_node *node)
        }
 }
 
+static ir_node *gen_ia32_l_Setcc(ir_node *node)
+{
+       ia32_condition_code_t cc;
+       dbg_info *dbgi      = get_irn_dbg_info(node);
+       ir_node  *block     = get_nodes_block(node);
+       ir_node  *new_block = be_transform_node(block);
+       ir_node  *cond      = get_irn_n(node, n_ia32_l_Setcc_cond);
+       ir_node  *flags     = get_flags_node(cond, &cc);
+       ir_node  *new_node  = new_bd_ia32_Setcc(dbgi, new_block, flags, cc);
+       SET_IA32_ORIG_NODE(new_node, node);
+       return new_node;
+}
 
 /**
  * Create a conversion from x87 state register to general purpose.
@@ -3924,7 +3929,7 @@ static ir_node *gen_Conv(ir_node *node)
                        }
                } else {
                        /* this should be optimized already, but who knows... */
-                       DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
+                       DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node);)
                        DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
                        return be_transform_node(op);
                }
@@ -4136,8 +4141,8 @@ static ir_node *gen_be_AddSP(ir_node *node)
        ir_node *new_node = gen_binop(node, sp, sz, new_bd_ia32_SubSP,
                                      match_am | match_immediate);
        assert(is_ia32_SubSP(new_node));
-       arch_irn_set_register(new_node, pn_ia32_SubSP_stack,
-                             &ia32_registers[REG_ESP]);
+       arch_set_irn_register_out(new_node, pn_ia32_SubSP_stack,
+                                 &ia32_registers[REG_ESP]);
        return new_node;
 }
 
@@ -4152,8 +4157,8 @@ static ir_node *gen_be_SubSP(ir_node *node)
        ir_node *new_node = gen_binop(node, sp, sz, new_bd_ia32_AddSP,
                                      match_am | match_immediate);
        assert(is_ia32_AddSP(new_node));
-       arch_irn_set_register(new_node, pn_ia32_AddSP_stack,
-                             &ia32_registers[REG_ESP]);
+       arch_set_irn_register_out(new_node, pn_ia32_AddSP_stack,
+                                 &ia32_registers[REG_ESP]);
        return new_node;
 }
 
@@ -4194,7 +4199,7 @@ static ir_node *gen_Phi(ir_node *node)
        copy_node_attr(irg, node, phi);
        be_duplicate_deps(node, phi);
 
-       arch_set_out_register_req(phi, 0, req);
+       arch_set_irn_register_req_out(phi, 0, req);
 
        be_enqueue_preds(node);
 
@@ -4836,7 +4841,8 @@ static ir_node *gen_be_Call(ir_node *node)
        i    = get_irn_arity(node) - 1;
        fpcw = be_transform_node(get_irn_n(node, i--));
        for (; i >= n_be_Call_first_arg; --i) {
-               arch_register_req_t const *const req = arch_get_register_req(node, i);
+               arch_register_req_t const *const req
+                       = arch_get_irn_register_req_in(node, i);
                ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
 
                assert(req->type == arch_register_req_type_limited);
@@ -4932,7 +4938,7 @@ static ir_node *gen_return_address(ir_node *node)
                assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
                                && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
                                && (int)pn_ia32_Load_res == (int)pn_ia32_res);
-               arch_irn_add_flags(load, arch_irn_flags_rematerializable);
+               arch_add_irn_flags(load, arch_irn_flags_rematerializable);
        }
 
        SET_IA32_ORIG_NODE(load, node);
@@ -4983,7 +4989,7 @@ static ir_node *gen_frame_address(ir_node *node)
                assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
                                && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
                                && (int)pn_ia32_Load_res == (int)pn_ia32_res);
-               arch_irn_add_flags(load, arch_irn_flags_rematerializable);
+               arch_add_irn_flags(load, arch_irn_flags_rematerializable);
        }
 
        SET_IA32_ORIG_NODE(load, node);
@@ -4996,7 +5002,7 @@ static ir_node *gen_frame_address(ir_node *node)
 static ir_node *gen_prefetch(ir_node *node)
 {
        dbg_info       *dbgi;
-       ir_node        *ptr, *block, *mem, *base, *index;
+       ir_node        *ptr, *block, *mem, *base, *idx;
        ir_node        *param,  *new_node;
        long           rw, locality;
        ir_tarval      *tv;
@@ -5015,8 +5021,8 @@ static ir_node *gen_prefetch(ir_node *node)
        memset(&addr, 0, sizeof(addr));
        ptr = get_Builtin_param(node, 0);
        ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
-       base  = addr.base;
-       index = addr.index;
+       base = addr.base;
+       idx  = addr.index;
 
        if (base == NULL) {
                base = noreg_GP;
@@ -5024,10 +5030,10 @@ static ir_node *gen_prefetch(ir_node *node)
                base = be_transform_node(base);
        }
 
-       if (index == NULL) {
-               index = noreg_GP;
+       if (idx == NULL) {
+               idx = noreg_GP;
        } else {
-               index = be_transform_node(index);
+               idx = be_transform_node(idx);
        }
 
        dbgi     = get_irn_dbg_info(node);
@@ -5036,7 +5042,7 @@ static ir_node *gen_prefetch(ir_node *node)
 
        if (rw == 1 && ia32_cg_config.use_3dnow_prefetch) {
                /* we have 3DNow!, this was already checked above */
-               new_node = new_bd_ia32_PrefetchW(dbgi, block, base, index, mem);
+               new_node = new_bd_ia32_PrefetchW(dbgi, block, base, idx, mem);
        } else if (ia32_cg_config.use_sse_prefetch) {
                /* note: rw == 1 is IGNORED in that case */
                param    = get_Builtin_param(node, 2);
@@ -5046,22 +5052,22 @@ static ir_node *gen_prefetch(ir_node *node)
                /* SSE style prefetch */
                switch (locality) {
                case 0:
-                       new_node = new_bd_ia32_PrefetchNTA(dbgi, block, base, index, mem);
+                       new_node = new_bd_ia32_PrefetchNTA(dbgi, block, base, idx, mem);
                        break;
                case 1:
-                       new_node = new_bd_ia32_Prefetch2(dbgi, block, base, index, mem);
+                       new_node = new_bd_ia32_Prefetch2(dbgi, block, base, idx, mem);
                        break;
                case 2:
-                       new_node = new_bd_ia32_Prefetch1(dbgi, block, base, index, mem);
+                       new_node = new_bd_ia32_Prefetch1(dbgi, block, base, idx, mem);
                        break;
                default:
-                       new_node = new_bd_ia32_Prefetch0(dbgi, block, base, index, mem);
+                       new_node = new_bd_ia32_Prefetch0(dbgi, block, base, idx, mem);
                        break;
                }
        } else {
                assert(ia32_cg_config.use_3dnow_prefetch);
                /* 3DNow! style prefetch */
-               new_node = new_bd_ia32_Prefetch(dbgi, block, base, index, mem);
+               new_node = new_bd_ia32_Prefetch(dbgi, block, base, idx, mem);
        }
 
        set_irn_pinned(new_node, get_irn_pinned(node));
@@ -5568,7 +5574,7 @@ static ir_node *gen_Proj_Builtin(ir_node *proj)
 static ir_node *gen_be_IncSP(ir_node *node)
 {
        ir_node *res = be_duplicate_node(node);
-       arch_irn_add_flags(res, arch_irn_flags_modify_flags);
+       arch_add_irn_flags(res, arch_irn_flags_modify_flags);
 
        return res;
 }
@@ -5590,7 +5596,7 @@ static ir_node *gen_Proj_be_Call(ir_node *node)
        }
        /* transform call modes */
        if (mode_is_data(mode)) {
-               const arch_register_class_t *cls = arch_get_irn_reg_class_out(node);
+               const arch_register_class_t *cls = arch_get_irn_reg_class(node);
                mode = cls->mode;
        }
 
@@ -5604,8 +5610,8 @@ static ir_node *gen_Proj_be_Call(ir_node *node)
        } else if (proj == pn_be_Call_X_regular) {
                proj = pn_ia32_Call_X_regular;
        } else {
-               arch_register_req_t const *const req    = arch_get_register_req_out(node);
-               int                        const n_outs = arch_irn_get_n_outs(new_call);
+               arch_register_req_t const *const req    = arch_get_irn_register_req(node);
+               int                        const n_outs = arch_get_irn_n_outs(new_call);
                int                              i;
 
                assert(proj      >= pn_be_Call_first_res);
@@ -5613,7 +5619,7 @@ static ir_node *gen_Proj_be_Call(ir_node *node)
 
                for (i = 0; i < n_outs; ++i) {
                        arch_register_req_t const *const new_req
-                               = arch_get_out_register_req(new_call, i);
+                               = arch_get_irn_register_req_out(new_call, i);
 
                        if (!(new_req->type & arch_register_req_type_limited) ||
                            new_req->cls      != req->cls                     ||
@@ -5660,7 +5666,7 @@ static ir_node *gen_Proj_ASM(ir_node *node)
        long     pos      = get_Proj_proj(node);
 
        if (mode == mode_M) {
-               pos = arch_irn_get_n_outs(new_pred)-1;
+               pos = arch_get_irn_n_outs(new_pred)-1;
        } else if (mode_is_int(mode) || mode_is_reference(mode)) {
                mode = mode_Iu;
        } else if (mode_is_float(mode)) {
@@ -5773,6 +5779,7 @@ static void register_transformers(void)
        be_set_transform_function(op_ia32_l_LLtoFloat, gen_ia32_l_LLtoFloat);
        be_set_transform_function(op_ia32_l_Mul,       gen_ia32_l_Mul);
        be_set_transform_function(op_ia32_l_Sbb,       gen_ia32_l_Sbb);
+       be_set_transform_function(op_ia32_l_Setcc,     gen_ia32_l_Setcc);
        be_set_transform_function(op_ia32_l_Sub,       gen_ia32_l_Sub);
        be_set_transform_function(op_ia32_GetEIP,      be_duplicate_node);
        be_set_transform_function(op_ia32_Minus64Bit,  be_duplicate_node);
@@ -5839,14 +5846,14 @@ static void postprocess_fp_call_results(void)
                        ir_type *res_tp = get_method_res_type(mtp, j);
                        ir_node *res, *new_res;
                        const ir_edge_t *edge, *next;
-                       ir_mode *mode;
+                       ir_mode *res_mode;
 
                        if (! is_atomic_type(res_tp)) {
                                /* no floating point return */
                                continue;
                        }
-                       mode = get_type_mode(res_tp);
-                       if (! mode_is_float(mode)) {
+                       res_mode = get_type_mode(res_tp);
+                       if (! mode_is_float(res_mode)) {
                                /* no floating point return */
                                continue;
                        }
@@ -5867,12 +5874,12 @@ static void postprocess_fp_call_results(void)
                                        dbg_info *db    = get_irn_dbg_info(succ);
                                        ir_node  *block = get_nodes_block(succ);
                                        ir_node  *base  = get_irn_n(succ, n_ia32_xStore_base);
-                                       ir_node  *index = get_irn_n(succ, n_ia32_xStore_index);
+                                       ir_node  *idx   = get_irn_n(succ, n_ia32_xStore_index);
                                        ir_node  *mem   = get_irn_n(succ, n_ia32_xStore_mem);
                                        ir_node  *value = get_irn_n(succ, n_ia32_xStore_val);
                                        ir_mode  *mode  = get_ia32_ls_mode(succ);
 
-                                       ir_node  *st = new_bd_ia32_vfst(db, block, base, index, mem, value, mode);
+                                       ir_node  *st = new_bd_ia32_vfst(db, block, base, idx, mem, value, mode);
                                        //ir_node  *mem = new_r_Proj(st, mode_M, pn_ia32_vfst_M);
                                        set_ia32_am_offs_int(st, get_ia32_am_offs_int(succ));
                                        if (is_ia32_use_frame(succ))
@@ -5886,7 +5893,11 @@ static void postprocess_fp_call_results(void)
                                        assert((long)pn_ia32_xStore_X_except == (long)pn_ia32_vfst_X_except);
 
                                        exchange(succ, st);
-                               } else if (new_res == NULL) {
+
+                                       continue;
+                               }
+
+                               if (new_res == NULL) {
                                        dbg_info *db       = get_irn_dbg_info(call);
                                        ir_node  *block    = get_nodes_block(call);
                                        ir_node  *frame    = get_irg_frame(current_ir_graph);
@@ -5897,7 +5908,7 @@ static void postprocess_fp_call_results(void)
 
                                        /* store st(0) on stack */
                                        vfst = new_bd_ia32_vfst(db, block, frame, noreg_GP, call_mem,
-                                                               res, mode);
+                                                               res, res_mode);
                                        set_ia32_op_type(vfst, ia32_AddrModeD);
                                        set_ia32_use_frame(vfst);
 
@@ -5905,11 +5916,11 @@ static void postprocess_fp_call_results(void)
 
                                        /* load into SSE register */
                                        xld = new_bd_ia32_xLoad(db, block, frame, noreg_GP, vfst_mem,
-                                                               mode);
+                                                               res_mode);
                                        set_ia32_op_type(xld, ia32_AddrModeS);
                                        set_ia32_use_frame(xld);
 
-                                       new_res = new_r_Proj(xld, mode, pn_ia32_xLoad_res);
+                                       new_res = new_r_Proj(xld, res_mode, pn_ia32_xLoad_res);
                                        new_mem = new_r_Proj(xld, mode_M, pn_ia32_xLoad_M);
 
                                        if (old_mem != NULL) {