OSDN Git Service

gcc/
[pf3gnuchains/gcc-fork.git] / libgcc / config / ia64 / crtbegin.S
1 /* Copyright (C) 2000, 2001, 2003, 2005, 2009 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
44 dtor_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