don't do AGGRESSIVE_AM
[libfirm] / ir / be / ia32 / ia32_x87.c
index cb17768..2a60119 100644 (file)
@@ -1166,8 +1166,8 @@ static int sim_store(x87_state *state, ir_node *n, ir_op *op, ir_op *op_p) {
        } else {
                op2_idx = x87_on_stack(state, op2_reg_idx);
                live_after_node = is_vfp_live(arch_register_get_index(op2), live);
-               assert(op2_idx >= 0);
                DB((dbg, LEVEL_1, ">>> %+F %s ->\n", n, arch_register_get_name(op2)));
+               assert(op2_idx >= 0);
        }
 
        mode  = get_ia32_ls_mode(n);
@@ -1288,9 +1288,6 @@ GEN_BINOP(fprem)
 
 GEN_UNOP(fabs)
 GEN_UNOP(fchs)
-GEN_UNOP(fsin)
-GEN_UNOP(fcos)
-GEN_UNOP(fsqrt)
 
 GEN_LOAD(fld)
 GEN_LOAD(fild)
@@ -1315,8 +1312,10 @@ static int sim_fCondJmp(x87_state *state, ir_node *n) {
        ia32_x87_attr_t *attr;
        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));
-       const arch_register_t *op2 = x87_get_irn_register(sim, get_irn_n(n, BINOP_IDX_2));
+       ir_node               *op1_node = get_irn_n(n, n_ia32_vfCondJmp_left);
+       ir_node               *op2_node = get_irn_n(n, n_ia32_vfCondJmp_right);
+       const arch_register_t *op1      = x87_get_irn_register(sim, op1_node);
+       const arch_register_t *op2      = x87_get_irn_register(sim, op2_node);
        int reg_index_1 = arch_register_get_index(op1);
        int reg_index_2 = arch_register_get_index(op2);
        unsigned live = vfp_live_args_after(sim, n, 0);
@@ -2006,6 +2005,43 @@ static x87_state *x87_kill_deads(x87_simulator *sim, ir_node *block, x87_state *
        return state;
 }  /* x87_kill_deads */
 
+/**
+ * If we have PhiEs with unknown operands then we have to make sure that some
+ * value is actually put onto the stack.
+ */
+static void fix_unknown_phis(x87_state *state, ir_node *block,
+                             ir_node *pred_block, int pos)
+{
+       ir_node *node, *op;
+
+       sched_foreach(block, node) {
+               ir_node               *zero;
+               const arch_register_t *reg;
+               ia32_x87_attr_t       *attr;
+
+               if(!is_Phi(node))
+                       break;
+
+               op = get_Phi_pred(node, pos);
+               if(!is_ia32_Unknown_VFP(op))
+                       continue;
+
+               reg = arch_get_irn_register(state->sim->arch_env, node);
+
+               /* create a zero at end of pred block */
+               zero = new_rd_ia32_fldz(NULL, current_ir_graph, pred_block, mode_E);
+               x87_push(state, arch_register_get_index(reg), zero);
+
+               attr = get_ia32_x87_attr(zero);
+               attr->x87[2] = &ia32_st_regs[0];
+
+               assert(is_ia32_fldz(zero));
+               sched_add_before(sched_last(pred_block), zero);
+
+               set_Phi_pred(node, pos, zero);
+       }
+}
+
 /**
  * Run a simulation and fix all virtual instructions for a block.
  *
@@ -2030,6 +2066,8 @@ 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);
+       /* create a new state, will be changed */
+       state = x87_clone_state(sim, state);
 
        /* beware, n might change */
        for (n = sched_first(block); !sched_is_end(n); n = next) {
@@ -2043,12 +2081,6 @@ static void x87_simulate_block(x87_simulator *sim, ir_node *block) {
 
                func = (sim_func)op->ops.generic;
 
-               /* have work to do */
-               if (state == bl_state->begin) {
-                       /* create a new state, will be changed */
-                       state = x87_clone_state(sim, state);
-               }
-
                /* simulate it */
                node_inserted = (*func)(state, n);
 
@@ -2064,6 +2096,8 @@ static void x87_simulate_block(x87_simulator *sim, ir_node *block) {
 
        start_block = get_irg_start_block(get_irn_irg(block));
 
+       DB((dbg, LEVEL_2, "State at Block end:\n ")); DEBUG_ONLY(x87_dump_stack(state));
+
        /* check if the state must be shuffled */
        foreach_block_succ(block, edge) {
                ir_node *succ = get_edge_src_irn(edge);
@@ -2074,10 +2108,16 @@ static void x87_simulate_block(x87_simulator *sim, ir_node *block) {
 
                succ_state = x87_get_bl_state(sim, succ);
 
+               fix_unknown_phis(state, succ, block, get_edge_src_pos(edge));
+
                if (succ_state->begin == NULL) {
+                       DB((dbg, LEVEL_2, "Set begin state for succ %+F:\n", succ));
+                       DEBUG_ONLY(x87_dump_stack(state));
                        succ_state->begin = state;
+
                        waitq_put(sim->worklist, succ);
                } else {
+                       DB((dbg, LEVEL_2, "succ %+F already has a state, shuffling\n", succ));
                        /* There is already a begin state for the successor, bad.
                           Do the necessary permutations.
                           Note that critical edges are removed, so this is always possible:
@@ -2088,8 +2128,6 @@ static void x87_simulate_block(x87_simulator *sim, ir_node *block) {
                }
        }
        bl_state->end = state;
-
-       DB((dbg, LEVEL_2, "State at Block end:\n ")); DEBUG_ONLY(x87_dump_stack(state));
 }  /* x87_simulate_block */
 
 /**
@@ -2128,9 +2166,6 @@ static void x87_init_simulator(x87_simulator *sim, ir_graph *irg,
        ASSOC_IA32(fprem);
        ASSOC_IA32(fabs);
        ASSOC_IA32(fchs);
-       ASSOC_IA32(fsin);
-       ASSOC_IA32(fcos);
-       ASSOC_IA32(fsqrt);
        ASSOC_IA32(fist);
        ASSOC_IA32(fst);
        ASSOC_IA32(fCondJmp);