aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/avr/libgcc.S
diff options
context:
space:
mode:
authorAnatoly Sokolov <aesok@post.ru>2009-01-12 23:41:57 +0300
committerAnatoly Sokolov <aesok@gcc.gnu.org>2009-01-12 23:41:57 +0300
commit33faafca375f8c5c4113b4f0628c69add6971ee6 (patch)
treec7a39deb7e47b8cb26126aa2186b6e53d7128969 /gcc/config/avr/libgcc.S
parent634b5df5d5c0ccfaa523ca0f9a737df3c0f28372 (diff)
downloadgcc-33faafca375f8c5c4113b4f0628c69add6971ee6.zip
gcc-33faafca375f8c5c4113b4f0628c69add6971ee6.tar.gz
gcc-33faafca375f8c5c4113b4f0628c69add6971ee6.tar.bz2
re PR target/29141 (static constructors beyond 64k fail)
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
Diffstat (limited to 'gcc/config/avr/libgcc.S')
-rw-r--r--gcc/config/avr/libgcc.S92
1 files changed, 83 insertions, 9 deletions
diff --git a/gcc/config/avr/libgcc.S b/gcc/config/avr/libgcc.S
index a63b26a..14bd1d3 100644
--- a/gcc/config/avr/libgcc.S
+++ b/gcc/config/avr/libgcc.S
@@ -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) */
+