mips.md (GPR2): New mode iterator.
authorAdam Nemet <anemet@caviumnetworks.com>
Thu, 10 Apr 2008 18:28:45 +0000 (18:28 +0000)
committerAdam Nemet <nemet@gcc.gnu.org>
Thu, 10 Apr 2008 18:28:45 +0000 (18:28 +0000)
* config/mips/mips.md (GPR2): New mode iterator.
(seq): Add comment.
(*seq_<mode>, *seq_<mode>_mips16, *sne_<mode>, *sgt<u>_<mode>,
*sgt<u>_<mode>_mips16, *sge<u>_<mode>, *slt<u>_<mode>,
*slt<u>_<mode>_mips16 *sle<u>_<mode>, *sle<u>_<mode>_mips16):
Rewrite these to take two modes, the mode of comparison and the
mode of the destination.
* config/mips/mips.c (mips_expand_scc): Instead of having
paradoxical subreg as destination, expand "narrowing" scc if mode
of comparison is SI and target is requested in DI mode.
(mips_emit_int_order_test): Update comment.  Make mode of
comparison match CMP0 rather than TARGET.  When creating inverse
target use mode of TARGET.

testsuite/

* gcc.target/mips/scc-2.c: New test.
* gcc.target/mips/scc-3.c: New test.
* gcc.target/mips/scc-4.c: New test.

From-SVN: r134167

gcc/ChangeLog
gcc/config/mips/mips.c
gcc/config/mips/mips.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/mips/scc-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/mips/scc-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/mips/scc-4.c [new file with mode: 0644]

index ba6a33f6bc32bcbf8bd01481fba42f45125f0d28..d2599353201cc12f64490447d833d28439be67de 100644 (file)
@@ -1,3 +1,19 @@
+2008-04-10  Adam Nemet  <anemet@caviumnetworks.com>
+
+       * config/mips/mips.md (GPR2): New mode iterator.
+       (seq): Add comment.
+       (*seq_<mode>, *seq_<mode>_mips16, *sne_<mode>, *sgt<u>_<mode>,
+       *sgt<u>_<mode>_mips16, *sge<u>_<mode>, *slt<u>_<mode>,
+       *slt<u>_<mode>_mips16 *sle<u>_<mode>, *sle<u>_<mode>_mips16):
+       Rewrite these to take two modes, the mode of comparison and the
+       mode of the destination.
+       * config/mips/mips.c (mips_expand_scc): Instead of having
+       paradoxical subreg as destination, expand "narrowing" scc if mode
+       of comparison is SI and target is requested in DI mode.
+       (mips_emit_int_order_test): Update comment.  Make mode of
+       comparison match CMP0 rather than TARGET.  When creating inverse
+       target use mode of TARGET.
+
 2008-04-10  Adam Nemet  <anemet@caviumnetworks.com>
 
        * gcov-dump.c (tag_summary): Only print summaries for the first
index b9c49500dc4a1d4e777a1c73733dfa8cc8c8a496..d69169f13a748e977713c3071120c23ea405d931 100644 (file)
@@ -3715,9 +3715,9 @@ mips_canonicalize_int_order_test (enum rtx_code *code, rtx *cmp1,
 }
 
 /* Compare CMP0 and CMP1 using ordering test 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 TARGET to the
-   inverse of the result and flip *INVERT_PTR instead.  */
+   in TARGET.  CMP0 and TARGET are register_operands.  If INVERT_PTR
+   is nonnull, it's OK to set TARGET to the inverse of the result and
+   flip *INVERT_PTR instead.  */
 
 static void
 mips_emit_int_order_test (enum rtx_code code, bool *invert_ptr,
@@ -3728,7 +3728,7 @@ mips_emit_int_order_test (enum rtx_code code, bool *invert_ptr,
   /* First see if there is a MIPS instruction that can do this operation.
      If not, try doing the same for the inverse operation.  If that also
      fails, force CMP1 into a register and try again.  */
-  mode = GET_MODE (target);
+  mode = GET_MODE (cmp0);
   if (mips_canonicalize_int_order_test (&code, &cmp1, mode))
     mips_emit_binary (code, target, cmp0, cmp1);
   else
@@ -3741,7 +3741,7 @@ mips_emit_int_order_test (enum rtx_code code, bool *invert_ptr,
        }
       else if (invert_ptr == 0)
        {
-         rtx inv_target = gen_reg_rtx (mode);
+         rtx inv_target = gen_reg_rtx (GET_MODE (target));
          mips_emit_binary (inv_code, inv_target, cmp0, cmp1);
          mips_emit_binary (XOR, target, inv_target, const1_rtx);
        }
@@ -3868,7 +3868,7 @@ mips_emit_compare (enum rtx_code *code, rtx *op0, rtx *op1, bool need_eq_ne_p)
 /* Try comparing cmp_operands[0] and cmp_operands[1] using rtl code CODE.
    Store the result in TARGET and return true if successful.
 
-   On 64-bit targets, TARGET may be wider than cmp_operands[0].  */
+   On 64-bit targets, TARGET may be narrower than cmp_operands[0].  */
 
 bool
 mips_expand_scc (enum rtx_code code, rtx target)
@@ -3876,7 +3876,6 @@ mips_expand_scc (enum rtx_code code, rtx target)
   if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
     return false;
 
-  target = gen_lowpart (GET_MODE (cmp_operands[0]), target);
   if (code == EQ || code == NE)
     {
       rtx zie = mips_zero_if_equal (cmp_operands[0], cmp_operands[1]);
index 2083cb9ff50380b02201010f0d7589507a8a49d7..cbdcdc6ed13193334b3b330e26fb0e9e709ea504 100644 (file)
 ;; from the same template.
 (define_mode_iterator GPR [SI (DI "TARGET_64BIT")])
 
+;; A copy of GPR that can be used when a pattern has two independent
+;; modes.
+(define_mode_iterator GPR2 [SI (DI "TARGET_64BIT")])
+
 ;; This mode iterator allows :P to be used for patterns that operate on
 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
 ;;
 ;;  ....................
 
+;; Destination is always set in SI mode.
+
 (define_expand "seq"
   [(set (match_operand:SI 0 "register_operand")
        (eq:SI (match_dup 1)
   ""
   { if (mips_expand_scc (EQ, operands[0])) DONE; else FAIL; })
 
-(define_insn "*seq_<mode>"
-  [(set (match_operand:GPR 0 "register_operand" "=d")
-       (eq:GPR (match_operand:GPR 1 "register_operand" "d")
-               (const_int 0)))]
+(define_insn "*seq_<GPR:mode><GPR2:mode>"
+  [(set (match_operand:GPR2 0 "register_operand" "=d")
+       (eq:GPR2 (match_operand:GPR 1 "register_operand" "d")
+                (const_int 0)))]
   "!TARGET_MIPS16"
   "sltu\t%0,%1,1"
   [(set_attr "type" "slt")
-   (set_attr "mode" "<MODE>")])
+   (set_attr "mode" "<GPR:MODE>")])
 
-(define_insn "*seq_<mode>_mips16"
-  [(set (match_operand:GPR 0 "register_operand" "=t")
-       (eq:GPR (match_operand:GPR 1 "register_operand" "d")
-               (const_int 0)))]
+(define_insn "*seq_<GPR:mode><GPR2:mode>_mips16"
+  [(set (match_operand:GPR2 0 "register_operand" "=t")
+       (eq:GPR2 (match_operand:GPR 1 "register_operand" "d")
+                (const_int 0)))]
   "TARGET_MIPS16"
   "sltu\t%1,1"
   [(set_attr "type" "slt")
-   (set_attr "mode" "<MODE>")])
+   (set_attr "mode" "<GPR:MODE>")])
 
 ;; "sne" uses sltu instructions in which the first operand is $0.
 ;; This isn't possible in mips16 code.
   "!TARGET_MIPS16"
   { if (mips_expand_scc (NE, operands[0])) DONE; else FAIL; })
 
-(define_insn "*sne_<mode>"
-  [(set (match_operand:GPR 0 "register_operand" "=d")
-       (ne:GPR (match_operand:GPR 1 "register_operand" "d")
-               (const_int 0)))]
+(define_insn "*sne_<GPR:mode><GPR2:mode>"
+  [(set (match_operand:GPR2 0 "register_operand" "=d")
+       (ne:GPR2 (match_operand:GPR 1 "register_operand" "d")
+                (const_int 0)))]
   "!TARGET_MIPS16"
   "sltu\t%0,%.,%1"
   [(set_attr "type" "slt")
-   (set_attr "mode" "<MODE>")])
+   (set_attr "mode" "<GPR:MODE>")])
 
 (define_expand "sgt<u>"
   [(set (match_operand:SI 0 "register_operand")
   ""
   { if (mips_expand_scc (<CODE>, operands[0])) DONE; else FAIL; })
 
-(define_insn "*sgt<u>_<mode>"
-  [(set (match_operand:GPR 0 "register_operand" "=d")
-       (any_gt:GPR (match_operand:GPR 1 "register_operand" "d")
-                   (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
+(define_insn "*sgt<u>_<GPR:mode><GPR2:mode>"
+  [(set (match_operand:GPR2 0 "register_operand" "=d")
+       (any_gt:GPR2 (match_operand:GPR 1 "register_operand" "d")
+                    (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
   "!TARGET_MIPS16"
   "slt<u>\t%0,%z2,%1"
   [(set_attr "type" "slt")
-   (set_attr "mode" "<MODE>")])
+   (set_attr "mode" "<GPR:MODE>")])
 
-(define_insn "*sgt<u>_<mode>_mips16"
-  [(set (match_operand:GPR 0 "register_operand" "=t")
-       (any_gt:GPR (match_operand:GPR 1 "register_operand" "d")
-                   (match_operand:GPR 2 "register_operand" "d")))]
+(define_insn "*sgt<u>_<GPR:mode><GPR2:mode>_mips16"
+  [(set (match_operand:GPR2 0 "register_operand" "=t")
+       (any_gt:GPR2 (match_operand:GPR 1 "register_operand" "d")
+                    (match_operand:GPR 2 "register_operand" "d")))]
   "TARGET_MIPS16"
   "slt<u>\t%2,%1"
   [(set_attr "type" "slt")
-   (set_attr "mode" "<MODE>")])
+   (set_attr "mode" "<GPR:MODE>")])
 
 (define_expand "sge<u>"
   [(set (match_operand:SI 0 "register_operand")
   ""
   { if (mips_expand_scc (<CODE>, operands[0])) DONE; else FAIL; })
 
-(define_insn "*sge<u>_<mode>"
-  [(set (match_operand:GPR 0 "register_operand" "=d")
-       (any_ge:GPR (match_operand:GPR 1 "register_operand" "d")
-                   (const_int 1)))]
+(define_insn "*sge<u>_<GPR:mode><GPR2:mode>"
+  [(set (match_operand:GPR2 0 "register_operand" "=d")
+       (any_ge:GPR2 (match_operand:GPR 1 "register_operand" "d")
+                    (const_int 1)))]
   "!TARGET_MIPS16"
   "slt<u>\t%0,%.,%1"
   [(set_attr "type" "slt")
-   (set_attr "mode" "<MODE>")])
+   (set_attr "mode" "<GPR:MODE>")])
 
 (define_expand "slt<u>"
   [(set (match_operand:SI 0 "register_operand")
   ""
   { if (mips_expand_scc (<CODE>, operands[0])) DONE; else FAIL; })
 
-(define_insn "*slt<u>_<mode>"
-  [(set (match_operand:GPR 0 "register_operand" "=d")
-       (any_lt:GPR (match_operand:GPR 1 "register_operand" "d")
-                   (match_operand:GPR 2 "arith_operand" "dI")))]
+(define_insn "*slt<u>_<GPR:mode><GPR2:mode>"
+  [(set (match_operand:GPR2 0 "register_operand" "=d")
+       (any_lt:GPR2 (match_operand:GPR 1 "register_operand" "d")
+                    (match_operand:GPR 2 "arith_operand" "dI")))]
   "!TARGET_MIPS16"
   "slt<u>\t%0,%1,%2"
   [(set_attr "type" "slt")
-   (set_attr "mode" "<MODE>")])
+   (set_attr "mode" "<GPR:MODE>")])
 
-(define_insn "*slt<u>_<mode>_mips16"
-  [(set (match_operand:GPR 0 "register_operand" "=t,t")
-       (any_lt:GPR (match_operand:GPR 1 "register_operand" "d,d")
-                   (match_operand:GPR 2 "arith_operand" "d,I")))]
+(define_insn "*slt<u>_<GPR:mode><GPR2:mode>_mips16"
+  [(set (match_operand:GPR2 0 "register_operand" "=t,t")
+       (any_lt:GPR2 (match_operand:GPR 1 "register_operand" "d,d")
+                    (match_operand:GPR 2 "arith_operand" "d,I")))]
   "TARGET_MIPS16"
   "slt<u>\t%1,%2"
   [(set_attr "type" "slt")
-   (set_attr "mode" "<MODE>")
+   (set_attr "mode" "<GPR:MODE>")
    (set_attr_alternative "length"
                [(const_int 4)
                 (if_then_else (match_operand 2 "m16_uimm8_1")
   ""
   { if (mips_expand_scc (<CODE>, operands[0])) DONE; else FAIL; })
 
-(define_insn "*sle<u>_<mode>"
-  [(set (match_operand:GPR 0 "register_operand" "=d")
-       (any_le:GPR (match_operand:GPR 1 "register_operand" "d")
-                   (match_operand:GPR 2 "sle_operand" "")))]
+(define_insn "*sle<u>_<GPR:mode><GPR2:mode>"
+  [(set (match_operand:GPR2 0 "register_operand" "=d")
+       (any_le:GPR2 (match_operand:GPR 1 "register_operand" "d")
+                    (match_operand:GPR 2 "sle_operand" "")))]
   "!TARGET_MIPS16"
 {
   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
   return "slt<u>\t%0,%1,%2";
 }
   [(set_attr "type" "slt")
-   (set_attr "mode" "<MODE>")])
+   (set_attr "mode" "<GPR:MODE>")])
 
-(define_insn "*sle<u>_<mode>_mips16"
-  [(set (match_operand:GPR 0 "register_operand" "=t")
-       (any_le:GPR (match_operand:GPR 1 "register_operand" "d")
-                   (match_operand:GPR 2 "sle_operand" "")))]
+(define_insn "*sle<u>_<GPR:mode><GPR2:mode>_mips16"
+  [(set (match_operand:GPR2 0 "register_operand" "=t")
+       (any_le:GPR2 (match_operand:GPR 1 "register_operand" "d")
+                    (match_operand:GPR 2 "sle_operand" "")))]
   "TARGET_MIPS16"
 {
   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
   return "slt<u>\t%1,%2";
 }
   [(set_attr "type" "slt")
-   (set_attr "mode" "<MODE>")
+   (set_attr "mode" "<GPR:MODE>")
    (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1")
                                      (const_int 4)
                                      (const_int 8)))])
index 1eab06bf7783daef6033d013941aff2063bc5847..b22bcd48bc42f84d54cdae3bbd59eb6a6e7d5d93 100644 (file)
@@ -1,3 +1,9 @@
+2008-04-10  Adam Nemet  <anemet@caviumnetworks.com>
+
+       * gcc.target/mips/scc-2.c: New test.
+       * gcc.target/mips/scc-3.c: New test.
+       * gcc.target/mips/scc-4.c: New test.
+
 2008-04-10  Ira Rosen  <irar@il.ibm.com>
 
        PR tree-optimization/35821
diff --git a/gcc/testsuite/gcc.target/mips/scc-2.c b/gcc/testsuite/gcc.target/mips/scc-2.c
new file mode 100644 (file)
index 0000000..7964227
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-mips-options "-O -mgp64" } */
+
+/* { dg-final { scan-assembler-not "and\t\|andi\t\|ext\t\|sll\t\|srl\t" } } */
+/* { dg-final { scan-assembler-times "slt\t\|sltu\t" 12 } } */
+
+
+#define TEST(N, LHS, REL, RHS) \
+  NOMIPS16 long long w##N (int a, int b) {return LHS REL RHS;} \
+  NOMIPS16 int n##N (long long a, long long b) {return LHS REL RHS;} \
+
+TEST (eq, a, ==, 0);
+TEST (ne, a, !=, 0);
+TEST (gt, a, >, b);
+TEST (ge, a, >=, 1);
+TEST (lt, a, <, b);
+TEST (le, a, <=, 11);
diff --git a/gcc/testsuite/gcc.target/mips/scc-3.c b/gcc/testsuite/gcc.target/mips/scc-3.c
new file mode 100644 (file)
index 0000000..e496d40
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-mips-options "-O -mabi=o64" } */
+
+/* { dg-final { scan-assembler-not "and\t\|andi\t\|ext\t\|sll\t\|srl\t" } } */
+/* { dg-final { scan-assembler-times "slt\t\|sltu\t" 8 } } */
+
+
+#define TEST(N, LHS, REL, RHS) \
+  MIPS16 long long w##N (int a, int b) {return LHS REL RHS;} \
+  MIPS16 int n##N (long long a, long long b) {return LHS REL RHS;} \
+
+TEST (eq, a, ==, 0);
+
+TEST (gt, a, >, b);
+
+TEST (lt, a, <, b);
+TEST (le, a, <=, 11);
diff --git a/gcc/testsuite/gcc.target/mips/scc-4.c b/gcc/testsuite/gcc.target/mips/scc-4.c
new file mode 100644 (file)
index 0000000..fd6e932
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-mips-options "-O -mabi=o64" } */
+
+/* { dg-final { scan-assembler "slt\t" } } */
+/* { dg-final { scan-assembler "sltu\t\|xor\t\|xori\t" } } */
+
+/* This test should work both in mips16 and non-mips16 mode.  */
+
+int
+f (long long a, long long b)
+{
+  return a > 5;
+}