aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorGeorg-Johann Lay <avr@gjlay.de>2011-05-16 14:20:19 +0000
committerGeorg-Johann Lay <gjl@gcc.gnu.org>2011-05-16 14:20:19 +0000
commit687027a4d55c087c933ef94868ff5450311e98ca (patch)
treec33cf38081412e0395b8d552fc0d917f941aa4d1 /gcc
parentf24a5190c25a90ec8734ce62b68c081681a314fe (diff)
downloadgcc-687027a4d55c087c933ef94868ff5450311e98ca.zip
gcc-687027a4d55c087c933ef94868ff5450311e98ca.tar.gz
gcc-687027a4d55c087c933ef94868ff5450311e98ca.tar.bz2
re PR middle-end/27663 (missed-optimization transforming a byte array to unsigned long)
PR target/27663 PR target/41076 * config/avr/predicates.md (const_8_16_24_operand): New predicate. * config/avr/avr.md ("*ior<mode>qi.byte0", "*ior<mode>qi.byte1-3"): New define_insn_and_split patterns. From-SVN: r173792
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/avr/avr.md39
-rwxr-xr-xgcc/config/avr/predicates.md7
3 files changed, 54 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b8af4fb..8ba223f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,13 @@
2011-05-16 Georg-Johann Lay <avr@gjlay.de>
+ PR target/27663
+ PR target/41076
+ * config/avr/predicates.md (const_8_16_24_operand): New predicate.
+ * config/avr/avr.md ("*ior<mode>qi.byte0",
+ "*ior<mode>qi.byte1-3"): New define_insn_and_split patterns.
+
+2011-05-16 Georg-Johann Lay <avr@gjlay.de>
+
PR target/45099
* config/avr/avr.c (avr_function_arg_advance): Error if a fixed
register is needed for a function argument.
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index 1ab3033..efe6bb6 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -3388,3 +3388,42 @@
clr __zero_reg__"
[(set_attr "length" "3")
(set_attr "cc" "clobber")])
+
+
+;; Some combine patterns that try to fix bad code when a value is composed
+;; from byte parts like in PR27663.
+;; The patterns give some release but the code still is not optimal,
+;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
+;; That switch obfuscates things here and in many other places.
+
+(define_insn_and_split "*ior<mode>qi.byte0"
+ [(set (match_operand:HISI 0 "register_operand" "=r")
+ (ior:HISI
+ (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
+ (match_operand:HISI 2 "register_operand" "0")))]
+ ""
+ "#"
+ "reload_completed"
+ [(set (match_dup 3)
+ (ior:QI (match_dup 3)
+ (match_dup 1)))]
+ {
+ operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
+ })
+
+(define_insn_and_split "*ior<mode>qi.byte1-3"
+ [(set (match_operand:HISI 0 "register_operand" "=r")
+ (ior:HISI
+ (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
+ (match_operand:QI 2 "const_8_16_24_operand" "n"))
+ (match_operand:HISI 3 "register_operand" "0")))]
+ "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 4)
+ (ior:QI (match_dup 4)
+ (match_dup 1)))]
+ {
+ int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
+ operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
+ })
diff --git a/gcc/config/avr/predicates.md b/gcc/config/avr/predicates.md
index 9a3473b..a7cc2ba 100755
--- a/gcc/config/avr/predicates.md
+++ b/gcc/config/avr/predicates.md
@@ -138,3 +138,10 @@
(define_predicate "pseudo_register_operand"
(and (match_code "reg")
(match_test "!HARD_REGISTER_P (op)")))
+
+;; Return true if OP is a constant integer that is either
+;; 8 or 16 or 24.
+(define_predicate "const_8_16_24_operand"
+ (and (match_code "const_int")
+ (match_test "8 == INTVAL(op) || 16 == INTVAL(op) || 24 == INTVAL(op)")))
+