X-Git-Url: https://oss.titaniummirror.com/gitweb?a=blobdiff_plain;f=gcc%2Fconfig%2Favr%2Flibgcc.S;fp=gcc%2Fconfig%2Favr%2Flibgcc.S;h=b6262b338dde77f892801ee4cd12fd3d13779cf1;hb=6fed43773c9b0ce596dca5686f37ac3fc0fa11c0;hp=d324a2166a61e8918cc18b857ebda7b0eb249abf;hpb=27b11d56b743098deb193d510b337ba22dc52e5c;p=msp430-gcc.git diff --git a/gcc/config/avr/libgcc.S b/gcc/config/avr/libgcc.S index d324a216..b6262b33 100644 --- a/gcc/config/avr/libgcc.S +++ b/gcc/config/avr/libgcc.S @@ -1,36 +1,33 @@ /* -*- Mode: Asm -*- */ -/* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1998, 1999, 2000, 2007, 2008, 2009 + Free Software Foundation, Inc. Contributed by Denis Chertykov This file is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any +Free Software Foundation; either version 3, or (at your option) any later version. -In addition to the permissions in the GNU General Public License, the -Free Software Foundation gives you unlimited permission to link the -compiled version of this file into combinations with other programs, -and to distribute those combinations without any restriction coming -from the use of this file. (The General Public License restrictions -do apply in other respects; for example, they cover modification of -the file, and distribution when not linked into a combine -executable.) - This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ #define __zero_reg__ r1 #define __tmp_reg__ r0 #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. @@ -40,7 +37,7 @@ Boston, MA 02111-1307, USA. */ .section .text.libgcc, "ax", @progbits .macro mov_l r_dest, r_src -#if defined (__AVR_ENHANCED__) +#if defined (__AVR_HAVE_MOVW__) movw \r_dest, \r_src #else mov \r_dest, \r_src @@ -48,7 +45,7 @@ Boston, MA 02111-1307, USA. */ .endm .macro mov_h r_dest, r_src -#if defined (__AVR_ENHANCED__) +#if defined (__AVR_HAVE_MOVW__) ; empty #else mov \r_dest, \r_src @@ -56,7 +53,7 @@ Boston, MA 02111-1307, USA. */ .endm /* Note: mulqi3, mulhi3 are open-coded on the enhanced core. */ -#if !defined (__AVR_ENHANCED__) +#if !defined (__AVR_HAVE_MUL__) /******************************************************* Multiplication 8 x 8 *******************************************************/ @@ -159,7 +156,7 @@ __mulhi3_exit: .endfunc #endif /* defined (L_mulhi3) */ -#endif /* !defined (__AVR_ENHANCED__) */ +#endif /* !defined (__AVR_HAVE_MUL__) */ #if defined (L_mulhisi3) .global __mulhisi3 @@ -217,7 +214,7 @@ __umulhisi3: .global __mulsi3 .func __mulsi3 __mulsi3: -#if defined (__AVR_ENHANCED__) +#if defined (__AVR_HAVE_MUL__) mul r_arg1L, r_arg2L movw r_resL, r0 mul r_arg1H, r_arg2H @@ -276,12 +273,12 @@ __mulsi3_skip1: cpc r_arg1H,r_arg1L brne __mulsi3_loop ; exit if multiplier = 0 __mulsi3_exit: - mov r_arg1HH,r_resHH ; result to return register - mov r_arg1HL,r_resHL - mov r_arg1H,r_resH - mov r_arg1L,r_resL + mov_h r_arg1HH,r_resHH ; result to return register + mov_l r_arg1HL,r_resHL + mov_h r_arg1H,r_resH + mov_l r_arg1L,r_resL ret -#endif /* !defined (__AVR_ENHANCED__) */ +#endif /* defined (__AVR_HAVE_MUL__) */ #undef r_arg1L #undef r_arg1H #undef r_arg1HL @@ -593,7 +590,12 @@ __prologue_saves__: out __SP_H__,r29 out __SREG__,__tmp_reg__ out __SP_L__,r28 +#if defined (__AVR_HAVE_EIJMP_EICALL__) + eijmp +#else ijmp +#endif + .endfunc #endif /* defined (L_prologue) */ @@ -637,11 +639,20 @@ __epilogue_restores__: #endif /* defined (L_epilogue) */ #ifdef L_exit - .weak _exit + .section .fini9,"ax",@progbits + .global _exit .func _exit _exit: - rjmp _exit -.endfunc + .weak exit +exit: + + /* Code from .fini8 ... .fini1 sections inserted by ld script. */ + + .section .fini0,"ax",@progbits + cli +__stop_program: + rjmp __stop_program + .endfunc #endif /* defined (L_exit) */ #ifdef L_cleanup @@ -658,19 +669,231 @@ _cleanup: __tablejump2__: lsl r30 rol r31 -#if defined (__AVR_ENHANCED__) + .global __tablejump__ +__tablejump__: +#if defined (__AVR_HAVE_LPMX__) lpm __tmp_reg__, Z+ lpm r31, Z mov r30, __tmp_reg__ + +#if defined (__AVR_HAVE_EIJMP_EICALL__) + eijmp +#else ijmp +#endif + #else lpm + adiw r30, 1 push r0 - inc r30 ; table is word aligned, no carry to high byte lpm push r0 +#if defined (__AVR_HAVE_EIJMP_EICALL__) + push __zero_reg__ +#endif ret #endif -.endfunc + .endfunc #endif /* defined (L_tablejump) */ +#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) + 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 + lpm + adiw r30, 1 +#endif + st X+, r0 +.L__do_copy_data_start: + cpi r26, lo8(__data_end) + cpc r27, r17 + 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. */ + +#ifdef L_clear_bss + .section .init4,"ax",@progbits + .global __do_clear_bss +__do_clear_bss: + ldi r17, hi8(__bss_end) + ldi r26, lo8(__bss_start) + ldi r27, hi8(__bss_start) + rjmp .do_clear_bss_start +.do_clear_bss_loop: + st X+, __zero_reg__ +.do_clear_bss_start: + cpi r26, lo8(__bss_end) + cpc r27, r17 + brne .do_clear_bss_loop +#endif /* L_clear_bss */ + +/* __do_global_ctors and __do_global_dtors are only necessary + if there are any constructors/destructors. */ + +#if defined (__AVR_HAVE_JMP_CALL__) +#define XCALL call +#else +#define XCALL rcall +#endif + +#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) + 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__ +.L__do_global_ctors_start: + cpi r28, lo8(__ctors_start) + cpc r29, r17 + 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) + 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 +.L__do_global_dtors_start: + cpi r28, lo8(__dtors_end) + cpc r29, r17 + 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) */ +