Georg-Johann Lay schrieb: > This solves some missed optimization that can be seen when moving > around bits. > > There are 4 combiner patterns that operate on regs and one that uses > them as intermediate patterns and works on I/O. Even if just an > intermediate pattern matches it's still an improvement because avoid > of shift. > > Tested on some home-brew example. > > Ok if I see no regressions?
The original patch has a thinko. The source bit is always 0. Besides that, the (set (zero_extract is now allowed to handle constant sources, too. The new patch fixes that and passes testsuite. Johann > 2011-04-20 Georg-Johann Lay <a...@gjlay.de> > > PR target/42210 > > * config/avr/avr.md ("*movbitqi.1-6.a", "*movbitqi.1-6.b", > "*movbitqi.0", "*movbitqi.7", "*movbitqi.io"): New insns. >
Index: config/avr/avr.md =================================================================== --- config/avr/avr.md (Revision 172770) +++ config/avr/avr.md (Arbeitskopie) @@ -3388,3 +3388,84 @@ (define_insn "fmulsu" clr __zero_reg__" [(set_attr "length" "3") (set_attr "cc" "clobber")]) + + +;; Some combiner patterns dealing with bits. +;; See PR42210 + +;; Move bit $3.$4 into bit $0.$4 +(define_insn "*movbitqi.1-6.a" + [(set (match_operand:QI 0 "register_operand" "=r") + (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0") + (match_operand:QI 2 "single_zero_operand" "n")) + (and:QI (ashift:QI (match_operand:QI 3 "register_operand" "r") + (match_operand:QI 4 "const_int_operand" "n")) + (match_operand:QI 5 "single_one_operand" "n"))))] + "optimize + && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode)) + && INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))" + "bst %3,0\;bld %0,%4" + [(set_attr "length" "2") + (set_attr "cc" "none")]) + +;; Move bit $3.0 into bit $0.$4 +;; Variation of above. Unfortunately, there is no canonicalized representation +;; of moving around bits. So what we see here depends on how user writes down +;; bit manipulations. +(define_insn "*movbitqi.1-6.b" + [(set (match_operand:QI 0 "register_operand" "=r") + (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0") + (match_operand:QI 2 "single_zero_operand" "n")) + (ashift:QI (and:QI (match_operand:QI 3 "register_operand" "r") + (const_int 1)) + (match_operand:QI 4 "const_int_operand" "n"))))] + "optimize + && INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))" + "bst %3,0\;bld %0,%4" + [(set_attr "length" "2") + (set_attr "cc" "none")]) + +;; Move bit $3.0 into bit $0.0. +;; For bit 0, combiner generates slightly different pattern. +(define_insn "*movbitqi.0" + [(set (match_operand:QI 0 "register_operand" "=r") + (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0") + (match_operand:QI 2 "single_zero_operand" "n")) + (and:QI (match_operand:QI 3 "register_operand" "r") + (const_int 1))))] + "optimize + && 0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))" + "bst %3,0\;bld %0,0" + [(set_attr "length" "2") + (set_attr "cc" "none")]) + +;; Move bit $2.0 into bit $0.7. +;; For bit 7, combiner generates slightly different pattern +(define_insn "*movbitqi.7" + [(set (match_operand:QI 0 "register_operand" "=r") + (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0") + (const_int 127)) + (ashift:QI (match_operand:QI 2 "register_operand" "r") + (const_int 7))))] + "optimize" + "bst %2,0\;bld %0,7" + [(set_attr "length" "2") + (set_attr "cc" "none")]) + +;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM +;; and input/output match. We provide a special pattern for this, because +;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the +;; operation on I/O is atomic. +(define_insn "*movbitqi.io" + [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n,n,n")) + (const_int 1) + (match_operand 1 "const_int_operand" "n,n,n")) + (match_operand:QI 2 "nonmemory_operand" "L,P,r"))] + "optimize + && IN_RANGE (INTVAL(operands[1]), 0, 7)" + "@ + cbi %m0-0x20,%1 + sbi %m0-0x20,%1 + sbrc %2,0\;sbi %m0-0x20,%1\;sbrs %2,0\;cbi %m0-0x20,%1" + [(set_attr "length" "1,1,4") + (set_attr "cc" "none")])