diff mbox

[AVR] : Solve PR42210

Message ID 4DB07C01.1050503@redhat.com
State New
Headers show

Commit Message

Richard Henderson April 21, 2011, 6:48 p.m. UTC
On 04/21/2011 05:31 AM, Georg-Johann Lay wrote:
> +;; Some combiner patterns dealing with bits.
> +;; See PR42210
> +
> +;; Move bit $3.$4 into bit $0.$4
> +(define_insn "*movbitqi.1-6.a"
...
> +(define_insn "*movbitqi.1-6.b"
...
> +(define_insn "*movbitqi.0"
...
> +(define_insn "*movbitqi.7"

This looks to be way more complicated than necessary.  Consider implementing the
extzv and insv named patterns, and using zero_extract properly.

E.g. the following, lightly tested.  Looking again at the comment on your last
pattern, it looks like that one would still need to be included.


r~
diff mbox

Patch

diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index 1ab3033..e557fcd 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -3388,3 +3388,74 @@ 
 	clr __zero_reg__"
   [(set_attr "length" "3")
    (set_attr "cc" "clobber")])
+
+(define_expand "extzv"
+  [(set (match_operand:QI 0 "register_operand" "")
+	(zero_extract:QI
+	  (match_operand:QI 1 "register_operand" "")
+	  (match_operand:QI 2 "const1_operand" "")
+	  (match_operand:QI 3 "const_0_to_7_operand" "")))]
+  ""
+  "")
+
+(define_expand "insv"
+  [(set (zero_extract:QI
+	  (match_operand:QI 0 "register_operand" "")
+	  (match_operand:QI 1 "const1_operand" "")
+	  (match_operand:QI 2 "const_0_to_7_operand" ""))
+	(match_operand:QI 3 "nonmemory_operand" ""))]
+  ""
+  "")
+
+(define_insn "*movbitqi_reg_ext"
+  [(set (match_operand:QI 0 "register_operand" "=r")
+	(zero_extract:QI
+	  (match_operand:QI 1 "register_operand" "r")
+	  (const_int 1)
+	  (match_operand 2 "const_0_to_7_operand" "")))]
+  ""
+  "bst %1,%2\;bld %0,0"
+  [(set_attr "length" "2")
+   (set_attr "cc" "none")])
+
+(define_insn "*movbitqi_ext_ext"
+  [(set (zero_extract:QI
+	  (match_operand:QI 0 "register_operand" "+r")
+	  (const_int 1)
+	  (match_operand 1 "const_0_to_7_operand" ""))
+	(zero_extract:QI
+	  (match_operand:QI 2 "register_operand" "r")
+	  (const_int 1)
+	  (match_operand 3 "const_0_to_7_operand" "")))]
+  ""
+  "bst %2,%3\;bld %0,%1"
+  [(set_attr "length" "2")
+   (set_attr "cc" "none")])
+
+(define_insn "*movbitqi_ext_reg"
+  [(set (zero_extract:QI
+	  (match_operand:QI 0 "register_operand" "+*d,*d,r,r,r")
+	  (const_int 1)
+	  (match_operand 1 "const_0_to_7_operand" ""))
+	(match_operand:QI 2 "nonmemory_operand" "L,P,L,P,r"))]
+  ""
+{
+  switch (which_alternative)
+    {
+    case 0:
+      operands[2] = gen_int_mode (~(1 << INTVAL (operands[1])), QImode);
+      return "andi %0,%2";
+    case 1:
+      operands[2] = gen_int_mode (1 << INTVAL (operands[1]), QImode);
+      return "ori %0,%2";
+    case 2:
+      return "clt\;bld %0,%1";
+    case 3:
+      return "set\;bld %0,%1";
+    case 4:
+      return "bst %2,0\;bld %0,%1";
+    }
+  gcc_unreachable ();
+}
+  [(set_attr "length" "1,1,2,2,2")
+   (set_attr "cc" "set_zn,set_zn,none,none,none")])
diff --git a/gcc/config/avr/predicates.md b/gcc/config/avr/predicates.md
index 9a3473b..e0142d1 100755
--- a/gcc/config/avr/predicates.md
+++ b/gcc/config/avr/predicates.md
@@ -62,6 +62,11 @@ 
   (and (match_code "const_int,const_double")
        (match_test "op == CONST0_RTX (mode)")))
 
+;; Return 1 if OP is the one constant for MODE.
+(define_predicate "const1_operand"
+  (and (match_code "const_int")
+       (match_test "op == CONST1_RTX (mode)")))
+
 ;; Returns true if OP is either the constant zero or a register.
 (define_predicate "reg_or_0_operand"
   (ior (match_operand 0 "register_operand")
@@ -106,6 +111,11 @@ 
   (and (match_code "const_int")
        (match_test "exact_log2(~INTVAL (op) & GET_MODE_MASK (mode)) >= 0")))
 
+;; Return true if OP is a constant between 0 and 7.
+(define_predicate "const_0_to_7_operand"
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (INTVAL (op), 0, 7)")))
+
 ;;
 (define_predicate "avr_sp_immediate_operand"
   (and (match_code "const_int")