summaryrefslogtreecommitdiffstats
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/config/avr/avr.md113
-rwxr-xr-xgcc/config/avr/predicates.md11
3 files changed, 134 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0560f55a5f8..6e4895eeb0a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2011-06-06 Richard Henderson <rth@redhat.com>
+ Georg-Johann Lay <avr@gjlay.de>
+
+ PR target/42210
+ * config/avr/predicates.md (const1_operand, const_0_to_7_operand):
+ New predicates.
+ * config/avr/avr.md ("insv"): New insn expander.
+ ("*movbitqi.1-6.a", "*movbitqi.1-6.b", "*movbitqi.0", "*insv.io",
+ "*insv.not.io", "*insv.reg"): New insns.
+
2011-06-06 Hans-Peter Nilsson <hp@bitrange.com>
PR target/49285
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index efe6bb6914f..4138f2b9df9 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -3390,6 +3390,119 @@
(set_attr "cc" "clobber")])
+;; Some combiner patterns dealing with bits.
+;; See PR42210
+
+;; Move bit $3.0 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_0_to_7_operand" "n"))
+ (match_operand:QI 5 "single_one_operand" "n"))))]
+ "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))
+ && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & 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_0_to_7_operand" "n"))))]
+ "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))))]
+ "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))))]
+ ""
+ "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 "*insv.io"
+ [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n,n,n"))
+ (const_int 1)
+ (match_operand:QI 1 "const_0_to_7_operand" "n,n,n"))
+ (match_operand:QI 2 "nonmemory_operand" "L,P,r"))]
+ ""
+ "@
+ 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")])
+
+(define_insn "*insv.not.io"
+ [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n"))
+ (const_int 1)
+ (match_operand:QI 1 "const_0_to_7_operand" "n"))
+ (not:QI (match_operand:QI 2 "register_operand" "r")))]
+ ""
+ "sbrs %2,0\;sbi %m0-0x20,%1\;sbrc %2,0\;cbi %m0-0x20,%1"
+ [(set_attr "length" "4")
+ (set_attr "cc" "none")])
+
+;; The insv expander.
+;; We only support 1-bit inserts
+(define_expand "insv"
+ [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "")
+ (match_operand:QI 1 "const1_operand" "") ; width
+ (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos
+ (match_operand:QI 3 "nonmemory_operand" ""))]
+ "optimize"
+ "")
+
+;; Insert bit $2.0 into $0.$1
+(define_insn "*insv.reg"
+ [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l")
+ (const_int 1)
+ (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
+ (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))]
+ ""
+ "@
+ bst %2,0\;bld %0,%1
+ andi %0,lo8(~(1<<%1))
+ ori %0,lo8(1<<%1)
+ clt\;bld %0,%1
+ set\;bld %0,%1"
+ [(set_attr "length" "2,1,1,2,2")
+ (set_attr "cc" "none,set_zn,set_zn,none,none")])
+
+
;; Some combine patterns that try to fix bad code when a value is composed
;; from byte parts like in PR27663.
;; The patterns give some release but the code still is not optimal,
diff --git a/gcc/config/avr/predicates.md b/gcc/config/avr/predicates.md
index a7cc2ba052f..056a1650b79 100755
--- a/gcc/config/avr/predicates.md
+++ b/gcc/config/avr/predicates.md
@@ -62,6 +62,17 @@
(and (match_code "const_int,const_double")
(match_test "op == CONST0_RTX (mode)")))
+;; Return 1 if OP is the one constant integer for MODE.
+(define_predicate "const1_operand"
+ (and (match_code "const_int")
+ (match_test "op == CONST1_RTX (mode)")))
+
+
+;; Return 1 if OP is constant integer 0..7 for MODE.
+(define_predicate "const_0_to_7_operand"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 0, 7)")))
+
;; Returns true if OP is either the constant zero or a register.
(define_predicate "reg_or_0_operand"
(ior (match_operand 0 "register_operand")
OpenPOWER on IntegriCloud