]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/gcc/config/rs6000/eabi.asm
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / 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         .file   "eabi.asm"
40         .section ".text"
41         #include "ppc-asm.h"
42
43 #ifndef __powerpc64__
44
45          .section ".got2","aw"
46         .align  2
47 .LCTOC1 = . /* +32768 */
48
49 /* Table of addresses */
50 .Ltable = .-.LCTOC1
51         .long   .LCTOC1                         /* address we are really at */
52
53 .Lsda = .-.LCTOC1
54         .long   _SDA_BASE_                      /* address of the first small data area */
55
56 .Lsdas = .-.LCTOC1
57         .long   __SDATA_START__                 /* start of .sdata/.sbss section */
58
59 .Lsdae = .-.LCTOC1
60         .long   __SBSS_END__                    /* end of .sdata/.sbss section */
61
62 .Lsda2 = .-.LCTOC1
63         .long   _SDA2_BASE_                     /* address of the second small data area */
64
65 .Lsda2s = .-.LCTOC1
66         .long   __SDATA2_START__                /* start of .sdata2/.sbss2 section */
67
68 .Lsda2e = .-.LCTOC1
69         .long   __SBSS2_END__                   /* end of .sdata2/.sbss2 section */
70
71 #ifdef _RELOCATABLE
72 .Lgots = .-.LCTOC1
73         .long   __GOT_START__                   /* Global offset table start */
74
75 .Lgotm1 = .-.LCTOC1
76         .long   _GLOBAL_OFFSET_TABLE_-4         /* end of GOT ptrs before BLCL + 3 reserved words */
77
78 .Lgotm2 = .-.LCTOC1
79         .long   _GLOBAL_OFFSET_TABLE_+12        /* start of GOT ptrs after BLCL + 3 reserved words */
80
81 .Lgote = .-.LCTOC1
82         .long   __GOT_END__                     /* Global offset table end */
83
84 .Lgot2s = .-.LCTOC1
85         .long   __GOT2_START__                  /* -mrelocatable GOT pointers start */
86
87 .Lgot2e = .-.LCTOC1
88         .long   __GOT2_END__                    /* -mrelocatable GOT pointers end */
89
90 .Lfixups = .-.LCTOC1
91         .long   __FIXUP_START__                 /* start of .fixup section */
92
93 .Lfixupe = .-.LCTOC1
94         .long   __FIXUP_END__                   /* end of .fixup section */
95
96 .Lctors = .-.LCTOC1
97         .long   __CTOR_LIST__                   /* start of .ctor section */
98
99 .Lctore = .-.LCTOC1
100         .long   __CTOR_END__                    /* end of .ctor section */
101
102 .Ldtors = .-.LCTOC1
103         .long   __DTOR_LIST__                   /* start of .dtor section */
104
105 .Ldtore = .-.LCTOC1
106         .long   __DTOR_END__                    /* end of .dtor section */
107
108 .Lexcepts = .-.LCTOC1
109         .long   __EXCEPT_START__                /* start of .gcc_except_table section */
110
111 .Lexcepte = .-.LCTOC1
112         .long   __EXCEPT_END__                  /* end of .gcc_except_table section */
113
114 .Linit = .-.LCTOC1
115         .long   .Linit_p                        /* address of variable to say we've been called */
116
117         .text
118         .align  2
119 .Lptr:
120         .long   .LCTOC1-.Laddr                  /* PC relative pointer to .got2 */
121 #endif
122
123         .data
124         .align  2
125 .Linit_p:
126         .long   0
127
128         .text
129
130 FUNC_START(__eabi)
131
132 /* Eliminate -mrelocatable code if not -mrelocatable, so that this file can
133    be assembled with other assemblers than GAS.  */
134
135 #ifndef _RELOCATABLE
136         addis   10,0,.Linit_p@ha                /* init flag */
137         addis   11,0,.LCTOC1@ha                 /* load address of .LCTOC1 */
138         lwz     9,.Linit_p@l(10)                /* init flag */
139         addi    11,11,.LCTOC1@l
140         cmplwi  2,9,0                           /* init flag != 0? */
141         bnelr   2                               /* return now, if we've been called already */
142         stw     1,.Linit_p@l(10)                /* store a nonzero value in the done flag */
143
144 #else /* -mrelocatable */
145         mflr    0
146         bl      .Laddr                          /* get current address */
147 .Laddr:
148         mflr    12                              /* real address of .Laddr */
149         lwz     11,(.Lptr-.Laddr)(12)           /* linker generated address of .LCTOC1 */
150         add     11,11,12                        /* correct to real pointer */
151         lwz     12,.Ltable(11)                  /* get linker's idea of where .Laddr is */
152         lwz     10,.Linit(11)                   /* address of init flag */
153         subf.   12,12,11                        /* calculate difference */
154         lwzx    9,10,12                         /* done flag */
155         cmplwi  2,9,0                           /* init flag != 0? */
156         mtlr    0                               /* restore in case branch was taken */
157         bnelr   2                               /* return now, if we've been called already */
158         stwx    1,10,12                         /* store a nonzero value in the done flag */
159         beq+    0,.Lsdata                       /* skip if we don't need to relocate */
160
161 /* We need to relocate the .got2 pointers.  */
162
163         lwz     3,.Lgot2s(11)                   /* GOT2 pointers start */
164         lwz     4,.Lgot2e(11)                   /* GOT2 pointers end */
165         add     3,12,3                          /* adjust pointers */
166         add     4,12,4
167         bl      FUNC_NAME(__eabi_convert)       /* convert pointers in .got2 section */
168
169 /* Fixup the .ctor section for static constructors */
170
171         lwz     3,.Lctors(11)                   /* constructors pointers start */
172         lwz     4,.Lctore(11)                   /* constructors pointers end */
173         bl      FUNC_NAME(__eabi_convert)       /* convert constructors */
174
175 /* Fixup the .dtor section for static destructors */
176
177         lwz     3,.Ldtors(11)                   /* destructors pointers start */
178         lwz     4,.Ldtore(11)                   /* destructors pointers end */
179         bl      FUNC_NAME(__eabi_convert)       /* convert destructors */
180
181 /* Fixup the .gcc_except_table section for G++ exceptions */
182
183         lwz     3,.Lexcepts(11)                 /* exception table pointers start */
184         lwz     4,.Lexcepte(11)                 /* exception table pointers end */
185         bl      FUNC_NAME(__eabi_convert)       /* convert exceptions */
186
187 /* Fixup the addresses in the GOT below _GLOBAL_OFFSET_TABLE_-4 */
188
189         lwz     3,.Lgots(11)                    /* GOT table pointers start */
190         lwz     4,.Lgotm1(11)                   /* GOT table pointers below _GLOBAL_OFFSET_TABLE-4 */
191         bl      FUNC_NAME(__eabi_convert)       /* convert lower GOT */
192
193 /* Fixup the addresses in the GOT above _GLOBAL_OFFSET_TABLE_+12 */
194
195         lwz     3,.Lgotm2(11)                   /* GOT table pointers above _GLOBAL_OFFSET_TABLE+12 */
196         lwz     4,.Lgote(11)                    /* GOT table pointers end */
197         bl      FUNC_NAME(__eabi_convert)       /* convert lower GOT */
198
199 /* Fixup any user initialized pointers now (the compiler drops pointers to */
200 /* each of the relocs that it does in the .fixup section).  */
201
202 .Lfix:
203         lwz     3,.Lfixups(11)                  /* fixup pointers start */
204         lwz     4,.Lfixupe(11)                  /* fixup pointers end */
205         bl      FUNC_NAME(__eabi_uconvert)      /* convert user initialized pointers */
206
207 .Lsdata:
208         mtlr    0                               /* restore link register */
209 #endif /* _RELOCATABLE */
210
211 /* Only load up register 13 if there is a .sdata and/or .sbss section */
212         lwz     3,.Lsdas(11)                    /* start of .sdata/.sbss section */
213         lwz     4,.Lsdae(11)                    /* end of .sdata/.sbss section */
214         cmpw    1,3,4                           /* .sdata/.sbss section non-empty? */
215         beq-    1,.Lsda2l                       /* skip loading r13 */
216
217         lwz     13,.Lsda(11)                    /* load r13 with _SDA_BASE_ address */
218
219 /* Only load up register 2 if there is a .sdata2 and/or .sbss2 section */
220
221 .Lsda2l:        
222         lwz     3,.Lsda2s(11)                   /* start of .sdata/.sbss section */
223         lwz     4,.Lsda2e(11)                   /* end of .sdata/.sbss section */
224         cmpw    1,3,4                           /* .sdata/.sbss section non-empty? */
225         beq+    1,.Ldone                        /* skip loading r2 */
226
227         lwz     2,.Lsda2(11)                    /* load r2 with _SDA2_BASE_ address */
228
229 /* Done adjusting pointers, return by way of doing the C++ global constructors.  */
230
231 .Ldone:
232         b       FUNC_NAME(__init)       /* do any C++ global constructors (which returns to caller) */
233 FUNC_END(__eabi)
234
235 /* Special subroutine to convert a bunch of pointers directly.
236    r0           has original link register
237    r3           has low pointer to convert
238    r4           has high pointer to convert
239    r5 .. r10    are scratch registers
240    r11          has the address of .LCTOC1 in it.
241    r12          has the value to add to each pointer
242    r13 .. r31   are unchanged */
243         
244 FUNC_START(__eabi_convert)
245         cmplw   1,3,4                           /* any pointers to convert? */
246         subf    5,3,4                           /* calculate number of words to convert */
247         bclr    4,4                             /* return if no pointers */
248
249         srawi   5,5,2
250         addi    3,3,-4                          /* start-4 for use with lwzu */
251         mtctr   5
252
253 .Lcvt:
254         lwzu    6,4(3)                          /* pointer to convert */
255         cmpwi   0,6,0
256         beq-    .Lcvt2                          /* if pointer is null, don't convert */
257
258         add     6,6,12                          /* convert pointer */
259         stw     6,0(3)
260 .Lcvt2:
261         bdnz+   .Lcvt
262         blr
263
264 FUNC_END(__eabi_convert)
265
266 /* Special subroutine to convert the pointers the user has initialized.  The
267    compiler has placed the address of the initialized pointer into the .fixup
268    section.
269
270    r0           has original link register
271    r3           has low pointer to convert
272    r4           has high pointer to convert
273    r5 .. r10    are scratch registers
274    r11          has the address of .LCTOC1 in it.
275    r12          has the value to add to each pointer
276    r13 .. r31   are unchanged */
277         
278 FUNC_START(__eabi_uconvert)
279         cmplw   1,3,4                           /* any pointers to convert? */
280         subf    5,3,4                           /* calculate number of words to convert */
281         bclr    4,4                             /* return if no pointers */
282
283         srawi   5,5,2
284         addi    3,3,-4                          /* start-4 for use with lwzu */
285         mtctr   5
286
287 .Lucvt:
288         lwzu    6,4(3)                          /* next pointer to pointer to convert */
289         add     6,6,12                          /* adjust pointer */
290         lwz     7,0(6)                          /* get the pointer it points to */
291         stw     6,0(3)                          /* store adjusted pointer */
292         add     7,7,12                          /* adjust */
293         stw     7,0(6)
294         bdnz+   .Lucvt
295         blr
296
297 FUNC_END(__eabi_uconvert)
298
299 #endif