libgcc.S (__RAMPZ__): Define.
authorAnatoly Sokolov <aesok@post.ru>
Fri, 22 Feb 2008 20:16:50 +0000 (23:16 +0300)
committerAnatoly Sokolov <aesok@gcc.gnu.org>
Fri, 22 Feb 2008 20:16:50 +0000 (23:16 +0300)
* config/avr/libgcc.S (__RAMPZ__): Define.
(__do_copy_data): Add for devices with 128KB code memory.

From-SVN: r132555

gcc/ChangeLog
gcc/config/avr/libgcc.S

index fd4ca31f25749327f2c146ac14d38850ca84ac61..52921c35dd9008806d0bcd494066cc08e4ca4ba7 100644 (file)
@@ -1,3 +1,8 @@
+2008-02-22  Anatoly Sokolov <aesok@post.ru>
+
+       * config/avr/libgcc.S (__RAMPZ__): Define.
+       (__do_copy_data): Add for devices with 128KB code memory.
+
 2008-02-22  Nathan Froyd  <froydnj@codesourcery.com>
 
        * config/rs6000/linuxspe.h (SUBSUBTARGET_OVERRIDE_OPTIONS):
index 397778b82d9409497d016dcced84b292593713ea..8fdba55f775caef541c7e1bc932755d6d514083d 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.  */