diff mbox

[avr] PR 55181 work around do_store_flag producing shifts for bit extractions

Message ID 44459b42-61ae-9602-108f-1ff73387df42@gjlay.de
State New
Headers show

Commit Message

Georg-Johann Lay Aug. 3, 2016, 3:41 p.m. UTC
do_store_flag has hard-coded right shift for testing a bit, I found no way to 
let the backend direct expr.c into generating an extzv.  As rectifying the 
middle-end is beyond by time frame, here is yet another kludge to catch the 
situation by means of a pattern.


Also hints are welcome if I overlooked something, i.e. if there is a better 
approach to fix this in the avr BE.  FYI, avr has no barrel shifter and hence 
shifts are very costly.

Ok for trunk if nobody comes up with a better solution?

Johann



gcc/
	PR 55181
	* config/avr/avr.md: New pattern to work around do_store_flag
	generating shift instructions for bit extractions.

Comments

Denis Chertykov Aug. 3, 2016, 5:20 p.m. UTC | #1
2016-08-03 18:41 GMT+03:00 Georg-Johann Lay <avr@gjlay.de>:
> do_store_flag has hard-coded right shift for testing a bit, I found no way
> to let the backend direct expr.c into generating an extzv.  As rectifying
> the middle-end is beyond by time frame, here is yet another kludge to catch
> the situation by means of a pattern.
>
>
> Also hints are welcome if I overlooked something, i.e. if there is a better
> approach to fix this in the avr BE.  FYI, avr has no barrel shifter and
> hence shifts are very costly.
>
> Ok for trunk if nobody comes up with a better solution?
>
> Johann
>
>
>
> gcc/
>         PR 55181
>         * config/avr/avr.md: New pattern to work around do_store_flag
>         generating shift instructions for bit extractions.
>
>

I have no objections.
diff mbox

Patch

Index: config/avr/avr.md
===================================================================
--- config/avr/avr.md	(revision 238983)
+++ config/avr/avr.md	(working copy)
@@ -6691,6 +6691,29 @@  (define_insn_and_split "*extzv.qihi2"
     operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
   })
 
+;; ??? do_store_flag emits a hard-coded right shift to extract a bit without
+;; even considering rtx_costs, extzv, or a bit-test.  See PR 55181 for an example.
+(define_insn_and_split "*extract.subreg.bit"
+  [(set (match_operand:QI 0 "register_operand"                                       "=r")
+        (and:QI (subreg:QI (any_shiftrt:HISI (match_operand:HISI 1 "register_operand" "r")
+                                             (match_operand:QI 2 "const_int_operand"  "n"))
+                           0)
+                (const_int 1)))]
+  "INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
+  { gcc_unreachable(); }
+  "&& reload_completed"
+  [;; "*extzv"
+   (set (match_dup 0)
+        (zero_extract:QI (match_dup 3)
+                         (const_int 1)
+                         (match_dup 4)))]
+  {
+    int bitno = INTVAL (operands[2]);
+    operands[3] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, bitno / 8);
+    operands[4] = GEN_INT (bitno % 8);
+  })
+
+                                        
 
 ;; Fixed-point instructions
 (include "avr-fixed.md")