diff options
author | Thomas Schwinge <thomas@codesourcery.com> | 2013-12-20 09:29:29 +0100 |
---|---|---|
committer | Thomas Schwinge <thomas@codesourcery.com> | 2013-12-20 09:29:29 +0100 |
commit | a65dd355fb80a05215e15ae97649de52aec885e3 (patch) | |
tree | 81701bb0c6b648630f2bf1729a85d7f5eb49e67b /sysdeps/powerpc/powerpc64/dl-trampoline.S | |
parent | 296a5732f94abe4d5699dc981e4ccfb950b48cee (diff) | |
parent | b4578bab30f72cddd2cf38abfb39f9c8dc892249 (diff) |
Merge branch 'baseline' into refs/top-bases/tschwinge/Roger_Whittaker
Diffstat (limited to 'sysdeps/powerpc/powerpc64/dl-trampoline.S')
-rw-r--r-- | sysdeps/powerpc/powerpc64/dl-trampoline.S | 195 |
1 files changed, 120 insertions, 75 deletions
diff --git a/sysdeps/powerpc/powerpc64/dl-trampoline.S b/sysdeps/powerpc/powerpc64/dl-trampoline.S index 4dde2763a3..69ce523e90 100644 --- a/sysdeps/powerpc/powerpc64/dl-trampoline.S +++ b/sysdeps/powerpc/powerpc64/dl-trampoline.S @@ -26,13 +26,13 @@ parm1 (r3) and the index (r0) need to be converted to an offset (index * 24) in parm2 (r4). */ -#define FRAME_SIZE 176 +#define FRAME_SIZE (FRAME_MIN_SIZE+64) /* We need to save the registers used to pass parameters, ie. r3 thru r10; Use local var space rather than the parameter save area, because gcc as of 2010/05 doesn't allocate a proper stack frame for a function that makes no calls except for __tls_get_addr and we might be here resolving the __tls_get_addr call. */ -#define INT_PARMS 112 +#define INT_PARMS FRAME_MIN_SIZE EALIGN(_dl_runtime_resolve, 4, 0) stdu r1,-FRAME_SIZE(r1) cfi_adjust_cfa_offset (FRAME_SIZE) @@ -48,36 +48,31 @@ EALIGN(_dl_runtime_resolve, 4, 0) mflr r0 std r8,INT_PARMS+40(r1) /* Store the LR in the LR Save area. */ - std r0,FRAME_SIZE+16(r1) - cfi_offset (lr, 16) - mfcr r0 + std r0,FRAME_SIZE+FRAME_LR_SAVE(r1) + cfi_offset (lr, FRAME_LR_SAVE) std r9,INT_PARMS+48(r1) std r10,INT_PARMS+56(r1) -/* I'm almost certain we don't have to save cr... be safe. */ - std r0,FRAME_SIZE+8(r1) bl JUMPTARGET(_dl_fixup) #ifndef SHARED nop #endif /* Put the registers back. */ - ld r0,FRAME_SIZE+16(r1) + ld r0,FRAME_SIZE+FRAME_LR_SAVE(r1) ld r10,INT_PARMS+56(r1) ld r9,INT_PARMS+48(r1) ld r8,INT_PARMS+40(r1) ld r7,INT_PARMS+32(r1) mtlr r0 - ld r0,FRAME_SIZE+8(r1) ld r6,INT_PARMS+24(r1) ld r5,INT_PARMS+16(r1) ld r4,INT_PARMS+8(r1) - mtcrf 0xFF,r0 -/* Load the target address, toc and static chain reg from the function - descriptor returned by fixup. */ - ld r0,0(r3) - ld r2,8(r3) - mtctr r0 - ld r11,16(r3) +/* Prepare for calling the function returned by fixup. */ + PPC64_LOAD_FUNCPTR r3 ld r3,INT_PARMS+0(r1) +#if _CALL_ELF == 2 +/* Restore the caller's TOC in case we jump to a local entry point. */ + ld r2,FRAME_SIZE+FRAME_TOC_SAVE(r1) +#endif /* Unwind the stack frame, and jump. */ addi r1,r1,FRAME_SIZE bctr @@ -85,17 +80,30 @@ END(_dl_runtime_resolve) #undef FRAME_SIZE #undef INT_PARMS - /* Stack layout: - +592 previous backchain - +584 spill_r31 - +576 spill_r30 - +560 v1 - +552 fp4 - +544 fp3 - +536 fp2 - +528 fp1 - +520 r4 - +512 r3 + /* Stack layout: ELFv2 ABI. + +752 previous backchain + +744 spill_r31 + +736 spill_r30 + +720 v8 + +704 v7 + +688 v6 + +672 v5 + +656 v4 + +640 v3 + +624 v2 + +608 v1 + +600 fp10 + ELFv1 ABI +592 fp9 + +592 previous backchain +584 fp8 + +584 spill_r31 +576 fp7 + +576 spill_r30 +568 fp6 + +560 v1 +560 fp5 + +552 fp4 +552 fp4 + +544 fp3 +544 fp3 + +536 fp2 +536 fp2 + +528 fp1 +528 fp1 + +520 r4 +520 r4 + +512 r3 +512 r3 return values +504 free +496 stackframe @@ -147,18 +155,24 @@ END(_dl_runtime_resolve) +64 parm3 +56 parm2 +48 parm1 - * Parameter save area, Allocated by the call, at least 8 double words - +40 TOC save area - +32 Reserved for linker - +24 Reserved for compiler + * Parameter save area + * (v1 ABI: Allocated by the call, at least 8 double words) + +40 v1 ABI: TOC save area + +32 v1 ABI: Reserved for linker + +24 v1 ABI: Reserved for compiler / v2 ABI: TOC save area +16 LR save area +8 CR save area r1+0 stack back chain */ -#define FRAME_SIZE 592 +#if _CALL_ELF == 2 +# define FRAME_SIZE 752 +# define VR_RTN 608 +#else +# define FRAME_SIZE 592 +# define VR_RTN 560 +#endif #define INT_RTN 512 #define FPR_RTN 528 -#define VR_RTN 560 #define STACK_FRAME 496 #define CALLING_LR 488 #define CALLING_SP 480 @@ -203,18 +217,14 @@ EALIGN(_dl_profile_resolve, 4, 0) mflr r5 std r7,INT_PARMS+32(r1) std r8,INT_PARMS+40(r1) -/* Store the LR in the LR Save area of the previous frame. */ -/* XXX Do we have to do this? */ +/* Store the LR in the LR Save area. */ la r8,FRAME_SIZE(r1) - std r5,FRAME_SIZE+16(r1) - cfi_offset (lr, 16) + std r5,FRAME_SIZE+FRAME_LR_SAVE(r1) + cfi_offset (lr, FRAME_LR_SAVE) std r5,CALLING_LR(r1) - mfcr r0 std r9,INT_PARMS+48(r1) std r10,INT_PARMS+56(r1) std r8,CALLING_SP(r1) -/* I'm almost certain we don't have to save cr... be safe. */ - std r0,FRAME_SIZE+8(r1) ld r12,.LC__dl_hwcap@toc(r2) #ifdef SHARED /* Load _rtld_local_ro._dl_hwcap. */ @@ -311,24 +321,22 @@ L(saveFP): lvx v12,r11,r10 lvx v13,r11,r9 L(restoreFXR): - ld r0,FRAME_SIZE+16(r1) + ld r0,FRAME_SIZE+FRAME_LR_SAVE(r1) ld r10,INT_PARMS+56(r1) ld r9,INT_PARMS+48(r1) ld r8,INT_PARMS+40(r1) ld r7,INT_PARMS+32(r1) mtlr r0 - ld r0,FRAME_SIZE+8(r1) ld r6,INT_PARMS+24(r1) ld r5,INT_PARMS+16(r1) ld r4,INT_PARMS+8(r1) - mtcrf 0xFF,r0 -/* Load the target address, toc and static chain reg from the function - descriptor returned by fixup. */ - ld r0,0(r3) - ld r2,8(r3) - ld r11,16(r3) +/* Prepare for calling the function returned by fixup. */ + PPC64_LOAD_FUNCPTR r3 ld r3,INT_PARMS+0(r1) - mtctr r0 +#if _CALL_ELF == 2 +/* Restore the caller's TOC in case we jump to a local entry point. */ + ld r2,FRAME_SIZE+FRAME_TOC_SAVE(r1) +#endif /* Load the floating point registers. */ lfd fp1,FPR_PARMS+0(r1) lfd fp2,FPR_PARMS+8(r1) @@ -344,10 +352,11 @@ L(restoreFXR): lfd fp12,FPR_PARMS+88(r1) lfd fp13,FPR_PARMS+96(r1) /* Unwind the stack frame, and jump. */ - ld r31,584(r1) - ld r30,576(r1) + ld r31,FRAME_SIZE-8(r1) + ld r30,FRAME_SIZE-16(r1) addi r1,r1,FRAME_SIZE bctr + L(do_pltexit): la r10,(VR_PARMS+0)(r1) la r9,(VR_PARMS+16)(r1) @@ -375,25 +384,19 @@ L(do_pltexit): lvx v12,r11,r10 lvx v13,r11,r9 L(restoreFXR2): - ld r0,FRAME_SIZE+16(r1) + ld r0,FRAME_SIZE+FRAME_LR_SAVE(r1) ld r10,INT_PARMS+56(r1) ld r9,INT_PARMS+48(r1) ld r8,INT_PARMS+40(r1) ld r7,INT_PARMS+32(r1) mtlr r0 - ld r0,FRAME_SIZE+8(r1) ld r6,INT_PARMS+24(r1) ld r5,INT_PARMS+16(r1) ld r4,INT_PARMS+8(r1) - mtcrf 0xFF,r0 -/* Load the target address, toc and static chain reg from the function - descriptor returned by fixup. */ - ld r0,0(r3) - std r2,40(r1) - ld r2,8(r3) - ld r11,16(r3) +/* Prepare for calling the function returned by fixup. */ + std r2,FRAME_TOC_SAVE(r1) + PPC64_LOAD_FUNCPTR r3 ld r3,INT_PARMS+0(r1) - mtctr r0 /* Load the floating point registers. */ lfd fp1,FPR_PARMS+0(r1) lfd fp2,FPR_PARMS+8(r1) @@ -410,21 +413,42 @@ L(restoreFXR2): lfd fp13,FPR_PARMS+96(r1) /* Call the target function. */ bctrl - ld r2,40(r1) + ld r2,FRAME_TOC_SAVE(r1) lwz r12,VR_VRSAVE(r1) /* But return here and store the return values. */ std r3,INT_RTN(r1) std r4,INT_RTN+8(r1) - stfd fp1,FPR_PARMS+0(r1) - stfd fp2,FPR_PARMS+8(r1) + stfd fp1,FPR_RTN+0(r1) + stfd fp2,FPR_RTN+8(r1) cmpdi cr0,r12,0 la r10,VR_RTN(r1) - stfd fp3,FPR_PARMS+16(r1) - stfd fp4,FPR_PARMS+24(r1) + stfd fp3,FPR_RTN+16(r1) + stfd fp4,FPR_RTN+24(r1) +#if _CALL_ELF == 2 + la r12,VR_RTN+16(r1) + stfd fp5,FPR_RTN+32(r1) + stfd fp6,FPR_RTN+40(r1) + li r5,32 + li r6,64 + stfd fp7,FPR_RTN+48(r1) + stfd fp8,FPR_RTN+56(r1) + stfd fp9,FPR_RTN+64(r1) + stfd fp10,FPR_RTN+72(r1) +#endif mr r3,r31 mr r4,r30 beq L(callpltexit) stvx v2,0,r10 +#if _CALL_ELF == 2 + stvx v3,0,r12 + stvx v4,r5,r10 + stvx v5,r5,r12 + addi r5,r5,64 + stvx v6,r6,r10 + stvx v7,r6,r12 + stvx v8,r5,r10 + stvx v9,r5,r12 +#endif L(callpltexit): addi r5,r1,INT_PARMS addi r6,r1,INT_RTN @@ -436,18 +460,39 @@ L(callpltexit): lwz r12,VR_VRSAVE(r1) ld r3,INT_RTN(r1) ld r4,INT_RTN+8(r1) - lfd fp1,FPR_PARMS+0(r1) - lfd fp2,FPR_PARMS+8(r1) + lfd fp1,FPR_RTN+0(r1) + lfd fp2,FPR_RTN+8(r1) cmpdi cr0,r12,0 - la r10,VR_RTN(r1) - lfd fp3,FPR_PARMS+16(r1) - lfd fp4,FPR_PARMS+24(r1) + la r11,VR_RTN(r1) + lfd fp3,FPR_RTN+16(r1) + lfd fp4,FPR_RTN+24(r1) +#if _CALL_ELF == 2 + la r12,VR_RTN+16(r1) + lfd fp5,FPR_RTN+32(r1) + lfd fp6,FPR_RTN+40(r1) + li r30,32 + li r31,64 + lfd fp7,FPR_RTN+48(r1) + lfd fp8,FPR_RTN+56(r1) + lfd fp9,FPR_RTN+64(r1) + lfd fp10,FPR_RTN+72(r1) +#endif beq L(pltexitreturn) - lvx v2,0,r10 + lvx v2,0,r11 +#if _CALL_ELF == 2 + lvx v3,0,r12 + lvx v4,r30,r11 + lvx v5,r30,r12 + addi r30,r30,64 + lvx v6,r31,r11 + lvx v7,r31,r12 + lvx v8,r30,r11 + lvx v9,r30,r12 +#endif L(pltexitreturn): - ld r0,FRAME_SIZE+16(r1) - ld r31,584(r1) - ld r30,576(r1) + ld r0,FRAME_SIZE+FRAME_LR_SAVE(r1) + ld r31,FRAME_SIZE-8(r1) + ld r30,FRAME_SIZE-16(r1) mtlr r0 ld r1,0(r1) blr |