OSDN Git Service

* config/avr/libgcc.S (__RAMPZ__): Define.
[pf3gnuchains/gcc-fork.git] / gcc / config / avr / libgcc.S
index 397778b..8fdba55 100644 (file)
@@ -32,6 +32,7 @@ Boston, MA 02110-1301, USA.  */
 #define __SREG__ 0x3f
 #define __SP_H__ 0x3e
 #define __SP_L__ 0x3d
+#define __RAMPZ__ 0x3B
 
 /* Most of the functions here are called directly from avr.md
    patterns, instead of using the standard libcall mechanisms.
@@ -686,20 +687,54 @@ __tablejump__:
        .endfunc
 #endif /* defined (L_tablejump) */
 
-/* __do_copy_data is only necessary if there is anything in .data section.
-   Does not use RAMPZ - crt*.o provides a replacement for >64K devices.  */
-
 #ifdef L_copy_data
        .section .init4,"ax",@progbits
        .global __do_copy_data
 __do_copy_data:
+#if defined(__AVR_HAVE_ELPMX__)
+       ldi     r17, hi8(__data_end)
+       ldi     r26, lo8(__data_start)
+       ldi     r27, hi8(__data_start)
+       ldi     r30, lo8(__data_load_start)
+       ldi     r31, hi8(__data_load_start)
+       ldi     r16, hh8(__data_load_start)
+       out     __RAMPZ__, r16
+       rjmp    .L__do_copy_data_start
+.L__do_copy_data_loop:
+       elpm    r0, Z+
+       st      X+, r0
+.L__do_copy_data_start:
+       cpi     r26, lo8(__data_end)
+       cpc     r27, r17
+       brne    .L__do_copy_data_loop
+#elif  !defined(__AVR_HAVE_ELPMX__) && defined(__AVR_HAVE_ELPM__)
+       ldi     r17, hi8(__data_end)
+       ldi     r26, lo8(__data_start)
+       ldi     r27, hi8(__data_start)
+       ldi     r30, lo8(__data_load_start)
+       ldi     r31, hi8(__data_load_start)
+       ldi     r16, hh8(__data_load_start - 0x10000)
+.L__do_copy_data_carry:
+       inc     r16
+       out     __RAMPZ__, r16
+       rjmp    .L__do_copy_data_start
+.L__do_copy_data_loop:
+       elpm
+       st      X+, r0
+       adiw    r30, 1
+       brcs    .L__do_copy_data_carry
+.L__do_copy_data_start:
+       cpi     r26, lo8(__data_end)
+       cpc     r27, r17
+       brne    .L__do_copy_data_loop
+#elif !defined(__AVR_HAVE_ELPMX__) && !defined(__AVR_HAVE_ELPM__)
        ldi     r17, hi8(__data_end)
        ldi     r26, lo8(__data_start)
        ldi     r27, hi8(__data_start)
        ldi     r30, lo8(__data_load_start)
        ldi     r31, hi8(__data_load_start)
-       rjmp    .do_copy_data_start
-.do_copy_data_loop:
+       rjmp    .L__do_copy_data_start
+.L__do_copy_data_loop:
 #if defined (__AVR_HAVE_LPMX__)
        lpm     r0, Z+
 #else
@@ -707,10 +742,11 @@ __do_copy_data:
        adiw    r30, 1
 #endif
        st      X+, r0
-.do_copy_data_start:
+.L__do_copy_data_start:
        cpi     r26, lo8(__data_end)
        cpc     r27, r17
-       brne    .do_copy_data_loop
+       brne    .L__do_copy_data_loop
+#endif /* !defined(__AVR_HAVE_ELPMX__) && !defined(__AVR_HAVE_ELPM__) */
 #endif /* L_copy_data */
 
 /* __do_clear_bss is only necessary if there is anything in .bss section.  */