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