aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorOleg Endo <olegendo@gcc.gnu.org>2012-06-14 19:33:10 +0000
committerOleg Endo <olegendo@gcc.gnu.org>2012-06-14 19:33:10 +0000
commit3f8d753f7fb8f9aa962fe5738a31d97055be6b30 (patch)
tree27432742d1ed42888267fe0dac1084e4d325e49a /gcc
parentc5b7018e029f05088b5b639d482a833ae0dd673d (diff)
downloadgcc-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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/sh/sh.md75
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