- return tem ? tem : gen_rtx (NEG, mode, XEXP (op1, 1));
- }
- else if (GET_CODE (op1) == PLUS
- && rtx_equal_p (XEXP (op1, 1), op0)
- && ! side_effects_p (op0))
- {
- rtx tem = simplify_unary_operation (NEG, mode, XEXP (op1, 0),
- mode);
-
- return tem ? tem : gen_rtx (NEG, mode, XEXP (op1, 0));
- }
-
- /* a - (a - b) -> b */
- if (GET_CODE (op1) == MINUS && rtx_equal_p (op0, XEXP (op1, 0))
- && ! side_effects_p (op0))
- return XEXP (op1, 1);
-
- /* (a +/- b) - (a +/- c) can be simplified. Do variants of
- this involving commutativity. The most common case is
- (a + C1) - (a + C2), but it's not hard to do all the cases. */
- if ((GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS)
- && (GET_CODE (op1) == PLUS || GET_CODE (op1) == MINUS))
- {
- rtx lhs0 = XEXP (op0, 0), lhs1 = XEXP (op0, 1);
- rtx rhs0 = XEXP (op1, 0), rhs1 = XEXP (op1, 1);
- int lhs_neg = GET_CODE (op0) == MINUS;
- int rhs_neg = GET_CODE (op1) == MINUS;
- rtx lhs = 0, rhs = 0;
-
- /* Set LHS and RHS to the two different terms. */
- if (rtx_equal_p (lhs0, rhs0) && ! side_effects_p (lhs0))
- lhs = lhs1, rhs = rhs1;
- else if (! rhs_neg && rtx_equal_p (lhs0, rhs1)
- && ! side_effects_p (lhs0))
- lhs = lhs1, rhs = rhs0;
- else if (! lhs_neg && rtx_equal_p (lhs1, rhs0)
- && ! side_effects_p (lhs1))
- lhs = lhs0, rhs = rhs1;
- else if (! lhs_neg && ! rhs_neg && rtx_equal_p (lhs1, rhs1)
- && ! side_effects_p (lhs1))
- lhs = lhs0, rhs = rhs0;
-
- /* The RHS is the operand of a MINUS, so its negation
- status should be complemented. */
- rhs_neg = ! rhs_neg;
-
- /* If we found two values equal, form the sum or difference
- of the remaining two terms. */
- if (lhs)
- {
- rtx tem = simplify_binary_operation (lhs_neg == rhs_neg
- ? PLUS : MINUS,
- mode,
- lhs_neg ? rhs : lhs,
- lhs_neg ? lhs : rhs);
- if (tem == 0)
- tem = gen_rtx (lhs_neg == rhs_neg
- ? PLUS : MINUS,
- mode, lhs_neg ? rhs : lhs,
- lhs_neg ? lhs : rhs);
-
- /* If both sides negated, negate result. */
- if (lhs_neg && rhs_neg)
- {
- rtx tem1
- = simplify_unary_operation (NEG, mode, tem, mode);
- if (tem1 == 0)
- tem1 = gen_rtx (NEG, mode, tem);
- tem = tem1;
- }
-
- return tem;
- }
-
- return 0;
- }
-
- /* c1 - (a + c2) becomes (c1 - c2) - a. */
- if (GET_CODE (op0) == CONST_INT && GET_CODE (op1) == PLUS
- && GET_CODE (XEXP (op1, 1)) == CONST_INT)
- {
- rtx tem = simplify_binary_operation (MINUS, mode, op0,
- XEXP (op1, 1));
-
- return tem ? gen_rtx (MINUS, mode, tem, XEXP (op1, 0)) : 0;
- }
-
- /* c1 - (c2 - a) becomes (c1 - c2) + a. */
- if (GET_CODE (op0) == CONST_INT && GET_CODE (op1) == MINUS
- && GET_CODE (XEXP (op1, 0)) == CONST_INT)
- {
- rtx tem = simplify_binary_operation (MINUS, mode, op0,
- XEXP (op1, 0));
-
- return (tem && GET_CODE (tem) == CONST_INT
- ? plus_constant (XEXP (op1, 1), INTVAL (tem))
- : 0);
- }