Letting GCC think that any mem-mem alternative is OK leads to trouble
with far mem to far mem moves, so split out the moves we can make.
Committed.

        * config/rl78/predicates.md (rl78_near_mem_operand): New.
        * config/rl78/rl78-virt.md (movqi_virt_mm, movqi_virt)
        (movhi_virt_mm): Split out near mem-mem moves to avoid problems
        with far-far moves.

 
Index: config/rl78/predicates.md
===================================================================
--- config/rl78/predicates.md   (revision 213995)
+++ config/rl78/predicates.md   (working copy)
@@ -30,12 +30,17 @@
 
 (define_predicate "rl78_nonfar_nonimm_operand"
   (and (match_operand 0 "nonimmediate_operand")
        (not (match_test "rl78_far_p (op)")))
 )
 
+(define_predicate "rl78_near_mem_operand"
+  (and (match_code "mem")
+       (match_test "!rl78_far_p (op) && rl78_as_legitimate_address (VOIDmode, 
XEXP (op, 0), true, ADDR_SPACE_GENERIC)"))
+)
+
 (define_predicate "ubyte_operand"
   (and (match_code "const_int")
        (match_test "IN_RANGE (INTVAL (op), 0, 255)")))
 
 (define_predicate "rl78_24_operand"
   (and (match_code "const_int")
Index: config/rl78/rl78-virt.md
===================================================================
--- config/rl78/rl78-virt.md    (revision 213996)
+++ config/rl78/rl78-virt.md    (working copy)
@@ -30,20 +30,36 @@
 
 (define_attr "valloc" "op1,op2,ro1,cmp,umul,macax"
   (const_string "op2"))
 
 ;;---------- Moving ------------------------
 
+(define_insn "*movqi_virt_mm"
+  [(set (match_operand:QI 0 "rl78_near_mem_operand" "=Y")
+       (match_operand    1 "rl78_near_mem_operand" "Y"))]
+  "rl78_virt_insns_ok ()"
+  "v.mov %0, %1"
+  [(set_attr "valloc" "op1")]
+)
+
 (define_insn "*movqi_virt"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=vY,v,Wfr")
-       (match_operand    1 "general_operand" "vInt8JY,Wfr,vInt8J"))]
+       (match_operand    1 "general_operand" "vInt8J,YWfr,vInt8J"))]
   "rl78_virt_insns_ok ()"
   "v.mov %0, %1"
   [(set_attr "valloc" "op1")]
 )
 
+(define_insn "*movhi_virt_mm"
+  [(set (match_operand:HI 0 "rl78_near_mem_operand" "=Y")
+       (match_operand:HI 1 "rl78_near_mem_operand" "Y"))]
+  "rl78_virt_insns_ok ()"
+  "v.movw %0, %1"
+  [(set_attr "valloc" "op1")]
+)
+
 (define_insn "*movhi_virt"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=vS,  Y,   v,   Wfr")
        (match_operand:HI 1 "general_operand"      "viYS, viS, Wfr, vi"))]
   "rl78_virt_insns_ok ()"
   "v.movw %0, %1"
   [(set_attr "valloc" "op1")]

Reply via email to