vfsub and vfdiv are now commutative, because there are reversed forms of these instru...
authorChristoph Mallon <christoph.mallon@gmx.de>
Sat, 11 Oct 2008 08:42:11 +0000 (08:42 +0000)
committerChristoph Mallon <christoph.mallon@gmx.de>
Sat, 11 Oct 2008 08:42:11 +0000 (08:42 +0000)
[r22664]

ir/be/ia32/ia32_transform.c
ir/be/ia32/ia32_x87.c

index ab8cf69..f54872b 100644 (file)
@@ -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);
        }
 }
 
index 9a6b1d4..644e11a 100644 (file)
@@ -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];