diff options
author | Anatoly Sokolov <aesok@post.ru> | 2009-01-12 23:41:57 +0300 |
---|---|---|
committer | Anatoly Sokolov <aesok@gcc.gnu.org> | 2009-01-12 23:41:57 +0300 |
commit | 33faafca375f8c5c4113b4f0628c69add6971ee6 (patch) | |
tree | c7a39deb7e47b8cb26126aa2186b6e53d7128969 /gcc/config/avr/libgcc.S | |
parent | 634b5df5d5c0ccfaa523ca0f9a737df3c0f28372 (diff) | |
download | gcc-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.S | 92 |
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) */ + |