BugFix: creation of Div/Mod nodes
[libfirm] / ir / be / ia32 / ia32_transform.c
index 63f4a9f..7e571d1 100644 (file)
@@ -397,7 +397,7 @@ static ir_node *gen_imm_Add(ia32_transform_env_t *env, ir_node *expr_op, ir_node
        DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
 
        /* try to optimize to inc/dec  */
-       if ((env->cg->opt & IA32_OPT_INCDEC) && tv) {
+       if ((env->cg->opt & IA32_OPT_INCDEC) && (get_ia32_op_type(const_op) == ia32_Const)) {
                /* optimize tarvals */
                class_tv    = classify_tarval(tv);
                class_negtv = classify_tarval(tarval_neg(tv));
@@ -417,6 +417,7 @@ static ir_node *gen_imm_Add(ia32_transform_env_t *env, ir_node *expr_op, ir_node
        if (normal_add) {
                new_op = new_rd_ia32_Add(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem);
                set_ia32_Immop_attr(new_op, const_op);
+               set_ia32_commutative(new_op);
        }
 
        return new_op;
@@ -884,7 +885,7 @@ static ir_node *generate_DivMod(ia32_transform_env_t *env, ir_node *dividend, ir
                edx_node = new_rd_Proj(dbg, irg, block, cltd, mode_Is, pn_ia32_Cdq_EDX);
        }
        else {
-               edx_node = new_rd_ia32_Const(dbg, irg, block, mode_Iu);
+               edx_node = new_rd_ia32_Const(dbg, irg, block, get_irg_no_mem(irg), mode_Iu);
                set_ia32_Const_type(edx_node, ia32_Const);
                set_ia32_Immop_tarval(edx_node, get_tarval_null(mode_Iu));
        }
@@ -900,10 +901,12 @@ static ir_node *generate_DivMod(ia32_transform_env_t *env, ir_node *dividend, ir
                proj = get_edge_src_irn(get_irn_out_edge_first(irn));
                assert(is_Proj(proj) && "non-Proj to Div/Mod node");
 
-               if (get_Proj_proj(proj) == pn_DivMod_res_div) {
+               if (get_irn_op(irn) == op_Div) {
+                       set_Proj_proj(proj, pn_DivMod_res_div);
                        in_keep[0] = new_rd_Proj(dbg, irg, block, res, mode_Is, pn_DivMod_res_mod);
                }
                else {
+                       set_Proj_proj(proj, pn_DivMod_res_mod);
                        in_keep[0] = new_rd_Proj(dbg, irg, block, res, mode_Is, pn_DivMod_res_div);
                }
 
@@ -1328,7 +1331,7 @@ static ir_node *gen_Store(ia32_transform_env_t *env) {
        /* address might be a constant (symconst or absolute address) */
        if (is_ia32_Const(ptr)) {
                sptr   = noreg;
-               is_imm = 0;
+               is_imm = 1;
        }
 
        if (mode_is_float(mode)) {
@@ -1342,7 +1345,7 @@ static ir_node *gen_Store(ia32_transform_env_t *env) {
                new_op = new_rd_ia32_Store8Bit(env->dbg, env->irg, env->block, sptr, noreg, sval, mem);
        }
        else {
-               new_op = new_rd_ia32_Store(env->dbg, env->irg, env->block, ptr, noreg, sval, mem);
+               new_op = new_rd_ia32_Store(env->dbg, env->irg, env->block, sptr, noreg, sval, mem);
        }
 
        /* stored const is an attribute (saves a register) */
@@ -1465,12 +1468,13 @@ static ir_node *gen_Cond(ia32_transform_env_t *env) {
                        }
                        else {
                                res = new_rd_ia32_CondJmp(dbg, irg, block, noreg, noreg, cmp_a, cmp_b, nomem);
+                               set_ia32_commutative(res);
                        }
                        set_ia32_res_mode(res, get_irn_mode(cmp_a));
                }
 
                set_ia32_pncode(res, get_Proj_proj(sel));
-               set_ia32_am_support(res, ia32_am_Source);
+               //set_ia32_am_support(res, ia32_am_Source);
        }
        else {
                /* determine the smallest switch case value */
@@ -1530,7 +1534,7 @@ static ir_node *gen_CopyB(ia32_transform_env_t *env) {
                rem = size & 0x3; /* size % 4 */
                size >>= 2;
 
-               res = new_rd_ia32_Const(dbg, irg, block, mode_Is);
+               res = new_rd_ia32_Const(dbg, irg, block, get_irg_no_mem(irg), mode_Is);
                set_ia32_op_type(res, ia32_Const);
                set_ia32_Immop_tarval(res, new_tarval_from_long(size, mode_Is));
 
@@ -2037,6 +2041,7 @@ void ia32_transform_sub_to_neg_add(ir_node *irn, ia32_code_gen_t *cg) {
                        set_ia32_am_support(res, ia32_am_Full);
                        set_ia32_commutative(res);
                }
+           set_ia32_res_mode(res, tenv.mode);
 
                SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(tenv.cg, irn));
                /* copy register */
@@ -2150,6 +2155,7 @@ void ia32_transform_lea_to_add(ir_node *irn, ia32_code_gen_t *cg) {
        arch_set_irn_register(cg->arch_env, res, out_reg);
        set_ia32_op_type(res, ia32_Normal);
        set_ia32_commutative(res);
+       set_ia32_res_mode(res, tenv.mode);
 
        if (imm) {
                set_ia32_cnst(res, offs);