diff options
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/avr/avr.md | 23 |
2 files changed, 29 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8261b41..0e5eea4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2016-08-04 Georg-Johann Lay <avr@gjlay.de> + + PR 55181 + * config/avr/avr.md: New pattern to work around do_store_flag + generating shift instructions for bit extractions. + 2016-08-04 Kugan Vivekanandarajah <kuganv@linaro.org> * tree-vrp.c (set_value_range): Use vrp_equiv_obstack with diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index 23790b6..97f3561 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -6691,6 +6691,29 @@ 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") |