Commit 5fb79e4c by Adam Nemet Committed by Adam Nemet

mips.md (GPR2): New mode iterator.

	* 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
parent 63d628b2
2008-04-10 Adam Nemet <anemet@caviumnetworks.com> 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 * gcov-dump.c (tag_summary): Only print summaries for the first
GCOV_COUNTERS_SUMMABLE counters. GCOV_COUNTERS_SUMMABLE counters.
......
...@@ -3715,9 +3715,9 @@ mips_canonicalize_int_order_test (enum rtx_code *code, rtx *cmp1, ...@@ -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 /* Compare CMP0 and CMP1 using ordering test CODE and store the result
in TARGET. CMP0 and TARGET are register_operands that have the same in TARGET. CMP0 and TARGET are register_operands. If INVERT_PTR
integer mode. If INVERT_PTR is nonnull, it's OK to set TARGET to the is nonnull, it's OK to set TARGET to the inverse of the result and
inverse of the result and flip *INVERT_PTR instead. */ flip *INVERT_PTR instead. */
static void static void
mips_emit_int_order_test (enum rtx_code code, bool *invert_ptr, 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, ...@@ -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. /* 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 If not, try doing the same for the inverse operation. If that also
fails, force CMP1 into a register and try again. */ 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)) if (mips_canonicalize_int_order_test (&code, &cmp1, mode))
mips_emit_binary (code, target, cmp0, cmp1); mips_emit_binary (code, target, cmp0, cmp1);
else else
...@@ -3741,7 +3741,7 @@ mips_emit_int_order_test (enum rtx_code code, bool *invert_ptr, ...@@ -3741,7 +3741,7 @@ mips_emit_int_order_test (enum rtx_code code, bool *invert_ptr,
} }
else if (invert_ptr == 0) 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 (inv_code, inv_target, cmp0, cmp1);
mips_emit_binary (XOR, target, inv_target, const1_rtx); 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) ...@@ -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. /* Try comparing cmp_operands[0] and cmp_operands[1] using rtl code CODE.
Store the result in TARGET and return true if successful. 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 bool
mips_expand_scc (enum rtx_code code, rtx target) mips_expand_scc (enum rtx_code code, rtx target)
...@@ -3876,7 +3876,6 @@ 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) if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
return false; return false;
target = gen_lowpart (GET_MODE (cmp_operands[0]), target);
if (code == EQ || code == NE) if (code == EQ || code == NE)
{ {
rtx zie = mips_zero_if_equal (cmp_operands[0], cmp_operands[1]); rtx zie = mips_zero_if_equal (cmp_operands[0], cmp_operands[1]);
......
...@@ -476,6 +476,10 @@ ...@@ -476,6 +476,10 @@
;; from the same template. ;; from the same template.
(define_mode_iterator GPR [SI (DI "TARGET_64BIT")]) (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 ;; This mode iterator allows :P to be used for patterns that operate on
;; pointer-sized quantities. Exactly one of the two alternatives will match. ;; pointer-sized quantities. Exactly one of the two alternatives will match.
(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")]) (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
...@@ -5065,6 +5069,8 @@ ...@@ -5065,6 +5069,8 @@
;; ;;
;; .................... ;; ....................
;; Destination is always set in SI mode.
(define_expand "seq" (define_expand "seq"
[(set (match_operand:SI 0 "register_operand") [(set (match_operand:SI 0 "register_operand")
(eq:SI (match_dup 1) (eq:SI (match_dup 1)
...@@ -5072,23 +5078,23 @@ ...@@ -5072,23 +5078,23 @@
"" ""
{ if (mips_expand_scc (EQ, operands[0])) DONE; else FAIL; }) { if (mips_expand_scc (EQ, operands[0])) DONE; else FAIL; })
(define_insn "*seq_<mode>" (define_insn "*seq_<GPR:mode><GPR2:mode>"
[(set (match_operand:GPR 0 "register_operand" "=d") [(set (match_operand:GPR2 0 "register_operand" "=d")
(eq:GPR (match_operand:GPR 1 "register_operand" "d") (eq:GPR2 (match_operand:GPR 1 "register_operand" "d")
(const_int 0)))] (const_int 0)))]
"!TARGET_MIPS16" "!TARGET_MIPS16"
"sltu\t%0,%1,1" "sltu\t%0,%1,1"
[(set_attr "type" "slt") [(set_attr "type" "slt")
(set_attr "mode" "<MODE>")]) (set_attr "mode" "<GPR:MODE>")])
(define_insn "*seq_<mode>_mips16" (define_insn "*seq_<GPR:mode><GPR2:mode>_mips16"
[(set (match_operand:GPR 0 "register_operand" "=t") [(set (match_operand:GPR2 0 "register_operand" "=t")
(eq:GPR (match_operand:GPR 1 "register_operand" "d") (eq:GPR2 (match_operand:GPR 1 "register_operand" "d")
(const_int 0)))] (const_int 0)))]
"TARGET_MIPS16" "TARGET_MIPS16"
"sltu\t%1,1" "sltu\t%1,1"
[(set_attr "type" "slt") [(set_attr "type" "slt")
(set_attr "mode" "<MODE>")]) (set_attr "mode" "<GPR:MODE>")])
;; "sne" uses sltu instructions in which the first operand is $0. ;; "sne" uses sltu instructions in which the first operand is $0.
;; This isn't possible in mips16 code. ;; This isn't possible in mips16 code.
...@@ -5100,14 +5106,14 @@ ...@@ -5100,14 +5106,14 @@
"!TARGET_MIPS16" "!TARGET_MIPS16"
{ if (mips_expand_scc (NE, operands[0])) DONE; else FAIL; }) { if (mips_expand_scc (NE, operands[0])) DONE; else FAIL; })
(define_insn "*sne_<mode>" (define_insn "*sne_<GPR:mode><GPR2:mode>"
[(set (match_operand:GPR 0 "register_operand" "=d") [(set (match_operand:GPR2 0 "register_operand" "=d")
(ne:GPR (match_operand:GPR 1 "register_operand" "d") (ne:GPR2 (match_operand:GPR 1 "register_operand" "d")
(const_int 0)))] (const_int 0)))]
"!TARGET_MIPS16" "!TARGET_MIPS16"
"sltu\t%0,%.,%1" "sltu\t%0,%.,%1"
[(set_attr "type" "slt") [(set_attr "type" "slt")
(set_attr "mode" "<MODE>")]) (set_attr "mode" "<GPR:MODE>")])
(define_expand "sgt<u>" (define_expand "sgt<u>"
[(set (match_operand:SI 0 "register_operand") [(set (match_operand:SI 0 "register_operand")
...@@ -5116,23 +5122,23 @@ ...@@ -5116,23 +5122,23 @@
"" ""
{ if (mips_expand_scc (<CODE>, operands[0])) DONE; else FAIL; }) { if (mips_expand_scc (<CODE>, operands[0])) DONE; else FAIL; })
(define_insn "*sgt<u>_<mode>" (define_insn "*sgt<u>_<GPR:mode><GPR2:mode>"
[(set (match_operand:GPR 0 "register_operand" "=d") [(set (match_operand:GPR2 0 "register_operand" "=d")
(any_gt:GPR (match_operand:GPR 1 "register_operand" "d") (any_gt:GPR2 (match_operand:GPR 1 "register_operand" "d")
(match_operand:GPR 2 "reg_or_0_operand" "dJ")))] (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
"!TARGET_MIPS16" "!TARGET_MIPS16"
"slt<u>\t%0,%z2,%1" "slt<u>\t%0,%z2,%1"
[(set_attr "type" "slt") [(set_attr "type" "slt")
(set_attr "mode" "<MODE>")]) (set_attr "mode" "<GPR:MODE>")])
(define_insn "*sgt<u>_<mode>_mips16" (define_insn "*sgt<u>_<GPR:mode><GPR2:mode>_mips16"
[(set (match_operand:GPR 0 "register_operand" "=t") [(set (match_operand:GPR2 0 "register_operand" "=t")
(any_gt:GPR (match_operand:GPR 1 "register_operand" "d") (any_gt:GPR2 (match_operand:GPR 1 "register_operand" "d")
(match_operand:GPR 2 "register_operand" "d")))] (match_operand:GPR 2 "register_operand" "d")))]
"TARGET_MIPS16" "TARGET_MIPS16"
"slt<u>\t%2,%1" "slt<u>\t%2,%1"
[(set_attr "type" "slt") [(set_attr "type" "slt")
(set_attr "mode" "<MODE>")]) (set_attr "mode" "<GPR:MODE>")])
(define_expand "sge<u>" (define_expand "sge<u>"
[(set (match_operand:SI 0 "register_operand") [(set (match_operand:SI 0 "register_operand")
...@@ -5141,14 +5147,14 @@ ...@@ -5141,14 +5147,14 @@
"" ""
{ if (mips_expand_scc (<CODE>, operands[0])) DONE; else FAIL; }) { if (mips_expand_scc (<CODE>, operands[0])) DONE; else FAIL; })
(define_insn "*sge<u>_<mode>" (define_insn "*sge<u>_<GPR:mode><GPR2:mode>"
[(set (match_operand:GPR 0 "register_operand" "=d") [(set (match_operand:GPR2 0 "register_operand" "=d")
(any_ge:GPR (match_operand:GPR 1 "register_operand" "d") (any_ge:GPR2 (match_operand:GPR 1 "register_operand" "d")
(const_int 1)))] (const_int 1)))]
"!TARGET_MIPS16" "!TARGET_MIPS16"
"slt<u>\t%0,%.,%1" "slt<u>\t%0,%.,%1"
[(set_attr "type" "slt") [(set_attr "type" "slt")
(set_attr "mode" "<MODE>")]) (set_attr "mode" "<GPR:MODE>")])
(define_expand "slt<u>" (define_expand "slt<u>"
[(set (match_operand:SI 0 "register_operand") [(set (match_operand:SI 0 "register_operand")
...@@ -5157,23 +5163,23 @@ ...@@ -5157,23 +5163,23 @@
"" ""
{ if (mips_expand_scc (<CODE>, operands[0])) DONE; else FAIL; }) { if (mips_expand_scc (<CODE>, operands[0])) DONE; else FAIL; })
(define_insn "*slt<u>_<mode>" (define_insn "*slt<u>_<GPR:mode><GPR2:mode>"
[(set (match_operand:GPR 0 "register_operand" "=d") [(set (match_operand:GPR2 0 "register_operand" "=d")
(any_lt:GPR (match_operand:GPR 1 "register_operand" "d") (any_lt:GPR2 (match_operand:GPR 1 "register_operand" "d")
(match_operand:GPR 2 "arith_operand" "dI")))] (match_operand:GPR 2 "arith_operand" "dI")))]
"!TARGET_MIPS16" "!TARGET_MIPS16"
"slt<u>\t%0,%1,%2" "slt<u>\t%0,%1,%2"
[(set_attr "type" "slt") [(set_attr "type" "slt")
(set_attr "mode" "<MODE>")]) (set_attr "mode" "<GPR:MODE>")])
(define_insn "*slt<u>_<mode>_mips16" (define_insn "*slt<u>_<GPR:mode><GPR2:mode>_mips16"
[(set (match_operand:GPR 0 "register_operand" "=t,t") [(set (match_operand:GPR2 0 "register_operand" "=t,t")
(any_lt:GPR (match_operand:GPR 1 "register_operand" "d,d") (any_lt:GPR2 (match_operand:GPR 1 "register_operand" "d,d")
(match_operand:GPR 2 "arith_operand" "d,I")))] (match_operand:GPR 2 "arith_operand" "d,I")))]
"TARGET_MIPS16" "TARGET_MIPS16"
"slt<u>\t%1,%2" "slt<u>\t%1,%2"
[(set_attr "type" "slt") [(set_attr "type" "slt")
(set_attr "mode" "<MODE>") (set_attr "mode" "<GPR:MODE>")
(set_attr_alternative "length" (set_attr_alternative "length"
[(const_int 4) [(const_int 4)
(if_then_else (match_operand 2 "m16_uimm8_1") (if_then_else (match_operand 2 "m16_uimm8_1")
...@@ -5187,29 +5193,29 @@ ...@@ -5187,29 +5193,29 @@
"" ""
{ if (mips_expand_scc (<CODE>, operands[0])) DONE; else FAIL; }) { if (mips_expand_scc (<CODE>, operands[0])) DONE; else FAIL; })
(define_insn "*sle<u>_<mode>" (define_insn "*sle<u>_<GPR:mode><GPR2:mode>"
[(set (match_operand:GPR 0 "register_operand" "=d") [(set (match_operand:GPR2 0 "register_operand" "=d")
(any_le:GPR (match_operand:GPR 1 "register_operand" "d") (any_le:GPR2 (match_operand:GPR 1 "register_operand" "d")
(match_operand:GPR 2 "sle_operand" "")))] (match_operand:GPR 2 "sle_operand" "")))]
"!TARGET_MIPS16" "!TARGET_MIPS16"
{ {
operands[2] = GEN_INT (INTVAL (operands[2]) + 1); operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
return "slt<u>\t%0,%1,%2"; return "slt<u>\t%0,%1,%2";
} }
[(set_attr "type" "slt") [(set_attr "type" "slt")
(set_attr "mode" "<MODE>")]) (set_attr "mode" "<GPR:MODE>")])
(define_insn "*sle<u>_<mode>_mips16" (define_insn "*sle<u>_<GPR:mode><GPR2:mode>_mips16"
[(set (match_operand:GPR 0 "register_operand" "=t") [(set (match_operand:GPR2 0 "register_operand" "=t")
(any_le:GPR (match_operand:GPR 1 "register_operand" "d") (any_le:GPR2 (match_operand:GPR 1 "register_operand" "d")
(match_operand:GPR 2 "sle_operand" "")))] (match_operand:GPR 2 "sle_operand" "")))]
"TARGET_MIPS16" "TARGET_MIPS16"
{ {
operands[2] = GEN_INT (INTVAL (operands[2]) + 1); operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
return "slt<u>\t%1,%2"; return "slt<u>\t%1,%2";
} }
[(set_attr "type" "slt") [(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") (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1")
(const_int 4) (const_int 4)
(const_int 8)))]) (const_int 8)))])
......
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> 2008-04-10 Ira Rosen <irar@il.ibm.com>
PR tree-optimization/35821 PR tree-optimization/35821
/* { 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);
/* { 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);
/* { 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;
}
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