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")]