diff options
author | Anatoly Sokolov <aesok@post.ru> | 2008-08-23 01:24:56 +0400 |
---|---|---|
committer | Anatoly Sokolov <aesok@gcc.gnu.org> | 2008-08-23 01:24:56 +0400 |
commit | d3dd4dbd1d3aaad14b4b112874613fbe70337f15 (patch) | |
tree | 92a6316cf812c8a355bda612642fd69592e6a976 /gcc/config/avr | |
parent | 36159cf85750e5b480e1918eb2c53905b715965f (diff) | |
download | gcc-d3dd4dbd1d3aaad14b4b112874613fbe70337f15.zip gcc-d3dd4dbd1d3aaad14b4b112874613fbe70337f15.tar.gz gcc-d3dd4dbd1d3aaad14b4b112874613fbe70337f15.tar.bz2 |
re PR target/11259 ([avr] gcc Double 'andi' missed optimization)
PR target/11259
* config/avr/avr.md (UNSPEC_SWAP): New constants.
(*swap): New insn pattern.
(*ashlqi3): Rename from ashlqi3 insn pattern.
(ashlqi3): New expanders.
(*lshrqi3): Rename from lshrqi3 insn pattern.
(lshrqi3): New expanders.
(ashlqi3_const4, ashlqi3_const5, ashlqi3_const6, lshrqi3_const4,
lshrqi3_const5, lshrqi3_const6): New splitters.
(andi, ashlqi3_l_const4, ashlqi3_l_const5, ashlqi3_l_const6,
lshrqi3_l_const4, lshrqi3_l_const5, lshrqi3_l_const6): Define
peephole2 patterns.
From-SVN: r139502
Diffstat (limited to 'gcc/config/avr')
-rw-r--r-- | gcc/config/avr/avr.md | 171 |
1 files changed, 169 insertions, 2 deletions
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index a6e4c3e..371ca76 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -54,6 +54,7 @@ (UNSPEC_INDEX_JMP 1) (UNSPEC_SEI 2) (UNSPEC_CLI 3) + (UNSPEC_SWAP 4) (UNSPECV_PROLOGUE_SAVES 0) (UNSPECV_EPILOGUE_RESTORES 1) @@ -1261,6 +1262,19 @@ [(set_attr "length" "4,4") (set_attr "cc" "set_n,set_n")]) +(define_peephole2 ; andi + [(set (match_operand:QI 0 "d_register_operand" "") + (and:QI (match_dup 0) + (match_operand:QI 1 "const_int_operand" ""))) + (set (match_dup 0) + (and:QI (match_dup 0) + (match_operand:QI 2 "const_int_operand" "")))] + "" + [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))] + { + operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2])); + }) + ;;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ;; ior @@ -1389,10 +1403,57 @@ [(set_attr "length" "4") (set_attr "cc" "set_n")]) +;; swap + +(define_insn "*swap" + [(set (match_operand:QI 0 "register_operand" "=r") + (unspec:QI [(match_operand:QI 1 "register_operand" "0")] + UNSPEC_SWAP))] + "" + "swap %0" + [(set_attr "length" "1") + (set_attr "cc" "none")]) + ;;<< << << << << << << << << << << << << << << << << << << << << << << << << << ;; arithmetic shift left -(define_insn "ashlqi3" +(define_expand "ashlqi3" + [(set (match_operand:QI 0 "register_operand" "") + (ashift:QI (match_operand:QI 1 "register_operand" "") + (match_operand:QI 2 "general_operand" "")))] + "" + "") + +(define_split ; ashlqi3_const4 + [(set (match_operand:QI 0 "d_register_operand" "") + (ashift:QI (match_dup 0) + (const_int 4)))] + "" + [(set (match_dup 0) (unspec:QI [(match_dup 0)] UNSPEC_SWAP)) + (set (match_dup 0) (and:QI (match_dup 0) (const_int -16)))] + "") + +(define_split ; ashlqi3_const5 + [(set (match_operand:QI 0 "d_register_operand" "") + (ashift:QI (match_dup 0) + (const_int 5)))] + "" + [(set (match_dup 0) (unspec:QI [(match_dup 0)] UNSPEC_SWAP)) + (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1))) + (set (match_dup 0) (and:QI (match_dup 0) (const_int -32)))] + "") + +(define_split ; ashlqi3_const6 + [(set (match_operand:QI 0 "d_register_operand" "") + (ashift:QI (match_dup 0) + (const_int 6)))] + "" + [(set (match_dup 0) (unspec:QI [(match_dup 0)] UNSPEC_SWAP)) + (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2))) + (set (match_dup 0) (and:QI (match_dup 0) (const_int -64)))] + "") + +(define_insn "*ashlqi3" [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r") (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0") (match_operand:QI 2 "general_operand" "r,L,P,K,n,n,Qm")))] @@ -1421,6 +1482,41 @@ ;; Optimize if a scratch register from LD_REGS happens to be available. +(define_peephole2 ; ashlqi3_l_const4 + [(set (match_operand:QI 0 "l_register_operand" "") + (ashift:QI (match_dup 0) + (const_int 4))) + (match_scratch:QI 1 "d")] + "" + [(set (match_dup 0) (unspec:QI [(match_dup 0)] UNSPEC_SWAP)) + (set (match_dup 1) (const_int -16)) + (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))] + "") + +(define_peephole2 ; ashlqi3_l_const5 + [(set (match_operand:QI 0 "l_register_operand" "") + (ashift:QI (match_dup 0) + (const_int 5))) + (match_scratch:QI 1 "d")] + "" + [(set (match_dup 0) (unspec:QI [(match_dup 0)] UNSPEC_SWAP)) + (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1))) + (set (match_dup 1) (const_int -32)) + (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))] + "") + +(define_peephole2 ; ashlqi3_l_const6 + [(set (match_operand:QI 0 "l_register_operand" "") + (ashift:QI (match_dup 0) + (const_int 6))) + (match_scratch:QI 1 "d")] + "" + [(set (match_dup 0) (unspec:QI [(match_dup 0)] UNSPEC_SWAP)) + (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2))) + (set (match_dup 1) (const_int -64)) + (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))] + "") + (define_peephole2 [(match_scratch:QI 3 "d") (set (match_operand:HI 0 "register_operand" "") @@ -1536,7 +1632,43 @@ ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> ;; logical shift right -(define_insn "lshrqi3" +(define_expand "lshrqi3" + [(set (match_operand:QI 0 "register_operand" "") + (lshiftrt:QI (match_operand:QI 1 "register_operand" "") + (match_operand:QI 2 "general_operand" "")))] + "" + "") + +(define_split ; lshrqi3_const4 + [(set (match_operand:QI 0 "d_register_operand" "") + (lshiftrt:QI (match_dup 0) + (const_int 4)))] + "" + [(set (match_dup 0) (unspec:QI [(match_dup 0)] UNSPEC_SWAP)) + (set (match_dup 0) (and:QI (match_dup 0) (const_int 15)))] + "") + +(define_split ; lshrqi3_const5 + [(set (match_operand:QI 0 "d_register_operand" "") + (lshiftrt:QI (match_dup 0) + (const_int 5)))] + "" + [(set (match_dup 0) (unspec:QI [(match_dup 0)] UNSPEC_SWAP)) + (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1))) + (set (match_dup 0) (and:QI (match_dup 0) (const_int 7)))] + "") + +(define_split ; lshrqi3_const6 + [(set (match_operand:QI 0 "d_register_operand" "") + (lshiftrt:QI (match_dup 0) + (const_int 6)))] + "" + [(set (match_dup 0) (unspec:QI [(match_dup 0)] UNSPEC_SWAP)) + (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2))) + (set (match_dup 0) (and:QI (match_dup 0) (const_int 3)))] + "") + +(define_insn "*lshrqi3" [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r") (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0") (match_operand:QI 2 "general_operand" "r,L,P,K,n,n,Qm")))] @@ -1565,6 +1697,41 @@ ;; Optimize if a scratch register from LD_REGS happens to be available. +(define_peephole2 ; lshrqi3_l_const4 + [(set (match_operand:QI 0 "l_register_operand" "") + (lshiftrt:QI (match_dup 0) + (const_int 4))) + (match_scratch:QI 1 "d")] + "" + [(set (match_dup 0) (unspec:QI [(match_dup 0)] UNSPEC_SWAP)) + (set (match_dup 1) (const_int 15)) + (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))] + "") + +(define_peephole2 ; lshrqi3_l_const5 + [(set (match_operand:QI 0 "l_register_operand" "") + (lshiftrt:QI (match_dup 0) + (const_int 5))) + (match_scratch:QI 1 "d")] + "" + [(set (match_dup 0) (unspec:QI [(match_dup 0)] UNSPEC_SWAP)) + (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1))) + (set (match_dup 1) (const_int 7)) + (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))] + "") + +(define_peephole2 ; lshrqi3_l_const6 + [(set (match_operand:QI 0 "l_register_operand" "") + (lshiftrt:QI (match_dup 0) + (const_int 6))) + (match_scratch:QI 1 "d")] + "" + [(set (match_dup 0) (unspec:QI [(match_dup 0)] UNSPEC_SWAP)) + (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2))) + (set (match_dup 1) (const_int 3)) + (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))] + "") + (define_peephole2 [(match_scratch:QI 3 "d") (set (match_operand:HI 0 "register_operand" "") |