minix/lib/csu/arch/sh3/crtbegin.S

367 lines
8.1 KiB
ArmAsm
Raw Normal View History

/* $NetBSD: crtbegin.S,v 1.2 2012/06/02 22:15:15 uwe Exp $ */
/*-
* Copyright (c) 2012 Valeriy E. Ushakov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <machine/asm.h>
RCSID("$NetBSD: crtbegin.S,v 1.2 2012/06/02 22:15:15 uwe Exp $")
.section .ctors, "aw", @progbits
.p2align 2
__CTOR_LIST__:
.long -1
.section .dtors, "aw", @progbits
.p2align 2
__DTOR_LIST__:
.long -1
.section .eh_frame, "a", @progbits
.p2align 2
__EH_FRAME_LIST__:
.section .jcr, "aw", @progbits
.p2align 2
__JCR_LIST__:
.section .data.rel, "aw", @progbits
.p2align 2
.globl __dso_handle
.hidden __dso_handle
.type __dso_handle, @object
.size __dso_handle, 4
__dso_handle:
#ifdef SHARED
.long __dso_handle
#else
.long 0
#endif
__dwarf_eh_object:
.zero 32
__initialized:
.zero 1
__finished:
.zero 1
.text
.weak __cxa_finalize
.weak __deregister_frame_info
.weak __register_frame_info
.weak _Jv_RegisterClasses
/*
* A bit of CPP syntactic sugar for accessing variables.
*
* For PIC we are obliged to use @(r0, r12) since r12 has the GOT
* address and only r0 can be used in @(r0, Rm) addressing mode, so we
* always load variable address to r0.
*/
#ifdef PIC
#define VAR_DATUM(var) var@GOTOFF
#define FUNC_DATUM(f) f@GOT
#define R0VAR (r0, r12)
#else
#define VAR_DATUM(var) var
#define FUNC_DATUM(f) f
#define R0VAR r0
#endif
__do_global_ctors_aux:
mov.l r8, @-sp
mov.l r9, @-sp
#ifdef PIC
mov.l r12, @-sp
mov.l .Lc_got, r12
mova .Lc_got, r0
add r0, r12
#endif
mov.l r14, @-sp
sts.l pr, @-sp
mov sp, r14
!! if (__initialized) return;
mov.l .Lc___initialized, r0
mov.b @R0VAR, r1
tst r1, r1
bf .Lc_return
!! __initialized = 1;
mov #1, r1
mov.b r1, @R0VAR
!! if (__register_frame_info)
!! __register_frame_info(&__EH_FRAME_LIST__[0], &__dwarf_eh_object)
#ifdef PIC
mov.l .Lc___register_frame_info_GOT, r0
mov.l @R0VAR, r1
tst r1, r1
bt .Lc___register_frame_info_done
mov.l .Lc___register_frame_info, r0
mov.l .Lc___EH_FRAME_LIST__, r4
mov.l .Lc___dwarf_eh_object, r5
add r12, r4
.Lc___register_frame_info_call:
CALL r0
add r12, r5
#else /* !PIC */
mov.l .Lc___register_frame_info, r0
tst r0, r0
bt .Lc___register_frame_info_done
mov.l .Lc___EH_FRAME_LIST__, r4
mov.l .Lc___dwarf_eh_object, r5
CALL r0
nop
#endif
.Lc___register_frame_info_done:
!! if (_Jv_RegisterClasses && __JCR_LIST__[0])
!! _Jv_RegisterClasses(&__JCR_LIST__[0]);
#ifdef PIC
mov.l .Lc__Jv_RegisterClasses_GOT, r0
mov.l @R0VAR, r1
tst r1, r1
bt .Lc__Jv_RegisterClasses_done
mov.l .Lc___JCR_LIST__, r0
mov.l @R0VAR, r1
tst r1, r1
bt .Lc__Jv_RegisterClasses_done
mov.l .Lc__Jv_RegisterClasses, r2
mov r0, r4
.Lc__Jv_RegisterClasses_call:
CALL r2
add r12, r4
#else /* !PIC */
mov.l .Lc__Jv_RegisterClasses, r2
tst r2, r2
bt .Lc__Jv_RegisterClasses_done
mov.l .Lc___JCR_LIST__, r0
mov.l @R0VAR, r1
tst r1, r1
bt .Lc__Jv_RegisterClasses_done
mov r0, r4
.Lc__Jv_RegisterClasses_call:
CALL r2
add r12, r4
#endif
.Lc__Jv_RegisterClasses_done:
!! call all constructors on __CTOR_LIST__ in reverse order
mov.l .Lc___CTOR_LIST_END__, r8
#ifdef PIC
add r12, r8
#endif
add #-4, r8
mov.l @r8, r9
not r9, r0 ! sentinel at __CTOR_LIST__[0] is -1
.Lc_ctor_list_loop:
tst r0, r0
bt.s .Lc_ctor_list_done
add #-4, r8
jsr @r9
mov.l @r8, r9
bra .Lc_ctor_list_loop
not r9, r0
.Lc_ctor_list_done:
.Lc_return:
mov r14, sp
lds.l @sp+, pr
mov.l @sp+, r14
#ifdef PIC
mov.l @sp+, r12
#endif
mov.l @sp+, r9
rts
mov.l @sp+, r8
.p2align 2
.Lc_got:
PIC_GOT_DATUM
.Lc___initialized:
.long VAR_DATUM(__initialized)
#ifdef PIC
.Lc___register_frame_info_GOT:
.long __register_frame_info@GOT
#endif
.Lc___register_frame_info:
CALL_DATUM(__register_frame_info, .Lc___register_frame_info_call)
.Lc___EH_FRAME_LIST__:
.long VAR_DATUM(__EH_FRAME_LIST__)
.Lc___dwarf_eh_object:
.long VAR_DATUM(__dwarf_eh_object)
#ifdef PIC
.Lc__Jv_RegisterClasses_GOT:
.long _Jv_RegisterClasses@GOT
#endif
.Lc__Jv_RegisterClasses:
CALL_DATUM(_Jv_RegisterClasses, .Lc__Jv_RegisterClasses_call)
.Lc___JCR_LIST__:
.long VAR_DATUM(__JCR_LIST__)
.Lc___CTOR_LIST_END__:
.long VAR_DATUM(__CTOR_LIST_END__)
__do_global_dtors_aux:
mov.l r8, @-sp
mov.l r9, @-sp
#ifdef PIC
mov.l r12, @-sp
mov.l .Ld_got, r12
mova .Ld_got, r0
add r0, r12
#endif
mov.l r14, @-sp
sts.l pr, @-sp
mov sp, r14
!! if (__finished) return;
mov.l .Ld___finished, r0
mov.b @R0VAR, r1
tst r1, r1
bf .Ld_return
!! __finished = 1;
mov #1, r1
mov.b r1, @R0VAR
#ifdef SHARED /* implies PIC */
!! if (__cxa_finalize)
!! __cxa_finalize(&__dso_handle);
mov.l .Ld___cxa_finalize_GOT, r0
mov.l @R0VAR, r1
tst r1, r1
bt .Ld___cxa_finalize_done
mov.l .Ld___cxa_finalize, r0
mov.l .Ld___dso_handle, r4
.Ld___cxa_finalize_call:
CALL r0
add r12, r4
.Ld___cxa_finalize_done:
#endif /* SHARED */
!! call all destructors on __DTOR_LIST__
mov.l .Ld___DTOR_LIST__, r8
#ifdef PIC
add r12, r8
#endif
add #4, r8 ! skip first entry that we know to be -1
mov.l @r8+, r9
tst r9, r9
.Ld_dtor_list_loop:
bt .Ld_dtor_list_done
jsr @r9
mov.l @r8+, r9
bra .Ld_dtor_list_loop
tst r9, r9
.Ld_dtor_list_done:
!! if (__deregister_frame_info)
!! __deregister_frame_info(&__EH_FRAME_LIST__[0]);
#ifdef PIC
mov.l .Ld___deregister_frame_info_GOT, r0
mov.l @R0VAR, r1
tst r1, r1
bt .Ld___deregister_frame_info_done
mov.l .Ld___deregister_frame_info, r0
mov.l .Ld___EH_FRAME_LIST__, r4
.Ld___deregister_frame_info_call:
CALL r0
add r12, r4
#else /* !PIC */
mov.l .Ld___deregister_frame_info, r0
tst r0, r0
bt .Ld___deregister_frame_info_done
mov.l .Ld___EH_FRAME_LIST__, r4
CALL r0
nop
#endif
.Ld___deregister_frame_info_done:
.Ld_return:
mov r14, sp
lds.l @sp+, pr
mov.l @sp+, r14
#ifdef PIC
mov.l @sp+, r12
#endif
mov.l @sp+, r9
rts
mov.l @sp+, r8
.p2align 2
.Ld_got:
PIC_GOT_DATUM
.Ld___finished:
.long VAR_DATUM(__finished)
#ifdef SHARED /* implies PIC */
.Ld___cxa_finalize_GOT:
.long __cxa_finalize@GOT
.Ld___cxa_finalize:
CALL_DATUM(__cxa_finalize, .Ld___cxa_finalize_call)
.Ld___dso_handle:
.long VAR_DATUM(__dso_handle)
#endif
.Ld___DTOR_LIST__:
.long VAR_DATUM(__DTOR_LIST__)
#ifdef PIC
.Ld___deregister_frame_info_GOT:
.long __deregister_frame_info@GOT
#endif
.Ld___deregister_frame_info:
CALL_DATUM(__deregister_frame_info, .Ld___deregister_frame_info_call)
.Ld___EH_FRAME_LIST__:
.long VAR_DATUM(__EH_FRAME_LIST__)
#define _CALL_INIT_FINI_FUNCTION(func) \
mov.l 1f, r1; \
mova 2f, r0; \
0: braf r1; /* NB: branch, not call ... */ \
lds r0, pr; /* skip the following .long when returning */ \
.p2align 2; \
1: .long func - (0b+4); \
2: ;
.section .init, "ax", @progbits
_CALL_INIT_FINI_FUNCTION(__do_global_ctors_aux)
.section .fini, "ax", @progbits
_CALL_INIT_FINI_FUNCTION(__do_global_dtors_aux)