Replace x87_fxch_shuffle() + sched_add_before() by x87_create_fxch().
[libfirm] / ir / be / ia32 / ia32_x87.c
index 702ce99..202f57b 100644 (file)
@@ -420,36 +420,34 @@ static inline const arch_register_t *get_st_reg(int index)
        return &ia32_registers[REG_ST0 + index];
 }
 
-/* -------------- x87 perm --------------- */
-
 /**
- * Creates a fxch for shuffle.
- *
- * @param state     the x87 state
- * @param pos       parameter for fxch
- * @param block     the block were fxch is inserted
+ * Create a fxch node before another node.
  *
- * Creates a new fxch node and reroute the user of the old node
- * to the fxch.
+ * @param state   the x87 state
+ * @param n       the node after the fxch
+ * @param pos     exchange st(pos) with st(0)
  *
- * @return the fxch node
+ * @return the fxch
  */
-static ir_node *x87_fxch_shuffle(x87_state *state, int pos, ir_node *block)
+static ir_node *x87_create_fxch(x87_state *state, ir_node *n, int pos)
 {
-       ir_node         *fxch;
-       ia32_x87_attr_t *attr;
+       x87_fxch(state, pos);
 
-       fxch = new_bd_ia32_fxch(NULL, block);
-       attr = get_ia32_x87_attr(fxch);
+       ir_node         *const block = get_nodes_block(n);
+       ir_node         *const fxch  = new_bd_ia32_fxch(NULL, block);
+       ia32_x87_attr_t *const attr  = get_ia32_x87_attr(fxch);
        attr->x87[0] = get_st_reg(pos);
        attr->x87[2] = get_st_reg(0);
 
        keep_alive(fxch);
 
-       x87_fxch(state, pos);
+       sched_add_before(n, fxch);
+       DB((dbg, LEVEL_1, "<<< %s %s, %s\n", get_irn_opname(fxch), attr->x87[0]->name, attr->x87[2]->name));
        return fxch;
 }
 
+/* -------------- x87 perm --------------- */
+
 /**
  * Calculate the necessary permutations to reach dst_state.
  *
@@ -470,7 +468,6 @@ static x87_state *x87_shuffle(ir_node *block, x87_state *state, const x87_state
        int      i, n_cycles, k, ri;
        unsigned cycles[4], all_mask;
        char     cycle_idx[4][8];
-       ir_node  *fxch, *before, *after;
 
        assert(state->depth == dst_state->depth);
 
@@ -546,84 +543,41 @@ static x87_state *x87_shuffle(ir_node *block, x87_state *state, const x87_state
        }
 #endif
 
-       after = NULL;
-
        /*
         * Find the place node must be insert.
         * We have only one successor block, so the last instruction should
         * be a jump.
         */
-       before = sched_last(block);
+       ir_node *const before = sched_last(block);
        assert(is_cfop(before));
 
        /* now do the permutations */
        for (ri = 0; ri < n_cycles; ++ri) {
                if ((cycles[ri] & 1) == 0) {
                        /* this cycle does not include the tos */
-                       fxch = x87_fxch_shuffle(state, cycle_idx[ri][0], block);
-                       if (after)
-                               sched_add_after(after, fxch);
-                       else
-                               sched_add_before(before, fxch);
-                       after = fxch;
+                       x87_create_fxch(state, before, cycle_idx[ri][0]);
                }
                for (k = 1; cycle_idx[ri][k] != -1; ++k) {
-                       fxch = x87_fxch_shuffle(state, cycle_idx[ri][k], block);
-                       if (after)
-                               sched_add_after(after, fxch);
-                       else
-                               sched_add_before(before, fxch);
-                       after = fxch;
+                       x87_create_fxch(state, before, cycle_idx[ri][k]);
                }
                if ((cycles[ri] & 1) == 0) {
                        /* this cycle does not include the tos */
-                       fxch = x87_fxch_shuffle(state, cycle_idx[ri][0], block);
-                       sched_add_after(after, fxch);
+                       x87_create_fxch(state, before, cycle_idx[ri][0]);
                }
        }
        return state;
 }
 
-/**
- * Create a fxch node before another node.
- *
- * @param state   the x87 state
- * @param n       the node after the fxch
- * @param pos     exchange st(pos) with st(0)
- *
- * @return the fxch
- */
-static ir_node *x87_create_fxch(x87_state *state, ir_node *n, int pos)
-{
-       ir_node         *fxch;
-       ia32_x87_attr_t *attr;
-       ir_node         *block = get_nodes_block(n);
-
-       x87_fxch(state, pos);
-
-       fxch = new_bd_ia32_fxch(NULL, block);
-       attr = get_ia32_x87_attr(fxch);
-       attr->x87[0] = get_st_reg(pos);
-       attr->x87[2] = get_st_reg(0);
-
-       keep_alive(fxch);
-
-       sched_add_before(n, fxch);
-       DB((dbg, LEVEL_1, "<<< %s %s, %s\n", get_irn_opname(fxch), attr->x87[0]->name, attr->x87[2]->name));
-       return fxch;
-}
-
 /**
  * Create a fpush before node n.
  *
  * @param state     the x87 state
  * @param n         the node after the fpush
  * @param pos       push st(pos) on stack
- * @param op_idx    replace input op_idx of n with the fpush result
+ * @param val       the value to push
  */
-static void x87_create_fpush(x87_state *state, ir_node *n, int pos, int op_idx)
+static void x87_create_fpush(x87_state *state, ir_node *n, int pos, ir_node *const val)
 {
-       ir_node               *const val = get_irn_n(n, op_idx);
        arch_register_t const *const out = x87_get_irn_register(val);
        x87_push_dbl(state, arch_register_get_index(out), val);
 
@@ -874,7 +828,7 @@ static int sim_binop(x87_state *state, ir_node *n, const exchange_tmpl *tmpl)
                        if (op1_live_after) {
                                /* Both operands are live: push the first one.
                                   This works even for op1 == op2. */
-                               x87_create_fpush(state, n, op1_idx, n_ia32_binary_right);
+                               x87_create_fpush(state, n, op1_idx, op2);
                                /* now do fxxx (tos=tos X op) */
                                op1_idx = 0;
                                op2_idx += 1;
@@ -950,7 +904,7 @@ static int sim_binop(x87_state *state, ir_node *n, const exchange_tmpl *tmpl)
                /* second operand is an address mode */
                if (op1_live_after) {
                        /* first operand is live: push it here */
-                       x87_create_fpush(state, n, op1_idx, n_ia32_binary_left);
+                       x87_create_fpush(state, n, op1_idx, op1);
                        op1_idx = 0;
                } else {
                        /* first operand is dead: bring it to tos */
@@ -1007,12 +961,13 @@ static int sim_unop(x87_state *state, ir_node *n, ir_op *op)
        DB((dbg, LEVEL_1, ">>> %+F -> %s\n", n, out->name));
        DEBUG_ONLY(vfp_dump_live(live);)
 
-       arch_register_t const *const op1_reg     = x87_get_irn_register(get_irn_n(n, 0));
+       ir_node               *const op1         = get_irn_n(n, 0);
+       arch_register_t const *const op1_reg     = x87_get_irn_register(op1);
        int                    const op1_reg_idx = arch_register_get_index(op1_reg);
        int                    const op1_idx     = x87_on_stack(state, op1_reg_idx);
        if (is_vfp_live(op1_reg_idx, live)) {
                /* push the operand here */
-               x87_create_fpush(state, n, op1_idx, 0);
+               x87_create_fpush(state, n, op1_idx, op1);
        } else {
                /* operand is dead, bring it to tos */
                if (op1_idx != 0) {
@@ -1110,7 +1065,7 @@ static int sim_store(x87_state *state, ir_node *n, ir_op *op, ir_op *op_p)
                if (get_mode_size_bits(mode) > (mode_is_int(mode) ? 32 : 64)) {
                        if (x87_get_depth(state) < N_ia32_st_REGS) {
                                /* ok, we have a free register: push + fstp */
-                               x87_create_fpush(state, n, op2_idx, n_ia32_vfst_val);
+                               x87_create_fpush(state, n, op2_idx, val);
                                x87_pop(state);
                                x87_patch_insn(n, op_p);
                        } else {