aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorKazu Hirata <kazu@cs.umass.edu>2003-01-07 16:02:20 +0000
committerKazu Hirata <kazu@gcc.gnu.org>2003-01-07 16:02:20 +0000
commitf9ac2f95ec83f10ccc2266ccba9755b9466008d8 (patch)
tree0666458d633ce85b9280c444d0f41e6714a4b499 /gcc
parentc93721124b765f21e04fb1d3031510ac86dbd41e (diff)
downloadgcc-f9ac2f95ec83f10ccc2266ccba9755b9466008d8.zip
gcc-f9ac2f95ec83f10ccc2266ccba9755b9466008d8.tar.gz
gcc-f9ac2f95ec83f10ccc2266ccba9755b9466008d8.tar.bz2
h8300.c (output_logical_op): Simplify and optimize the handling of SImode.
* 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/h8300/h8300.c108
2 files changed, 80 insertions, 36 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5eb9fc2..03b0d83 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c
index 3f2a358..d7e5219 100644
--- a/gcc/config/h8300/h8300.c
+++ b/gcc/config/h8300/h8300.c
@@ -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;
}