Patchwork [AVR] : Fix PR33049 (implement extzv)

login
register
mail settings
Submitter Georg-Johann Lay
Date June 20, 2011, 5:52 p.m.
Message ID <4DFF88C7.3080809@gjlay.de>
Download mbox | patch
Permalink /patch/101172/
State New
Headers show

Comments

Georg-Johann Lay - June 20, 2011, 5:52 p.m.
This is an optimization patch that implements extzv for 1-bit extracts.

The nice thing is that AVR can do this easily with a BLD/CLR/BST
sequence, without putting pressure on d-regs and without the
requirement of source being in the same register as destination.

extzv can also be seen in conjunction with zero_extend which, without
this patch, will lead to a 16-bit loop just to get one bit from a
position with a known offset.  So there are two splits to split the
high-part away.

Tested without regression.

Johann

	PR target/33049
	* config/avr/avr.md (extzv): New expander.
	(*extzv, *extzv.qihi1, *extzv.qihi2): New insn-and-split.
Denis Chertykov - June 21, 2011, 7:08 a.m.
2011/6/20 Georg-Johann Lay <avr@gjlay.de>:
> This is an optimization patch that implements extzv for 1-bit extracts.


> +(define_insn_and_split "*extzv"
> +  [(set (match_operand:QI 0 "register_operand"                    "=*d,*d,*d,r")
> +        (zero_extract:QI (match_operand:QI 1 "register_operand"     "0,r,0,r")
> +                         (const_int 1)
> +                         (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,n")))]
> +  ""
> +  "@
> +	andi %0,1
> +	mov %0,%1\;andi %0,1
> +	lsr %0\;andi %0,1
> +	bst %1,%2\;clr %0\;bld %0,0"

Why you have a second constraint alternative (*d,r,L) ?
IMHO it's unnecessary.

> +   && REGNO (operands[0]) >= 16"

It's not a good practice to refer to register as number.

Denis.

Patch

Index: config/avr/avr.md
===================================================================
--- config/avr/avr.md	(revision 175201)
+++ config/avr/avr.md	(working copy)
@@ -3540,3 +3540,75 @@  (define_insn_and_split "*ior<mode>qi.byt
     int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
     operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
   })
+
+(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_insn_and_split "*extzv"
+  [(set (match_operand:QI 0 "register_operand"                   "=*d,*d,*d,r")
+        (zero_extract:QI (match_operand:QI 1 "register_operand"     "0,r,0,r")
+                         (const_int 1)
+                         (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,n")))]
+  ""
+  "@
+	andi %0,1
+	mov %0,%1\;andi %0,1
+	lsr %0\;andi %0,1
+	bst %1,%2\;clr %0\;bld %0,0"
+  "reload_completed
+   && INTVAL (operands[2]) == 4
+   && REGNO (operands[0]) == REGNO (operands[1])
+   && REGNO (operands[0]) >= 16"
+  [(set (match_dup 0)
+        (rotate:QI (match_dup 0)
+                   (const_int 4)))
+   (set (match_dup 0)
+        (and:QI (match_dup 0)
+                (const_int 1)))]
+  ""
+  [(set_attr "length" "1,2,2,3")
+   (set_attr "cc" "set_zn,set_zn,set_zn,clobber")])
+
+(define_insn_and_split "*extzv.qihi1"
+  [(set (match_operand:HI 0 "register_operand"                   "=*d,*d,*d,r")
+        (zero_extract:HI (match_operand:QI 1 "register_operand"     "0,r,0,r")
+                         (const_int 1)
+                         (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,n")))]
+  ""
+  "#"
+  ""
+  [(set (match_dup 3)
+        (zero_extract:QI (match_dup 1)
+                         (const_int 1)
+                         (match_dup 2)))
+   (set (match_dup 4)
+        (const_int 0))]
+  {
+    operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
+    operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
+  })
+
+(define_insn_and_split "*extzv.qihi2"
+  [(set (match_operand:HI 0 "register_operand"                    "=*d,*d,*d,r")
+        (zero_extend:HI 
+         (zero_extract:QI (match_operand:QI 1 "register_operand"     "0,r,0,r")
+                          (const_int 1)
+                          (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,n"))))]
+  ""
+  "#"
+  ""
+  [(set (match_dup 3)
+        (zero_extract:QI (match_dup 1)
+                         (const_int 1)
+                         (match_dup 2)))
+   (set (match_dup 4)
+        (const_int 0))]
+  {
+    operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
+    operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
+  })