diff options
author | echristo <echristo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-07-13 18:36:35 +0000 |
---|---|---|
committer | echristo <echristo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-07-13 18:36:35 +0000 |
commit | 3e3a0a79c6d4fd4ce136737047f8bad349639526 (patch) | |
tree | e6a88209dbd7bddc35981a1b456add1f5bfa3aa7 | |
parent | 9f88bc9d58141d0f6285e942656c2f0e959a654f (diff) | |
download | gcc-3e3a0a79c6d4fd4ce136737047f8bad349639526.tar.gz |
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/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/config/mips/mips.c | 49 |
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); |