--- h8300.md.movmd-movsd	2012-12-17 21:09:54.206021172 +0900
+++ h8300.md	2012-12-17 21:09:54.347822608 +0900
@@ -569,6 +569,50 @@
    (set_attr "can_delay" "no")
    (set_attr "cc" "none,clobber")])
 
+;	nop
+(define_insn "*movmd_nop"
+  [(unspec [(const_int 0)] UNSPEC_MOVMD)]
+  ""
+  "nop"
+  )
+
+;
+;	mov.w	@mem,r5/r6
+;	movmd
+;
+;	mov.w	@mem,r5/r6
+;	nop
+;	movmd
+;
+(define_peephole2
+  [(set (match_operand:HI 7 "register_operand" "")
+        (match_operand:HI 8 "memory_operand" ""))
+   (parallel
+       [(set (mem:BLK (match_operand:HI 3 "register_operand" ""))
+             (mem:BLK (match_operand:HI 4 "register_operand" "")))
+        (unspec [(match_operand:HI 5 "register_operand" "")
+                 (match_operand:HI 6 "const_int_operand" "")] UNSPEC_MOVMD)
+        (clobber (match_operand:HI 0 "register_operand" ""))
+        (clobber (match_operand:HI 1 "register_operand" ""))
+        (set (match_operand:HI 2 "register_operand" "")
+             (const_int 0))])]
+  "TARGET_H8300SX && TARGET_NORMAL_MODE
+   && ((REGNO (operands[7]) == SOURCE_REG)
+       || (REGNO (operands[7]) == DESTINATION_REG))"
+  [(set (match_dup 7)
+        (match_dup 8))
+   (unspec [(const_int 0)] UNSPEC_MOVMD)
+   (parallel
+       [(set (mem:BLK (match_dup 3))
+             (mem:BLK (match_dup 4)))
+        (unspec [(match_dup 5)
+                 (match_dup 6)] UNSPEC_MOVMD)
+        (clobber (match_dup 0))
+        (clobber (match_dup 1))
+        (set (match_dup 2)
+             (const_int 0))])]
+  "")
+
 (define_insn "movmd_internal"
   [(set (mem:BLK (match_operand:SI 3 "register_operand" "0,r"))
 	(mem:BLK (match_operand:SI 4 "register_operand" "1,1")))
@@ -586,6 +630,43 @@
    (set_attr "can_delay" "no")
    (set_attr "cc" "none,clobber")])
 
+;
+;       mov.l   @mem,er5/er6
+;       movmd
+;
+;       mov.l   @mem,er5/er6
+;       nop
+;       movmd
+;
+(define_peephole2
+  [(set (match_operand:SI 7 "register_operand" "")
+        (match_operand:SI 8 "memory_operand" ""))
+   (parallel
+       [(set (mem:BLK (match_operand:SI 3 "register_operand" ""))
+             (mem:BLK (match_operand:SI 4 "register_operand" "")))
+        (unspec [(match_operand:HI 5 "register_operand" "")
+                 (match_operand:HI 6 "const_int_operand" "")] UNSPEC_MOVMD)
+        (clobber (match_operand:SI 0 "register_operand" ""))
+        (clobber (match_operand:SI 1 "register_operand" ""))
+        (set (match_operand:HI 2 "register_operand" "")
+             (const_int 0))])]
+  "TARGET_H8300SX && !TARGET_NORMAL_MODE
+   && ((REGNO (operands[7]) == SOURCE_REG)
+       || (REGNO (operands[7]) == DESTINATION_REG))"
+  [(set (match_dup 7)
+        (match_dup 8))
+   (unspec [(const_int 0)] UNSPEC_MOVMD)
+   (parallel
+       [(set (mem:BLK (match_dup 3))
+             (mem:BLK (match_dup 4)))
+        (unspec [(match_dup 5)
+                 (match_dup 6)] UNSPEC_MOVMD)
+        (clobber (match_dup 0))
+        (clobber (match_dup 1))
+        (set (match_dup 2)
+             (const_int 0))])]
+  "")
+
 ;; Split the above instruction if the destination register isn't er6.
 ;; We need a sequence like:
 ;;
@@ -613,7 +694,7 @@
   {
     rtx dest;
 
-    h8300_swap_into_er6 (XEXP (operands[0], 0));
+    h8300_swap_into_er6 (operands[4]/*XEXP (operands[0], 0)*/);
     dest = replace_equiv_address (operands[0], hard_frame_pointer_rtx);
     emit_insn (gen_movmd (dest, operands[1], operands[2], operands[3]));
     h8300_swap_out_of_er6 (operands[4]);
@@ -636,7 +717,7 @@
   {
     rtx dest;
 
-    h8300_swap_into_er6 (XEXP (operands[0], 0));
+    h8300_swap_into_er6 (operands[4]/*XEXP (operands[0], 0)*/);
     dest = replace_equiv_address (operands[0], hard_frame_pointer_rtx);
     emit_insn (gen_movmd (dest, operands[1], operands[2], operands[3]));
     h8300_swap_out_of_er6 (operands[4]);
@@ -695,6 +776,44 @@
   [(set_attr "length" "6,18")
    (set_attr "cc" "none,clobber")])
 
+;	nop
+(define_insn "*stpcpy_nop"
+  [(unspec [(const_int 0)] UNSPEC_STPCPY)]
+  ""
+  "nop"
+  )
+
+;
+;       mov.w   @mem,r5/r6
+;       movsd
+;
+;       mov.w   @mem,r5/r6
+;       nop
+;       movsd
+;
+(define_peephole2
+  [(set (match_operand:HI 5 "register_operand" "")
+        (match_operand:HI 6 "memory_operand" ""))
+   (set (mem:BLK (match_operand:HI 3 "register_operand" ""))
+        (unspec:BLK [(mem:BLK (match_operand:HI 4 "register_operand" ""))]
+                UNSPEC_STPCPY))
+   (clobber (match_operand:HI 0 "register_operand" ""))
+   (clobber (match_operand:HI 1 "register_operand" ""))
+   (clobber (match_operand:HI 2 "register_operand" ""))]
+  "TARGET_H8300SX && TARGET_NORMAL_MODE
+   && ((REGNO (operands[5]) == SOURCE_REG)
+       || (REGNO (operands[5]) == DESTINATION_REG))"
+  [(set (match_dup 5)
+        (match_dup 6))
+   (unspec [(const_int 0)] UNSPEC_STPCPY)
+   (set (mem:BLK (match_dup 3))
+        (unspec:BLK [(mem:BLK (match_dup 4))]
+                UNSPEC_STPCPY))
+   (clobber (match_dup 0))
+   (clobber (match_dup 1))
+   (clobber (match_dup 2))]
+  "")
+
 (define_insn "stpcpy_internal"
   [(set (mem:BLK (match_operand:SI 3 "register_operand" "0,r"))
 	(unspec:BLK [(mem:BLK (match_operand:SI 4 "register_operand" "1,1"))]
@@ -709,6 +828,37 @@
   [(set_attr "length" "6,18")
    (set_attr "cc" "none,clobber")])
 
+;
+;       mov.l   @mem,er5/er6
+;       movsd
+;
+;       mov.l   @mem,er5/er6
+;       nop
+;       movsd
+;
+(define_peephole2
+  [(set (match_operand:SI 5 "register_operand" "")
+        (match_operand:SI 6 "memory_operand" ""))
+   (set (mem:BLK (match_operand:SI 3 "register_operand" ""))
+        (unspec:BLK [(mem:BLK (match_operand:SI 4 "register_operand" ""))]
+                UNSPEC_STPCPY))
+   (clobber (match_operand:SI 0 "register_operand" ""))
+   (clobber (match_operand:SI 1 "register_operand" ""))
+   (clobber (match_operand:SI 2 "register_operand" ""))]
+  "TARGET_H8300SX && !TARGET_NORMAL_MODE
+   && ((REGNO (operands[5]) == SOURCE_REG)
+       || (REGNO (operands[5]) == DESTINATION_REG))"
+  [(set (match_dup 5)
+        (match_dup 6))
+   (unspec [(const_int 0)] UNSPEC_STPCPY)
+   (set (mem:BLK (match_dup 3))
+        (unspec:BLK [(mem:BLK (match_dup 4))]
+                UNSPEC_STPCPY))
+   (clobber (match_dup 0))
+   (clobber (match_dup 1))
+   (clobber (match_dup 2))]
+  "")
+
 ;; Split the above instruction if the destination isn't er6.  This works
 ;; in the same way as the movmd splitter.
 (define_split
@@ -724,7 +874,7 @@
   {
     rtx dest;
 
-    h8300_swap_into_er6 (XEXP (operands[0], 0));
+    h8300_swap_into_er6 (operands[2]/*XEXP (operands[0], 0)*/);
     dest = replace_equiv_address (operands[0], hard_frame_pointer_rtx);
     emit_insn (gen_movsd (dest, operands[1], operands[4]));
     h8300_swap_out_of_er6 (operands[2]);
@@ -744,7 +894,7 @@
   {
     rtx dest;
 
-    h8300_swap_into_er6 (XEXP (operands[0], 0));
+    h8300_swap_into_er6 (operands[2]/*XEXP (operands[0], 0)*/);
     dest = replace_equiv_address (operands[0], hard_frame_pointer_rtx);
     emit_insn (gen_movsd (dest, operands[1], operands[4]));
     h8300_swap_out_of_er6 (operands[2]);
