summaryrefslogtreecommitdiff
path: root/gcc/config/sparc
diff options
context:
space:
mode:
authordavem <davem@138bc75d-0d04-0410-961f-82ee72b054a4>2011-10-26 23:55:23 +0000
committerdavem <davem@138bc75d-0d04-0410-961f-82ee72b054a4>2011-10-26 23:55:23 +0000
commit40d0b2ad95242fed08fc7636b254bef981b15c95 (patch)
treee5135fa3732ec8fc08302acc0fa5e5b316c4c863 /gcc/config/sparc
parent277a5aebe0ed91e9cbefb40966e235daba0f1728 (diff)
downloadgcc-40d0b2ad95242fed08fc7636b254bef981b15c95.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@180550 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/sparc')
-rw-r--r--gcc/config/sparc/sparc.c14
-rw-r--r--gcc/config/sparc/sparc.md59
2 files changed, 65 insertions, 8 deletions
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 964bcaf15d6..80e05a61e47 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -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
for GTU/LEU, if both operands are registers swap them and fall
back to the easy case. */
@@ -2573,6 +2565,12 @@ emit_scc_insn (rtx operands[])
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. */
return false;
}
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index 2bae28e6e19..2b4b2bb54a4 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -713,6 +713,22 @@
""
[(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"
[(set (match_operand:DI 0 "register_operand" "=&r")
(ne:DI (match_operand:DI 1 "register_operand" "r")
@@ -804,6 +820,21 @@
""
[(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"
[(set (match_operand:DI 0 "register_operand" "=&r")
(eq:DI (match_operand:DI 1 "register_operand" "r")
@@ -928,6 +959,13 @@
"addx\t%%g0, 0, %0"
[(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"
[(set (match_operand:SI 0 "register_operand" "=r")
(neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
@@ -935,6 +973,13 @@
"subx\t%%g0, 0, %0"
[(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.
(define_insn "*neg_sltu_minus_x"
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -959,6 +1004,13 @@
"subx\t%%g0, -1, %0"
[(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"
[(set (match_operand:SI 0 "register_operand" "=r")
(neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
@@ -966,6 +1018,13 @@
"addx\t%%g0, -1, %0"
[(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.
;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
;; versions for v9.