aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorg-Johann Lay <avr@gjlay.de>2016-08-04 07:50:53 +0000
committerGeorg-Johann Lay <gjl@gcc.gnu.org>2016-08-04 07:50:53 +0000
commite7ff6a46c9d852aeabae483b45e0e30bd6322a10 (patch)
tree8b6958836ef2ee6dd440dad2756bd4fd6646bd88
parenta00084346a299e8154ede732c6d4d3ae56d1f66f (diff)
downloadgcc-e7ff6a46c9d852aeabae483b45e0e30bd6322a10.zip
gcc-e7ff6a46c9d852aeabae483b45e0e30bd6322a10.tar.gz
gcc-e7ff6a46c9d852aeabae483b45e0e30bd6322a10.tar.bz2
re PR target/55181 (Expensive shift loop where a bit-testing instruction could be used)
PR 55181 * config/avr/avr.md: New pattern to work around do_store_flag generating shift instructions for bit extractions. From-SVN: r239116
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/avr/avr.md23
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")