return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
}
+/* Return whether OP0 and OP1 should be swapped when expanding a commutative
+ binop. Order them according to commutative_operand_precedence and, if
+ possible, try to put TARGET or a pseudo first. */
+static bool
+swap_commutative_operands_with_target (rtx target, rtx op0, rtx op1)
+{
+ int op0_prec = commutative_operand_precedence (op0);
+ int op1_prec = commutative_operand_precedence (op1);
+
+ if (op0_prec < op1_prec)
+ return true;
+
+ if (op0_prec > op1_prec)
+ return false;
+
+ /* With equal precedence, both orders are ok, but it is better if the
+ first operand is TARGET, or if both TARGET and OP0 are pseudos. */
+ if (target == 0 || REG_P (target))
+ return (REG_P (op1) && !REG_P (op0)) || target == op1;
+ else
+ return rtx_equal_p (op1, target);
+}
+
+
/* Generate code to perform an operation specified by BINOPTAB
on operands OP0 and OP1, with result having machine-mode MODE.
{
commutative_op = 1;
- if (((target == 0 || REG_P (target))
- ? ((REG_P (op1)
- && !REG_P (op0))
- || target == op1)
- : rtx_equal_p (op1, target))
- || GET_CODE (op0) == CONST_INT)
+ if (swap_commutative_operands_with_target (target, op0, op1))
{
temp = op1;
op1 = op0;
sync_lock_test_and_set[i] = CODE_FOR_nothing;
sync_lock_release[i] = CODE_FOR_nothing;
-#ifdef HAVE_SECONDARY_RELOADS
reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
-#endif
}
/* Fill in the optabs with the insns we support. */
cc_op1 = XEXP (comparison, 1);
/* Expand both operands and force them in reg, if required. */
rtx_op1 = expand_expr (TREE_OPERAND (vec_cond_expr, 1),
- NULL_RTX, VOIDmode, 1);
+ NULL_RTX, VOIDmode, EXPAND_NORMAL);
if (!insn_data[icode].operand[1].predicate (rtx_op1, mode)
&& mode != VOIDmode)
rtx_op1 = force_reg (mode, rtx_op1);
rtx_op2 = expand_expr (TREE_OPERAND (vec_cond_expr, 2),
- NULL_RTX, VOIDmode, 1);
+ NULL_RTX, VOIDmode, EXPAND_NORMAL);
if (!insn_data[icode].operand[2].predicate (rtx_op2, mode)
&& mode != VOIDmode)
rtx_op2 = force_reg (mode, rtx_op2);