This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Patch,AVR]: Solve PR42210
- From: Georg-Johann Lay <avr at gjlay dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Anatoly Sokolov <aesok at post dot ru>, Denis Chertykov <chertykov at gmail dot com>, Eric Weddington <eric dot weddington at atmel dot com>
- Date: Wed, 20 Apr 2011 19:50:05 +0200
- Subject: [Patch,AVR]: Solve PR42210
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?
Johann
2011-04-20 Georg-Johann Lay <avr@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,81 @@ (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,%4\;bld %0,%4"
+ [(set_attr "length" "2")
+ (set_attr "cc" "none")])
+
+;; Move bit $3.$4 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,%4\;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.7 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,7\;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"))
+ (const_int 1) ;; width
+ (match_operand 1 "const_int_operand" "n")) ;; pos
+ (match_operand:QI 2 "register_operand" "r"))]
+ "optimize
+ && IN_RANGE (INTVAL(operands[1]), 0, 7)"
+ "sbrc %2,0\;sbi %m0-0x20,%1\;sbrs %2,0\;cbi %m0-0x20,%1"
+ [(set_attr "length" "4")
+ (set_attr "cc" "none")])