Commit ecd48505 by Eric Christopher Committed by Eric Christopher

mips.c (mips_canonicalize_comparison): New.

2005-07-13  Eric Christopher  <echristo@redhat.com>

        * config/mips/mips.c (mips_canonicalize_comparison): New.
        (mips_emit_int_relational): Use.

From-SVN: r101983
parent a8ba31f2
2005-07-13 Eric Christopher <echristo@redhat.com> 2005-07-13 Eric Christopher <echristo@redhat.com>
* config/mips/mips.c (mips_canonicalize_comparison): New.
(mips_emit_int_relational): Use.
2005-07-13 Eric Christopher <echristo@redhat.com>
* config.gcc (s390x-ibm-tpf*): Add extra_options. Remove * config.gcc (s390x-ibm-tpf*): Add extra_options. Remove
static extra parts. static extra parts.
* config/s390/s390.md: Include tpf.md. Move tpf specific * config/s390/s390.md: Include tpf.md. Move tpf specific
......
...@@ -2881,6 +2881,50 @@ mips_relational_operand_ok_p (enum rtx_code code, rtx cmp1) ...@@ -2881,6 +2881,50 @@ mips_relational_operand_ok_p (enum rtx_code code, rtx cmp1)
} }
} }
/* Canonicalize LE or LEU comparisons into LT comparisons when
possible to avoid extra instructions or inverting the
comparison. */
static bool
mips_canonicalize_comparison (enum rtx_code *code, rtx *cmp1,
enum machine_mode mode)
{
HOST_WIDE_INT original, plus_one;
if (GET_CODE (*cmp1) != CONST_INT)
return false;
original = INTVAL (*cmp1);
plus_one = trunc_int_for_mode (original + 1, mode);
switch (*code)
{
case LE:
if (original < plus_one)
{
*code = LT;
*cmp1 = force_reg (mode, GEN_INT (plus_one));
return true;
}
break;
case LEU:
if (plus_one != 0)
{
*code = LTU;
*cmp1 = force_reg (mode, GEN_INT (plus_one));
return true;
}
break;
default:
return false;
}
return false;
}
/* Compare CMP0 and CMP1 using relational operator CODE and store the /* Compare CMP0 and CMP1 using relational operator CODE and store the
result in TARGET. CMP0 and TARGET are register_operands that have result in TARGET. CMP0 and TARGET are register_operands that have
the same integer mode. If INVERT_PTR is nonnull, it's OK to set the same integer mode. If INVERT_PTR is nonnull, it's OK to set
...@@ -2891,11 +2935,14 @@ mips_emit_int_relational (enum rtx_code code, bool *invert_ptr, ...@@ -2891,11 +2935,14 @@ mips_emit_int_relational (enum rtx_code code, bool *invert_ptr,
rtx target, rtx cmp0, rtx cmp1) rtx target, rtx cmp0, rtx cmp1)
{ {
/* First see if there is a MIPS instruction that can do this operation /* First see if there is a MIPS instruction that can do this operation
with CMP1 in its current form. If not, try doing the same for the with CMP1 in its current form. If not, try to canonicalize the
comparison to LT. If that fails, try doing the same for the
inverse operation. If that also fails, force CMP1 into a register inverse operation. If that also fails, force CMP1 into a register
and try again. */ and try again. */
if (mips_relational_operand_ok_p (code, cmp1)) if (mips_relational_operand_ok_p (code, cmp1))
mips_emit_binary (code, target, cmp0, cmp1); mips_emit_binary (code, target, cmp0, cmp1);
else if (mips_canonicalize_comparison (&code, &cmp1, GET_MODE (target)))
mips_emit_binary (code, target, cmp0, cmp1);
else else
{ {
enum rtx_code inv_code = reverse_condition (code); enum rtx_code inv_code = reverse_condition (code);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment