This patch adds support for the Power10 BRD, BRW, and BRH instructions that do
byte swapping on values in GPRs.
This patch is a revision of the byte swap patch proposed in:
https://gcc.gnu.org/pipermail/gcc-patches/2020-June/546990.html
I changed the DI swap function bswapdi2_brd instead of bswapdi2_hw that I used
in the previous patch as requested.
I have changed all of the places that used 'future' to be 'power10'.
I have split the tests into 3 tests, one that tests BRH, one that tests BRW,
and one that tests BRD. The BRD test must have a 64-bit ABI, but the other two
do not.
I used '*' for the length attribute where it generates a single instruction.
I did not change the tests in the splitter as I don't see any easier way to do
the test. For reference, there are 3 cases:
1) Power10 instruction swapping a GPR which does not get split
2) Non-power10 instruction splitting the insn into component parts; (and)
3) Power9 instruction swapping a vector register which does not get split.
I have done bootstrap compilers and run make check with and without this patch
on a little endian power9 system running Linux. I have also done the boostrap
on a big endian power8 system with both 32/64-bit support, and the tests pass.
Can I check this patch into the master brannch?
gcc/
2020-06-30 Michael Meissner
* config/rs6000/rs6000.md (bswaphi2_reg): Generate the BRH
instruction on ISA 3.1.
(bswapsi2_reg): Generate the BRW instruction on ISA 3.1.
(bswapdi2): Rename bswapdi2_xxbrd to bswapdi2_brd.
(bswapdi2_brd): Rename from bswapdi2_xxbrd. Generate the BRD
instruction on ISA 3.1.
gcc/testsuite/
2020-06-30 Michael Meissner
* gcc.target/powerpc/bswap-brd.c: New test.
* gcc.target/powerpc/bswap-brw.c: New test.
* gcc.target/powerpc/bswap-brh.c: New test.
---
gcc/config/rs6000/rs6000.md | 44 +++-
gcc/testsuite/gcc.target/powerpc/bswap-brd.c | 23 +++
gcc/testsuite/gcc.target/powerpc/bswap-brh.c | 12
gcc/testsuite/gcc.target/powerpc/bswap-brw.c | 23 +++
4 files changed, 82 insertions(+), 20 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/powerpc/bswap-brd.c
create mode 100644 gcc/testsuite/gcc.target/powerpc/bswap-brh.c
create mode 100644 gcc/testsuite/gcc.target/powerpc/bswap-brw.c
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 7baaa61..86c8c02 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -2586,15 +2586,16 @@ (define_insn "bswap2_store"
[(set_attr "type" "store")])
(define_insn_and_split "bswaphi2_reg"
- [(set (match_operand:HI 0 "gpc_reg_operand" "=,wa")
+ [(set (match_operand:HI 0 "gpc_reg_operand" "=r,,wa")
(bswap:HI
-(match_operand:HI 1 "gpc_reg_operand" "r,wa")))
- (clobber (match_scratch:SI 2 "=,X"))]
+(match_operand:HI 1 "gpc_reg_operand" "r,r,wa")))
+ (clobber (match_scratch:SI 2 "=X,,X"))]
""
"@
+ brh %0,%1
#
xxbrh %x0,%x1"
- "reload_completed && int_reg_operand (operands[0], HImode)"
+ "reload_completed && !TARGET_POWER10 && int_reg_operand (operands[0],
HImode)"
[(set (match_dup 3)
(and:SI (lshiftrt:SI (match_dup 4)
(const_int 8))
@@ -2610,21 +2611,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" "*,12,*")
+ (set_attr "type" "shift,*,vecperm")
+ (set_attr "isa" "p10,*,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" "=,wa")
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=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_POWER10 && int_reg_operand (operands[0],
SImode)"
[(set (match_dup 0) ; DABC
(rotate:SI (match_dup 1)
(const_int 24)))
@@ -2641,9 +2643,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" "p10,*,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
@@ -2676,7