Commit 4f58c0d1 by Michael Meissner Committed by Michael Meissner

rs6000.md (bswaphi2_reg): On ISA 3.0 systems, enable generating XXBRH if the…

rs6000.md (bswaphi2_reg): On ISA 3.0 systems, enable generating XXBRH if the value is in a vector register.

[gcc]
2017-11-10  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* config/rs6000/rs6000.md (bswaphi2_reg): On ISA 3.0 systems,
	enable generating XXBRH if the value is in a vector register.
	(bswapsi2_reg): On ISA 3.0 systems, enable generating XXBRW if the
	value is in a vector register.
	(bswapdi2_reg): On ISA 3.0 systems, always use XXBRD to do
	register to register bswap64's instead of doing the GPR sequence
	used on previous machines.
	(bswapdi2_xxbrd): New insn.
	(bswapdi2_reg): Disallow on ISA 3.0.
	(register to register bswap64 splitter): Do not split the insn on
	ISA 3.0 systems that use XXBRD.

[gcc/testsuite]
2017-11-10  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* gcc.target/powerpc/p9-xxbr-3.c: New test.

From-SVN: r254643
parent d72b0a3f
2017-11-10 Michael Meissner <meissner@linux.vnet.ibm.com>
* config/rs6000/rs6000.md (bswaphi2_reg): On ISA 3.0 systems,
enable generating XXBRH if the value is in a vector register.
(bswapsi2_reg): On ISA 3.0 systems, enable generating XXBRW if the
value is in a vector register.
(bswapdi2_reg): On ISA 3.0 systems, always use XXBRD to do
register to register bswap64's instead of doing the GPR sequence
used on previous machines.
(bswapdi2_xxbrd): New insn.
(bswapdi2_reg): Disallow on ISA 3.0.
(register to register bswap64 splitter): Do not split the insn on
ISA 3.0 systems that use XXBRD.
2017-11-10 Martin Sebor <msebor@redhat.com> 2017-11-10 Martin Sebor <msebor@redhat.com>
PR c/81117 PR c/81117
...@@ -2432,13 +2432,15 @@ ...@@ -2432,13 +2432,15 @@
[(set_attr "type" "store")]) [(set_attr "type" "store")])
(define_insn_and_split "bswaphi2_reg" (define_insn_and_split "bswaphi2_reg"
[(set (match_operand:HI 0 "gpc_reg_operand" "=&r") [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wo")
(bswap:HI (bswap:HI
(match_operand:HI 1 "gpc_reg_operand" "r"))) (match_operand:HI 1 "gpc_reg_operand" "r,wo")))
(clobber (match_scratch:SI 2 "=&r"))] (clobber (match_scratch:SI 2 "=&r,X"))]
"" ""
"#" "@
"reload_completed" #
xxbrh %x0,%x1"
"reload_completed && int_reg_operand (operands[0], HImode)"
[(set (match_dup 3) [(set (match_dup 3)
(and:SI (lshiftrt:SI (match_dup 4) (and:SI (lshiftrt:SI (match_dup 4)
(const_int 8)) (const_int 8))
...@@ -2454,18 +2456,20 @@ ...@@ -2454,18 +2456,20 @@
operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0); operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0); operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
} }
[(set_attr "length" "12") [(set_attr "length" "12,4")
(set_attr "type" "*")]) (set_attr "type" "*,vecperm")])
;; We are always BITS_BIG_ENDIAN, so the bit positions below in ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
;; zero_extract insns do not change for -mlittle. ;; zero_extract insns do not change for -mlittle.
(define_insn_and_split "bswapsi2_reg" (define_insn_and_split "bswapsi2_reg"
[(set (match_operand:SI 0 "gpc_reg_operand" "=&r") [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wo")
(bswap:SI (bswap:SI
(match_operand:SI 1 "gpc_reg_operand" "r")))] (match_operand:SI 1 "gpc_reg_operand" "r,wo")))]
"" ""
"#" "@
"reload_completed" #
xxbrw %x0,%x1"
"reload_completed && int_reg_operand (operands[0], SImode)"
[(set (match_dup 0) ; DABC [(set (match_dup 0) ; DABC
(rotate:SI (match_dup 1) (rotate:SI (match_dup 1)
(const_int 24))) (const_int 24)))
...@@ -2481,7 +2485,9 @@ ...@@ -2481,7 +2485,9 @@
(const_int 255)) (const_int 255))
(and:SI (match_dup 0) (and:SI (match_dup 0)
(const_int -256))))] (const_int -256))))]
"") ""
[(set_attr "length" "12,4")
(set_attr "type" "*,vecperm")])
;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more ;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more
...@@ -2507,11 +2513,19 @@ ...@@ -2507,11 +2513,19 @@
emit_insn (gen_bswapdi2_load (dest, src)); emit_insn (gen_bswapdi2_load (dest, src));
else if (MEM_P (dest)) else if (MEM_P (dest))
emit_insn (gen_bswapdi2_store (dest, src)); emit_insn (gen_bswapdi2_store (dest, src));
else if (TARGET_P9_VECTOR)
emit_insn (gen_bswapdi2_xxbrd (dest, src));
else else
emit_insn (gen_bswapdi2_reg (dest, src)); emit_insn (gen_bswapdi2_reg (dest, src));
DONE; DONE;
} }
if (TARGET_P9_VECTOR && !MEM_P (src) && !MEM_P (dest))
{
emit_insn (gen_bswapdi2_xxbrd (dest, src));
DONE;
}
if (!TARGET_POWERPC64) if (!TARGET_POWERPC64)
{ {
/* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
...@@ -2537,12 +2551,19 @@ ...@@ -2537,12 +2551,19 @@
"stdbrx %1,%y0" "stdbrx %1,%y0"
[(set_attr "type" "store")]) [(set_attr "type" "store")])
(define_insn "bswapdi2_xxbrd"
[(set (match_operand:DI 0 "gpc_reg_operand" "=wo")
(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wo")))]
"TARGET_P9_VECTOR"
"xxbrd %x0,%x1"
[(set_attr "type" "vecperm")])
(define_insn "bswapdi2_reg" (define_insn "bswapdi2_reg"
[(set (match_operand:DI 0 "gpc_reg_operand" "=&r") [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r"))) (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
(clobber (match_scratch:DI 2 "=&r")) (clobber (match_scratch:DI 2 "=&r"))
(clobber (match_scratch:DI 3 "=&r"))] (clobber (match_scratch:DI 3 "=&r"))]
"TARGET_POWERPC64 && TARGET_LDBRX" "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
"#" "#"
[(set_attr "length" "36")]) [(set_attr "length" "36")])
...@@ -2691,7 +2712,7 @@ ...@@ -2691,7 +2712,7 @@
(bswap:DI (match_operand:DI 1 "gpc_reg_operand" ""))) (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
(clobber (match_operand:DI 2 "gpc_reg_operand" "")) (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
(clobber (match_operand:DI 3 "gpc_reg_operand" ""))] (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
"TARGET_POWERPC64 && reload_completed" "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
[(const_int 0)] [(const_int 0)]
" "
{ {
......
2017-11-10 Michael Meissner <meissner@linux.vnet.ibm.com>
* gcc.target/powerpc/p9-xxbr-3.c: New test.
2017-11-10 Uros Bizjak <ubizjak@gmail.com> 2017-11-10 Uros Bizjak <ubizjak@gmail.com>
* gcc.target/i386/force-indirect-call-1.c: Merge scan strings. * gcc.target/i386/force-indirect-call-1.c: Merge scan strings.
......
/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
/* { dg-require-effective-target powerpc_p9vector_ok } */
/* { dg-options "-mpower9-vector -O2" } */
/* Verify that the XXBR{H,W} instructions are generated if the value is
forced to be in a vector register, and XXBRD is generated all of the
time for register bswap64's. */
unsigned short
do_bswap16_mem (unsigned short *p)
{
return __builtin_bswap16 (*p); /* LHBRX. */
}
unsigned short
do_bswap16_reg (unsigned short a)
{
return __builtin_bswap16 (a); /* gpr sequences. */
}
void
do_bswap16_store (unsigned short *p, unsigned short a)
{
*p = __builtin_bswap16 (a); /* STHBRX. */
}
unsigned short
do_bswap16_vect (unsigned short a)
{
__asm__ (" # %x0" : "+v" (a));
return __builtin_bswap16 (a); /* XXBRW. */
}
unsigned int
do_bswap32_mem (unsigned int *p)
{
return __builtin_bswap32 (*p); /* LWBRX. */
}
unsigned int
do_bswap32_reg (unsigned int a)
{
return __builtin_bswap32 (a); /* gpr sequences. */
}
void
do_bswap32_store (unsigned int *p, unsigned int a)
{
*p = __builtin_bswap32 (a); /* STWBRX. */
}
unsigned int
do_bswap32_vect (unsigned int a)
{
__asm__ (" # %x0" : "+v" (a));
return __builtin_bswap32 (a); /* XXBRW. */
}
unsigned long
do_bswap64_mem (unsigned long *p)
{
return __builtin_bswap64 (*p); /* LDBRX. */
}
unsigned long
do_bswap64_reg (unsigned long a)
{
return __builtin_bswap64 (a); /* gpr sequences. */
}
void
do_bswap64_store (unsigned long *p, unsigned int a)
{
*p = __builtin_bswap64 (a); /* STDBRX. */
}
double
do_bswap64_double (unsigned long a)
{
return (double) __builtin_bswap64 (a); /* XXBRD. */
}
unsigned long
do_bswap64_vect (unsigned long a)
{
__asm__ (" # %x0" : "+v" (a)); /* XXBRD. */
return __builtin_bswap64 (a);
}
/* Make sure XXBR{H,W,D} is not generated by default. */
/* { dg-final { scan-assembler-times "xxbrd" 3 } } */
/* { dg-final { scan-assembler-times "xxbrh" 1 } } */
/* { dg-final { scan-assembler-times "xxbrw" 1 } } */
/* { dg-final { scan-assembler-times "ldbrx" 1 } } */
/* { dg-final { scan-assembler-times "lhbrx" 1 } } */
/* { dg-final { scan-assembler-times "lwbrx" 1 } } */
/* { dg-final { scan-assembler-times "stdbrx" 1 } } */
/* { dg-final { scan-assembler-times "sthbrx" 1 } } */
/* { dg-final { scan-assembler-times "stwbrx" 1 } } */
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