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