diff options
author | Oleg Endo <olegendo@gcc.gnu.org> | 2012-06-14 19:33:10 +0000 |
---|---|---|
committer | Oleg Endo <olegendo@gcc.gnu.org> | 2012-06-14 19:33:10 +0000 |
commit | 3f8d753f7fb8f9aa962fe5738a31d97055be6b30 (patch) | |
tree | 27432742d1ed42888267fe0dac1084e4d325e49a | |
parent | c5b7018e029f05088b5b639d482a833ae0dd673d (diff) | |
download | gcc-3f8d753f7fb8f9aa962fe5738a31d97055be6b30.zip gcc-3f8d753f7fb8f9aa962fe5738a31d97055be6b30.tar.gz gcc-3f8d753f7fb8f9aa962fe5738a31d97055be6b30.tar.bz2 |
re PR target/53568 (SH Target: Add support for bswap built-ins)
PR target/53568
* config/sh/sh.md: Add peephole for swapbsi2.
(*swapbisi2_and_shl8, *swapbhisi2): New insns and splits.
From-SVN: r188632
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/sh/sh.md | 75 |
2 files changed, 81 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1e6d89f..e9b0007 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2012-06-14 Oleg Endo <olegendo@gcc.gnu.org> + + PR target/53568 + * config/sh/sh.md: Add peephole for swapbsi2. + (*swapbisi2_and_shl8, *swapbhisi2): New insns and splits. + 2012-06-14 Uros Bizjak <ubizjak@gmail.com> * config/i386/i386.md (*zero_extendsidi2): Mark movd alternatives diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index 05a4f38..852f9fd 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -4561,6 +4561,81 @@ label: "swap.b %1,%0" [(set_attr "type" "arith")]) +;; The *swapbisi2_and_shl8 pattern helps the combine pass simplifying +;; partial byte swap expressions such as... +;; ((x & 0xFF) << 8) | ((x >> 8) & 0xFF). +;; ...which are currently not handled by the tree optimizers. +;; The combine pass will not initially try to combine the full expression, +;; but only some sub-expressions. In such a case the *swapbisi2_and_shl8 +;; pattern acts as an intermediate pattern that will eventually lead combine +;; to the swapbsi2 pattern above. +;; As a side effect this also improves code that does (x & 0xFF) << 8 +;; or (x << 8) & 0xFF00. +(define_insn_and_split "*swapbisi2_and_shl8" + [(set (match_operand:SI 0 "arith_reg_dest" "=r") + (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r") + (const_int 8)) + (const_int 65280)) + (match_operand:SI 2 "arith_reg_operand" "r")))] + "TARGET_SH1 && ! reload_in_progress && ! reload_completed" + "#" + "&& can_create_pseudo_p ()" + [(const_int 0)] +{ + rtx tmp0 = gen_reg_rtx (SImode); + rtx tmp1 = gen_reg_rtx (SImode); + + emit_insn (gen_zero_extendqisi2 (tmp0, gen_lowpart (QImode, operands[1]))); + emit_insn (gen_swapbsi2 (tmp1, tmp0)); + emit_insn (gen_iorsi3 (operands[0], tmp1, operands[2])); + DONE; +}) + +;; The *swapbhisi2 pattern is, like the *swapbisi2_and_shl8 pattern, another +;; intermediate pattern that will help the combine pass arriving at swapbsi2. +(define_insn_and_split "*swapbhisi2" + [(set (match_operand:SI 0 "arith_reg_dest" "=r") + (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r") + (const_int 8)) + (const_int 65280)) + (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))))] + "TARGET_SH1 && ! reload_in_progress && ! reload_completed" + "#" + "&& can_create_pseudo_p ()" + [(const_int 0)] +{ + rtx tmp = gen_reg_rtx (SImode); + + emit_insn (gen_zero_extendhisi2 (tmp, gen_lowpart (HImode, operands[1]))); + emit_insn (gen_swapbsi2 (operands[0], tmp)); + DONE; +}) + +;; In some cases the swapbsi2 pattern might leave a sequence such as... +;; swap.b r4,r4 +;; mov r4,r0 +;; +;; which can be simplified to... +;; swap.b r4,r0 +(define_peephole2 + [(set (match_operand:SI 0 "arith_reg_dest" "") + (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand" "") + (const_int 4294901760)) + (ior:SI (and:SI (ashift:SI (match_dup 1) (const_int 8)) + (const_int 65280)) + (and:SI (ashiftrt:SI (match_dup 1) (const_int 8)) + (const_int 255))))) + (set (match_operand:SI 2 "arith_reg_dest" "") + (match_dup 0))] + "TARGET_SH1 && peep2_reg_dead_p (2, operands[0])" + [(set (match_dup 2) + (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand" "") + (const_int 4294901760)) + (ior:SI (and:SI (ashift:SI (match_dup 1) (const_int 8)) + (const_int 65280)) + (and:SI (ashiftrt:SI (match_dup 1) (const_int 8)) + (const_int 255)))))]) + ;; ------------------------------------------------------------------------- ;; Zero extension instructions |