This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[AVR, Committed] Fix PR target/29141


Hello.

 This patch fix AVR target bug #29141: static constructors beyond 64k fail
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29141

 The constructors of global static objects fails while using flash addresses
over 0xFFFF, e.g. for bootloader purposes. The __do_global_ctors and
__do_global_dtors use LPM instruction for reading call address of
constructors and destructors from .ctors and .dtorss sections, and work
incorrectly if .ctors and .dtorss sections are located above 0xFFFF address.

  This patch adds new variants of __do_global_ctors and __do_global_dtors
for devices with ELPM instruction.

2009-01-12  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.


Index: gcc/config/avr/libgcc.S
===================================================================
--- gcc/config/avr/libgcc.S     (revision 143302)
+++ gcc/config/avr/libgcc.S     (working copy)
@@ -793,38 +793,112 @@
 #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: gcc/config/avr/t-avr
===================================================================
--- gcc/config/avr/t-avr        (revision 143302)
+++ gcc/config/avr/t-avr        (working copy)
@@ -14,6 +14,7 @@
        _exit \
        _cleanup \
        _tablejump \
+       _tablejump_elpm \
        _copy_data \
        _clear_bss \
        _ctors \


Anatoly.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]