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