From 6336e65949c0e379eff83a8c7db182bb6e0f0a94 Mon Sep 17 00:00:00 2001 From: Christoph Mallon Date: Sat, 11 Oct 2008 08:42:11 +0000 Subject: [PATCH] vfsub and vfdiv are now commutative, because there are reversed forms of these instructions. This enables more AM folding. [r22664] --- ir/be/ia32/ia32_transform.c | 25 ++++++++++++++----------- ir/be/ia32/ia32_x87.c | 18 ++++++++++-------- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/ir/be/ia32/ia32_transform.c b/ir/be/ia32/ia32_transform.c index ab8cf6991..f54872b47 100644 --- a/ir/be/ia32/ia32_transform.c +++ b/ir/be/ia32/ia32_transform.c @@ -878,18 +878,21 @@ static ir_node *get_fpcw(void) * @return The constructed ia32 node. */ static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2, - construct_binop_float_func *func, - match_flags_t flags) + construct_binop_float_func *func) { ir_mode *mode = get_irn_mode(node); dbg_info *dbgi; ir_node *block, *new_block, *new_node; ia32_address_mode_t am; ia32_address_t *addr = &am.addr; + ia32_x87_attr_t *attr; + /* All operations are considered commutative, because there are reverse + * variants */ + match_flags_t flags = match_commutative; /* cannot use address mode with long double on x87 */ - if (get_mode_size_bits(mode) > 64) - flags &= ~match_am; + if (get_mode_size_bits(mode) <= 64) + flags |= match_am; block = get_nodes_block(node); match_arguments(&am, block, op1, op2, NULL, flags); @@ -901,6 +904,9 @@ static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2, am.new_op1, am.new_op2, get_fpcw()); set_am_attributes(new_node, &am); + attr = get_ia32_x87_attr(new_node); + attr->attr.data.ins_permuted = am.ins_permuted; + SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node)); new_node = fix_mem_proj(new_node, &am); @@ -1047,8 +1053,7 @@ static ir_node *gen_Add(ir_node *node) { return gen_binop(node, op1, op2, new_rd_ia32_xAdd, match_commutative | match_am); else - return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd, - match_commutative | match_am); + return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd); } ia32_mark_non_am(node); @@ -1141,8 +1146,7 @@ static ir_node *gen_Mul(ir_node *node) { return gen_binop(node, op1, op2, new_rd_ia32_xMul, match_commutative | match_am); else - return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul, - match_commutative | match_am); + return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul); } return gen_binop(node, op1, op2, new_rd_ia32_IMul, match_commutative | match_am | match_mode_neutral | @@ -1262,8 +1266,7 @@ static ir_node *gen_Sub(ir_node *node) { if (ia32_cg_config.use_sse2) return gen_binop(node, op1, op2, new_rd_ia32_xSub, match_am); else - return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfsub, - match_am); + return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfsub); } if (is_Const(op2)) { @@ -1425,7 +1428,7 @@ static ir_node *gen_Quot(ir_node *node) if (ia32_cg_config.use_sse2) { return gen_binop(node, op1, op2, new_rd_ia32_xDiv, match_am); } else { - return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv, match_am); + return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv); } } diff --git a/ir/be/ia32/ia32_x87.c b/ir/be/ia32/ia32_x87.c index 9a6b1d42f..644e11ad4 100644 --- a/ir/be/ia32/ia32_x87.c +++ b/ir/be/ia32/ia32_x87.c @@ -900,6 +900,7 @@ static int sim_binop(x87_state *state, ir_node *n, const exchange_tmpl *tmpl) { int op2_idx = 0, op1_idx; int out_idx, do_pop = 0; ia32_x87_attr_t *attr; + int permuted; ir_node *patched_insn; ir_op *dst; x87_simulator *sim = state->sim; @@ -930,7 +931,12 @@ static int sim_binop(x87_state *state, ir_node *n, const exchange_tmpl *tmpl) { op1_live_after = is_vfp_live(arch_register_get_index(op1_reg), live); } + attr = get_ia32_x87_attr(n); + permuted = attr->attr.data.ins_permuted; + if (reg_index_2 != REG_VFP_NOREG) { + assert(!permuted); + if(reg_index_2 == REG_VFP_UKNWN) { op2_idx = 0; op2_live_after = 1; @@ -1026,20 +1032,17 @@ static int sim_binop(x87_state *state, ir_node *n, const exchange_tmpl *tmpl) { /* first operand is live: push it here */ x87_create_fpush(state, n, op1_idx, n_ia32_binary_left); op1_idx = 0; - /* use fxxx (tos = tos X mem) */ - dst = tmpl->normal_op; - out_idx = 0; } else { /* first operand is dead: bring it to tos */ if (op1_idx != 0) { x87_create_fxch(state, n, op1_idx); op1_idx = 0; } - - /* use fxxxp (tos = tos X mem) */ - dst = tmpl->normal_op; - out_idx = 0; } + + /* use fxxx (tos = tos X mem) */ + dst = permuted ? tmpl->reverse_op : tmpl->normal_op; + out_idx = 0; } patched_insn = x87_patch_insn(n, dst); @@ -1049,7 +1052,6 @@ static int sim_binop(x87_state *state, ir_node *n, const exchange_tmpl *tmpl) { } /* patch the operation */ - attr = get_ia32_x87_attr(n); attr->x87[0] = op1_reg = &ia32_st_regs[op1_idx]; if (reg_index_2 != REG_VFP_NOREG) { attr->x87[1] = op2_reg = &ia32_st_regs[op2_idx]; -- 2.20.1