fixed debug output of unary x87 nodes
[libfirm] / ir / be / ia32 / ia32_finish.c
index 2e3c6c7..04b3f10 100644 (file)
@@ -59,6 +59,7 @@ static void ia32_transform_sub_to_neg_add(ir_node *irn, ia32_code_gen_t *cg) {
                arch_set_irn_register(cg->arch_env, res, in2_reg);
 
                /* add to schedule */
+               sched_add_before(irn, get_Proj_pred(res));
                sched_add_before(irn, res);
 
                /* generate the add */
@@ -298,10 +299,36 @@ insert_copy:
                        }
                }
 
-               /* If we have a CondJmp/CmpSet/xCmpSet with immediate, we need to    */
-               /* check if it's the right operand, otherwise we have */
-               /* to change it, as CMP doesn't support immediate as  */
-               /* left operands.                                     */
+               /* check xCmp: try to avoid unordered cmp */
+               if ((is_ia32_xCmp(irn) || is_ia32_xCmpCMov(irn) || is_ia32_xCmpSet(irn)) &&
+                       op_tp == ia32_Normal    &&
+                       ! is_ia32_ImmConst(irn) && ! is_ia32_ImmSymConst(irn))
+               {
+                       long pnc = get_ia32_pncode(irn);
+
+                       if (pnc & pn_Cmp_Uo) {
+                               ir_node *tmp;
+                               int idx1 = 2, idx2 = 3;
+
+                               if (is_ia32_xCmpCMov(irn)) {
+                                       idx1 = 0;
+                                       idx2 = 1;
+                               }
+
+                               tmp = get_irn_n(irn, idx1);
+                               set_irn_n(irn, idx1, get_irn_n(irn, idx2));
+                               set_irn_n(irn, idx2, tmp);
+
+                               set_ia32_pncode(irn, get_negated_pnc(pnc, mode_D));
+                       }
+               }
+
+               /*
+                       If we have a CondJmp/CmpSet/xCmpSet with immediate,
+                       we need to check if it's the right operand, otherwise
+                       we have to change it, as CMP doesn't support immediate
+                       as left operands.
+               */
                if ((is_ia32_CondJmp(irn) || is_ia32_CmpSet(irn) || is_ia32_xCmpSet(irn)) &&
                        (is_ia32_ImmConst(irn) || is_ia32_ImmSymConst(irn))                   &&
                        op_tp == ia32_AddrModeS)
@@ -309,17 +336,8 @@ insert_copy:
                        set_ia32_op_type(irn, ia32_AddrModeD);
                        set_ia32_pncode(irn, get_inversed_pnc(get_ia32_pncode(irn)));
                }
-
-               /* check if there is a sub which need to be transformed */
-               ia32_transform_sub_to_neg_add(irn, cg);
-
-               /* transform a LEA into an Add if possible */
-               ia32_transform_lea_to_add(irn, cg);
        }
-end:
-
-       /* check for peephole optimization */
-       ia32_peephole_optimization(irn, cg);
+end: ;
 }
 
 /**
@@ -332,7 +350,7 @@ end:
  */
 static void fix_am_source(ir_node *irn, void *env) {
        ia32_code_gen_t *cg = env;
-       ir_node *base, *index;
+       ir_node *base, *index, *noreg;
        const arch_register_t *reg_base, *reg_index;
        const ia32_register_req_t **reqs;
        int n_res, i;
@@ -348,6 +366,8 @@ static void fix_am_source(ir_node *irn, void *env) {
        reg_index = arch_get_irn_register(cg->arch_env, index);
        reqs      = get_ia32_out_req_all(irn);
 
+       noreg = ia32_new_NoReg_gp(cg);
+
        n_res = get_ia32_n_res(irn);
 
        for (i = 0; i < n_res; i++) {
@@ -398,7 +418,7 @@ static void fix_am_source(ir_node *irn, void *env) {
                                /* insert the load into schedule */
                                sched_add_before(irn, load);
 
-                               ir_printf("irg %+F: build back AM source for node %+F, inserted load %+F\n", cg->irg, irn, load);
+                               DBG((cg->mod, LEVEL_3, "irg %+F: build back AM source for node %+F, inserted load %+F\n", cg->irg, irn, load));
 
                                load = new_r_Proj(cg->irg, block, load, ls_mode, pnres);
                                arch_set_irn_register(cg->arch_env, load, out_reg);
@@ -410,6 +430,8 @@ static void fix_am_source(ir_node *irn, void *env) {
                                set_irn_n(irn, 3, load);
 
                                /* this is a normal node now */
+                               set_irn_n(irn, 0, noreg);
+                               set_irn_n(irn, 1, noreg);
                                set_ia32_op_type(irn, ia32_Normal);
 
                                break;
@@ -427,6 +449,22 @@ static void ia32_finish_irg_walker(ir_node *block, void *env) {
                fix_am_source(irn, env);
        }
 
+       for (irn = sched_first(block); ! sched_is_end(irn); irn = next) {
+               ia32_code_gen_t *cg = env;
+               next = sched_next(irn);
+
+               if (is_ia32_irn(irn)) {
+                       /* check if there is a sub which need to be transformed */
+                       ia32_transform_sub_to_neg_add(irn, cg);
+
+                       /* transform a LEA into an Add if possible */
+                       ia32_transform_lea_to_add(irn, cg);
+
+                       /* check for peephole optimization */
+                       ia32_peephole_optimization(irn, cg);
+               }
+       }
+
        /* second: insert copies and finish irg */
        for (irn = sched_first(block); ! sched_is_end(irn); irn = next) {
                next = sched_next(irn);