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
This commit is contained in:
Oleg Endo 2012-06-14 19:33:10 +00:00
parent c5b7018e02
commit 3f8d753f7f
2 changed files with 81 additions and 0 deletions

View File

@ -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

View File

@ -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