gcc_assert (REG_Z == REGNO (XEXP (addr, 0))
&& n_bytes <= 4);
- if (regno_dest == LPM_REGNO)
- avr_asm_len ("%4lpm" CR_TAB
- "adiw %2,1", xop, plen, 2);
- else
- avr_asm_len ("%4lpm" CR_TAB
- "mov %A0,%3" CR_TAB
- "adiw %2,1", xop, plen, 3);
+ for (int i = 0; i < n_bytes; ++i)
+ {
+ rtx reg = simplify_gen_subreg (QImode, dest, GET_MODE (dest), i);
- if (n_bytes >= 2)
- avr_asm_len ("%4lpm" CR_TAB
- "mov %B0,%3" CR_TAB
- "adiw %2,1", xop, plen, 3);
+ if (i > 0)
+ avr_asm_len ("adiw %2,1", xop, plen, 1);
- if (n_bytes >= 3)
- avr_asm_len ("%4lpm" CR_TAB
- "mov %C0,%3" CR_TAB
- "adiw %2,1", xop, plen, 3);
+ avr_asm_len ("%4lpm", xop, plen, 1);
- if (n_bytes >= 4)
- avr_asm_len ("%4lpm" CR_TAB
- "mov %D0,%3" CR_TAB
- "adiw %2,1", xop, plen, 3);
+ if (REGNO (reg) != LPM_REGNO)
+ avr_asm_len ("mov %0,r0", ®, plen, 1);
+ }
+
+ if (! _reg_unused_after (insn, xop[2], false))
+ avr_asm_len ("adiw %2,1", xop, plen, 1);
break; /* POST_INC */
if (REGNO (base) > REG_Z)
return false;
+ if (! AVR_TINY
+ // Only keep base registers that can't do PLUS addressing.
+ && ((REGNO (base) != REG_X
+ && ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (mem)))
+ || avr_load_libgcc_p (mem)
+ || avr_mem_memx_p (mem)))
+ return false;
+
bool volatile_p = MEM_VOLATILE_P (mem);
bool mem_volatile_p = false;
if (frame_pointer_needed
--- /dev/null
+/* { dg-do run } */
+/* { dg-additional-options "-std=gnu99" } */
+
+typedef __UINT64_TYPE__ uint64_t;
+
+extern const uint64_t aa __asm ("real_aa");
+extern const uint64_t bb __asm ("real_bb");
+
+__attribute__((used)) const uint64_t real_aa = 0x1122334455667788;
+__attribute__((used)) const uint64_t real_bb = 0x0908070605040302;
+
+__attribute__((noinline,noclone))
+uint64_t add1 (const uint64_t *aa, const uint64_t *bb)
+{
+ return *aa + *bb;
+}
+
+#ifdef __FLASH
+extern const __flash uint64_t fa __asm ("real_fa");
+extern const __flash uint64_t fb __asm ("real_fb");
+
+__attribute__((used)) const __flash uint64_t real_fa = 0x1122334455667788;
+__attribute__((used)) const __flash uint64_t real_fb = 0x0908070605040302;
+
+__attribute__((noinline,noclone))
+uint64_t add2 (const __flash uint64_t *aa, const uint64_t *bb)
+{
+ return *aa + *bb;
+}
+
+uint64_t add3 (const uint64_t *aa, const __flash uint64_t *bb)
+{
+ return *aa + *bb;
+}
+
+uint64_t add4 (const __flash uint64_t *aa, const __flash uint64_t *bb)
+{
+ return *aa + *bb;
+}
+#endif /* have __flash */
+
+int main (void)
+{
+ if (add1 (&aa, &bb) != real_aa + real_bb)
+ __builtin_exit (__LINE__);
+
+#ifdef __FLASH
+ if (add2 (&fa, &bb) != real_fa + real_bb)
+ __builtin_exit (__LINE__);
+
+ if (add3 (&aa, &fb) != real_aa + real_fb)
+ __builtin_exit (__LINE__);
+
+ if (add4 (&fa, &fb) != real_fa + real_fb)
+ __builtin_exit (__LINE__);
+#endif
+
+ return 0;
+}