]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[multiple changes]
authorDavid Edelsohn <dje@gcc.gnu.org>
Wed, 22 Mar 2000 18:54:05 +0000 (13:54 -0500)
committerDavid Edelsohn <dje@gcc.gnu.org>
Wed, 22 Mar 2000 18:54:05 +0000 (13:54 -0500)
Wed Mar 22 13:11:54 2000  David Edelsohn  <edelsohn@gnu.org>

        * rs6000.c (reg_or_u_cint_operand): New function.
        (logical_operand): Handle 64-bit hosts.
        (logical_u_operand): New function.
        (non_logical_cint_operand): Handle 64-bit hosts.
        (non_logical_u_cint_operand): New function.
        (expand_block_move): Allow 8 DImode loads for PowerPC64.
        * rs6000.h (PREDICATE_CODES): Define new functions.
        * rs6000.md (iordi3, xordi3): Constant int must be unsigned 32-bits.
        (movdi_64): Bracket code intended for 64-bit hosts.  Create
        CONST_DOUBLE for 32-bit values.

Wed Mar 22 13:11:54 2000  Gabriel Paubert  <paubert@iram.es>

        * rs6000.md: Correct instructions length attributes and
        constraints on unsigned compare instructions.
        (*ne0): Disable for PowerPC64.

From-SVN: r32687

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/config/rs6000/rs6000.md

index 8e83eb9a17c77c781ae24bbf59794ae03094c1e9..fd99f0927d8bf3a4c97c25127f1de47a4299c72e 100644 (file)
@@ -1,3 +1,22 @@
+Wed Mar 22 13:11:54 2000  David Edelsohn  <edelsohn@gnu.org>
+
+       * rs6000.c (reg_or_u_cint_operand): New function.
+       (logical_operand): Handle 64-bit hosts.
+       (logical_u_operand): New function.
+       (non_logical_cint_operand): Handle 64-bit hosts.
+       (non_logical_u_cint_operand): New function.
+       (expand_block_move): Allow 8 DImode loads for PowerPC64.
+       * rs6000.h (PREDICATE_CODES): Define new functions.
+       * rs6000.md (iordi3, xordi3): Constant int must be unsigned 32-bits.
+       (movdi_64): Bracket code intended for 64-bit hosts.  Create
+       CONST_DOUBLE for 32-bit values.
+
+Wed Mar 22 13:11:54 2000  Gabriel Paubert  <paubert@iram.es>
+
+       * rs6000.md: Correct instructions length attributes and
+       constraints on unsigned compare instructions.
+       (*ne0): Disable for PowerPC64.
+       
 Tue Mar  7 21:41:17 2000  Jeffrey A Law  (law@cygnus.com)
 
        * cccp.c (handle_directive): Initialize backslash_newlines_p.
index 4595866ac0dd8d28177510243ff5fa3e7bae0543..51291d492caa2b91edbbe16b6001d9f46c696bab 100644 (file)
@@ -623,6 +623,27 @@ reg_or_cint_operand (op, mode)
             || gpc_reg_operand (op, mode));
 }
 
+/* Return 1 is the operand is either a non-special register or ANY
+   32-bit unsigned constant integer.  */
+
+int
+reg_or_u_cint_operand (op, mode)
+    register rtx op;
+    enum machine_mode mode;
+{
+     return (gpc_reg_operand (op, mode)
+            || (GET_CODE (op) == CONST_INT
+#if HOST_BITS_PER_WIDE_INT != 32
+                && INTVAL (op) < ((HOST_WIDE_INT) 1 << 32)
+#endif
+                && INTVAL (op) > 0)
+#if HOST_BITS_PER_WIDE_INT == 32
+            || (GET_CODE (op) == CONST_DOUBLE
+                && CONST_DOUBLE_HIGH (op) == 0)
+#endif
+        );
+}
+
 /* Return 1 if the operand is an operand that can be loaded via the GOT */
 
 int
@@ -905,8 +926,41 @@ logical_operand (op, mode)
 {
   return (gpc_reg_operand (op, mode)
          || (GET_CODE (op) == CONST_INT
-             && ((INTVAL (op) & (~ (HOST_WIDE_INT) 0xffff)) == 0
-                 || (INTVAL (op) & (~ (HOST_WIDE_INT) 0xffff0000)) == 0)));
+#if HOST_BITS_PER_WIDE_INT != 32
+             && INTVAL (op) > 0
+             && INTVAL (op) < ((HOST_WIDE_INT) 1 << 32)
+#endif
+             && ((INTVAL (op) & GET_MODE_MASK (mode)
+                  & (~ (HOST_WIDE_INT) 0xffff)) == 0
+                 || (INTVAL (op) & GET_MODE_MASK (mode)
+                     & (~ (unsigned HOST_WIDE_INT) 0xffff0000u)) == 0)));
+}
+
+/* Return 1 if the operand is a non-special register or a 32-bit constant
+   that can be used as the operand of an OR or XOR insn on the RS/6000.  */
+
+int
+logical_u_operand (op, mode)
+     register rtx op;
+     enum machine_mode mode;
+{
+  return (gpc_reg_operand (op, mode)
+         || (GET_CODE (op) == CONST_INT
+             && INTVAL (op) > 0
+#if HOST_BITS_PER_WIDE_INT != 32
+             && INTVAL (op) < ((HOST_WIDE_INT) 1 << 32)
+#endif
+             && ((INTVAL (op) & GET_MODE_MASK (mode)
+                  & (~ (HOST_WIDE_INT) 0xffff)) == 0
+                 || (INTVAL (op) & GET_MODE_MASK (mode)
+                     & (~ (unsigned HOST_WIDE_INT) 0xffff0000u)) == 0))
+#if HOST_BITS_PER_WIDE_INT == 32
+         || (GET_CODE (op) == CONST_DOUBLE
+             && CONST_DOUBLE_HIGH (op) == 0
+             && ((CONST_DOUBLE_LOW (op)
+                  & (~ (unsigned HOST_WIDE_INT) 0xffff0000u)) == 0))
+#endif
+      );
 }
 
 /* Return 1 if C is a constant that is not a logical operand (as
@@ -918,8 +972,39 @@ non_logical_cint_operand (op, mode)
      enum machine_mode mode ATTRIBUTE_UNUSED;
 {
   return (GET_CODE (op) == CONST_INT
-         && (INTVAL (op) & (~ (HOST_WIDE_INT) 0xffff)) != 0
-         && (INTVAL (op) & (~ (HOST_WIDE_INT) 0xffff0000)) != 0);
+#if HOST_BITS_PER_WIDE_INT != 32
+         && INTVAL (op) < ((HOST_WIDE_INT) 1 << 32)
+#endif
+         && (INTVAL (op) & GET_MODE_MASK (mode) &
+             (~ (HOST_WIDE_INT) 0xffff)) != 0
+         && (INTVAL (op) & GET_MODE_MASK (mode) &
+             (~ (unsigned HOST_WIDE_INT) 0xffff0000u)) != 0);
+}
+
+/* Return 1 if C is an unsigned 32-bit constant that is not a
+   logical operand (as above).  */
+
+int
+non_logical_u_cint_operand (op, mode)
+     register rtx op;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+  return ((GET_CODE (op) == CONST_INT
+          && INTVAL (op) > 0
+#if HOST_BITS_PER_WIDE_INT != 32
+          && INTVAL (op) < ((HOST_WIDE_INT) 1 << 32)
+#endif
+          && (INTVAL (op) & GET_MODE_MASK (mode)
+              & (~ (HOST_WIDE_INT) 0xffff)) != 0
+          && (INTVAL (op) & GET_MODE_MASK (mode)
+              & (~ (unsigned HOST_WIDE_INT) 0xffff0000u)) != 0)
+#if HOST_BITS_PER_WIDE_INT == 32
+         || (GET_CODE (op) == CONST_DOUBLE
+             && CONST_DOUBLE_HIGH (op) == 0
+             && (CONST_DOUBLE_LOW (op) & (~ (HOST_WIDE_INT) 0xffff)) != 0
+             && (CONST_DOUBLE_LOW (op)
+                 & (~ (unsigned HOST_WIDE_INT) 0xffff0000u)) != 0));
+#endif
 }
 
 /* Return 1 if C is a constant that can be encoded in a 32-bit mask on the
@@ -1916,13 +2001,19 @@ expand_block_move (operands)
      then don't generate more than 8 loads.  */
   if (TARGET_STRING)
     {
-      if (bytes > 4*8)
+      if (bytes > 8*4)
        return 0;
     }
   else if (! STRICT_ALIGNMENT)
     {
-      if (bytes > 4*8)
-       return 0;
+      if (TARGET_POWERPC64 && align >= 4)
+       {
+         if (bytes > 8*8)
+           return 0;
+       }
+      else
+       if (bytes > 8*4)
+         return 0;
     }
   else if (bytes > 8*align)
     return 0;
index 489f844efacff740648f1ed558d689be82152139..4fb7a5bc1cec45ce883e9a7693665d7b92b324b4 100644 (file)
@@ -3183,6 +3183,7 @@ do {                                                                      \
   {"reg_or_neg_short_operand", {SUBREG, REG, CONST_INT}},      \
   {"reg_or_u_short_operand", {SUBREG, REG, CONST_INT}},        \
   {"reg_or_cint_operand", {SUBREG, REG, CONST_INT}},           \
+  {"reg_or_u_cint_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \
   {"got_operand", {SYMBOL_REF, CONST, LABEL_REF}},             \
   {"got_no_const_operand", {SYMBOL_REF, LABEL_REF}},           \
   {"easy_fp_constant", {CONST_DOUBLE}},                                \
@@ -3196,7 +3197,9 @@ do {                                                                      \
   {"and_operand", {SUBREG, REG, CONST_INT}},                   \
   {"and64_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}},   \
   {"logical_operand", {SUBREG, REG, CONST_INT}},               \
+  {"logical_u_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \
   {"non_logical_cint_operand", {CONST_INT}},                   \
+  {"non_logical_u_cint_operand", {CONST_INT, CONST_DOUBLE}},   \
   {"mask_operand", {CONST_INT}},                               \
   {"mask64_operand", {CONST_INT, CONST_DOUBLE}},               \
   {"count_register_operand", {REG}},                           \
index 9b3c4306f77ce05ccea2c89e272d08c359b508c3..9da63a1423246e5aa07cbb671a301e4180ad513e 100644 (file)
   "TARGET_POWER"
   "@
    sle %0,%1,%2
-   {sli|slwi} %0,%1,%h2"
-  [(set_attr "length" "8")])
+   {sli|slwi} %0,%1,%h2")
 
 (define_insn "ashlsi3_no_power"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
        (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
                   (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
   "! TARGET_POWER"
-  "{sl|slw}%I2 %0,%1,%h2"
-  [(set_attr "length" "8")])
+  "{sl|slw}%I2 %0,%1,%h2")
 
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
 (define_expand "iordi3"
   [(set (match_operand:DI 0 "gpc_reg_operand" "")
        (ior:DI (match_operand:DI 1 "gpc_reg_operand" "")
-               (match_operand:DI 2 "reg_or_cint_operand" "")))]
+               (match_operand:DI 2 "reg_or_u_cint_operand" "")))]
   "TARGET_POWERPC64"
   "
 {
   if (GET_CODE (operands[2]) == CONST_INT
-      && ! logical_operand (operands[2], DImode))
+      && ! logical_u_operand (operands[2], DImode))
     {
       HOST_WIDE_INT value = INTVAL (operands[2]);
       rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1]))
       emit_insn (gen_iordi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
       DONE;
     }
+  else if (GET_CODE (operands[2]) == CONST_DOUBLE
+      && ! logical_u_operand (operands[2], DImode))
+    {
+      HOST_WIDE_INT value = CONST_DOUBLE_LOW (operands[2]);
+      rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1]))
+                ? operands[0] : gen_reg_rtx (DImode));
+
+      emit_insn (gen_iordi3 (tmp, operands[1],
+                            immed_double_const (value
+                                                & (~ (HOST_WIDE_INT) 0xffff),
+                                                0, DImode)));
+      emit_insn (gen_iordi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
+      DONE;
+    }
 }")
 
 (define_insn "*iordi3_internal1"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
        (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
-               (match_operand:DI 2 "logical_operand" "r,K,J")))]
+               (match_operand:DI 2 "logical_u_operand" "r,K,JF")))]
   "TARGET_POWERPC64"
   "@
    or %0,%1,%2
 (define_split
   [(set (match_operand:DI 0 "gpc_reg_operand" "")
        (ior:DI (match_operand:DI 1 "gpc_reg_operand" "")
-               (match_operand:DI 2 "non_logical_cint_operand" "")))]
+               (match_operand:DI 2 "non_logical_u_cint_operand" "")))]
   "TARGET_POWERPC64"
   [(set (match_dup 0) (ior:DI (match_dup 1) (match_dup 3)))
    (set (match_dup 0) (ior:DI (match_dup 0) (match_dup 4)))]
 "
 {
-  operands[3] = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff));
-  operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff);
+  if (GET_CODE (operands[2]) == CONST_DOUBLE)
+    {
+      HOST_WIDE_INT value = CONST_DOUBLE_LOW (operands[2]);
+      operands[3] = immed_double_const (value & (~ (HOST_WIDE_INT) 0xffff),
+                                       0, DImode);
+      operands[4] = GEN_INT (value & 0xffff);
+    }
+  else
+    {
+      operands[3] = GEN_INT (INTVAL (operands[2])
+                            & (~ (HOST_WIDE_INT) 0xffff));
+      operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff);
+    }
 }")
 
 (define_expand "xordi3"
   [(set (match_operand:DI 0 "gpc_reg_operand" "")
        (xor:DI (match_operand:DI 1 "gpc_reg_operand" "")
-               (match_operand:DI 2 "reg_or_cint_operand" "")))]
+               (match_operand:DI 2 "reg_or_u_cint_operand" "")))]
   "TARGET_POWERPC64"
   "
 {
   if (GET_CODE (operands[2]) == CONST_INT
-      && ! logical_operand (operands[2], DImode))
+      && ! logical_u_operand (operands[2], DImode))
     {
       HOST_WIDE_INT value = INTVAL (operands[2]);
       rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1]))
       emit_insn (gen_xordi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
       DONE;
     }
+  else if (GET_CODE (operands[2]) == CONST_DOUBLE
+      && ! logical_u_operand (operands[2], DImode))
+    {
+      HOST_WIDE_INT value = CONST_DOUBLE_LOW (operands[2]);
+      rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1]))
+                ? operands[0] : gen_reg_rtx (DImode));
+
+      emit_insn (gen_xordi3 (tmp, operands[1],
+                            immed_double_const (value
+                                                & (~ (HOST_WIDE_INT) 0xffff),
+                                                0, DImode)));
+      emit_insn (gen_xordi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
+      DONE;
+    }
 }")
 
 (define_insn "*xordi3_internal1"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
        (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
-               (match_operand:DI 2 "logical_operand" "r,K,J")))]
+               (match_operand:DI 2 "logical_u_operand" "r,K,JF")))]
   "TARGET_POWERPC64"
   "@
    xor %0,%1,%2
 (define_split
   [(set (match_operand:DI 0 "gpc_reg_operand" "")
         (xor:DI (match_operand:DI 1 "gpc_reg_operand" "")
-                (match_operand:DI 2 "non_logical_cint_operand" "")))]
+                (match_operand:DI 2 "non_logical_u_cint_operand" "")))]
   "TARGET_POWERPC64"
   [(set (match_dup 0) (xor:DI (match_dup 1) (match_dup 3)))
    (set (match_dup 0) (xor:DI (match_dup 0) (match_dup 4)))]
 "
 {
-  operands[3] = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff));
-  operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff);
+  if (GET_CODE (operands[2]) == CONST_DOUBLE)
+    {
+      HOST_WIDE_INT value = CONST_DOUBLE_LOW (operands[2]);
+      operands[3] = immed_double_const (value & (~ (HOST_WIDE_INT) 0xffff),
+                                       0, DImode);
+      operands[4] = GEN_INT (value & 0xffff);
+    }
+  else
+    {
+      operands[3] = GEN_INT (INTVAL (operands[2])
+                            & (~ (HOST_WIDE_INT) 0xffff));
+      operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff);
+    }
 }")
 
 (define_insn "*eqvdi3_internal1"
    (set (match_dup 3) (match_dup 1))]
   "
 {
+  HOST_WIDE_INT value = INTVAL (operands[1]);
   operands[2] = gen_rtx_SUBREG (SImode, operands[0], WORDS_BIG_ENDIAN == 0);
   operands[3] = gen_rtx_SUBREG (SImode, operands[0], WORDS_BIG_ENDIAN != 0);
 #if HOST_BITS_PER_WIDE_INT == 32
-  operands[4] = (INTVAL (operands[1]) & 0x80000000) ? constm1_rtx : const0_rtx;
+  operands[4] = (value & 0x80000000) ? constm1_rtx : const0_rtx;
 #else
-  operands[4] = GEN_INT ((HOST_WIDE_INT) INTVAL (operands[1]) >> 32);
-  operands[1] = GEN_INT (INTVAL (operands[1]) & 0xffffffff);
+  operands[4] = GEN_INT (value >> 32);
+  operands[1] = GEN_INT ((value & 0x7fffffff) - (value & 0x80000000));
 #endif
 }")
 
 (define_split
   [(set (match_operand:DI 0 "gpc_reg_operand" "")
        (match_operand:DI 1 "const_double_operand" ""))]
-  "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
+  "HOST_BITS_PER_WIDE_INT == 32 && TARGET_POWERPC64
+   && num_insns_constant (operands[1], DImode) > 1"
   [(set (match_dup 0)
        (match_dup 2))
    (set (match_dup 0)
                (match_dup 3)))]
   "
 {
-  HOST_WIDE_INT low;
-  HOST_WIDE_INT high;
-
   if (GET_CODE (operands[1]) == CONST_DOUBLE)
     {
-      low = CONST_DOUBLE_LOW (operands[1]);
-      high = CONST_DOUBLE_HIGH (operands[1]);
+      operands[2] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
+      operands[3] = immed_double_const (CONST_DOUBLE_LOW (operands[1]),
+                                       0, DImode);
     }
   else
-#if HOST_BITS_PER_WIDE_INT == 32
-    {
-      low = INTVAL (operands[1]);
-      high = (low < 0) ? ~0 : 0;
-    }
-#else
     {
-      low = INTVAL (operands[1]) & 0xffffffff;
-      high = (HOST_WIDE_INT) INTVAL (operands[1]) >> 32;
+      HOST_WIDE_INT value = INTVAL (operands[1]);
+      operands[2] = (value & 0x80000000) ? constm1_rtx : const0_rtx;
+      operands[3] = immed_double_const (value, 0, DImode);
     }
-#endif
+}")
 
-  operands[2] = GEN_INT (high);
-  operands[3] = GEN_INT (low);
+(define_split
+  [(set (match_operand:DI 0 "gpc_reg_operand" "")
+       (match_operand:DI 1 "const_int_operand" ""))]
+  "HOST_BITS_PER_WIDE_INT != 32 && TARGET_POWERPC64
+   && num_insns_constant (operands[1], DImode) > 1"
+  [(set (match_dup 0)
+       (match_dup 2))
+   (set (match_dup 0)
+       (ashift:DI (match_dup 0)
+                  (const_int 32)))
+   (set (match_dup 0)
+       (ior:DI (match_dup 0)
+               (match_dup 3)))]
+  "
+{
+#if HOST_BITS_PER_WIDE_INT != 32
+  HOST_WIDE_INT value = INTVAL (operands[1]);
+  operands[2] = GEN_INT (value >> 32);
+  operands[3] = GEN_INT ((value & 0x7fffffff) - (value & 0x80000000));
+#endif
 }")
 
 (define_insn ""
 (define_insn ""
   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
        (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
-                      (match_operand:SI 2 "reg_or_u_short_operand" "rI")))]
+                      (match_operand:SI 2 "reg_or_u_short_operand" "rK")))]
   ""
   "{cmpl%I2|cmplw%I2} %0,%1,%W2"
   [(set_attr "type" "compare")])
 (define_insn ""
   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
        (compare:CCUNS (match_operand:DI 1 "gpc_reg_operand" "r")
-                      (match_operand:DI 2 "reg_or_u_short_operand" "rI")))]
+                      (match_operand:DI 2 "reg_or_u_short_operand" "rK")))]
   ""
   "cmpld%I2 %0,%1,%W2"
   [(set_attr "type" "compare")])
        (lshiftrt:SI (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
                     (const_int 31)))
    (clobber (match_scratch:SI 2 "=&r"))]
-  "! TARGET_POWER"
+  "! TARGET_POWER && ! TARGET_POWERPC64"
   "{ai|addic} %2,%1,-1\;{sfe|subfe} %0,%2,%1"
   [(set_attr "length" "8")])