xref: /netbsd-src/external/gpl3/gcc/dist/libgcc/config/ia64/crtbegin.S (revision a24efa7dea9f1f56c3bdb15a927d3516792ace1c)
1/* Copyright (C) 2000-2015 Free Software Foundation, Inc.
2   Contributed by Jes Sorensen, <Jes.Sorensen@cern.ch>
3
4   This file is part of GCC.
5
6   GCC is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 3, or (at your option)
9   any later version.
10
11   GCC is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   Under Section 7 of GPL version 3, you are granted additional
17   permissions described in the GCC Runtime Library Exception, version
18   3.1, as published by the Free Software Foundation.
19
20   You should have received a copy of the GNU General Public License and
21   a copy of the GCC Runtime Library Exception along with this program;
22   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23   <http://www.gnu.org/licenses/>.  */
24
25#include "auto-host.h"
26
27.section .ctors,"aw","progbits"
28	.align	8
29__CTOR_LIST__:
30	data8	-1
31
32.section .dtors,"aw","progbits"
33	.align	8
34__DTOR_LIST__:
35	data8	-1
36
37.section .jcr,"aw","progbits"
38	.align	8
39__JCR_LIST__:
40
41.section .sdata
42	.type dtor_ptr,@object
43	.size dtor_ptr,8
44dtor_ptr:
45	data8	@gprel(__DTOR_LIST__ + 8)
46
47	/* A handle for __cxa_finalize to manage c++ local destructors.  */
48	.global __dso_handle
49	.type __dso_handle,@object
50	.size __dso_handle,8
51#ifdef SHARED
52	.section .data
53__dso_handle:
54	data8	__dso_handle
55#else
56	.section .bss
57	.align 8
58__dso_handle:
59	.skip	8
60#endif
61	.hidden __dso_handle
62
63
64#ifdef HAVE_INITFINI_ARRAY_SUPPORT
65
66.section .fini_array, "a"
67	data8 @fptr(__do_global_dtors_aux)
68
69.section .init_array, "a"
70	data8 @fptr(__do_jv_register_classes)
71	data8 @fptr(__do_global_ctors_aux)
72
73#else /* !HAVE_INITFINI_ARRAY_SUPPORT */
74/*
75 * Fragment of the ELF _fini routine that invokes our dtor cleanup.
76 *
77 * We make the call by indirection, because in large programs the
78 * .fini and .init sections are not in range of the destination, and
79 * we cannot allow the linker to insert a stub at the end of this
80 * fragment of the _fini function.  Further, Itanium does not implement
81 * the long branch instructions, and we do not wish every program to
82 * trap to the kernel for emulation.
83 *
84 * Note that we require __do_global_dtors_aux to preserve the GP,
85 * so that the next fragment in .fini gets the right value.
86 */
87.section .fini,"ax","progbits"
88	{ .mlx
89	  movl r2 = @pcrel(__do_global_dtors_aux - 16)
90	}
91	{ .mii
92	  mov r3 = ip
93	  ;;
94	  add r2 = r2, r3
95	  ;;
96	}
97	{ .mib
98	  nop 0
99	  mov b6 = r2
100	  br.call.sptk.many b0 = b6
101	}
102
103/* Likewise for _init.  */
104
105.section .init,"ax","progbits"
106	{ .mlx
107	  movl r2 = @pcrel(__do_jv_register_classes - 16)
108	}
109	{ .mii
110	  mov r3 = ip
111	  ;;
112	  add r2 = r2, r3
113	  ;;
114	}
115	{ .mib
116	  nop 0
117	  mov b6 = r2
118	  br.call.sptk.many b0 = b6
119	}
120#endif /* !HAVE_INITFINI_ARRAY_SUPPORT */
121
122.section .text
123	.align	32
124	.proc	__do_global_dtors_aux
125__do_global_dtors_aux:
126	.prologue
127#ifndef SHARED
128	.save ar.pfs, r35
129	alloc loc3 = ar.pfs, 0, 4, 1, 0
130	addl loc0 = @gprel(dtor_ptr), gp
131	.save rp, loc1
132	mov loc1 = rp
133	.body
134
135	mov loc2 = gp
136	nop 0
137	br.sptk.many .entry
138#else
139	/*
140		if (__cxa_finalize)
141		  __cxa_finalize(__dso_handle)
142	*/
143	.save ar.pfs, r35
144	alloc loc3 = ar.pfs, 0, 4, 1, 0
145	addl loc0 = @gprel(dtor_ptr), gp
146	addl r16 = @ltoff(@fptr(__cxa_finalize)), gp
147	;;
148
149	ld8 r16 = [r16]
150	;;
151	addl out0 = @ltoff(__dso_handle), gp
152	cmp.ne p7, p0 = r0, r16
153	;;
154
155	ld8 out0 = [out0]
156(p7)	ld8 r18 = [r16], 8
157	.save rp, loc1
158	mov loc1 = rp
159	.body
160	;;
161
162	mov loc2 = gp
163(p7)	ld8 gp = [r16]
164(p7)	mov b6 = r18
165
166	nop 0
167	nop 0
168(p7)	br.call.sptk.many rp = b6
169	;;
170
171	nop 0
172	nop 0
173	br.sptk.many .entry
174#endif
175	/*
176		do {
177		  dtor_ptr++;
178		  (*(dtor_ptr-1)) ();
179		} while (dtor_ptr);
180	*/
181.loop:
182	st8 [loc0] = r15		// update dtor_ptr (in memory)
183	ld8 r17 = [r16], 8		// r17 <- dtor's entry-point
184	nop 0
185	;;
186
187	ld8 gp = [r16]			// gp <- dtor's gp
188	mov b6 = r17
189	br.call.sptk.many rp = b6
190
191.entry:	ld8 r15 = [loc0]		// r15 <- dtor_ptr (gp-relative)
192	;;
193	add r16 = r15, loc2		// r16 <- dtor_ptr (absolute)
194	adds r15 = 8, r15
195	;;
196
197	ld8 r16 = [r16]			// r16 <- pointer to dtor's fdesc
198	mov rp = loc1
199	mov ar.pfs = loc3
200	;;
201
202	cmp.ne p6, p0 = r0, r16
203(p6)	br.cond.sptk.few .loop
204	br.ret.sptk.many rp
205	.endp __do_global_dtors_aux
206
207	.align	32
208	.proc	__do_jv_register_classes
209__do_jv_register_classes:
210	.prologue
211	.save ar.pfs, r33
212	alloc loc1 = ar.pfs, 0, 3, 1, 0
213	movl out0 = @gprel(__JCR_LIST__)
214	;;
215
216	addl r14 = @ltoff(@fptr(_Jv_RegisterClasses)), gp
217	add out0 = out0, gp
218	.save rp, loc0
219	mov loc0 = rp
220	.body
221	;;
222
223	ld8 r14 = [r14]
224	ld8 r15 = [out0]
225	cmp.ne p6, p0 = r0, r0
226	;;
227
228	cmp.eq.or p6, p0 = r0, r14
229	cmp.eq.or p6, p0 = r0, r15
230(p6)	br.ret.sptk.many rp
231
232	ld8 r15 = [r14], 8
233	;;
234	nop 0
235	mov b6 = r15
236
237	mov loc2 = gp
238	ld8 gp = [r14]
239	br.call.sptk.many rp = b6
240	;;
241
242	mov gp = loc2
243	mov rp = loc0
244	mov ar.pfs = loc1
245
246	nop 0
247	nop 0
248	br.ret.sptk.many rp
249	.endp	__do_jv_register_classes
250
251#ifdef SHARED
252.weak __cxa_finalize
253#endif
254.weak _Jv_RegisterClasses
255