h8300.c (output_logical_op): Simplify and optimize the handling of SImode.
authorKazu Hirata <kazu@cs.umass.edu>
Tue, 7 Jan 2003 16:02:20 +0000 (16:02 +0000)
committerKazu Hirata <kazu@gcc.gnu.org>
Tue, 7 Jan 2003 16:02:20 +0000 (16:02 +0000)
* config/h8300/h8300.c (output_logical_op): Simplify and
optimize the handling of SImode.
* config/h8300/h8300.c (compute_logical_op_length): Update
accordingly.
* config/h8300/h8300.c (compute_logical_op_cc): Likewise.

From-SVN: r60995

gcc/ChangeLog
gcc/config/h8300/h8300.c

index 5eb9fc2f93794f8f3d89756904c22451d7a29e45..03b0d83ac7bff04d7b7804ff08ea5cfa68e6c897 100644 (file)
@@ -1,3 +1,11 @@
+2003-01-07  Kazu Hirata  <kazu@cs.umass.edu>
+
+       * config/h8300/h8300.c (output_logical_op): Simplify and
+       optimize the handling of SImode.
+       * config/h8300/h8300.c (compute_logical_op_length): Update
+       accordingly.
+       * config/h8300/h8300.c (compute_logical_op_cc): Likewise.
+
 2003-01-07  Richard Sandiford  <rsandifo@redhat.com>
 
        * config/mips/mips.c (mips_va_arg): In the EABI code, apply the
index 3f2a358a35b90a1aa37c7f02ae5d39f3d88ee30c..d7e521900bbe8a133c0d935bb66df30432704a08 100644 (file)
@@ -2061,6 +2061,13 @@ output_logical_op (mode, operands)
   /* The determinant of the algorithm.  If we perform an AND, 0
      affects a bit.  Otherwise, 1 affects a bit.  */
   const unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
+  /* Break up DET into pieces.  */
+  const unsigned HOST_WIDE_INT b0 = (det >>  0) & 0xff;
+  const unsigned HOST_WIDE_INT b1 = (det >>  8) & 0xff;
+  const unsigned HOST_WIDE_INT w0 = (det >>  0) & 0xffff;
+  const unsigned HOST_WIDE_INT w1 = (det >> 16) & 0xffff;
+  int lower_half_easy_p = 0;
+  int upper_half_easy_p = 0;
   /* The name of an insn.  */
   const char *opname;
   char insn_buf[100];
@@ -2108,20 +2115,25 @@ output_logical_op (mode, operands)
        }
       break;
     case SImode:
-      /* First, see if we can finish with one insn.
+      if (TARGET_H8300H || TARGET_H8300S)
+       {
+         /* Determine if the lower half can be taken care of in no more
+            than two bytes.  */
+         lower_half_easy_p = (b0 == 0
+                              || b1 == 0
+                              || (code != IOR && w0 == 0xffff));
+
+         /* Determine if the upper half can be taken care of in no more
+            than two bytes.  */
+         upper_half_easy_p = ((code != IOR && w1 == 0xffff)
+                              || (code == AND && w1 == 0xff00));
+       }
 
-        If code is either AND or XOR, we exclude two special cases,
-        0xffffff00 and 0xffff00ff, because insns like sub.w or not.w
-        can do a better job.  */
+      /* Check if doing everything with one insn is no worse than
+        using multiple insns.  */
       if ((TARGET_H8300H || TARGET_H8300S)
-         && ((det & 0x0000ffff) != 0)
-         && ((det & 0xffff0000) != 0)
-         && (code == IOR || det != 0xffffff00)
-         && (code == IOR || det != 0xffff00ff)
-         && !(code == AND
-              && (det == 0xff00ffff
-                  || (det & 0xffff00ff) == 0xff000000
-                  || (det & 0xffffff00) == 0xff000000)))
+         && w0 != 0 && w1 != 0
+         && !(lower_half_easy_p && upper_half_easy_p))
        {
          sprintf (insn_buf, "%s.l\t%%S2,%%S0", opname);
          output_asm_insn (insn_buf, operands);
@@ -2214,6 +2226,13 @@ compute_logical_op_length (mode, operands)
   /* The determinant of the algorithm.  If we perform an AND, 0
      affects a bit.  Otherwise, 1 affects a bit.  */
   const unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
+  /* Break up DET into pieces.  */
+  const unsigned HOST_WIDE_INT b0 = (det >>  0) & 0xff;
+  const unsigned HOST_WIDE_INT b1 = (det >>  8) & 0xff;
+  const unsigned HOST_WIDE_INT w0 = (det >>  0) & 0xffff;
+  const unsigned HOST_WIDE_INT w1 = (det >> 16) & 0xffff;
+  int lower_half_easy_p = 0;
+  int upper_half_easy_p = 0;
   /* Insn length.  */
   unsigned int length = 0;
 
@@ -2242,20 +2261,25 @@ compute_logical_op_length (mode, operands)
        }
       break;
     case SImode:
-      /* First, see if we can finish with one insn.
+      if (TARGET_H8300H || TARGET_H8300S)
+       {
+         /* Determine if the lower half can be taken care of in no more
+            than two bytes.  */
+         lower_half_easy_p = (b0 == 0
+                              || b1 == 0
+                              || (code != IOR && w0 == 0xffff));
+
+         /* Determine if the upper half can be taken care of in no more
+            than two bytes.  */
+         upper_half_easy_p = ((code != IOR && w1 == 0xffff)
+                              || (code == AND && w1 == 0xff00));
+       }
 
-        If code is either AND or XOR, we exclude two special cases,
-        0xffffff00 and 0xffff00ff, because insns like sub.w or not.w
-        can do a better job.  */
+      /* Check if doing everything with one insn is no worse than
+        using multiple insns.  */
       if ((TARGET_H8300H || TARGET_H8300S)
-         && ((det & 0x0000ffff) != 0)
-         && ((det & 0xffff0000) != 0)
-         && (code == IOR || det != 0xffffff00)
-         && (code == IOR || det != 0xffff00ff)
-         && !(code == AND
-              && (det == 0xff00ffff
-                  || (det & 0xffff00ff) == 0xff000000
-                  || (det & 0xffffff00) == 0xff000000)))
+         && w0 != 0 && w1 != 0
+         && !(lower_half_easy_p && upper_half_easy_p))
        {
          if (REG_P (operands[2]))
            length += 4;
@@ -2336,6 +2360,13 @@ compute_logical_op_cc (mode, operands)
   /* The determinant of the algorithm.  If we perform an AND, 0
      affects a bit.  Otherwise, 1 affects a bit.  */
   const unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
+  /* Break up DET into pieces.  */
+  const unsigned HOST_WIDE_INT b0 = (det >>  0) & 0xff;
+  const unsigned HOST_WIDE_INT b1 = (det >>  8) & 0xff;
+  const unsigned HOST_WIDE_INT w0 = (det >>  0) & 0xffff;
+  const unsigned HOST_WIDE_INT w1 = (det >> 16) & 0xffff;
+  int lower_half_easy_p = 0;
+  int upper_half_easy_p = 0;
   /* Condition code.  */
   enum attr_cc cc = CC_CLOBBER;
 
@@ -2351,20 +2382,25 @@ compute_logical_op_cc (mode, operands)
        }
       break;
     case SImode:
-      /* First, see if we can finish with one insn.
+      if (TARGET_H8300H || TARGET_H8300S)
+       {
+         /* Determine if the lower half can be taken care of in no more
+            than two bytes.  */
+         lower_half_easy_p = (b0 == 0
+                              || b1 == 0
+                              || (code != IOR && w0 == 0xffff));
+
+         /* Determine if the upper half can be taken care of in no more
+            than two bytes.  */
+         upper_half_easy_p = ((code != IOR && w1 == 0xffff)
+                              || (code == AND && w1 == 0xff00));
+       }
 
-        If code is either AND or XOR, we exclude two special cases,
-        0xffffff00 and 0xffff00ff, because insns like sub.w or not.w
-        can do a better job.  */
+      /* Check if doing everything with one insn is no worse than
+        using multiple insns.  */
       if ((TARGET_H8300H || TARGET_H8300S)
-         && ((det & 0x0000ffff) != 0)
-         && ((det & 0xffff0000) != 0)
-         && (code == IOR || det != 0xffffff00)
-         && (code == IOR || det != 0xffff00ff)
-         && !(code == AND
-              && (det == 0xff00ffff
-                  || (det & 0xffff00ff) == 0xff000000
-                  || (det & 0xffffff00) == 0xff000000)))
+         && w0 != 0 && w1 != 0
+         && !(lower_half_easy_p && upper_half_easy_p))
        {
          cc = CC_SET_ZNV;
        }