diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fd4ca31f257..52921c35dd9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2008-02-22 Anatoly Sokolov + + * config/avr/libgcc.S (__RAMPZ__): Define. + (__do_copy_data): Add for devices with 128KB code memory. + 2008-02-22 Nathan Froyd * config/rs6000/linuxspe.h (SUBSUBTARGET_OVERRIDE_OPTIONS): diff --git a/gcc/config/avr/libgcc.S b/gcc/config/avr/libgcc.S index 397778b82d9..8fdba55f775 100644 --- a/gcc/config/avr/libgcc.S +++ b/gcc/config/avr/libgcc.S @@ -32,6 +32,7 @@ Boston, MA 02110-1301, USA. */ #define __SREG__ 0x3f #define __SP_H__ 0x3e #define __SP_L__ 0x3d +#define __RAMPZ__ 0x3B /* Most of the functions here are called directly from avr.md patterns, instead of using the standard libcall mechanisms. @@ -686,20 +687,54 @@ __tablejump__: .endfunc #endif /* defined (L_tablejump) */ -/* __do_copy_data is only necessary if there is anything in .data section. - Does not use RAMPZ - crt*.o provides a replacement for >64K devices. */ - #ifdef L_copy_data .section .init4,"ax",@progbits .global __do_copy_data __do_copy_data: +#if defined(__AVR_HAVE_ELPMX__) ldi r17, hi8(__data_end) ldi r26, lo8(__data_start) ldi r27, hi8(__data_start) ldi r30, lo8(__data_load_start) ldi r31, hi8(__data_load_start) - rjmp .do_copy_data_start -.do_copy_data_loop: + ldi r16, hh8(__data_load_start) + out __RAMPZ__, r16 + rjmp .L__do_copy_data_start +.L__do_copy_data_loop: + elpm r0, Z+ + st X+, r0 +.L__do_copy_data_start: + cpi r26, lo8(__data_end) + cpc r27, r17 + brne .L__do_copy_data_loop +#elif !defined(__AVR_HAVE_ELPMX__) && defined(__AVR_HAVE_ELPM__) + ldi r17, hi8(__data_end) + ldi r26, lo8(__data_start) + ldi r27, hi8(__data_start) + ldi r30, lo8(__data_load_start) + ldi r31, hi8(__data_load_start) + ldi r16, hh8(__data_load_start - 0x10000) +.L__do_copy_data_carry: + inc r16 + out __RAMPZ__, r16 + rjmp .L__do_copy_data_start +.L__do_copy_data_loop: + elpm + st X+, r0 + adiw r30, 1 + brcs .L__do_copy_data_carry +.L__do_copy_data_start: + cpi r26, lo8(__data_end) + cpc r27, r17 + brne .L__do_copy_data_loop +#elif !defined(__AVR_HAVE_ELPMX__) && !defined(__AVR_HAVE_ELPM__) + ldi r17, hi8(__data_end) + ldi r26, lo8(__data_start) + ldi r27, hi8(__data_start) + ldi r30, lo8(__data_load_start) + ldi r31, hi8(__data_load_start) + rjmp .L__do_copy_data_start +.L__do_copy_data_loop: #if defined (__AVR_HAVE_LPMX__) lpm r0, Z+ #else @@ -707,10 +742,11 @@ __do_copy_data: adiw r30, 1 #endif st X+, r0 -.do_copy_data_start: +.L__do_copy_data_start: cpi r26, lo8(__data_end) cpc r27, r17 - brne .do_copy_data_loop + brne .L__do_copy_data_loop +#endif /* !defined(__AVR_HAVE_ELPMX__) && !defined(__AVR_HAVE_ELPM__) */ #endif /* L_copy_data */ /* __do_clear_bss is only necessary if there is anything in .bss section. */