re PR target/29141 (static constructors beyond 64k fail)
authorAnatoly Sokolov <aesok@post.ru>
Mon, 12 Jan 2009 20:41:57 +0000 (23:41 +0300)
committerAnatoly Sokolov <aesok@gcc.gnu.org>
Mon, 12 Jan 2009 20:41:57 +0000 (23:41 +0300)
PR target/29141
* config/avr/t-avr (LIB1ASMFUNCS): Add _tablejump_elpm.
* config/avr/libgcc.S (__do_global_ctors, __do_global_dtors): Add
variant for devices with 3-byte PC.
(__tablejump_elpm__) : New.

From-SVN: r143306

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

index 21c58ec..e3ccd79 100644 (file)
@@ -1,3 +1,11 @@
+2009-01-03  Anatoly Sokolov  <aesok@post.ru>
+
+       PR target/29141
+       * config/avr/t-avr (LIB1ASMFUNCS): Add _tablejump_elpm.
+       * config/avr/libgcc.S (__do_global_ctors, __do_global_dtors): Add
+       variant for devices with 3-byte PC.
+       (__tablejump_elpm__) : New.
+
 2009-01-12  Jakub Jelinek  <jakub@redhat.com>
 
        PR c/32041
index a63b26a..14bd1d3 100644 (file)
@@ -1,5 +1,5 @@
 /*  -*- Mode: Asm -*-  */
-/* Copyright (C) 1998, 1999, 2000, 2007, 2008 
+/* Copyright (C) 1998, 1999, 2000, 2007, 2008, 2009
    Free Software Foundation, Inc.
    Contributed by Denis Chertykov <denisc@overta.ru>
 
@@ -793,38 +793,112 @@ __do_clear_bss:
 #ifdef L_ctors
        .section .init6,"ax",@progbits
        .global __do_global_ctors
+#if defined(__AVR_HAVE_RAMPZ__)
 __do_global_ctors:
        ldi     r17, hi8(__ctors_start)
+       ldi     r16, hh8(__ctors_start)
        ldi     r28, lo8(__ctors_end)
        ldi     r29, hi8(__ctors_end)
-       rjmp    .do_global_ctors_start
-.do_global_ctors_loop:
+       ldi     r20, hh8(__ctors_end)
+       rjmp    .L__do_global_ctors_start
+.L__do_global_ctors_loop:
+       sbiw    r28, 2
+       sbc     r20, __zero_reg__
+       mov_h   r31, r29
+       mov_l   r30, r28
+       out     __RAMPZ__, r20
+       XCALL   __tablejump_elpm__
+.L__do_global_ctors_start:
+       cpi     r28, lo8(__ctors_start)
+       cpc     r29, r17
+       cpc     r20, r16
+       brne    .L__do_global_ctors_loop
+#else
+__do_global_ctors:
+       ldi     r17, hi8(__ctors_start)
+       ldi     r28, lo8(__ctors_end)
+       ldi     r29, hi8(__ctors_end)
+       rjmp    .L__do_global_ctors_start
+.L__do_global_ctors_loop:
        sbiw    r28, 2
        mov_h   r31, r29
        mov_l   r30, r28
        XCALL   __tablejump__
-.do_global_ctors_start:
+.L__do_global_ctors_start:
        cpi     r28, lo8(__ctors_start)
        cpc     r29, r17
-       brne    .do_global_ctors_loop
+       brne    .L__do_global_ctors_loop
+#endif /* defined(__AVR_HAVE_RAMPZ__) */
 #endif /* L_ctors */
 
 #ifdef L_dtors
        .section .fini6,"ax",@progbits
        .global __do_global_dtors
+#if defined(__AVR_HAVE_RAMPZ__)
 __do_global_dtors:
        ldi     r17, hi8(__dtors_end)
+       ldi     r16, hh8(__dtors_end)
        ldi     r28, lo8(__dtors_start)
        ldi     r29, hi8(__dtors_start)
-       rjmp    .do_global_dtors_start
-.do_global_dtors_loop:
+       ldi     r20, hh8(__dtors_start)
+       rjmp    .L__do_global_dtors_start
+.L__do_global_dtors_loop:
+       sbiw    r28, 2
+       sbc     r20, __zero_reg__
+       mov_h   r31, r29
+       mov_l   r30, r28
+       out     __RAMPZ__, r20
+       XCALL   __tablejump_elpm__
+.L__do_global_dtors_start:
+       cpi     r28, lo8(__dtors_end)
+       cpc     r29, r17
+       cpc     r20, r16
+       brne    .L__do_global_dtors_loop
+#else
+__do_global_dtors:
+       ldi     r17, hi8(__dtors_end)
+       ldi     r28, lo8(__dtors_start)
+       ldi     r29, hi8(__dtors_start)
+       rjmp    .L__do_global_dtors_start
+.L__do_global_dtors_loop:
        mov_h   r31, r29
        mov_l   r30, r28
        XCALL   __tablejump__
        adiw    r28, 2
-.do_global_dtors_start:
+.L__do_global_dtors_start:
        cpi     r28, lo8(__dtors_end)
        cpc     r29, r17
-       brne    .do_global_dtors_loop
+       brne    .L__do_global_dtors_loop
+#endif /* defined(__AVR_HAVE_RAMPZ__) */
 #endif /* L_dtors */
 
+#ifdef L_tablejump_elpm
+       .global __tablejump_elpm__
+       .func   __tablejump_elpm__
+__tablejump_elpm__:
+#if defined (__AVR_HAVE_ELPM__)
+#if defined (__AVR_HAVE_LPMX__)
+       elpm    __tmp_reg__, Z+
+       elpm    r31, Z
+       mov     r30, __tmp_reg__
+#if defined (__AVR_HAVE_EIJMP_EICALL__)
+       eijmp
+#else
+       ijmp
+#endif
+
+#else
+       elpm
+       adiw    r30, 1
+       push    r0
+       elpm
+       push    r0
+#if defined (__AVR_HAVE_EIJMP_EICALL__)
+        push    __zero_reg__
+#endif
+       ret
+#endif
+#endif /* defined (__AVR_HAVE_ELPM__) */
+       .endfunc
+#endif /* defined (L_tablejump_elpm) */
+
index 410a705..cbb4781 100644 (file)
@@ -14,6 +14,7 @@ LIB1ASMFUNCS = \
        _exit \
        _cleanup \
        _tablejump \
+       _tablejump_elpm \
        _copy_data \
        _clear_bss \
        _ctors \