Add support for generating BRH/BRW/BRD when -mcpu=future is used.

gcc/
2020-06-01  Michael Meissner  <meiss...@linux.ibm.com>

        * config/rs6000/rs6000.md (bswaphi2_reg): If -mcpu=future,
        generate the BRH instruction.
        (bswapsi2_reg): If -mcpu=future, generate the BRW instruction.
        (bswapdi2): Rename bswapdi2_xxbrd to bswapdi2_hw.
        (bswapdi2_hw): Rename from bswapdi2_xxbrd.  If -mcpu=future,
        generate the BRD instruction.

testsuite/
2020-06-01  Michael Meissner  <meiss...@linux.ibm.com>

        * gcc.target/powerpc/bswap64-5.c: New test.
---
 gcc/config/rs6000/rs6000.md                  | 44 +++++++++++++++-------------
 gcc/testsuite/gcc.target/powerpc/bswap64-5.c | 42 ++++++++++++++++++++++++++
 2 files changed, 66 insertions(+), 20 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/bswap64-5.c

diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 0aa5265..3310b4b 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -2585,15 +2585,16 @@ (define_insn "bswap<mode>2_store"
   [(set_attr "type" "store")])
 
 (define_insn_and_split "bswaphi2_reg"
-  [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wa")
+  [(set (match_operand:HI 0 "gpc_reg_operand" "=r,&r,wa")
        (bswap:HI
-        (match_operand:HI 1 "gpc_reg_operand" "r,wa")))
-   (clobber (match_scratch:SI 2 "=&r,X"))]
+        (match_operand:HI 1 "gpc_reg_operand" "r,r,wa")))
+   (clobber (match_scratch:SI 2 "=X,&r,X"))]
   ""
   "@
+   brh %0,%1
    #
    xxbrh %x0,%x1"
-  "reload_completed && int_reg_operand (operands[0], HImode)"
+  "reload_completed && !TARGET_FUTURE && int_reg_operand (operands[0], HImode)"
   [(set (match_dup 3)
        (and:SI (lshiftrt:SI (match_dup 4)
                             (const_int 8))
@@ -2609,21 +2610,22 @@ (define_insn_and_split "bswaphi2_reg"
   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
 }
-  [(set_attr "length" "12,4")
-   (set_attr "type" "*,vecperm")
-   (set_attr "isa" "*,p9v")])
+  [(set_attr "length" "4,12,4")
+   (set_attr "type" "shift,*,vecperm")
+   (set_attr "isa" "fut,*,p9v")])
 
 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
 ;; zero_extract insns do not change for -mlittle.
 (define_insn_and_split "bswapsi2_reg"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wa")
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,&r,wa")
        (bswap:SI
-        (match_operand:SI 1 "gpc_reg_operand" "r,wa")))]
+        (match_operand:SI 1 "gpc_reg_operand" "r,r,wa")))]
   ""
   "@
+   brw %0,%1
    #
    xxbrw %x0,%x1"
-  "reload_completed && int_reg_operand (operands[0], SImode)"
+  "reload_completed && !TARGET_FUTURE && int_reg_operand (operands[0], SImode)"
   [(set (match_dup 0)                                  ; DABC
        (rotate:SI (match_dup 1)
                   (const_int 24)))
@@ -2640,9 +2642,9 @@ (define_insn_and_split "bswapsi2_reg"
                (and:SI (match_dup 0)
                        (const_int -256))))]
   ""
-  [(set_attr "length" "12,4")
-   (set_attr "type" "*,vecperm")
-   (set_attr "isa" "*,p9v")])
+  [(set_attr "length" "4,12,4")
+   (set_attr "type" "shift,*,vecperm")
+   (set_attr "isa" "fut,*,p9v")])
 
 ;; 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
@@ -2675,7 +2677,7 @@ (define_expand "bswapdi2"
          emit_insn (gen_bswapdi2_store (dest, src));
         }
       else if (TARGET_P9_VECTOR)
-       emit_insn (gen_bswapdi2_xxbrd (dest, src));
+       emit_insn (gen_bswapdi2_hw (dest, src));
       else
        emit_insn (gen_bswapdi2_reg (dest, src));
       DONE;
@@ -2706,13 +2708,15 @@ (define_insn "bswapdi2_store"
   "stdbrx %1,%y0"
   [(set_attr "type" "store")])
 
-(define_insn "bswapdi2_xxbrd"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=wa")
-       (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wa")))]
+(define_insn "bswapdi2_hw"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,wa")
+       (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r,wa")))]
   "TARGET_P9_VECTOR"
-  "xxbrd %x0,%x1"
-  [(set_attr "type" "vecperm")
-   (set_attr "isa" "p9v")])
+  "@
+   brd %0,%1
+   xxbrd %x0,%x1"
+  [(set_attr "type" "shift,vecperm")
+   (set_attr "isa" "fut,p9v")])
 
 (define_insn "bswapdi2_reg"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
diff --git a/gcc/testsuite/gcc.target/powerpc/bswap64-5.c 
b/gcc/testsuite/gcc.target/powerpc/bswap64-5.c
new file mode 100644
index 0000000..9183e16
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/bswap64-5.c
@@ -0,0 +1,42 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_future_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=future" } */
+
+/* This tests whether -mcpu=future generates the new byte swap
+   instructions (brd, brw, brh).  */
+
+unsigned short
+bswap_short (unsigned short a)
+{
+  return __builtin_bswap16 (a); /* { dg-final { scan-assembler {\mbrh\M} } } */
+}
+
+unsigned int
+bswap_int (unsigned int a)
+{
+  return __builtin_bswap32 (a); /* { dg-final { scan-assembler {\mbrw\M} } } */
+}
+
+unsigned long
+bswap_long (unsigned long a)
+{
+  return __builtin_bswap64 (a); /* { dg-final { scan-assembler {\mbrd\M} } } */
+}
+
+double
+bswap_int_dbl (unsigned int a)
+{
+  unsigned int b = a;
+  __asm__ (" # %x0" : "+wa" (b));
+  /* { dg-final { scan-assembler {\mxxbrw\M} } } */
+  return (double) __builtin_bswap32 (b);
+}
+
+double
+bswap_long_dbl (unsigned long a)
+{
+  unsigned long b = a;
+  __asm__ (" # %x0" : "+wa" (b));
+  /* { dg-final { scan-assembler {\mxxbrd\M} } } */
+  return (double) __builtin_bswap64 (b);
+}
-- 
1.8.3.1

Reply via email to