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