Commit 9aa6a9b5 by David S. Miller Committed by David S. Miller

Improve sparc setcc generation and add testcases.

gcc/

	* config/sparc/sparc.c (emit_scc_insn): Do not try v9 sequences until
	LEU/LTU/GEU/GTU is attempted.
	* config/sparc/sparc.md (*neg_snesi_sign_extend): New 64-bit insn
	and split.
	(*neg_seqsi_sign_extend): Likewise.
	(*sltu_extend_sp64, *neg_sltu_extend_sp64, *sgeu_extend_sp64,
	*neg_sgeu_extend_sp64): New insns.

gcc/testsuite/

	* gcc.target/sparc/setcc-1.c: New test.
	* gcc.target/sparc/setcc-2.c: New test.

From-SVN: r180550
parent 28c2f60e
2011-10-26 David S. Miller <davem@davemloft.net> 2011-10-26 David S. Miller <davem@davemloft.net>
* config/sparc/sparc.c (emit_scc_insn): Do not try v9 sequences until
LEU/LTU/GEU/GTU is attempted.
* config/sparc/sparc.md (*neg_snesi_sign_extend): New 64-bit insn
and split.
(*neg_seqsi_sign_extend): Likewise.
(*sltu_extend_sp64, *neg_sltu_extend_sp64, *sgeu_extend_sp64,
*neg_sgeu_extend_sp64): New insns.
* config/sparc/sparc-protos.h (sparc_expand_conditional_move): Declare. * config/sparc/sparc-protos.h (sparc_expand_conditional_move): Declare.
* config/sparc/sparc.md (mov<I:mode>cc, mov<F:mode>cc): Call it. * config/sparc/sparc.md (mov<I:mode>cc, mov<F:mode>cc): Call it.
(*mov<I:mode>_cc_v9): Normalize to expect operand 0 always in operand 4. (*mov<I:mode>_cc_v9): Normalize to expect operand 0 always in operand 4.
...@@ -2541,14 +2541,6 @@ emit_scc_insn (rtx operands[]) ...@@ -2541,14 +2541,6 @@ emit_scc_insn (rtx operands[])
} }
} }
/* For the rest, on v9 we can use conditional moves. */
if (TARGET_V9)
{
if (gen_v9_scc (operands[0], code, x, y))
return true;
}
/* We can do LTU and GEU using the addx/subx instructions too. And /* We can do LTU and GEU using the addx/subx instructions too. And
for GTU/LEU, if both operands are registers swap them and fall for GTU/LEU, if both operands are registers swap them and fall
back to the easy case. */ back to the easy case. */
...@@ -2573,6 +2565,12 @@ emit_scc_insn (rtx operands[]) ...@@ -2573,6 +2565,12 @@ emit_scc_insn (rtx operands[])
return true; return true;
} }
/* All the posibilities to use addx/subx based sequences has been
exhausted, try for a 3 instruction sequence using v9 conditional
moves. */
if (TARGET_V9 && gen_v9_scc (operands[0], code, x, y))
return true;
/* Nope, do branches. */ /* Nope, do branches. */
return false; return false;
} }
......
...@@ -713,6 +713,22 @@ ...@@ -713,6 +713,22 @@
"" ""
[(set_attr "length" "2")]) [(set_attr "length" "2")])
(define_insn_and_split "*neg_snesi_sign_extend"
[(set (match_operand:DI 0 "register_operand" "=r")
(neg:DI (ne:DI (match_operand:SI 1 "register_operand" "r")
(const_int 0))))
(clobber (reg:CC CC_REG))]
"TARGET_ARCH64"
"#"
"&& 1"
[(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
(match_dup 1))
(const_int 0)))
(set (match_dup 0) (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG)
(const_int 0)))))]
""
[(set_attr "length" "2")])
(define_insn_and_split "*snedi_zero" (define_insn_and_split "*snedi_zero"
[(set (match_operand:DI 0 "register_operand" "=&r") [(set (match_operand:DI 0 "register_operand" "=&r")
(ne:DI (match_operand:DI 1 "register_operand" "r") (ne:DI (match_operand:DI 1 "register_operand" "r")
...@@ -804,6 +820,21 @@ ...@@ -804,6 +820,21 @@
"" ""
[(set_attr "length" "2")]) [(set_attr "length" "2")])
(define_insn_and_split "*neg_seqsi_sign_extend"
[(set (match_operand:DI 0 "register_operand" "=r")
(neg:DI (eq:DI (match_operand:SI 1 "register_operand" "r")
(const_int 0))))
(clobber (reg:CC CC_REG))]
"TARGET_ARCH64"
"#"
"&& 1"
[(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
(const_int 0)))
(set (match_dup 0) (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG)
(const_int 0)))))]
""
[(set_attr "length" "2")])
(define_insn_and_split "*seqdi_zero" (define_insn_and_split "*seqdi_zero"
[(set (match_operand:DI 0 "register_operand" "=&r") [(set (match_operand:DI 0 "register_operand" "=&r")
(eq:DI (match_operand:DI 1 "register_operand" "r") (eq:DI (match_operand:DI 1 "register_operand" "r")
...@@ -928,6 +959,13 @@ ...@@ -928,6 +959,13 @@
"addx\t%%g0, 0, %0" "addx\t%%g0, 0, %0"
[(set_attr "type" "ialuX")]) [(set_attr "type" "ialuX")])
(define_insn "*sltu_extend_sp64"
[(set (match_operand:DI 0 "register_operand" "=r")
(ltu:DI (reg:CC CC_REG) (const_int 0)))]
"TARGET_ARCH64"
"addx\t%%g0, 0, %0"
[(set_attr "type" "ialuX")])
(define_insn "*neg_sltu_insn" (define_insn "*neg_sltu_insn"
[(set (match_operand:SI 0 "register_operand" "=r") [(set (match_operand:SI 0 "register_operand" "=r")
(neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))] (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
...@@ -935,6 +973,13 @@ ...@@ -935,6 +973,13 @@
"subx\t%%g0, 0, %0" "subx\t%%g0, 0, %0"
[(set_attr "type" "ialuX")]) [(set_attr "type" "ialuX")])
(define_insn "*neg_sltu_extend_sp64"
[(set (match_operand:DI 0 "register_operand" "=r")
(sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))))]
"TARGET_ARCH64"
"subx\t%%g0, 0, %0"
[(set_attr "type" "ialuX")])
;; ??? Combine should canonicalize these next two to the same pattern. ;; ??? Combine should canonicalize these next two to the same pattern.
(define_insn "*neg_sltu_minus_x" (define_insn "*neg_sltu_minus_x"
[(set (match_operand:SI 0 "register_operand" "=r") [(set (match_operand:SI 0 "register_operand" "=r")
...@@ -959,6 +1004,13 @@ ...@@ -959,6 +1004,13 @@
"subx\t%%g0, -1, %0" "subx\t%%g0, -1, %0"
[(set_attr "type" "ialuX")]) [(set_attr "type" "ialuX")])
(define_insn "*sgeu_extend_sp64"
[(set (match_operand:DI 0 "register_operand" "=r")
(geu:DI (reg:CC CC_REG) (const_int 0)))]
"TARGET_ARCH64"
"subx\t%%g0, -1, %0"
[(set_attr "type" "ialuX")])
(define_insn "*neg_sgeu_insn" (define_insn "*neg_sgeu_insn"
[(set (match_operand:SI 0 "register_operand" "=r") [(set (match_operand:SI 0 "register_operand" "=r")
(neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))] (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
...@@ -966,6 +1018,13 @@ ...@@ -966,6 +1018,13 @@
"addx\t%%g0, -1, %0" "addx\t%%g0, -1, %0"
[(set_attr "type" "ialuX")]) [(set_attr "type" "ialuX")])
(define_insn "*neg_sgeu_extend_sp64"
[(set (match_operand:DI 0 "register_operand" "=r")
(sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0)))))]
"TARGET_ARCH64"
"addx\t%%g0, -1, %0"
[(set_attr "type" "ialuX")])
;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in. ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
;; versions for v9. ;; versions for v9.
......
2011-10-26 David S. Miller <davem@davemloft.net>
* gcc.target/sparc/setcc-1.c: New test.
* gcc.target/sparc/setcc-2.c: New test.
2011-10-26 Joseph Myers <joseph@codesourcery.com> 2011-10-26 Joseph Myers <joseph@codesourcery.com>
* gcc.dg/tls/thr-cse-1.c: For i?86-*-mingw*, check for multiple * gcc.dg/tls/thr-cse-1.c: For i?86-*-mingw*, check for multiple
......
/* { dg-do compile } */
/* { dg-options "-O1" } */
int neq (int a, int b)
{
return a != b;
}
int eq (int a, int b)
{
return a == b;
}
int lt (unsigned int a, unsigned int b)
{
return a < b;
}
int leq (unsigned int a, unsigned int b)
{
return a <= b;
}
int geq (unsigned int a, unsigned int b)
{
return a >= b;
}
int gt (unsigned int a, unsigned int b)
{
return a > b;
}
/* { dg-final { scan-assembler-times "xor\t%" 2 } } */
/* { dg-final { scan-assembler-times "subcc\t%" 2 } } */
/* { dg-final { scan-assembler-times "addx\t%" 3 } } */
/* { dg-final { scan-assembler-times "subx\t%" 3 } } */
/* { dg-final { scan-assembler-times "cmp\t%" 4 } } */
/* { dg-final { scan-assembler-not "sra\t%" { target lp64 } } } */
/* { dg-do compile } */
/* { dg-options "-O1" } */
int neq (int a, int b)
{
return -(a != b);
}
int eq (int a, int b)
{
return -(a == b);
}
int lt (unsigned int a, unsigned int b)
{
return -(a < b);
}
int leq (unsigned int a, unsigned int b)
{
return -(a <= b);
}
int geq (unsigned int a, unsigned int b)
{
return -(a >= b);
}
int gt (unsigned int a, unsigned int b)
{
return -(a > b);
}
/* { dg-final { scan-assembler-times "xor\t%" 2 } } */
/* { dg-final { scan-assembler-times "subcc\t%" 2 } } */
/* { dg-final { scan-assembler-times "addx\t%" 3 } } */
/* { dg-final { scan-assembler-times "subx\t%" 3 } } */
/* { dg-final { scan-assembler-times "cmp\t%" 4 } } */
/* { dg-final { scan-assembler-not "sra\t%" { target lp64 } } } */
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