remove old debug printf
[libfirm] / ir / be / ia32 / ia32_x87.c
index 456a621..fdceee7 100644 (file)
@@ -6,10 +6,9 @@
  *
  * $Id$
  */
-
 #ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif /* HAVE_CONFIG_H */
+#include <config.h>
+#endif
 
 #include <assert.h>
 
@@ -19,6 +18,7 @@
 #include "iredges_t.h"
 #include "irgmod.h"
 #include "ircons.h"
+#include "irgwalk.h"
 #include "obst.h"
 #include "pmap.h"
 #include "pdeq.h"
 #define N_x87_REGS 8
 
 /* first and second binop index */
-#define BINOP_IDX_1    2
+#define BINOP_IDX_1 2
 #define BINOP_IDX_2 3
 
 /* the unop index */
-#define UNOP_IDX  0
+#define UNOP_IDX 0
 
 /* the store val index */
 #define STORE_VAL_IDX 2
@@ -109,13 +109,13 @@ typedef unsigned char vfp_liveness;
  * The x87 simulator.
  */
 struct _x87_simulator {
-       struct obstack obst;      /**< An obstack for fast allocating. */
-       pmap *blk_states;         /**< Map blocks to states. */
-       const arch_env_t *env;    /**< The architecture environment. */
-       be_lv_t *lv;              /**< intrablock liveness. */
-       vfp_liveness *live;       /**< Liveness information. */
-       unsigned n_idx;           /**< The cached get_irg_last_idx() result. */
-       waitq *worklist;          /**< list of blocks to process. */
+       struct obstack obst;        /**< An obstack for fast allocating. */
+       pmap *blk_states;           /**< Map blocks to states. */
+       const arch_env_t *arch_env; /**< The architecture environment. */
+       be_lv_t *lv;                /**< intrablock liveness. */
+       vfp_liveness *live;         /**< Liveness information. */
+       unsigned n_idx;             /**< The cached get_irg_last_idx() result. */
+       waitq *worklist;            /**< list of blocks to process. */
 };
 
 /**
@@ -129,6 +129,7 @@ static int x87_get_depth(const x87_state *state) {
        return state->depth;
 }
 
+#if 0
 /**
  * Check if the state is empty.
  *
@@ -139,6 +140,7 @@ static int x87_get_depth(const x87_state *state) {
 static int x87_state_is_empty(const x87_state *state) {
        return state->depth == 0;
 }
+#endif
 
 /**
  * Return the virtual register index at st(pos).
@@ -176,7 +178,8 @@ static void x87_dump_stack(const x87_state *state) {
        int i;
 
        for (i = state->depth - 1; i >= 0; --i) {
-               DB((dbg, LEVEL_2, "vf%d ", x87_get_st_reg(state, i)));
+               DB((dbg, LEVEL_2, "vf%d(%+F) ", x87_get_st_reg(state, i),
+                   x87_get_st_node(state, i)));
        }
        DB((dbg, LEVEL_2, "<-- TOS\n"));
 }  /* x87_dump_stack */
@@ -429,7 +432,7 @@ static ir_node *get_irn_Proj_for_mode(ir_node *n, ir_mode *m) {
 static INLINE const arch_register_t *x87_get_irn_register(x87_simulator *sim, const ir_node *irn) {
        const arch_register_t *res;
 
-       res = arch_get_irn_register(sim->env, irn);
+       res = arch_get_irn_register(sim->arch_env, irn);
        assert(res->reg_class->regs == ia32_vfp_regs);
        return res;
 }
@@ -680,6 +683,7 @@ static ir_node *x87_create_fpop(x87_state *state, ir_node *n, int num, ir_node *
                attr->x87[1] = &ia32_st_regs[0];
                attr->x87[2] = &ia32_st_regs[0];
 
+               keep_alive(fpop);
                sched_add_before(n, fpop);
                DB((dbg, LEVEL_1, "<<< %s %s\n", get_irn_opname(fpop), attr->x87[0]->name));
 
@@ -731,7 +735,7 @@ static vfp_liveness vfp_liveness_transfer(x87_simulator *sim, ir_node *irn, vfp_
 {
        int i, n;
        const arch_register_class_t *cls = &ia32_reg_classes[CLASS_ia32_vfp];
-       const arch_env_t *arch_env = sim->env;
+       const arch_env_t *arch_env = sim->arch_env;
 
        if (arch_irn_consider_in_reg_alloc(arch_env, cls, irn)) {
                        const arch_register_t *reg = x87_get_irn_register(sim, irn);
@@ -763,7 +767,7 @@ static vfp_liveness vfp_liveness_end_of_block(x87_simulator *sim, const ir_node
        int i;
        vfp_liveness live = 0;
        const arch_register_class_t *cls = &ia32_reg_classes[CLASS_ia32_vfp];
-       const arch_env_t *arch_env = sim->env;
+       const arch_env_t *arch_env = sim->arch_env;
        const be_lv_t *lv = sim->lv;
 
        be_lv_foreach(lv, block, be_lv_state_end, i) {
@@ -868,6 +872,7 @@ static int sim_binop(x87_state *state, ir_node *n, const exchange_tmpl *tmpl) {
        int op2_idx, op1_idx;
        int out_idx, do_pop = 0;
        ia32_attr_t *attr;
+       ir_node *patched_insn;
        ir_op *dst;
        x87_simulator         *sim = state->sim;
        const arch_register_t *op1 = x87_get_irn_register(sim, get_irn_n(n, BINOP_IDX_1));
@@ -916,8 +921,7 @@ static int sim_binop(x87_state *state, ir_node *n, const exchange_tmpl *tmpl) {
                                out_idx = 0;
                                dst = tmpl->normal_op;
                        }
-               }
-               else {
+               } else {
                        /* Second operand is dead. */
                        if (is_vfp_live(arch_register_get_index(op1), live)) {
                                /* First operand is live: bring second to tos. */
@@ -930,8 +934,7 @@ static int sim_binop(x87_state *state, ir_node *n, const exchange_tmpl *tmpl) {
                                /* now do fxxxr (tos = op X tos) */
                                out_idx = 0;
                                dst = tmpl->reverse_op;
-                       }
-                       else {
+                       } else {
                                /* Both operands are dead here, pop them from the stack. */
                                if (op2_idx == 0) {
                                        if (op1_idx == 0) {
@@ -939,22 +942,19 @@ static int sim_binop(x87_state *state, ir_node *n, const exchange_tmpl *tmpl) {
                                                /* here fxxx (tos = tos X tos) */
                                                dst = tmpl->normal_op;
                                                out_idx = 0;
-                                       }
-                                       else {
+                                       } else {
                                                /* now do fxxxp (op = op X tos, pop) */
                                                dst = tmpl->normal_pop_op;
                                                do_pop = 1;
                                                out_idx = op1_idx;
                                        }
-                               }
-                               else if (op1_idx == 0) {
+                               } else if (op1_idx == 0) {
                                        assert(op1_idx != op2_idx);
                                        /* now do fxxxrp (op = tos X op, pop) */
                                        dst = tmpl->reverse_pop_op;
                                        do_pop = 1;
                                        out_idx = op2_idx;
-                               }
-                               else {
+                               } else {
                                        /* Bring the second on top. */
                                        x87_create_fxch(state, n, op2_idx, BINOP_IDX_2);
                                        if (op1_idx == op2_idx) {
@@ -964,8 +964,7 @@ static int sim_binop(x87_state *state, ir_node *n, const exchange_tmpl *tmpl) {
                                                /* use fxxx (tos = tos X tos) */
                                                dst = tmpl->normal_op;
                                                out_idx = 0;
-                                       }
-                                       else {
+                                       } else {
                                                /* op2 is on tos now */
                                                op2_idx = 0;
                                                /* use fxxxp (op = op X tos, pop) */
@@ -976,8 +975,7 @@ static int sim_binop(x87_state *state, ir_node *n, const exchange_tmpl *tmpl) {
                                }
                        }
                }
-       }
-       else {
+       } else {
                /* second operand is an address mode */
                if (is_vfp_live(arch_register_get_index(op1), live)) {
                        /* first operand is live: push it here */
@@ -986,8 +984,7 @@ static int sim_binop(x87_state *state, ir_node *n, const exchange_tmpl *tmpl) {
                        /* use fxxx (tos = tos X mem) */
                        dst = tmpl->normal_op;
                        out_idx = 0;
-               }
-               else {
+               } else {
                        /* first operand is dead: bring it to tos */
                        if (op1_idx != 0) {
                                x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
@@ -1000,7 +997,8 @@ static int sim_binop(x87_state *state, ir_node *n, const exchange_tmpl *tmpl) {
                }
        }
 
-       x87_set_st(state, arch_register_get_index(out), x87_patch_insn(n, dst), out_idx);
+       patched_insn = x87_patch_insn(n, dst);
+       x87_set_st(state, arch_register_get_index(out), patched_insn, out_idx);
        if (do_pop) {
                x87_pop(state);
        }
@@ -1203,7 +1201,7 @@ static int sim_store(x87_state *state, ir_node *n, ir_op *op, ir_op *op_p) {
 
                                assert(mem && "Store memory not found");
 
-                               arch_set_irn_register(sim->env, rproj, op2);
+                               arch_set_irn_register(sim->arch_env, rproj, op2);
 
                                /* reroute all former users of the store memory to the load memory */
                                edges_reroute(mem, mproj, irg);
@@ -1248,11 +1246,11 @@ static int sim_store(x87_state *state, ir_node *n, ir_op *op, ir_op *op_p) {
  * Simulate a virtual Phi.
  * Just for cosmetic reasons change the mode of Phi nodes to mode_E.
  *
- * @param state  the x87 state
- * @param n      the node that should be simulated (and patched)
- * @param env    the architecture environment
+ * @param state       the x87 state
+ * @param n           the node that should be simulated (and patched)
+ * @param arch_env    the architecture environment
  */
-static int sim_Phi(x87_state *state, ir_node *n, const arch_env_t *env) {
+static int sim_Phi(x87_state *state, ir_node *n, const arch_env_t *arch_env) {
        ir_mode *mode = get_irn_mode(n);
 
        if (mode_is_float(mode))
@@ -1261,7 +1259,6 @@ static int sim_Phi(x87_state *state, ir_node *n, const arch_env_t *env) {
        return 0;
 }  /* sim_Phi */
 
-
 #define _GEN_BINOP(op, rev) \
 static int sim_##op(x87_state *state, ir_node *n) { \
        exchange_tmpl tmpl = { op_ia32_##op, op_ia32_##rev, op_ia32_##op##p, op_ia32_##rev##p }; \
@@ -1305,7 +1302,6 @@ GEN_LOAD(fld)
 GEN_LOAD(fild)
 GEN_LOAD(fldz)
 GEN_LOAD(fld1)
-GEN_LOAD2(fConst, fldConst)
 
 GEN_STORE(fst)
 GEN_STORE(fist)
@@ -1351,8 +1347,10 @@ static int sim_fCondJmp(x87_state *state, ir_node *n) {
                                /* both operands are live */
 
                                if (op1_idx == 0) {
+                                       /* res = tos X op */
                                        dst = op_ia32_fcomJmp;
                                } else if (op2_idx == 0) {
+                                       /* res = op X tos */
                                        dst = op_ia32_fcomrJmp;
                                } else {
                                        /* bring the first one to tos */
@@ -1360,10 +1358,10 @@ static int sim_fCondJmp(x87_state *state, ir_node *n) {
                                        if (op2_idx == 0)
                                                op2_idx = op1_idx;
                                        op1_idx = 0;
+                                       /* res = tos X op */
                                        dst     = op_ia32_fcomJmp;
                                }
-                       }
-                       else {
+                       } else {
                                /* second live, first operand is dead here, bring it to tos.
                                   This means further, op1_idx != op2_idx. */
                                assert(op1_idx != op2_idx);
@@ -1373,11 +1371,11 @@ static int sim_fCondJmp(x87_state *state, ir_node *n) {
                                                op2_idx = op1_idx;
                                        op1_idx = 0;
                                }
+                               /* res = tos X op, pop */
                                dst     = op_ia32_fcompJmp;
                                pop_cnt = 1;
                        }
-               }
-               else {
+               } else {
                        /* second operand is dead */
                        if (is_vfp_live(arch_register_get_index(op1), live)) {
                                /* first operand is live: bring second to tos.
@@ -1389,10 +1387,10 @@ static int sim_fCondJmp(x87_state *state, ir_node *n) {
                                                op1_idx = op2_idx;
                                        op2_idx = 0;
                                }
+                               /* res = op X tos, pop */
                                dst     = op_ia32_fcomrpJmp;
                                pop_cnt = 1;
-                       }
-                       else {
+                       } else {
                                /* both operands are dead here, check first for identity. */
                                if (op1_idx == op2_idx) {
                                        /* identically, one pop needed */
@@ -1401,6 +1399,7 @@ static int sim_fCondJmp(x87_state *state, ir_node *n) {
                                                op1_idx = 0;
                                                op2_idx = 0;
                                        }
+                                       /* res = tos X op, pop */
                                        dst     = op_ia32_fcompJmp;
                                        pop_cnt = 1;
                                }
@@ -1411,56 +1410,60 @@ static int sim_fCondJmp(x87_state *state, ir_node *n) {
                                        if (op1_idx != 0) {
                                                /* bring the first on top */
                                                x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
+                                               assert(op2_idx != 0);
                                                op1_idx = 0;
                                        }
+                                       /* res = tos X op, pop, pop */
                                        dst     = op_ia32_fcomppJmp;
                                        pop_cnt = 2;
-                               }
-                               else if (op1_idx == 1) {
+                               } else if (op1_idx == 1) {
                                        /* good, first operand is already in the right place, move the second */
                                        if (op2_idx != 0) {
                                                /* bring the first on top */
                                                x87_create_fxch(state, n, op2_idx, BINOP_IDX_2);
+                                               assert(op1_idx != 0);
                                                op2_idx = 0;
                                        }
                                        dst     = op_ia32_fcomrppJmp;
                                        pop_cnt = 2;
-                               }
-                               else {
+                               } else {
                                        /* if one is already the TOS, we need two fxch */
                                        if (op1_idx == 0) {
                                                /* first one is TOS, move to st(1) */
                                                x87_create_fxch(state, n, 1, BINOP_IDX_1);
+                                               assert(op2_idx != 1);
                                                op1_idx = 1;
                                                x87_create_fxch(state, n, op2_idx, BINOP_IDX_2);
                                                op2_idx = 0;
+                                               /* res = op X tos, pop, pop */
                                                dst     = op_ia32_fcomrppJmp;
                                                pop_cnt = 2;
-                                       }
-                                       else if (op2_idx == 0) {
+                                       } else if (op2_idx == 0) {
                                                /* second one is TOS, move to st(1) */
                                                x87_create_fxch(state, n, 1, BINOP_IDX_2);
+                                               assert(op1_idx != 1);
                                                op2_idx = 1;
                                                x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
                                                op1_idx = 0;
-                                               dst     = op_ia32_fcomrppJmp;
+                                               /* res = tos X op, pop, pop */
+                                               dst     = op_ia32_fcomppJmp;
                                                pop_cnt = 2;
-                                       }
-                                       else {
+                                       } else {
                                                /* none of them is either TOS or st(1), 3 fxch needed */
                                                x87_create_fxch(state, n, op2_idx, BINOP_IDX_2);
+                                               assert(op1_idx != 0);
                                                x87_create_fxch(state, n, 1, BINOP_IDX_2);
                                                op2_idx = 1;
                                                x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
                                                op1_idx = 0;
+                                               /* res = tos X op, pop, pop */
                                                dst     = op_ia32_fcomppJmp;
                                                pop_cnt = 2;
                                        }
                                }
                        }
                }
-       }
-       else {
+       } else {
                /* second operand is an address mode */
                if (is_vfp_live(arch_register_get_index(op1), live)) {
                        /* first operand is live: bring it to TOS */
@@ -1469,8 +1472,7 @@ static int sim_fCondJmp(x87_state *state, ir_node *n) {
                                op1_idx = 0;
                        }
                        dst = op_ia32_fcomJmp;
-               }
-               else {
+               } else {
                        /* first operand is dead: bring it to tos */
                        if (op1_idx != 0) {
                                x87_create_fxch(state, n, op1_idx, BINOP_IDX_1);
@@ -1508,6 +1510,72 @@ static int sim_fCondJmp(x87_state *state, ir_node *n) {
        return 0;
 }  /* sim_fCondJmp */
 
+static ir_node *create_Copy(x87_state *state, ir_node *n) {
+       x87_simulator *sim = state->sim;
+       ir_graph *irg = get_irn_irg(n);
+       dbg_info *n_dbg = get_irn_dbg_info(n);
+       ir_mode *mode = get_irn_mode(n);
+       ir_node *block = get_nodes_block(n);
+       ir_node *pred = get_irn_n(n, 0);
+       ir_node *(*cnstr)(dbg_info *, ir_graph *, ir_node *, ir_mode *) = NULL;
+       ir_node *res;
+       const arch_register_t *out;
+       const arch_register_t *op1;
+       ia32_attr_t *attr;
+
+       /* Do not copy constants, recreate them. */
+       switch (get_ia32_irn_opcode(pred)) {
+       case iro_ia32_Unknown_VFP:
+       case iro_ia32_fldz:
+               cnstr = new_rd_ia32_fldz;
+               break;
+       case iro_ia32_fld1:
+               cnstr = new_rd_ia32_fld1;
+               break;
+       case iro_ia32_fldpi:
+               cnstr = new_rd_ia32_fldpi;
+               break;
+       case iro_ia32_fldl2e:
+               cnstr = new_rd_ia32_fldl2e;
+               break;
+       case iro_ia32_fldl2t:
+               cnstr = new_rd_ia32_fldl2t;
+               break;
+       case iro_ia32_fldlg2:
+               cnstr = new_rd_ia32_fldlg2;
+               break;
+       case iro_ia32_fldln2:
+               cnstr = new_rd_ia32_fldln2;
+               break;
+       }
+
+       out = x87_get_irn_register(sim, n);
+       op1 = x87_get_irn_register(sim, pred);
+
+       if(cnstr != NULL) {
+               /* copy a constant */
+               res = (*cnstr)(n_dbg, irg, block, mode);
+
+               x87_push(state, arch_register_get_index(out), res);
+
+               attr = get_ia32_attr(res);
+               attr->x87[2] = out = &ia32_st_regs[0];
+       } else {
+               int op1_idx = x87_on_stack(state, arch_register_get_index(op1));
+
+               res = new_rd_ia32_fpushCopy(n_dbg, irg, block, pred, mode);
+
+               x87_push(state, arch_register_get_index(out), res);
+
+               attr = get_ia32_attr(res);
+               attr->x87[0] = op1 = &ia32_st_regs[op1_idx];
+               attr->x87[2] = out = &ia32_st_regs[0];
+       }
+       arch_set_irn_register(sim->arch_env, res, out);
+
+       return res;
+}
+
 /**
  * Simulate a be_Copy.
  *
@@ -1515,169 +1583,110 @@ static int sim_fCondJmp(x87_state *state, ir_node *n) {
  * @param n      the node that should be simulated (and patched)
  */
 static int sim_Copy(x87_state *state, ir_node *n) {
-       ir_mode *mode = get_irn_mode(n);
+       x87_simulator         *sim;
+       ir_node               *pred;
+       const arch_register_t *out;
+       const arch_register_t *op1;
+       ir_node               *node, *next;
+       ia32_attr_t           *attr;
+       int                   op1_idx, out_idx;
+       unsigned              live;
 
-       if (mode_is_float(mode)) {
-               x87_simulator         *sim = state->sim;
-               ir_node               *pred = get_irn_n(n, 0);
-               const arch_register_t *out = x87_get_irn_register(sim, n);
-               const arch_register_t *op1 = x87_get_irn_register(sim, pred);
-               ir_node               *node, *next;
-               ia32_attr_t           *attr;
-               int                   op1_idx, out_idx;
-               unsigned              live = vfp_live_args_after(sim, n, REGMASK(out));
-               ir_node               *(*cnstr)(dbg_info *, ir_graph *, ir_node *, ir_mode *);
-
-               DB((dbg, LEVEL_1, ">>> %+F %s -> %s\n", n,
-                       arch_register_get_name(op1), arch_register_get_name(out)));
-               DEBUG_ONLY(vfp_dump_live(live));
+       ir_mode *mode = get_irn_mode(n);
 
-               /* Do not copy constants, recreate them. */
-               switch (get_ia32_irn_opcode(pred)) {
-               case iro_ia32_fldz:
-                       cnstr = new_rd_ia32_fldz;
-                       break;
-               case iro_ia32_fld1:
-                       cnstr = new_rd_ia32_fld1;
-                       break;
-               case iro_ia32_fldpi:
-                       cnstr = new_rd_ia32_fldpi;
-                       break;
-               case iro_ia32_fldl2e:
-                       cnstr = new_rd_ia32_fldl2e;
-                       break;
-               case iro_ia32_fldl2t:
-                       cnstr = new_rd_ia32_fldl2t;
-                       break;
-               case iro_ia32_fldlg2:
-                       cnstr = new_rd_ia32_fldlg2;
-                       break;
-               case iro_ia32_fldln2:
-                       cnstr = new_rd_ia32_fldln2;
-                       break;
-               default:
-                       goto no_constant;
-               }
+       if (!mode_is_float(mode))
+               return 0;
 
-               /* copy a constant */
-               node = (*cnstr)(get_irn_dbg_info(n), get_irn_irg(n), get_nodes_block(n), mode);
-               arch_set_irn_register(sim->env, node, out);
+       sim = state->sim;
+       pred = get_irn_n(n, 0);
+       out = x87_get_irn_register(sim, n);
+       op1 = x87_get_irn_register(sim, pred);
+       live = vfp_live_args_after(sim, n, REGMASK(out));
 
-               x87_push(state, arch_register_get_index(out), node);
+       DB((dbg, LEVEL_1, ">>> %+F %s -> %s\n", n,
+               arch_register_get_name(op1), arch_register_get_name(out)));
+       DEBUG_ONLY(vfp_dump_live(live));
 
-               attr = get_ia32_attr(node);
-               attr->x87[2] = out = &ia32_st_regs[0];
+       /* handle the infamous unknown value */
+       if (arch_register_get_index(op1) == REG_VFP_UKNWN) {
+               /* Operand is still live, a real copy. We need here an fpush that can
+                  hold a a register, so use the fpushCopy or recreate constants */
+               node = create_Copy(state, n);
 
+               assert(is_ia32_fldz(node));
                next = sched_next(n);
                sched_remove(n);
                exchange(n, node);
                sched_add_before(next, node);
-               DB((dbg, LEVEL_1, ">>> %+F -> %s\n", node, arch_register_get_name(out)));
+
+               DB((dbg, LEVEL_1, "<<< %+F %s -> %s\n", node, op1->name,
+                   arch_get_irn_register(sim->arch_env, node)->name));
                return 0;
+       }
 
-no_constant:
-               /* handle the infamous unknown value */
-               if (arch_register_get_index(op1) == REG_VFP_UKNWN) {
-                       /* This happens before Phi nodes */
-                       if (x87_state_is_empty(state)) {
-                               /* create some value */
-                               x87_patch_insn(n, op_ia32_fldz);
-                               attr = get_ia32_attr(n);
-                               attr->x87[2] = out = &ia32_st_regs[0];
-                               DB((dbg, LEVEL_1, "<<< %+F -> %s\n", n,
-                                       arch_register_get_name(out)));
-                       } else {
-                               /* Just copy one. We need here an fpush that can hold a
-                                  a register, so use the fpushCopy. */
-                               node = new_rd_ia32_fpushCopy(get_irn_dbg_info(n), get_irn_irg(n), get_nodes_block(n), get_irn_n(n, 0), mode);
-                               arch_set_irn_register(sim->env, node, out);
-
-                               x87_push(state, arch_register_get_index(out), node);
-
-                               attr = get_ia32_attr(node);
-                               attr->x87[0] = op1 =
-                               attr->x87[2] = out = &ia32_st_regs[0];
-
-                               next = sched_next(n);
-                               sched_remove(n);
-                               exchange(n, node);
-                               sched_add_before(next, node);
-                               DB((dbg, LEVEL_1, "<<< %+F %s -> %s\n", node,
-                                       arch_register_get_name(op1),
-                                       arch_register_get_name(out)));
-                       }
-                       return 0;
-               }
+       op1_idx = x87_on_stack(state, arch_register_get_index(op1));
 
-               op1_idx = x87_on_stack(state, arch_register_get_index(op1));
+       if (is_vfp_live(arch_register_get_index(op1), live)) {
+               /* Operand is still live, a real copy. We need here an fpush that can
+                  hold a a register, so use the fpushCopy or recreate constants */
+               node = create_Copy(state, n);
 
-               if (is_vfp_live(arch_register_get_index(op1), live)) {
-                       /* Operand is still live,a real copy. We need here an fpush that can hold a
-                          a register, so use the fpushCopy. */
-                       node = new_rd_ia32_fpushCopy(get_irn_dbg_info(n), get_irn_irg(n), get_nodes_block(n), get_irn_n(n, 0), mode);
-                       arch_set_irn_register(sim->env, node, out);
+               next = sched_next(n);
+               sched_remove(n);
+               exchange(n, node);
+               sched_add_before(next, node);
+               DB((dbg, LEVEL_1, "<<< %+F %s -> %s\n", node, op1->name,
+                   arch_get_irn_register(sim->arch_env, node)->name));
+       } else {
+               out_idx = x87_on_stack(state, arch_register_get_index(out));
 
-                       x87_push(state, arch_register_get_index(out), node);
+               if (out_idx >= 0 && out_idx != op1_idx) {
+                       /* Matze: out already on stack? how can this happen? */
+                       assert(0);
 
-                       attr = get_ia32_attr(node);
-                       attr->x87[0] = op1 = &ia32_st_regs[op1_idx];
-                       attr->x87[2] = out = &ia32_st_regs[0];
+                       /* op1 must be killed and placed where out is */
+                       if (out_idx == 0) {
+                               /* best case, simple remove and rename */
+                               x87_patch_insn(n, op_ia32_Pop);
+                               attr = get_ia32_attr(n);
+                               attr->x87[0] = op1 = &ia32_st_regs[0];
 
-                       next = sched_next(n);
-                       sched_remove(n);
-                       exchange(n, node);
-                       sched_add_before(next, node);
-                       DB((dbg, LEVEL_1, ">>> %+F %s -> %s\n", node, op1->name, out->name));
-               }
-               else {
-                       out_idx = x87_on_stack(state, arch_register_get_index(out));
-
-                       if (out_idx >= 0 && out_idx != op1_idx) {
-                               /* op1 must be killed and placed where out is */
-                               if (out_idx == 0) {
-                                       /* best case, simple remove and rename */
-                                       x87_patch_insn(n, op_ia32_Pop);
-                                       attr = get_ia32_attr(n);
-                                       attr->x87[0] = op1 = &ia32_st_regs[0];
-
-                                       x87_pop(state);
-                                       x87_set_st(state, arch_register_get_index(out), n, op1_idx - 1);
+                               x87_pop(state);
+                               x87_set_st(state, arch_register_get_index(out), n, op1_idx - 1);
+                       } else {
+                               /* move op1 to tos, store and pop it */
+                               if (op1_idx != 0) {
+                                       x87_create_fxch(state, n, op1_idx, 0);
+                                       op1_idx = 0;
                                }
-                               else {
-                                       /* move op1 to tos, store and pop it */
-                                       if (op1_idx != 0) {
-                                               x87_create_fxch(state, n, op1_idx, 0);
-                                               op1_idx = 0;
-                                       }
-                                       x87_patch_insn(n, op_ia32_Pop);
-                                       attr = get_ia32_attr(n);
-                                       attr->x87[0] = op1 = &ia32_st_regs[out_idx];
+                               x87_patch_insn(n, op_ia32_Pop);
+                               attr = get_ia32_attr(n);
+                               attr->x87[0] = op1 = &ia32_st_regs[out_idx];
 
-                                       x87_pop(state);
-                                       x87_set_st(state, arch_register_get_index(out), n, out_idx - 1);
-                               }
-                               DB((dbg, LEVEL_1, ">>> %+F %s\n", n, op1->name));
-                       }
-                       else {
-                               /* just a virtual copy */
-                               x87_set_st(state, arch_register_get_index(out), get_unop_op(n), op1_idx);
-                               sched_remove(n);
-                               DB((dbg, LEVEL_1, ">>> KILLED %s\n", get_irn_opname(n)));
-                               exchange(n, get_unop_op(n));
+                               x87_pop(state);
+                               x87_set_st(state, arch_register_get_index(out), n, out_idx - 1);
                        }
+                       DB((dbg, LEVEL_1, "<<< %+F %s\n", n, op1->name));
+               } else {
+                       /* just a virtual copy */
+                       x87_set_st(state, arch_register_get_index(out), get_unop_op(n), op1_idx);
+                       sched_remove(n);
+                       DB((dbg, LEVEL_1, "<<< KILLED %s\n", get_irn_opname(n)));
+                       exchange(n, get_unop_op(n));
                }
        }
+
        return 0;
 }  /* sim_Copy */
 
 /**
  * Simulate a be_Call.
  *
- * @param state  the x87 state
- * @param n      the node that should be simulated
- * @param env    the architecture environment
+ * @param state      the x87 state
+ * @param n          the node that should be simulated
+ * @param arch_env   the architecture environment
  */
-static int sim_Call(x87_state *state, ir_node *n, const arch_env_t *env) {
+static int sim_Call(x87_state *state, ir_node *n, const arch_env_t *arch_env) {
        ir_type *call_tp = be_Call_get_type(n);
 
        /* at the begin of a call the x87 state should be empty */
@@ -1709,7 +1718,6 @@ static int sim_Call(x87_state *state, ir_node *n, const arch_env_t *env) {
  *
  * @param state  the x87 state
  * @param n      the node that should be simulated (and patched)
- * @param env    the architecture environment
  *
  * Should not happen, spills are lowered before x87 simulator see them.
  */
@@ -1723,7 +1731,6 @@ static int sim_Spill(x87_state *state, ir_node *n) {
  *
  * @param state  the x87 state
  * @param n      the node that should be simulated (and patched)
- * @param env    the architecture environment
  *
  * Should not happen, reloads are lowered before x87 simulator see them.
  */
@@ -1737,7 +1744,6 @@ static int sim_Reload(x87_state *state, ir_node *n) {
  *
  * @param state  the x87 state
  * @param n      the node that should be simulated (and patched)
- * @param env    the architecture environment
  */
 static int sim_Return(x87_state *state, ir_node *n) {
        int n_res = be_Return_get_n_rets(n);
@@ -1904,7 +1910,7 @@ static void x87_simulate_block(x87_simulator *sim, ir_node *block) {
        if(bl_state->end != NULL)
                return;
 
-       update_liveness(sim, block);
+       //update_liveness(sim, block);
 
        DB((dbg, LEVEL_1, "Simulate %+F\n", block));
        DB((dbg, LEVEL_2, "State at Block begin:\n "));
@@ -1913,7 +1919,7 @@ static void x87_simulate_block(x87_simulator *sim, ir_node *block) {
        /* at block begin, kill all dead registers */
        state = x87_kill_deads(sim, block, state);
 
-       /* beware, n might changed */
+       /* beware, n might change */
        for (n = sched_first(block); !sched_is_end(n); n = next) {
                int node_inserted;
                sim_func func;
@@ -1974,15 +1980,16 @@ static void x87_simulate_block(x87_simulator *sim, ir_node *block) {
 /**
  * Create a new x87 simulator.
  *
- * @param sim   a simulator handle, will be initialized
- * @param irg   the current graph
- * @param env   the architecture environment
+ * @param sim       a simulator handle, will be initialized
+ * @param irg       the current graph
+ * @param arch_env  the architecture environment
  */
-static void x87_init_simulator(x87_simulator *sim, ir_graph *irg, const arch_env_t *env)
+static void x87_init_simulator(x87_simulator *sim, ir_graph *irg,
+                               const arch_env_t *arch_env)
 {
        obstack_init(&sim->obst);
        sim->blk_states = pmap_create();
-       sim->env        = env;
+       sim->arch_env   = arch_env;
        sim->n_idx      = get_irg_last_idx(irg);
        sim->live       = obstack_alloc(&sim->obst, sizeof(*sim->live) * sim->n_idx);
 
@@ -1997,7 +2004,6 @@ static void x87_init_simulator(x87_simulator *sim, ir_graph *irg, const arch_env
 #define ASSOC(op)       (op_ ## op)->ops.generic = (op_func)(sim_##op)
 #define ASSOC_IA32(op)  (op_ia32_v ## op)->ops.generic = (op_func)(sim_##op)
 #define ASSOC_BE(op)    (op_be_ ## op)->ops.generic = (op_func)(sim_##op)
-       ASSOC_IA32(fConst);
        ASSOC_IA32(fld);
        ASSOC_IA32(fild);
        ASSOC_IA32(fld1);
@@ -2038,6 +2044,12 @@ static void x87_destroy_simulator(x87_simulator *sim) {
        DB((dbg, LEVEL_1, "x87 Simulator stopped\n\n"));
 }  /* x87_destroy_simulator */
 
+static void update_liveness_walker(ir_node *block, void *data)
+{
+       x87_simulator *sim = data;
+       update_liveness(sim, block);
+}
+
 /**
  * Run a simulation and fix all virtual instructions for a graph.
  *
@@ -2046,14 +2058,14 @@ static void x87_destroy_simulator(x87_simulator *sim) {
  *
  * Needs a block-schedule.
  */
-void x87_simulate_graph(const arch_env_t *env, be_irg_t *birg) {
+void x87_simulate_graph(const arch_env_t *arch_env, be_irg_t *birg) {
        ir_node       *block, *start_block;
        blk_state     *bl_state;
        x87_simulator sim;
        ir_graph      *irg = birg->irg;
 
        /* create the simulator */
-       x87_init_simulator(&sim, irg, env);
+       x87_init_simulator(&sim, irg, arch_env);
 
        start_block = get_irg_start_block(irg);
        bl_state = x87_get_bl_state(&sim, start_block);
@@ -2069,19 +2081,13 @@ void x87_simulate_graph(const arch_env_t *env, be_irg_t *birg) {
        be_assure_liveness(birg);
        sim.lv = birg->lv;
 
-#if 0
-       /* Create the worklist for the schedule and calculate the liveness
-          for all nodes. We must precalculate this info, because the
-          simulator adds new nodes (and possible before Phi nodes) which
-          let fail the old lazy calculation.
-          On the other hand we reduce the computation amount due to
-          precaching from O(n^2) to O(n) at the expense of O(n) cache memory.
+       /* Calculate the liveness for all nodes. We must precalculate this info,
+        * because the simulator adds new nodes (possible before Phi nodes) which
+        * would let a lazy calculation fail.
+        * On the other hand we reduce the computation amount due to
+        * precaching from O(n^2) to O(n) at the expense of O(n) cache memory.
         */
-       for (i = 0, n = ARR_LEN(blk_list); i < n; ++i) {
-               update_liveness(&sim, lv, blk_list[i]);
-               waitq_put(worklist, blk_list[i]);
-       }
-#endif
+       irg_block_walk_graph(irg, update_liveness_walker, NULL, &sim);
 
        /* iterate */
        do {