This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[AVR, Committed] Fix PR target/29141
- From: Anatoly Sokolov <aesok at post dot ru>
- To: gcc-patches at gcc dot gnu dot org
- Cc: aesok at post dot ru, eweddington at cso dot atmel dot com
- Date: Mon, 12 Jan 2009 23:42:29 +0300
- Subject: [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.