Correct errors in sparc SImode popcount/clz patterns when 64-bit.

* config/sparc/sparc.md (popcount<mode>2, clz<mode>2): Split up into...
	(popcountdi2, popcountsi2, clzdi2, clzsi2): Explicit expanders, in the
	SI mode 64-bit code gen case explicitly zero-extend and truncate.
	(*popcount<mode>_sp64): Split up into...
	(*popcountdi_sp64, *popcountsi_64): Explicit instantiations, and in the
	SImode case use truncate.
	(*clzsi_sp64): Rewrite to use truncate, and let the expander emit the
	subtract so the compiler can optimize it.
	(SIDI): Remove unused mode iterator.

From-SVN: r179628
This commit is contained in:
David S. Miller 2011-10-06 19:15:39 +00:00 committed by David S. Miller
parent f4b31a33a2
commit 908e19d0d0
2 changed files with 83 additions and 30 deletions

View File

@ -1,3 +1,15 @@
2011-10-06 David S. Miller <davem@davemloft.net>
* config/sparc/sparc.md (popcount<mode>2, clz<mode>2): Split up into...
(popcountdi2, popcountsi2, clzdi2, clzsi2): Explicit expanders, in the
SI mode 64-bit code gen case explicitly zero-extend and truncate.
(*popcount<mode>_sp64): Split up into...
(*popcountdi_sp64, *popcountsi_64): Explicit instantiations, and in the
SImode case use truncate.
(*clzsi_sp64): Rewrite to use truncate, and let the expander emit the
subtract so the compiler can optimize it.
(SIDI): Remove unused mode iterator.
2011-10-06 Bernd Schmidt <bernds@codesourcery.com>
* function.c (thread_prologue_and_epilogue_insns): Emit split

View File

@ -206,8 +206,6 @@
(define_mode_iterator V64N8 [V2SI V4HI])
(define_mode_iterator SIDI [SI DI])
;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
@ -6806,21 +6804,57 @@
[(set_attr "type" "multi")
(set_attr "length" "8")])
(define_expand "popcount<mode>2"
[(set (match_operand:SIDI 0 "register_operand" "")
(popcount:SIDI (match_operand:SIDI 1 "register_operand" "")))]
(define_expand "popcountdi2"
[(set (match_operand:DI 0 "register_operand" "")
(popcount:DI (match_operand:DI 1 "register_operand" "")))]
"TARGET_POPC"
{
if (! TARGET_ARCH64)
{
emit_insn (gen_popcount<mode>_v8plus (operands[0], operands[1]));
emit_insn (gen_popcountdi_v8plus (operands[0], operands[1]));
DONE;
}
})
(define_insn "*popcount<mode>_sp64"
[(set (match_operand:SIDI 0 "register_operand" "=r")
(popcount:SIDI (match_operand:SIDI 1 "register_operand" "r")))]
(define_insn "*popcountdi_sp64"
[(set (match_operand:DI 0 "register_operand" "=r")
(popcount:DI (match_operand:DI 1 "register_operand" "r")))]
"TARGET_POPC && TARGET_ARCH64"
"popc\t%1, %0")
(define_insn "popcountdi_v8plus"
[(set (match_operand:DI 0 "register_operand" "=r")
(popcount:DI (match_operand:DI 1 "register_operand" "r")))
(clobber (match_scratch:SI 2 "=&h"))]
"TARGET_POPC && ! TARGET_ARCH64"
{
if (sparc_check_64 (operands[1], insn) <= 0)
output_asm_insn ("srl\t%L1, 0, %L1", operands);
return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tpopc\t%2, %L0\n\tclr\t%H0";
}
[(set_attr "type" "multi")
(set_attr "length" "5")])
(define_expand "popcountsi2"
[(set (match_dup 2)
(zero_extend:DI (match_operand:SI 1 "register_operand" "")))
(set (match_operand:SI 0 "register_operand" "")
(truncate:SI (popcount:DI (match_dup 2))))]
"TARGET_POPC"
{
if (! TARGET_ARCH64)
{
emit_insn (gen_popcountsi_v8plus (operands[0], operands[1]));
DONE;
}
else
operands[2] = gen_reg_rtx (DImode);
})
(define_insn "*popcountsi_sp64"
[(set (match_operand:SI 0 "register_operand" "=r")
(truncate:SI
(popcount:DI (match_operand:DI 1 "register_operand" "r"))))]
"TARGET_POPC && TARGET_ARCH64"
"popc\t%1, %0")
@ -6836,27 +6870,14 @@
[(set_attr "type" "multi")
(set_attr "length" "2")])
(define_insn "popcountdi_v8plus"
[(set (match_operand:DI 0 "register_operand" "=r")
(popcount:DI (match_operand:DI 1 "register_operand" "r")))
(clobber (match_scratch:SI 2 "=&h"))]
"TARGET_POPC && ! TARGET_ARCH64"
{
if (sparc_check_64 (operands[1], insn) <= 0)
output_asm_insn ("srl\t%L1, 0, %L1", operands);
return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tpopc\t%2, %L0\n\tclr\t%H0";
}
[(set_attr "type" "multi")
(set_attr "length" "5")])
(define_expand "clz<mode>2"
[(set (match_operand:SIDI 0 "register_operand" "")
(clz:SIDI (match_operand:SIDI 1 "register_operand" "")))]
(define_expand "clzdi2"
[(set (match_operand:DI 0 "register_operand" "")
(clz:DI (match_operand:DI 1 "register_operand" "")))]
"TARGET_VIS3"
{
if (! TARGET_ARCH64)
{
emit_insn (gen_clz<mode>_v8plus (operands[0], operands[1]));
emit_insn (gen_clzdi_v8plus (operands[0], operands[1]));
DONE;
}
})
@ -6880,13 +6901,33 @@
[(set_attr "type" "multi")
(set_attr "length" "5")])
(define_expand "clzsi2"
[(set (match_dup 2)
(zero_extend:DI (match_operand:SI 1 "register_operand" "")))
(set (match_dup 3)
(truncate:SI (clz:DI (match_dup 2))))
(set (match_operand:SI 0 "register_operand" "")
(minus:SI (match_dup 3) (const_int 32)))]
"TARGET_VIS3"
{
if (! TARGET_ARCH64)
{
emit_insn (gen_clzsi_v8plus (operands[0], operands[1]));
DONE;
}
else
{
operands[2] = gen_reg_rtx (DImode);
operands[3] = gen_reg_rtx (SImode);
}
})
(define_insn "*clzsi_sp64"
[(set (match_operand:SI 0 "register_operand" "=r")
(clz:SI (match_operand:SI 1 "register_operand" "r")))]
(truncate:SI
(clz:DI (match_operand:DI 1 "register_operand" "r"))))]
"TARGET_VIS3 && TARGET_ARCH64"
"lzd\t%1, %0\n\tsub\t%0, 32, %0"
[(set_attr "type" "multi")
(set_attr "length" "2")])
"lzd\t%1, %0")
(define_insn "clzsi_v8plus"
[(set (match_operand:SI 0 "register_operand" "=r")