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
This commit is contained in:
Kazu Hirata 2003-01-07 16:02:20 +00:00 committed by Kazu Hirata
parent c93721124b
commit f9ac2f95ec
2 changed files with 80 additions and 36 deletions

View 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

View 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));
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. */
/* 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));
}
/* 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));
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. */
/* 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));
}
/* 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));
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. */
/* 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));
}
/* 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;
}