diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7a03dd94da3a..ce64d10b0ff7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2007-03-31  Anatoly Sokolov <aesok@post.ru>
+
+	* config/avr/predicates.md (even_register_operand, 
+	odd_register_operand): New predicates.
+	* config/avr/avr.md (movw peephole2): New.
+	(movw_r peephole2): New.
+
 2007-03-30  Rafael Avila de Espindola  <espindola@google.com>
 
 	* tree.h (get_signed_or_unsigned_type): New.
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index d0b96e113034..0eb88491117f 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -283,6 +283,34 @@
   [(set_attr "length" "2,6,7,2,6,5,2")
    (set_attr "cc" "none,clobber,clobber,none,clobber,none,none")])
 
+(define_peephole2 ; movw
+  [(set (match_operand:QI 0 "even_register_operand" "")
+        (match_operand:QI 1 "even_register_operand" ""))
+   (set (match_operand:QI 2 "odd_register_operand" "")
+        (match_operand:QI 3 "odd_register_operand" ""))]
+  "(AVR_HAVE_MOVW
+    && REGNO (operands[0]) == REGNO (operands[2]) - 1
+    && REGNO (operands[1]) == REGNO (operands[3]) - 1)"
+  [(set (match_dup 4) (match_dup 5))]
+  {
+    operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
+    operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
+  })
+
+(define_peephole2 ; movw_r
+  [(set (match_operand:QI 0 "odd_register_operand" "")
+        (match_operand:QI 1 "odd_register_operand" ""))
+   (set (match_operand:QI 2 "even_register_operand" "")
+        (match_operand:QI 3 "even_register_operand" ""))]
+  "(AVR_HAVE_MOVW
+    && REGNO (operands[2]) == REGNO (operands[0]) - 1
+    && REGNO (operands[3]) == REGNO (operands[1]) - 1)"
+  [(set (match_dup 4) (match_dup 5))]
+  {
+    operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
+    operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
+  })
+
 ;;==========================================================================
 ;; move double word (32 bit)
 
diff --git a/gcc/config/avr/predicates.md b/gcc/config/avr/predicates.md
index 4a0dd1c0cba5..291bd85bbe78 100755
--- a/gcc/config/avr/predicates.md
+++ b/gcc/config/avr/predicates.md
@@ -28,6 +28,16 @@
   (and (match_code "reg")
        (match_test "REGNO (op) >= 16 && REGNO (op) <= 31")))
 
+(define_predicate "even_register_operand"
+  (and (match_code "reg")
+       (and (match_test "REGNO (op) <= 31")
+            (match_test "(REGNO (op) & 1) == 0"))))
+
+(define_predicate "odd_register_operand"
+  (and (match_code "reg")
+       (and (match_test "REGNO (op) <= 31")
+            (match_test "(REGNO (op) & 1) != 0"))))
+
 ;; SP register.
 (define_predicate "stack_register_operand"
   (and (match_code "reg")