OSDN Git Service

* simplify-rtx.c (simplify_binary_operation_1): Try to simplify away
authorbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 3 Aug 2010 23:48:52 +0000 (23:48 +0000)
committerbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 3 Aug 2010 23:48:52 +0000 (23:48 +0000)
NEG as operand of a MULT by merging it with the other operand.
* combine.c (make_compound_operation): Use trunc_int_for_mode when
generating a MULT with constant.  Canonicalize PLUS and MINUS involving
MULT.
* config/arm/constraints.md (M): Examine only 32 bits of a
HOST_WIDE_INT.
* config/arm/predicates.md (power_of_two_operand): Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@162849 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/combine.c
gcc/config/arm/constraints.md
gcc/config/arm/predicates.md
gcc/simplify-rtx.c

index d9da4e3..0361f83 100644 (file)
@@ -1,3 +1,14 @@
+2010-08-03  Bernd Schmidt  <bernds@codesourcery.com>
+
+       * simplify-rtx.c (simplify_binary_operation_1): Try to simplify away
+       NEG as operand of a MULT by merging it with the other operand.
+       * combine.c (make_compound_operation): Use trunc_int_for_mode when
+       generating a MULT with constant.  Canonicalize PLUS and MINUS involving
+       MULT.
+       * config/arm/constraints.md (M): Examine only 32 bits of a
+       HOST_WIDE_INT.
+       * config/arm/predicates.md (power_of_two_operand): Likewise.
+
 2010-08-03  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>
 
        * config/spu/spu.c (spu_emit_branch_hint): Do not access NOTE_KIND of
index 1991f34..0725c86 100644 (file)
@@ -7110,13 +7110,79 @@ make_compound_operation (rtx x, enum rtx_code in_code)
          && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT
          && INTVAL (XEXP (x, 1)) >= 0)
        {
+         HOST_WIDE_INT count = INTVAL (XEXP (x, 1));
+         HOST_WIDE_INT multval = (HOST_WIDE_INT) 1 << count;
+
          new_rtx = make_compound_operation (XEXP (x, 0), next_code);
-         new_rtx = gen_rtx_MULT (mode, new_rtx,
-                             GEN_INT ((HOST_WIDE_INT) 1
-                                      << INTVAL (XEXP (x, 1))));
+         if (GET_CODE (new_rtx) == NEG)
+           {
+             new_rtx = XEXP (new_rtx, 0);
+             multval = -multval;
+           }
+         multval = trunc_int_for_mode (multval, mode);
+         new_rtx = gen_rtx_MULT (mode, new_rtx, GEN_INT (multval));
        }
       break;
 
+    case PLUS:
+      lhs = XEXP (x, 0);
+      rhs = XEXP (x, 1);
+      lhs = make_compound_operation (lhs, MEM);
+      rhs = make_compound_operation (rhs, MEM);
+      if (GET_CODE (lhs) == MULT && GET_CODE (XEXP (lhs, 0)) == NEG
+         && SCALAR_INT_MODE_P (mode))
+       {
+         tem = simplify_gen_binary (MULT, mode, XEXP (XEXP (lhs, 0), 0),
+                                    XEXP (lhs, 1));
+         new_rtx = simplify_gen_binary (MINUS, mode, rhs, tem);
+       }
+      else if (GET_CODE (lhs) == MULT
+              && (CONST_INT_P (XEXP (lhs, 1)) && INTVAL (XEXP (lhs, 1)) < 0))
+       {
+         tem = simplify_gen_binary (MULT, mode, XEXP (lhs, 0),
+                                    simplify_gen_unary (NEG, mode,
+                                                        XEXP (lhs, 1),
+                                                        mode));
+         new_rtx = simplify_gen_binary (MINUS, mode, rhs, tem);
+       }
+      else
+       {
+         SUBST (XEXP (x, 0), lhs);
+         SUBST (XEXP (x, 1), rhs);
+         goto maybe_swap;
+       }
+      x = gen_lowpart (mode, new_rtx);
+      goto maybe_swap;
+
+    case MINUS:
+      lhs = XEXP (x, 0);
+      rhs = XEXP (x, 1);
+      lhs = make_compound_operation (lhs, MEM);
+      rhs = make_compound_operation (rhs, MEM);
+      if (GET_CODE (rhs) == MULT && GET_CODE (XEXP (rhs, 0)) == NEG
+         && SCALAR_INT_MODE_P (mode))
+       {
+         tem = simplify_gen_binary (MULT, mode, XEXP (XEXP (rhs, 0), 0),
+                                    XEXP (rhs, 1));
+         new_rtx = simplify_gen_binary (PLUS, mode, tem, lhs);
+       }
+      else if (GET_CODE (rhs) == MULT
+              && (CONST_INT_P (XEXP (rhs, 1)) && INTVAL (XEXP (rhs, 1)) < 0))
+       {
+         tem = simplify_gen_binary (MULT, mode, XEXP (rhs, 0),
+                                    simplify_gen_unary (NEG, mode,
+                                                        XEXP (rhs, 1),
+                                                        mode));
+         new_rtx = simplify_gen_binary (PLUS, mode, tem, lhs);
+       }
+      else
+       {
+         SUBST (XEXP (x, 0), lhs);
+         SUBST (XEXP (x, 1), rhs);
+         return x;
+       }
+      return gen_lowpart (mode, new_rtx);
+
     case AND:
       /* If the second operand is not a constant, we can't do anything
         with it.  */
@@ -7345,6 +7411,7 @@ make_compound_operation (rtx x, enum rtx_code in_code)
          SUBST (XVECEXP (x, i, j), new_rtx);
        }
 
+ maybe_swap:
   /* If this is a commutative operation, the changes to the operands
      may have made it noncanonical.  */
   if (COMMUTATIVE_ARITH_P (x)
index 9ee681c..fce8b5e 100644 (file)
  "In Thumb-1 state a constant that is a multiple of 4 in the range 0-1020."
  (and (match_code "const_int")
       (match_test "TARGET_32BIT ? ((ival >= 0 && ival <= 32)
-                                || ((ival & (ival - 1)) == 0))
+                                || (((ival & (ival - 1)) & 0xFFFFFFFF) == 0))
                   : ival >= 0 && ival <= 1020 && (ival & 3) == 0")))
 
 (define_constraint "N"
index 235545b..5481708 100644 (file)
 (define_predicate "power_of_two_operand"
   (match_code "const_int")
 {
-  HOST_WIDE_INT value = INTVAL (op);
+  unsigned HOST_WIDE_INT value = INTVAL (op) & 0xffffffff;
 
   return value != 0 && (value & (value - 1)) == 0;
 })
index 8e29d2d..86de77e 100644 (file)
@@ -2109,6 +2109,19 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
       if (trueop1 == constm1_rtx)
        return simplify_gen_unary (NEG, mode, op0, mode);
 
+      if (GET_CODE (op0) == NEG)
+       {
+         rtx temp = simplify_unary_operation (NEG, mode, op1, mode);
+         if (temp)
+           return simplify_gen_binary (MULT, mode, XEXP (op0, 0), temp);
+       }
+      if (GET_CODE (op1) == NEG)
+       {
+         rtx temp = simplify_unary_operation (NEG, mode, op0, mode);
+         if (temp)
+           return simplify_gen_binary (MULT, mode, temp, XEXP (op1, 0));
+       }
+
       /* Maybe simplify x * 0 to 0.  The reduction is not valid if
         x is NaN, since x * 0 is then also NaN.  Nor is it valid
         when the mode has signed zeros, since multiplying a negative