xref: /minix/lib/csu/arch/sh3/crtbegin.S (revision 84d9c625)
1/*	$NetBSD: crtbegin.S,v 1.3 2013/09/12 15:36:14 joerg Exp $	*/
2/*-
3 * Copyright (c) 2012 Valeriy E. Ushakov
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in
14 *    the documentation and/or other materials provided with the
15 *    distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
21 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
27 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <machine/asm.h>
32
33RCSID("$NetBSD: crtbegin.S,v 1.3 2013/09/12 15:36:14 joerg Exp $")
34
35	.section	.ctors, "aw", @progbits
36	.p2align 2
37__CTOR_LIST__:
38	.long -1
39
40	.section	.dtors, "aw", @progbits
41	.p2align 2
42__DTOR_LIST__:
43	.long -1
44
45	.section	.eh_frame, "a", @progbits
46	.p2align 2
47__EH_FRAME_LIST__:
48
49	.section	.jcr, "aw", @progbits
50	.p2align 2
51__JCR_LIST__:
52
53	.section	.data.rel, "aw", @progbits
54	.p2align 2
55	.globl	__dso_handle
56	.hidden	__dso_handle
57	.type	__dso_handle, @object
58	.size	__dso_handle, 4
59__dso_handle:
60#ifdef SHARED
61	.long	__dso_handle
62#else
63	.long	0
64#endif
65
66__dwarf_eh_object:
67	.zero	32
68
69__initialized:
70	.zero	1
71__finished:
72	.zero	1
73
74	.text
75	.weak	__cxa_finalize
76	.weak	__deregister_frame_info
77	.weak	__register_frame_info
78	.weak	_Jv_RegisterClasses
79
80/*
81 * A bit of CPP syntactic sugar for accessing variables.
82 *
83 * For PIC we are obliged to use @(r0, r12) since r12 has the GOT
84 * address and only r0 can be used in @(r0, Rm) addressing mode, so we
85 * always load variable address to r0.
86 */
87#ifdef __PIC__
88#define VAR_DATUM(var)	var@GOTOFF
89#define FUNC_DATUM(f)	f@GOT
90#define R0VAR		(r0, r12)
91#else
92#define VAR_DATUM(var)	var
93#define FUNC_DATUM(f)	f
94#define R0VAR		r0
95#endif
96
97
98__do_global_ctors_aux:
99        mov.l   r8, @-sp
100        mov.l   r9, @-sp
101#ifdef __PIC__
102        mov.l   r12, @-sp
103        mov.l   .Lc_got, r12
104        mova    .Lc_got, r0
105        add     r0, r12
106#endif
107        mov.l   r14, @-sp
108        sts.l   pr, @-sp
109	mov     sp, r14
110
111	!! if (__initialized) return;
112	mov.l	.Lc___initialized, r0
113	mov.b	@R0VAR, r1
114	tst	r1, r1
115	bf	.Lc_return
116
117	!! __initialized = 1;
118	mov	#1, r1
119	mov.b	r1, @R0VAR
120
121
122	!! if (__register_frame_info)
123	!!     __register_frame_info(&__EH_FRAME_LIST__[0], &__dwarf_eh_object)
124#ifdef __PIC__
125	mov.l	.Lc___register_frame_info_GOT, r0
126	mov.l	@R0VAR, r1
127	tst	r1, r1
128	bt	.Lc___register_frame_info_done
129	mov.l	.Lc___register_frame_info, r0
130	mov.l	.Lc___EH_FRAME_LIST__, r4
131	mov.l	.Lc___dwarf_eh_object, r5
132	add	r12, r4
133.Lc___register_frame_info_call:
134	CALL	r0
135	 add	r12, r5
136#else /* !PIC */
137	mov.l	.Lc___register_frame_info, r0
138	tst	r0, r0
139	bt	.Lc___register_frame_info_done
140	mov.l	.Lc___EH_FRAME_LIST__, r4
141	mov.l	.Lc___dwarf_eh_object, r5
142	CALL	r0
143	 nop
144#endif
145.Lc___register_frame_info_done:
146
147	!!  if (_Jv_RegisterClasses && __JCR_LIST__[0])
148	!!      _Jv_RegisterClasses(&__JCR_LIST__[0]);
149#ifdef __PIC__
150	mov.l	.Lc__Jv_RegisterClasses_GOT, r0
151	mov.l	@R0VAR, r1
152	tst	r1, r1
153	bt	.Lc__Jv_RegisterClasses_done
154
155	mov.l	.Lc___JCR_LIST__, r0
156	mov.l	@R0VAR, r1
157	tst	r1, r1
158	bt	.Lc__Jv_RegisterClasses_done
159
160	mov.l	.Lc__Jv_RegisterClasses, r2
161	mov	r0, r4
162.Lc__Jv_RegisterClasses_call:
163	CALL	r2
164	 add	r12, r4
165
166#else /* !PIC */
167	mov.l	.Lc__Jv_RegisterClasses, r2
168	tst	r2, r2
169	bt	.Lc__Jv_RegisterClasses_done
170
171	mov.l	.Lc___JCR_LIST__, r0
172	mov.l	@R0VAR, r1
173	tst	r1, r1
174	bt	.Lc__Jv_RegisterClasses_done
175
176	mov	r0, r4
177.Lc__Jv_RegisterClasses_call:
178	CALL	r2
179	 add	r12, r4
180#endif
181.Lc__Jv_RegisterClasses_done:
182
183
184	!! call all constructors on __CTOR_LIST__ in reverse order
185	mov.l	.Lc___CTOR_LIST_END__, r8
186#ifdef __PIC__
187	add	r12, r8
188#endif
189	add	#-4, r8
190	mov.l	@r8, r9
191	not	r9, r0		! sentinel at __CTOR_LIST__[0] is -1
192.Lc_ctor_list_loop:
193	tst	r0, r0
194	bt.s	.Lc_ctor_list_done
195	 add	#-4, r8
196	jsr	@r9
197	 mov.l	@r8, r9
198	bra	.Lc_ctor_list_loop
199	 not	r9, r0
200.Lc_ctor_list_done:
201
202.Lc_return:
203	mov	r14, sp
204	lds.l	@sp+, pr
205	mov.l	@sp+, r14
206#ifdef __PIC__
207	mov.l	@sp+, r12
208#endif
209	mov.l	@sp+, r9
210	rts
211	 mov.l	@sp+, r8
212
213	.p2align 2
214.Lc_got:
215	PIC_GOT_DATUM
216.Lc___initialized:
217	.long	VAR_DATUM(__initialized)
218#ifdef __PIC__
219.Lc___register_frame_info_GOT:
220	.long	__register_frame_info@GOT
221#endif
222.Lc___register_frame_info:
223	CALL_DATUM(__register_frame_info, .Lc___register_frame_info_call)
224.Lc___EH_FRAME_LIST__:
225	.long	VAR_DATUM(__EH_FRAME_LIST__)
226.Lc___dwarf_eh_object:
227	.long	VAR_DATUM(__dwarf_eh_object)
228#ifdef __PIC__
229.Lc__Jv_RegisterClasses_GOT:
230	.long	_Jv_RegisterClasses@GOT
231#endif
232.Lc__Jv_RegisterClasses:
233	CALL_DATUM(_Jv_RegisterClasses, .Lc__Jv_RegisterClasses_call)
234.Lc___JCR_LIST__:
235	.long	VAR_DATUM(__JCR_LIST__)
236.Lc___CTOR_LIST_END__:
237	.long	VAR_DATUM(__CTOR_LIST_END__)
238
239
240__do_global_dtors_aux:
241        mov.l   r8, @-sp
242        mov.l   r9, @-sp
243#ifdef __PIC__
244        mov.l   r12, @-sp
245        mov.l   .Ld_got, r12
246        mova    .Ld_got, r0
247        add     r0, r12
248#endif
249        mov.l   r14, @-sp
250        sts.l   pr, @-sp
251	mov     sp, r14
252
253	!! if (__finished) return;
254	mov.l	.Ld___finished, r0
255	mov.b	@R0VAR, r1
256	tst	r1, r1
257	bf	.Ld_return
258
259	!! __finished = 1;
260	mov	#1, r1
261	mov.b	r1, @R0VAR
262
263#ifdef SHARED /* implies PIC */
264	!! if (__cxa_finalize)
265	!!     __cxa_finalize(&__dso_handle);
266	mov.l	.Ld___cxa_finalize_GOT, r0
267	mov.l	@R0VAR, r1
268	tst	r1, r1
269	bt	.Ld___cxa_finalize_done
270	mov.l	.Ld___cxa_finalize, r0
271	mov.l	.Ld___dso_handle, r4
272.Ld___cxa_finalize_call:
273	CALL	r0
274	 add	r12, r4
275.Ld___cxa_finalize_done:
276#endif	/* SHARED */
277
278	!! call all destructors on __DTOR_LIST__
279	mov.l	.Ld___DTOR_LIST__, r8
280#ifdef __PIC__
281	add	r12, r8
282#endif
283	add	#4, r8		! skip first entry that we know to be -1
284	mov.l	@r8+, r9
285	tst	r9, r9
286.Ld_dtor_list_loop:
287	bt	.Ld_dtor_list_done
288	jsr	@r9
289	 mov.l	@r8+, r9
290	bra	.Ld_dtor_list_loop
291	 tst	r9, r9
292.Ld_dtor_list_done:
293
294	!! if (__deregister_frame_info)
295	!!     __deregister_frame_info(&__EH_FRAME_LIST__[0]);
296#ifdef __PIC__
297	mov.l	.Ld___deregister_frame_info_GOT, r0
298	mov.l	@R0VAR, r1
299	tst	r1, r1
300	bt	.Ld___deregister_frame_info_done
301	mov.l	.Ld___deregister_frame_info, r0
302	mov.l	.Ld___EH_FRAME_LIST__, r4
303.Ld___deregister_frame_info_call:
304	CALL	r0
305	 add	r12, r4
306#else /* !PIC */
307	mov.l	.Ld___deregister_frame_info, r0
308	tst	r0, r0
309	bt	.Ld___deregister_frame_info_done
310	mov.l	.Ld___EH_FRAME_LIST__, r4
311	CALL	r0
312	 nop
313#endif
314.Ld___deregister_frame_info_done:
315
316.Ld_return:
317	mov	r14, sp
318	lds.l	@sp+, pr
319	mov.l	@sp+, r14
320#ifdef __PIC__
321	mov.l	@sp+, r12
322#endif
323	mov.l	@sp+, r9
324	rts
325	 mov.l	@sp+, r8
326
327	.p2align 2
328.Ld_got:
329	PIC_GOT_DATUM
330.Ld___finished:
331	.long	VAR_DATUM(__finished)
332#ifdef SHARED /* implies PIC */
333.Ld___cxa_finalize_GOT:
334	.long	__cxa_finalize@GOT
335.Ld___cxa_finalize:
336	CALL_DATUM(__cxa_finalize, .Ld___cxa_finalize_call)
337.Ld___dso_handle:
338	.long	VAR_DATUM(__dso_handle)
339#endif
340.Ld___DTOR_LIST__:
341	.long	VAR_DATUM(__DTOR_LIST__)
342#ifdef __PIC__
343.Ld___deregister_frame_info_GOT:
344	.long	__deregister_frame_info@GOT
345#endif
346.Ld___deregister_frame_info:
347	CALL_DATUM(__deregister_frame_info, .Ld___deregister_frame_info_call)
348.Ld___EH_FRAME_LIST__:
349	.long	VAR_DATUM(__EH_FRAME_LIST__)
350
351
352
353#define _CALL_INIT_FINI_FUNCTION(func)					\
354	mov.l	1f, r1;							\
355	mova	2f, r0;							\
3560:	braf	r1;	/* NB: branch, not call ... */			\
357	 lds	r0, pr;	/* skip the following .long when returning */	\
358	.p2align 2;							\
3591:	.long func - (0b+4);						\
3602:	;
361
362	.section	.init, "ax", @progbits
363	_CALL_INIT_FINI_FUNCTION(__do_global_ctors_aux)
364
365	.section	.fini, "ax", @progbits
366	_CALL_INIT_FINI_FUNCTION(__do_global_dtors_aux)
367