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