Blame sysdeps/powerpc/powerpc64/dl-trampoline.S

Packit 6c4009
/* PLT trampolines.  PPC64 version.
Packit 6c4009
   Copyright (C) 2005-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#include <sysdep.h>
Packit 6c4009
#include <rtld-global-offsets.h>
Packit 6c4009
Packit 6c4009
Packit 6c4009
	.section ".text"
Packit 6c4009
/* On entry r0 contains the index of the PLT entry we need to fixup
Packit 6c4009
   and r11 contains the link_map (from PLT0+16).  The link_map becomes
Packit 6c4009
   parm1 (r3) and the index (r0) need to be converted to an offset
Packit 6c4009
   (index * 24) in parm2 (r4).  */
Packit 6c4009
Packit 6c4009
#define FRAME_SIZE (FRAME_MIN_SIZE+64)
Packit 6c4009
/* We need to save the registers used to pass parameters, ie. r3 thru
Packit 6c4009
   r10;  Use local var space rather than the parameter save area,
Packit 6c4009
   because gcc as of 2010/05 doesn't allocate a proper stack frame for
Packit 6c4009
   a function that makes no calls except for __tls_get_addr and we
Packit 6c4009
   might be here resolving the __tls_get_addr call.  */
Packit 6c4009
#define INT_PARMS FRAME_MIN_SIZE
Packit 6c4009
ENTRY (_dl_runtime_resolve, 4)
Packit 6c4009
	stdu	r1,-FRAME_SIZE(r1)
Packit 6c4009
	cfi_adjust_cfa_offset (FRAME_SIZE)
Packit 6c4009
	std	r3,INT_PARMS+0(r1)
Packit 6c4009
	mr	r3,r11
Packit 6c4009
	std	r4,INT_PARMS+8(r1)
Packit 6c4009
	sldi	r4,r0,1
Packit 6c4009
	std	r5,INT_PARMS+16(r1)
Packit 6c4009
	add	r4,r4,r0
Packit 6c4009
	std	r6,INT_PARMS+24(r1)
Packit 6c4009
	sldi	r4,r4,3
Packit 6c4009
	std	r7,INT_PARMS+32(r1)
Packit 6c4009
	mflr	r0
Packit 6c4009
	std	r8,INT_PARMS+40(r1)
Packit 6c4009
/* Store the LR in the LR Save area.  */
Packit 6c4009
	std	r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
Packit 6c4009
	cfi_offset (lr, FRAME_LR_SAVE)
Packit 6c4009
	std	r9,INT_PARMS+48(r1)
Packit 6c4009
	std	r10,INT_PARMS+56(r1)
Packit 6c4009
	bl	JUMPTARGET(_dl_fixup)
Packit 6c4009
#ifndef SHARED
Packit 6c4009
	nop
Packit 6c4009
#endif
Packit 6c4009
/* Put the registers back.  */
Packit 6c4009
	ld	r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
Packit 6c4009
	ld	r10,INT_PARMS+56(r1)
Packit 6c4009
	ld	r9,INT_PARMS+48(r1)
Packit 6c4009
	ld	r8,INT_PARMS+40(r1)
Packit 6c4009
	ld	r7,INT_PARMS+32(r1)
Packit 6c4009
	mtlr	r0
Packit 6c4009
	ld	r6,INT_PARMS+24(r1)
Packit 6c4009
	ld	r5,INT_PARMS+16(r1)
Packit 6c4009
	ld	r4,INT_PARMS+8(r1)
Packit 6c4009
/* Prepare for calling the function returned by fixup.  */
Packit 6c4009
	PPC64_LOAD_FUNCPTR r3
Packit 6c4009
	ld	r3,INT_PARMS+0(r1)
Packit 6c4009
#if _CALL_ELF == 2
Packit 6c4009
/* Restore the caller's TOC in case we jump to a local entry point.  */
Packit 6c4009
	ld	r2,FRAME_SIZE+FRAME_TOC_SAVE(r1)
Packit 6c4009
#endif
Packit 6c4009
/* Unwind the stack frame, and jump.  */
Packit 6c4009
	addi	r1,r1,FRAME_SIZE
Packit 6c4009
	bctr
Packit 6c4009
END(_dl_runtime_resolve)
Packit 6c4009
#undef FRAME_SIZE
Packit 6c4009
#undef INT_PARMS
Packit 6c4009
Packit 6c4009
	/* Stack layout:		ELFv2 ABI.
Packit 6c4009
					+752   previous backchain
Packit 6c4009
					+744   spill_r31
Packit 6c4009
					+736   spill_r30
Packit 6c4009
					+720   v8
Packit 6c4009
					+704   v7
Packit 6c4009
					+688   v6
Packit 6c4009
					+672   v5
Packit 6c4009
					+656   v4
Packit 6c4009
					+640   v3
Packit 6c4009
					+624   v2
Packit 6c4009
					+608   v1
Packit 6c4009
					+600   fp10
Packit 6c4009
	  ELFv1 ABI			+592   fp9
Packit 6c4009
	  +592   previous backchain	+584   fp8
Packit 6c4009
	  +584   spill_r31		+576   fp7
Packit 6c4009
	  +576   spill_r30		+568   fp6
Packit 6c4009
	  +560   v1			+560   fp5
Packit 6c4009
	  +552   fp4			+552   fp4
Packit 6c4009
	  +544   fp3			+544   fp3
Packit 6c4009
	  +536   fp2			+536   fp2
Packit 6c4009
	  +528   fp1			+528   fp1
Packit 6c4009
	  +520   r4			+520   r4
Packit 6c4009
	  +512   r3			+512   r3
Packit 6c4009
	   return values
Packit 6c4009
          +504   free
Packit 6c4009
	  +496   stackframe
Packit 6c4009
	  +488   lr
Packit 6c4009
	  +480   r1
Packit 6c4009
	  +464   v13
Packit 6c4009
	  +448   v12
Packit 6c4009
	  +432   v11
Packit 6c4009
	  +416   v10
Packit 6c4009
	  +400   v9
Packit 6c4009
	  +384   v8
Packit 6c4009
	  +368   v7
Packit 6c4009
	  +352   v6
Packit 6c4009
	  +336   v5
Packit 6c4009
	  +320   v4
Packit 6c4009
	  +304   v3
Packit 6c4009
	  +288   v2
Packit 6c4009
	 * VMX Parms in V2-V13, V0-V1 are scratch
Packit 6c4009
	  +284   vrsave
Packit 6c4009
	  +280   free
Packit 6c4009
	  +272   fp13
Packit 6c4009
	  +264   fp12
Packit 6c4009
	  +256   fp11
Packit 6c4009
	  +248   fp10
Packit 6c4009
	  +240   fp9
Packit 6c4009
	  +232   fp8
Packit 6c4009
	  +224   fp7
Packit 6c4009
	  +216   fp6
Packit 6c4009
	  +208   fp5
Packit 6c4009
	  +200   fp4
Packit 6c4009
	  +192   fp3
Packit 6c4009
	  +184   fp2
Packit 6c4009
	  +176   fp1
Packit 6c4009
	 * FP Parms in FP1-FP13, FP0 is a scratch register
Packit 6c4009
	  +168   r10
Packit 6c4009
	  +160   r9
Packit 6c4009
	  +152   r8
Packit 6c4009
	  +144   r7
Packit 6c4009
	  +136   r6
Packit 6c4009
	  +128   r5
Packit 6c4009
	  +120   r4
Packit 6c4009
	  +112   r3
Packit 6c4009
	 * Integer parms in R3-R10, R0 is scratch, R1 SP, R2 is TOC
Packit 6c4009
	  +104   parm8
Packit 6c4009
	  +96    parm7
Packit 6c4009
	  +88    parm6
Packit 6c4009
	  +80    parm5
Packit 6c4009
	  +72    parm4
Packit 6c4009
	  +64    parm3
Packit 6c4009
	  +56    parm2
Packit 6c4009
	  +48    parm1
Packit 6c4009
	 * Parameter save area
Packit 6c4009
	 * (v1 ABI: Allocated by the call, at least 8 double words)
Packit 6c4009
	  +40    v1 ABI: TOC save area
Packit 6c4009
	  +32    v1 ABI: Reserved for linker
Packit 6c4009
	  +24    v1 ABI: Reserved for compiler / v2 ABI: TOC save area
Packit 6c4009
	  +16    LR save area
Packit 6c4009
	  +8     CR save area
Packit 6c4009
	r1+0     stack back chain
Packit 6c4009
	*/
Packit 6c4009
#if _CALL_ELF == 2
Packit 6c4009
# define FRAME_SIZE 752
Packit 6c4009
# define VR_RTN 608
Packit 6c4009
#else
Packit 6c4009
# define FRAME_SIZE 592
Packit 6c4009
# define VR_RTN 560
Packit 6c4009
#endif
Packit 6c4009
#define INT_RTN 512
Packit 6c4009
#define FPR_RTN 528
Packit 6c4009
#define STACK_FRAME 496
Packit 6c4009
#define CALLING_LR 488
Packit 6c4009
#define CALLING_SP 480
Packit 6c4009
#define INT_PARMS 112
Packit 6c4009
#define FPR_PARMS 176
Packit 6c4009
#define VR_PARMS 288
Packit 6c4009
#define VR_VRSAVE 284
Packit 6c4009
	.section	".toc","aw"
Packit 6c4009
.LC__dl_hwcap:
Packit 6c4009
# ifdef SHARED
Packit 6c4009
	.tc _rtld_local_ro[TC],_rtld_local_ro
Packit 6c4009
# else
Packit 6c4009
	.tc _dl_hwcap[TC],_dl_hwcap
Packit 6c4009
# endif
Packit 6c4009
	.section ".text"
Packit 6c4009
Packit 6c4009
	.machine	"altivec"
Packit 6c4009
/* On entry r0 contains the index of the PLT entry we need to fixup
Packit 6c4009
   and r11 contains the link_map (from PLT0+16).  The link_map becomes
Packit 6c4009
   parm1 (r3) and the index (r0) needs to be converted to an offset
Packit 6c4009
   (index * 24) in parm2 (r4).  */
Packit 6c4009
#ifndef PROF
Packit 6c4009
ENTRY (_dl_profile_resolve, 4)
Packit 6c4009
/* Spill r30, r31 to preserve the link_map* and reloc_addr, in case we
Packit 6c4009
   need to call _dl_call_pltexit.  */
Packit 6c4009
	std	r31,-8(r1)
Packit 6c4009
	std	r30,-16(r1)
Packit 6c4009
/* We need to save the registers used to pass parameters, ie. r3 thru
Packit 6c4009
   r10; the registers are saved in a stack frame.  */
Packit 6c4009
	stdu	r1,-FRAME_SIZE(r1)
Packit 6c4009
	cfi_adjust_cfa_offset (FRAME_SIZE)
Packit 6c4009
	cfi_offset(r31,-8)
Packit 6c4009
	cfi_offset(r30,-16)
Packit 6c4009
	std	r3,INT_PARMS+0(r1)
Packit 6c4009
	mr	r3,r11
Packit 6c4009
	std	r4,INT_PARMS+8(r1)
Packit 6c4009
	sldi	r4,r0,1		/* index * 2 */
Packit 6c4009
	std	r5,INT_PARMS+16(r1)
Packit 6c4009
	add	r4,r4,r0	/* index * 3 */
Packit 6c4009
	std	r6,INT_PARMS+24(r1)
Packit 6c4009
	sldi	r4,r4,3		/* index * 24  == PLT offset */
Packit 6c4009
	mflr	r5
Packit 6c4009
	std	r7,INT_PARMS+32(r1)
Packit 6c4009
	std	r8,INT_PARMS+40(r1)
Packit 6c4009
/* Store the LR in the LR Save area.  */
Packit 6c4009
	la	r8,FRAME_SIZE(r1)
Packit 6c4009
	std	r5,FRAME_SIZE+FRAME_LR_SAVE(r1)
Packit 6c4009
	cfi_offset (lr, FRAME_LR_SAVE)
Packit 6c4009
	std	r5,CALLING_LR(r1)
Packit 6c4009
	std	r9,INT_PARMS+48(r1)
Packit 6c4009
	std	r10,INT_PARMS+56(r1)
Packit 6c4009
	std	r8,CALLING_SP(r1)
Packit 6c4009
	ld	r12,.LC__dl_hwcap@toc(r2)
Packit 6c4009
#ifdef SHARED
Packit 6c4009
	/* Load _rtld_local_ro._dl_hwcap.  */
Packit 6c4009
	ld	r12,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r12)
Packit 6c4009
#else
Packit 6c4009
	ld	r12,0(r12) /* Load extern _dl_hwcap.  */
Packit 6c4009
#endif
Packit 6c4009
	andis.  r0,r12,(PPC_FEATURE_HAS_ALTIVEC >> 16)
Packit 6c4009
	beq	L(saveFP)
Packit 6c4009
	la	r10,(VR_PARMS+0)(r1)
Packit 6c4009
	la	r9,(VR_PARMS+16)(r1)
Packit 6c4009
	li	r11,32
Packit 6c4009
	li	r12,64
Packit 6c4009
	stvx	v2,0,r10
Packit 6c4009
	stvx	v3,0,r9
Packit 6c4009
Packit 6c4009
	stvx	v4,r11,r10
Packit 6c4009
	stvx	v5,r11,r9
Packit 6c4009
	addi	r11,r11,64
Packit 6c4009
Packit 6c4009
	stvx	v6,r12,r10
Packit 6c4009
	stvx	v7,r12,r9
Packit 6c4009
	addi	r12,r12,64
Packit 6c4009
Packit 6c4009
	stvx	v8,r11,r10
Packit 6c4009
	stvx	v9,r11,r9
Packit 6c4009
	addi	r11,r11,64
Packit 6c4009
Packit 6c4009
	stvx	v10,r12,r10
Packit 6c4009
	stvx	v11,r12,r9
Packit 6c4009
	mfspr	r0,VRSAVE
Packit 6c4009
Packit 6c4009
	stvx	v12,r11,r10
Packit 6c4009
	stvx	v13,r11,r9
Packit 6c4009
L(saveFP):
Packit 6c4009
	stw	r0,VR_VRSAVE(r1)
Packit 6c4009
/* Save floating registers.  */
Packit 6c4009
	stfd	fp1,FPR_PARMS+0(r1)
Packit 6c4009
	stfd	fp2,FPR_PARMS+8(r1)
Packit 6c4009
	stfd	fp3,FPR_PARMS+16(r1)
Packit 6c4009
	stfd	fp4,FPR_PARMS+24(r1)
Packit 6c4009
	stfd	fp5,FPR_PARMS+32(r1)
Packit 6c4009
	stfd	fp6,FPR_PARMS+40(r1)
Packit 6c4009
	stfd	fp7,FPR_PARMS+48(r1)
Packit 6c4009
	stfd	fp8,FPR_PARMS+56(r1)
Packit 6c4009
	stfd	fp9,FPR_PARMS+64(r1)
Packit 6c4009
	stfd	fp10,FPR_PARMS+72(r1)
Packit 6c4009
	stfd	fp11,FPR_PARMS+80(r1)
Packit 6c4009
	li	r0,-1
Packit 6c4009
	stfd	fp12,FPR_PARMS+88(r1)
Packit 6c4009
	stfd	fp13,FPR_PARMS+96(r1)
Packit 6c4009
/* Load the extra parameters.  */
Packit 6c4009
	addi	r6,r1,INT_PARMS
Packit 6c4009
	addi	r7,r1,STACK_FRAME
Packit 6c4009
/* Save  link_map* and reloc_addr parms for later.  */
Packit 6c4009
	mr	r31,r3
Packit 6c4009
	mr	r30,r4
Packit 6c4009
	std	r0,0(r7)
Packit 6c4009
	bl	JUMPTARGET(_dl_profile_fixup)
Packit 6c4009
#ifndef SHARED
Packit 6c4009
	nop
Packit 6c4009
#endif
Packit 6c4009
/* Test *framesizep > 0 to see if need to do pltexit processing.  */
Packit 6c4009
	ld	r0,STACK_FRAME(r1)
Packit 6c4009
/* Put the registers back.  */
Packit 6c4009
	lwz	r12,VR_VRSAVE(r1)
Packit 6c4009
	cmpdi	cr1,r0,0
Packit 6c4009
	cmpdi	cr0,r12,0
Packit 6c4009
	bgt	cr1,L(do_pltexit)
Packit 6c4009
	la	r10,(VR_PARMS+0)(r1)
Packit 6c4009
	la	r9,(VR_PARMS+16)(r1)
Packit 6c4009
/* VRSAVE must be non-zero if VMX is present and VRs are in use. */
Packit 6c4009
	beq	L(restoreFXR)
Packit 6c4009
	li	r11,32
Packit 6c4009
	li	r12,64
Packit 6c4009
	lvx	v2,0,r10
Packit 6c4009
	lvx	v3,0,r9
Packit 6c4009
Packit 6c4009
	lvx	v4,r11,r10
Packit 6c4009
	lvx	v5,r11,r9
Packit 6c4009
	addi	r11,r11,64
Packit 6c4009
Packit 6c4009
	lvx	v6,r12,r10
Packit 6c4009
	lvx	v7,r12,r9
Packit 6c4009
	addi	r12,r12,64
Packit 6c4009
Packit 6c4009
	lvx	v8,r11,r10
Packit 6c4009
	lvx	v9,r11,r9
Packit 6c4009
	addi	r11,r11,64
Packit 6c4009
Packit 6c4009
	lvx	v10,r12,r10
Packit 6c4009
	lvx	v11,r12,r9
Packit 6c4009
Packit 6c4009
	lvx	v12,r11,r10
Packit 6c4009
	lvx	v13,r11,r9
Packit 6c4009
L(restoreFXR):
Packit 6c4009
	ld	r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
Packit 6c4009
	ld	r10,INT_PARMS+56(r1)
Packit 6c4009
	ld	r9,INT_PARMS+48(r1)
Packit 6c4009
	ld	r8,INT_PARMS+40(r1)
Packit 6c4009
	ld	r7,INT_PARMS+32(r1)
Packit 6c4009
	mtlr	r0
Packit 6c4009
	ld	r6,INT_PARMS+24(r1)
Packit 6c4009
	ld	r5,INT_PARMS+16(r1)
Packit 6c4009
	ld	r4,INT_PARMS+8(r1)
Packit 6c4009
/* Prepare for calling the function returned by fixup.  */
Packit 6c4009
	PPC64_LOAD_FUNCPTR r3
Packit 6c4009
	ld	r3,INT_PARMS+0(r1)
Packit 6c4009
#if _CALL_ELF == 2
Packit 6c4009
/* Restore the caller's TOC in case we jump to a local entry point.  */
Packit 6c4009
	ld	r2,FRAME_SIZE+FRAME_TOC_SAVE(r1)
Packit 6c4009
#endif
Packit 6c4009
/* Load the floating point registers.  */
Packit 6c4009
	lfd	fp1,FPR_PARMS+0(r1)
Packit 6c4009
	lfd	fp2,FPR_PARMS+8(r1)
Packit 6c4009
	lfd	fp3,FPR_PARMS+16(r1)
Packit 6c4009
	lfd	fp4,FPR_PARMS+24(r1)
Packit 6c4009
	lfd	fp5,FPR_PARMS+32(r1)
Packit 6c4009
	lfd	fp6,FPR_PARMS+40(r1)
Packit 6c4009
	lfd	fp7,FPR_PARMS+48(r1)
Packit 6c4009
	lfd	fp8,FPR_PARMS+56(r1)
Packit 6c4009
	lfd	fp9,FPR_PARMS+64(r1)
Packit 6c4009
	lfd	fp10,FPR_PARMS+72(r1)
Packit 6c4009
	lfd	fp11,FPR_PARMS+80(r1)
Packit 6c4009
	lfd	fp12,FPR_PARMS+88(r1)
Packit 6c4009
	lfd	fp13,FPR_PARMS+96(r1)
Packit 6c4009
/* Unwind the stack frame, and jump.  */
Packit 6c4009
	ld	r31,FRAME_SIZE-8(r1)
Packit 6c4009
	ld	r30,FRAME_SIZE-16(r1)
Packit 6c4009
	addi	r1,r1,FRAME_SIZE
Packit 6c4009
	bctr
Packit 6c4009
Packit 6c4009
L(do_pltexit):
Packit 6c4009
	la	r10,(VR_PARMS+0)(r1)
Packit 6c4009
	la	r9,(VR_PARMS+16)(r1)
Packit 6c4009
	beq	L(restoreFXR2)
Packit 6c4009
	li	r11,32
Packit 6c4009
	li	r12,64
Packit 6c4009
	lvx	v2,0,r10
Packit 6c4009
	lvx	v3,0,r9
Packit 6c4009
Packit 6c4009
	lvx	v4,r11,r10
Packit 6c4009
	lvx	v5,r11,r9
Packit 6c4009
	addi	r11,r11,64
Packit 6c4009
Packit 6c4009
	lvx	v6,r12,r10
Packit 6c4009
	lvx	v7,r12,r9
Packit 6c4009
	addi	r12,r12,64
Packit 6c4009
Packit 6c4009
	lvx	v8,r11,r10
Packit 6c4009
	lvx	v9,r11,r9
Packit 6c4009
	addi	r11,r11,64
Packit 6c4009
Packit 6c4009
	lvx	v10,r12,r10
Packit 6c4009
	lvx	v11,r12,r9
Packit 6c4009
Packit 6c4009
	lvx	v12,r11,r10
Packit 6c4009
	lvx	v13,r11,r9
Packit 6c4009
L(restoreFXR2):
Packit 6c4009
	ld	r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
Packit 6c4009
	ld	r10,INT_PARMS+56(r1)
Packit 6c4009
	ld	r9,INT_PARMS+48(r1)
Packit 6c4009
	ld	r8,INT_PARMS+40(r1)
Packit 6c4009
	ld	r7,INT_PARMS+32(r1)
Packit 6c4009
	mtlr	r0
Packit 6c4009
	ld	r6,INT_PARMS+24(r1)
Packit 6c4009
	ld	r5,INT_PARMS+16(r1)
Packit 6c4009
	ld	r4,INT_PARMS+8(r1)
Packit 6c4009
/* Prepare for calling the function returned by fixup.  */
Packit 6c4009
	std	r2,FRAME_TOC_SAVE(r1)
Packit 6c4009
	PPC64_LOAD_FUNCPTR r3
Packit 6c4009
	ld	r3,INT_PARMS+0(r1)
Packit 6c4009
/* Load the floating point registers.  */
Packit 6c4009
	lfd	fp1,FPR_PARMS+0(r1)
Packit 6c4009
	lfd	fp2,FPR_PARMS+8(r1)
Packit 6c4009
	lfd	fp3,FPR_PARMS+16(r1)
Packit 6c4009
	lfd	fp4,FPR_PARMS+24(r1)
Packit 6c4009
	lfd	fp5,FPR_PARMS+32(r1)
Packit 6c4009
	lfd	fp6,FPR_PARMS+40(r1)
Packit 6c4009
	lfd	fp7,FPR_PARMS+48(r1)
Packit 6c4009
	lfd	fp8,FPR_PARMS+56(r1)
Packit 6c4009
	lfd	fp9,FPR_PARMS+64(r1)
Packit 6c4009
	lfd	fp10,FPR_PARMS+72(r1)
Packit 6c4009
	lfd	fp11,FPR_PARMS+80(r1)
Packit 6c4009
	lfd	fp12,FPR_PARMS+88(r1)
Packit 6c4009
	lfd	fp13,FPR_PARMS+96(r1)
Packit 6c4009
/* Call the target function.  */
Packit 6c4009
	bctrl
Packit 6c4009
	ld	r2,FRAME_TOC_SAVE(r1)
Packit 6c4009
	lwz	r12,VR_VRSAVE(r1)
Packit 6c4009
/* But return here and store the return values.  */
Packit 6c4009
	std	r3,INT_RTN(r1)
Packit 6c4009
	std	r4,INT_RTN+8(r1)
Packit 6c4009
	stfd	fp1,FPR_RTN+0(r1)
Packit 6c4009
	stfd	fp2,FPR_RTN+8(r1)
Packit 6c4009
	cmpdi	cr0,r12,0
Packit 6c4009
	la	r10,VR_RTN(r1)
Packit 6c4009
	stfd	fp3,FPR_RTN+16(r1)
Packit 6c4009
	stfd	fp4,FPR_RTN+24(r1)
Packit 6c4009
#if _CALL_ELF == 2
Packit 6c4009
	la	r12,VR_RTN+16(r1)
Packit 6c4009
	stfd	fp5,FPR_RTN+32(r1)
Packit 6c4009
	stfd	fp6,FPR_RTN+40(r1)
Packit 6c4009
	li	r5,32
Packit 6c4009
	li	r6,64
Packit 6c4009
	stfd	fp7,FPR_RTN+48(r1)
Packit 6c4009
	stfd	fp8,FPR_RTN+56(r1)
Packit 6c4009
	stfd	fp9,FPR_RTN+64(r1)
Packit 6c4009
	stfd	fp10,FPR_RTN+72(r1)
Packit 6c4009
#endif
Packit 6c4009
	mr	r3,r31
Packit 6c4009
	mr	r4,r30
Packit 6c4009
	beq	L(callpltexit)
Packit 6c4009
	stvx	v2,0,r10
Packit 6c4009
#if _CALL_ELF == 2
Packit 6c4009
	stvx	v3,0,r12
Packit 6c4009
	stvx	v4,r5,r10
Packit 6c4009
	stvx	v5,r5,r12
Packit 6c4009
	addi	r5,r5,64
Packit 6c4009
	stvx	v6,r6,r10
Packit 6c4009
	stvx	v7,r6,r12
Packit 6c4009
	stvx	v8,r5,r10
Packit 6c4009
	stvx	v9,r5,r12
Packit 6c4009
#endif
Packit 6c4009
L(callpltexit):
Packit 6c4009
	addi	r5,r1,INT_PARMS
Packit 6c4009
	addi	r6,r1,INT_RTN
Packit 6c4009
	bl	JUMPTARGET(_dl_call_pltexit)
Packit 6c4009
#ifndef SHARED
Packit 6c4009
	nop
Packit 6c4009
#endif
Packit 6c4009
/* Restore the return values from target function.  */
Packit 6c4009
	lwz	r12,VR_VRSAVE(r1)
Packit 6c4009
	ld	r3,INT_RTN(r1)
Packit 6c4009
	ld	r4,INT_RTN+8(r1)
Packit 6c4009
	lfd	fp1,FPR_RTN+0(r1)
Packit 6c4009
	lfd	fp2,FPR_RTN+8(r1)
Packit 6c4009
	cmpdi	cr0,r12,0
Packit 6c4009
	la	r11,VR_RTN(r1)
Packit 6c4009
	lfd	fp3,FPR_RTN+16(r1)
Packit 6c4009
	lfd	fp4,FPR_RTN+24(r1)
Packit 6c4009
#if _CALL_ELF == 2
Packit 6c4009
	la	r12,VR_RTN+16(r1)
Packit 6c4009
	lfd	fp5,FPR_RTN+32(r1)
Packit 6c4009
	lfd	fp6,FPR_RTN+40(r1)
Packit 6c4009
	li	r30,32
Packit 6c4009
	li	r31,64
Packit 6c4009
	lfd	fp7,FPR_RTN+48(r1)
Packit 6c4009
	lfd	fp8,FPR_RTN+56(r1)
Packit 6c4009
	lfd	fp9,FPR_RTN+64(r1)
Packit 6c4009
	lfd	fp10,FPR_RTN+72(r1)
Packit 6c4009
#endif
Packit 6c4009
	beq	L(pltexitreturn)
Packit 6c4009
	lvx	v2,0,r11
Packit 6c4009
#if _CALL_ELF == 2
Packit 6c4009
	lvx	v3,0,r12
Packit 6c4009
	lvx	v4,r30,r11
Packit 6c4009
	lvx	v5,r30,r12
Packit 6c4009
	addi	r30,r30,64
Packit 6c4009
	lvx	v6,r31,r11
Packit 6c4009
	lvx	v7,r31,r12
Packit 6c4009
	lvx	v8,r30,r11
Packit 6c4009
	lvx	v9,r30,r12
Packit 6c4009
#endif
Packit 6c4009
L(pltexitreturn):
Packit 6c4009
	ld	r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
Packit 6c4009
	ld	r31,FRAME_SIZE-8(r1)
Packit 6c4009
	ld	r30,FRAME_SIZE-16(r1)
Packit 6c4009
	mtlr	r0
Packit 6c4009
	ld	r1,0(r1)
Packit 6c4009
	blr
Packit 6c4009
END(_dl_profile_resolve)
Packit 6c4009
#endif