OSDN Git Service

2008-11-18 Kai Tietz <kai.tietz@onevision.com>
[pf3gnuchains/gcc-fork.git] / gcc / config / rs6000 / eabi.asm
1 /*
2  * Special support for eabi and SVR4
3  *
4  *   Copyright (C) 1995, 1996, 1998, 2000, 2001 Free Software Foundation, Inc.
5  *   Written By Michael Meissner
6  * 
7  * This file is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the
9  * Free Software Foundation; either version 2, or (at your option) any
10  * later version.
11  * 
12  * In addition to the permissions in the GNU General Public License, the
13  * Free Software Foundation gives you unlimited permission to link the
14  * compiled version of this file with other programs, and to distribute
15  * those programs without any restriction coming from the use of this
16  * file.  (The General Public License restrictions do apply in other
17  * respects; for example, they cover modification of the file, and
18  * distribution when not linked into another program.)
19  * 
20  * This file is distributed in the hope that it will be useful, but
21  * WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23  * General Public License for more details.
24  * 
25  * You should have received a copy of the GNU General Public License
26  * along with this program; see the file COPYING.  If not, write to
27  * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
28  * Boston, MA 02110-1301, USA.
29  * 
30  *    As a special exception, if you link this library with files
31  *    compiled with GCC to produce an executable, this does not cause
32  *    the resulting executable to be covered by the GNU General Public License.
33  *    This exception does not however invalidate any other reasons why
34  *    the executable file might be covered by the GNU General Public License.
35  */ 
36
37 /* Do any initializations needed for the eabi environment */
38
39         .section ".text"
40         #include "ppc-asm.h"
41
42 #ifndef __powerpc64__
43
44          .section ".got2","aw"
45         .align  2
46 .LCTOC1 = . /* +32768 */
47
48 /* Table of addresses */
49 .Ltable = .-.LCTOC1
50         .long   .LCTOC1                         /* address we are really at */
51
52 .Lsda = .-.LCTOC1
53         .long   _SDA_BASE_                      /* address of the first small data area */
54
55 .Lsdas = .-.LCTOC1
56         .long   __SDATA_START__                 /* start of .sdata/.sbss section */
57
58 .Lsdae = .-.LCTOC1
59         .long   __SBSS_END__                    /* end of .sdata/.sbss section */
60
61 .Lsda2 = .-.LCTOC1
62         .long   _SDA2_BASE_                     /* address of the second small data area */
63
64 .Lsda2s = .-.LCTOC1
65         .long   __SDATA2_START__                /* start of .sdata2/.sbss2 section */
66
67 .Lsda2e = .-.LCTOC1
68         .long   __SBSS2_END__                   /* end of .sdata2/.sbss2 section */
69
70 #ifdef _RELOCATABLE
71 .Lgots = .-.LCTOC1
72         .long   __GOT_START__                   /* Global offset table start */
73
74 .Lgotm1 = .-.LCTOC1
75         .long   _GLOBAL_OFFSET_TABLE_-4         /* end of GOT ptrs before BLCL + 3 reserved words */
76
77 .Lgotm2 = .-.LCTOC1
78         .long   _GLOBAL_OFFSET_TABLE_+12        /* start of GOT ptrs after BLCL + 3 reserved words */
79
80 .Lgote = .-.LCTOC1
81         .long   __GOT_END__                     /* Global offset table end */
82
83 .Lgot2s = .-.LCTOC1
84         .long   __GOT2_START__                  /* -mrelocatable GOT pointers start */
85
86 .Lgot2e = .-.LCTOC1
87         .long   __GOT2_END__                    /* -mrelocatable GOT pointers end */
88
89 .Lfixups = .-.LCTOC1
90         .long   __FIXUP_START__                 /* start of .fixup section */
91
92 .Lfixupe = .-.LCTOC1
93         .long   __FIXUP_END__                   /* end of .fixup section */
94
95 .Lctors = .-.LCTOC1
96         .long   __CTOR_LIST__                   /* start of .ctor section */
97
98 .Lctore = .-.LCTOC1
99         .long   __CTOR_END__                    /* end of .ctor section */
100
101 .Ldtors = .-.LCTOC1
102         .long   __DTOR_LIST__                   /* start of .dtor section */
103
104 .Ldtore = .-.LCTOC1
105         .long   __DTOR_END__                    /* end of .dtor section */
106
107 .Lexcepts = .-.LCTOC1
108         .long   __EXCEPT_START__                /* start of .gcc_except_table section */
109
110 .Lexcepte = .-.LCTOC1
111         .long   __EXCEPT_END__                  /* end of .gcc_except_table section */
112
113 .Linit = .-.LCTOC1
114         .long   .Linit_p                        /* address of variable to say we've been called */
115
116         .text
117         .align  2
118 .Lptr:
119         .long   .LCTOC1-.Laddr                  /* PC relative pointer to .got2 */
120 #endif
121
122         .data
123         .align  2
124 .Linit_p:
125         .long   0
126
127         .text
128
129 FUNC_START(__eabi)
130
131 /* Eliminate -mrelocatable code if not -mrelocatable, so that this file can
132    be assembled with other assemblers than GAS.  */
133
134 #ifndef _RELOCATABLE
135         addis   10,0,.Linit_p@ha                /* init flag */
136         addis   11,0,.LCTOC1@ha                 /* load address of .LCTOC1 */
137         lwz     9,.Linit_p@l(10)                /* init flag */
138         addi    11,11,.LCTOC1@l
139         cmplwi  2,9,0                           /* init flag != 0? */
140         bnelr   2                               /* return now, if we've been called already */
141         stw     1,.Linit_p@l(10)                /* store a nonzero value in the done flag */
142
143 #else /* -mrelocatable */
144         mflr    0
145         bl      .Laddr                          /* get current address */
146 .Laddr:
147         mflr    12                              /* real address of .Laddr */
148         lwz     11,(.Lptr-.Laddr)(12)           /* linker generated address of .LCTOC1 */
149         add     11,11,12                        /* correct to real pointer */
150         lwz     12,.Ltable(11)                  /* get linker's idea of where .Laddr is */
151         lwz     10,.Linit(11)                   /* address of init flag */
152         subf.   12,12,11                        /* calculate difference */
153         lwzx    9,10,12                         /* done flag */
154         cmplwi  2,9,0                           /* init flag != 0? */
155         mtlr    0                               /* restore in case branch was taken */
156         bnelr   2                               /* return now, if we've been called already */
157         stwx    1,10,12                         /* store a nonzero value in the done flag */
158         beq+    0,.Lsdata                       /* skip if we don't need to relocate */
159
160 /* We need to relocate the .got2 pointers.  */
161
162         lwz     3,.Lgot2s(11)                   /* GOT2 pointers start */
163         lwz     4,.Lgot2e(11)                   /* GOT2 pointers end */
164         add     3,12,3                          /* adjust pointers */
165         add     4,12,4
166         bl      FUNC_NAME(__eabi_convert)       /* convert pointers in .got2 section */
167
168 /* Fixup the .ctor section for static constructors */
169
170         lwz     3,.Lctors(11)                   /* constructors pointers start */
171         lwz     4,.Lctore(11)                   /* constructors pointers end */
172         bl      FUNC_NAME(__eabi_convert)       /* convert constructors */
173
174 /* Fixup the .dtor section for static destructors */
175
176         lwz     3,.Ldtors(11)                   /* destructors pointers start */
177         lwz     4,.Ldtore(11)                   /* destructors pointers end */
178         bl      FUNC_NAME(__eabi_convert)       /* convert destructors */
179
180 /* Fixup the .gcc_except_table section for G++ exceptions */
181
182         lwz     3,.Lexcepts(11)                 /* exception table pointers start */
183         lwz     4,.Lexcepte(11)                 /* exception table pointers end */
184         bl      FUNC_NAME(__eabi_convert)       /* convert exceptions */
185
186 /* Fixup the addresses in the GOT below _GLOBAL_OFFSET_TABLE_-4 */
187
188         lwz     3,.Lgots(11)                    /* GOT table pointers start */
189         lwz     4,.Lgotm1(11)                   /* GOT table pointers below _GLOBAL_OFFSET_TABLE-4 */
190         bl      FUNC_NAME(__eabi_convert)       /* convert lower GOT */
191
192 /* Fixup the addresses in the GOT above _GLOBAL_OFFSET_TABLE_+12 */
193
194         lwz     3,.Lgotm2(11)                   /* GOT table pointers above _GLOBAL_OFFSET_TABLE+12 */
195         lwz     4,.Lgote(11)                    /* GOT table pointers end */
196         bl      FUNC_NAME(__eabi_convert)       /* convert lower GOT */
197
198 /* Fixup any user initialized pointers now (the compiler drops pointers to */
199 /* each of the relocs that it does in the .fixup section).  */
200
201 .Lfix:
202         lwz     3,.Lfixups(11)                  /* fixup pointers start */
203         lwz     4,.Lfixupe(11)                  /* fixup pointers end */
204         bl      FUNC_NAME(__eabi_uconvert)      /* convert user initialized pointers */
205
206 .Lsdata:
207         mtlr    0                               /* restore link register */
208 #endif /* _RELOCATABLE */
209
210 /* Only load up register 13 if there is a .sdata and/or .sbss section */
211         lwz     3,.Lsdas(11)                    /* start of .sdata/.sbss section */
212         lwz     4,.Lsdae(11)                    /* end of .sdata/.sbss section */
213         cmpw    1,3,4                           /* .sdata/.sbss section non-empty? */
214         beq-    1,.Lsda2l                       /* skip loading r13 */
215
216         lwz     13,.Lsda(11)                    /* load r13 with _SDA_BASE_ address */
217
218 /* Only load up register 2 if there is a .sdata2 and/or .sbss2 section */
219
220 .Lsda2l:        
221         lwz     3,.Lsda2s(11)                   /* start of .sdata/.sbss section */
222         lwz     4,.Lsda2e(11)                   /* end of .sdata/.sbss section */
223         cmpw    1,3,4                           /* .sdata/.sbss section non-empty? */
224         beq+    1,.Ldone                        /* skip loading r2 */
225
226         lwz     2,.Lsda2(11)                    /* load r2 with _SDA2_BASE_ address */
227
228 /* Done adjusting pointers, return by way of doing the C++ global constructors.  */
229
230 .Ldone:
231         b       FUNC_NAME(__init)       /* do any C++ global constructors (which returns to caller) */
232 FUNC_END(__eabi)
233
234 /* Special subroutine to convert a bunch of pointers directly.
235    r0           has original link register
236    r3           has low pointer to convert
237    r4           has high pointer to convert
238    r5 .. r10    are scratch registers
239    r11          has the address of .LCTOC1 in it.
240    r12          has the value to add to each pointer
241    r13 .. r31   are unchanged */
242         
243 FUNC_START(__eabi_convert)
244         cmplw   1,3,4                           /* any pointers to convert? */
245         subf    5,3,4                           /* calculate number of words to convert */
246         bclr    4,4                             /* return if no pointers */
247
248         srawi   5,5,2
249         addi    3,3,-4                          /* start-4 for use with lwzu */
250         mtctr   5
251
252 .Lcvt:
253         lwzu    6,4(3)                          /* pointer to convert */
254         cmpwi   0,6,0
255         beq-    .Lcvt2                          /* if pointer is null, don't convert */
256
257         add     6,6,12                          /* convert pointer */
258         stw     6,0(3)
259 .Lcvt2:
260         bdnz+   .Lcvt
261         blr
262
263 FUNC_END(__eabi_convert)
264
265 /* Special subroutine to convert the pointers the user has initialized.  The
266    compiler has placed the address of the initialized pointer into the .fixup
267    section.
268
269    r0           has original link register
270    r3           has low pointer to convert
271    r4           has high pointer to convert
272    r5 .. r10    are scratch registers
273    r11          has the address of .LCTOC1 in it.
274    r12          has the value to add to each pointer
275    r13 .. r31   are unchanged */
276         
277 FUNC_START(__eabi_uconvert)
278         cmplw   1,3,4                           /* any pointers to convert? */
279         subf    5,3,4                           /* calculate number of words to convert */
280         bclr    4,4                             /* return if no pointers */
281
282         srawi   5,5,2
283         addi    3,3,-4                          /* start-4 for use with lwzu */
284         mtctr   5
285
286 .Lucvt:
287         lwzu    6,4(3)                          /* next pointer to pointer to convert */
288         add     6,6,12                          /* adjust pointer */
289         lwz     7,0(6)                          /* get the pointer it points to */
290         stw     6,0(3)                          /* store adjusted pointer */
291         add     7,7,12                          /* adjust */
292         stw     7,0(6)
293         bdnz+   .Lucvt
294         blr
295
296 FUNC_END(__eabi_uconvert)
297
298 #endif