* rampz_rtx et al. were missing MEM_VOLATILE_P.  This is needed because
  avr_emit_cpymemhi is setting RAMPZ explicitly with an own insn.

* avr_out_cpymem was missing a final RAMPZ = 0 on EBI devices.

This only affects the __flash1 ... __flash5 spaces since the other ASes
use different routines,

Applies as obvious.

Johann

--

AVR: target/118000 - Fix copymem from address-spaces.

* rampz_rtx et al. were missing MEM_VOLATILE_P.  This is needed because
  avr_emit_cpymemhi is setting RAMPZ explicitly with an own insn.

* avr_out_cpymem was missing a final RAMPZ = 0 on EBI devices.

This only affects the __flash1 ... __flash5 spaces since the other ASes
use different routines,

gcc/
        PR target/118000
        * config/avr/avr.cc (avr_init_expanders) <sreg_rtx>
        <rampd_rtx, rampx_rtx, rampy_rtx, rampz_rtx>: Set MEM_VOLATILE_P.
        (avr_out_cpymem) [ELPM && EBI]: Restore RAMPZ to 0 after.


diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc
index ef236016990..05a6905b5d6 100644
--- a/gcc/config/avr/avr.cc
+++ b/gcc/config/avr/avr.cc
@@ -596,6 +596,12 @@ avr_init_expanders (void)
   rampy_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampy));
   rampz_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampz));

+  MEM_VOLATILE_P (sreg_rtx) = 1;
+  MEM_VOLATILE_P (rampd_rtx) = 1;
+  MEM_VOLATILE_P (rampx_rtx) = 1;
+  MEM_VOLATILE_P (rampy_rtx) = 1;
+  MEM_VOLATILE_P (rampz_rtx) = 1;
+
   xstring_empty = gen_rtx_CONST_STRING (VOIDmode, "");
   xstring_e = gen_rtx_CONST_STRING (VOIDmode, "e");

@@ -14857,9 +14863,16 @@ avr_out_cpymem (rtx_insn * /*insn*/, rtx *op, int *plen)
                   "sbci %B1,0", xop, plen, 2);
     }

-  /* Loop until zero */
+  // Loop until zero.
+  avr_asm_len ("brne 0b", xop, plen, 1);
+

-  return avr_asm_len ("brne 0b", xop, plen, 1);
+  // Restore RAMPZ on EBI devices.
+  if (as >= ADDR_SPACE_FLASH1
+      && AVR_HAVE_ELPM && AVR_HAVE_RAMPD)
+    avr_asm_len ("out %i0,__zero_reg__", &rampz_rtx, plen, 1);
+
+  return "";
 }


Reply via email to