aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorechristo <echristo@138bc75d-0d04-0410-961f-82ee72b054a4>2005-07-13 18:36:35 +0000
committerechristo <echristo@138bc75d-0d04-0410-961f-82ee72b054a4>2005-07-13 18:36:35 +0000
commit3e3a0a79c6d4fd4ce136737047f8bad349639526 (patch)
treee6a88209dbd7bddc35981a1b456add1f5bfa3aa7
parent9f88bc9d58141d0f6285e942656c2f0e959a654f (diff)
2005-07-13 Eric Christopher <echristo@redhat.com>
* config/mips/mips.c (mips_canonicalize_comparison): New. (mips_emit_int_relational): Use. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@101983 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/mips/mips.c49
2 files changed, 53 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 42d34f4dc3f..4eccac89594 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,10 @@
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
static extra parts.
* config/s390/s390.md: Include tpf.md. Move tpf specific
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 9cfcaf9527b..0dee266559d 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -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
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
@@ -2891,11 +2935,14 @@ mips_emit_int_relational (enum rtx_code code, bool *invert_ptr,
rtx target, rtx cmp0, rtx cmp1)
{
/* 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
and try again. */
if (mips_relational_operand_ok_p (code, 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
{
enum rtx_code inv_code = reverse_condition (code);