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.
*
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);
}
#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);
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;
/* 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 */
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) {
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 {