/* PLT trampolines. hppa version.
   Copyright (C) 2005-2014 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library.  If not, see
   <http://www.gnu.org/licenses/>.  */

#include <sysdep.h>

/* This code gets called via the .plt stub, and is used in
   dl-runtime.c to call the `_dl_fixup' function and then redirect
   to the address it returns. `_dl_fixup' takes two arguments, however
   `_dl_profile_fixup' takes a number of parameters for use with
   library auditing (LA).

   WARNING: This template is also used by gcc's __cffc, and expects
   that the "bl" for _dl_runtime_resolve exist at a particular offset.
   Do not change this template without changing gcc, while the prefix
   "bl" should fix everything so gcc finds the right spot, it will
   slow down __cffc when it attempts to call fixup to resolve function
   descriptor references. Please refer to gcc/gcc/config/pa/fptr.c

   Enter with r19 = reloc offset, r20 = got-8, r21 = fixup ltp.  */

	/* RELOCATION MARKER: bl to provide gcc's __cffc with fixup loc. */
	.text
	/* THIS CODE DOES NOT EXECUTE */
	bl	_dl_fixup, %r2
        .text
        .global _dl_runtime_resolve
        .type _dl_runtime_resolve,@function
	cfi_startproc
        .align 4
_dl_runtime_resolve:
        .PROC
        .CALLINFO FRAME=128,CALLS,SAVE_RP,ENTRY_GR=3
        .ENTRY
        /* SAVE_RP says we do */
        stw	%rp, -20(%sp)

	/* Save static link register */
	stw	%r29,-16(%sp)
 	/* Save argument registers */
	stw	%r26,-36(%sp)
	stw	%r25,-40(%sp)
	stw	%r24,-44(%sp)
	stw	%r23,-48(%sp)

	/* Build a call frame, and save structure pointer. */
	copy	%sp, %r1	/* Copy previous sp */
	/* Save function result address (on entry) */
	stwm	%r28,128(%sp)
	/* Fillin some frame info to follow ABI */
	stw	%r1,-4(%sp)	/* Previous sp */
	stw	%r21,-32(%sp)	/* PIC register value */

	/* Save input floating point registers. This must be done
	   in the new frame since the previous frame doesn't have
	   enough space */
	ldo	-56(%sp),%r1
	fstd,ma	%fr4,-8(%r1)
	fstd,ma	%fr5,-8(%r1)
	fstd,ma	%fr6,-8(%r1)
	fstd,ma	%fr7,-8(%r1)

 	/* Set up args to fixup func, needs only two arguments  */
	ldw	8+4(%r20),%r26		/* (1) got[1] == struct link_map */
	copy	%r19,%r25		/* (2) reloc offset  */

 	/* Call the real address resolver. */
	bl	_dl_fixup,%rp
	copy	%r21,%r19		/* set fixup func ltp */

	/* Load up the returned func descriptor */
	copy	%r28, %r22
	copy	%r29, %r19

	/* Reload arguments fp args */
	ldo	-56(%sp),%r1
	fldd,ma	-8(%r1),%fr4
	fldd,ma	-8(%r1),%fr5
	fldd,ma	-8(%r1),%fr6
	fldd,ma	-8(%r1),%fr7

	/* Adjust sp, and restore function result address*/
	ldwm	-128(%sp),%r28

	/* Reload static link register */
	ldw	-16(%sp),%r29
	/* Reload general args */
	ldw	-36(%sp),%r26
	ldw	-40(%sp),%r25
	ldw	-44(%sp),%r24
	ldw	-48(%sp),%r23

	/* Jump to new function, but return to previous function */
	bv	%r0(%r22)
	ldw	-20(%sp),%rp
        .EXIT
        .PROCEND
	cfi_endproc
	.size   _dl_runtime_resolve, . - _dl_runtime_resolve

        .text
        .global _dl_runtime_profile
        .type _dl_runtime_profile,@function
	cfi_startproc
        .align 4
_dl_runtime_profile:
        .PROC
        .CALLINFO FRAME=192,CALLS,SAVE_RP,ENTRY_GR=3
        .ENTRY

        /* SAVE_RP says we do */
        stw	%rp, -20(%sp)
	/* Save static link register */
	stw	%r29,-16(%sp)

	/* Build a call frame, and save structure pointer. */
	copy	%sp, %r1	/* Copy previous sp */
	/* Save function result address (on entry) */
	stwm	%r28,192(%sp)
	/* Fillin some frame info to follow ABI */
	stw	%r1,-4(%sp)	/* Previous sp */
	stw	%r21,-32(%sp)	/* PIC register value */

	/* Create La_hppa_retval */
	/* -140, lrv_r28
           -136, lrv_r29
           -132, 4 byte pad
           -128, lr_fr4 (8 bytes) */

	/* Create save space for _dl_profile_fixup arguments
	   -120, Saved reloc offset
	   -116, Saved struct link_map
	   -112, *framesizep */

	/* Create La_hppa_regs */
	/* 32-bit registers */
	stw	%r26,-108(%sp)
	stw	%r25,-104(%sp)
	stw	%r24,-100(%sp)
	stw	%r23,-96(%sp)
	/* -92, 4 byte pad */
	/* 64-bit floating point registers */
	ldo	-88(%sp),%r1
	fstd,ma	%fr4,8(%r1)
	fstd,ma	%fr5,8(%r1)
	fstd,ma	%fr6,8(%r1)
	fstd,ma	%fr7,8(%r1)
	/* 32-bit stack pointer and return register */
	stw	%sp,-56(%sp)
	stw	%r2,-52(%sp)


 	/* Set up args to fixup func, needs five arguments  */
	ldw	8+4(%r20),%r26		/* (1) got[1] == struct link_map */
	stw	%r26,-116(%sp)		/* Save struct link_map */
	copy	%r19,%r25		/* (2) reloc offset  */
	stw	%r25,-120(%sp)		/* Save reloc offset */
	copy    %rp,%r24		/* (3) profile_fixup needs rp */
	ldo	-56(%sp),%r23		/* (4) La_hppa_regs */
	ldo	-112(%sp), %r1
	stw	%r1, -52(%sp)		/* (5) long int *framesizep */

 	/* Call the real address resolver. */
	bl	_dl_profile_fixup,%rp
	copy	%r21,%r19		/* set fixup func ltp */

	/* Load up the returned function descriptor */
	copy	%r28, %r22
	copy	%r29, %r19

	/* Restore gr/fr/sp/rp */
	ldw	-108(%sp),%r26
	ldw	-104(%sp),%r25
	ldw	-100(%sp),%r24
	ldw	-96(%sp),%r23
	/* -92, 4 byte pad, skip */
	ldo	-88(%sp),%r1
	fldd,ma	8(%r1),%fr4
	fldd,ma	8(%r1),%fr5
	fldd,ma	8(%r1),%fr6
	fldd,ma	8(%r1),%fr7
	ldw	-52(%sp),%rp

	/* Reload static link register -(192+16) without adjusting stack */
	ldw	-208(%sp),%r29

	/* *framesizep is >= 0 if we have to run pltexit */
	ldw	-112(%sp),%r28
	cmpb,>>=,N %r0,%r28,L(cpe)

	/* Adjust sp, and restore function result address*/
	ldwm	-192(%sp),%r28
	/* Jump to new function, but return to previous function */
	bv	%r0(%r22)
	ldw	-20(%sp),%rp
	/* NO RETURN */

L(nf):
	/* Call the returned function descriptor */
	bv	%r0(%r22)
	nop
	b,n	L(cont)

L(cpe):
	/* We are going to call the resolved function, but we have a
	   stack frame in the middle. We use the value of framesize to
	   guess how much extra frame we need, and how much frame to
	   copy forward. */

	/* Round to nearest multiple of 64 */
	addi	63, %r28, %r28
	depi	0, 27, 6, %r28

	/* Calcualte start of stack copy */
	ldo	-192(%sp),%r2

	/* Increate the stack by *framesizep */
	copy	%sp, %r1
	add	%sp, %r28, %sp
	/* Save stack pointer */
	stw	%r1, -4(%sp)

	/* Single byte copy of prevous stack onto newly allocated stack */
1:	ldb	%r28(%r2), %r1
	add	%r28, %sp, %r26
	stb	%r1, 0(%r26)
	addi,<	-1,%r28,%r28
	b,n	1b

	/* Retore r28 and r27 and r2 already points at -192(%sp) */
	ldw	0(%r2),%r28
	ldw	84(%r2),%r26

	/* Calculate address of L(cont) */
	b,l	L(nf),%r2
	depwi 0,31,2,%r2
L(cont):
	/* Undo fake stack */
	ldw	-4(%sp),%r1
	copy	%r1, %sp

	/* Arguments to _dl_call_pltexit */
	ldw	-116(%sp), %r26		/* (1) got[1] == struct link_map */
	ldw 	-120(%sp), %r25		/* (2) reloc offsets */
	ldo	-56(%sp), %r24		/* (3) *La_hppa_regs */
	ldo	-124(%sp), %r23		/* (4) *La_hppa_retval */

	/* Fill *La_hppa_retval */
	stw	%r28,-140(%sp)
	stw	%r29,-136(%sp)
	ldo	-128(%sp), %r1
	fstd	%fr4,0(%r1)

	/* Call _dl_call_pltexit */
	bl	_dl_call_pltexit,%rp
	nop

	/* Restore *La_hppa_retval */
	ldw	-140(%sp), %r28
	ldw	-136(%sp), %r29
	ldo	-128(%sp), %r1
	fldd	0(%r1), %fr4

	/* Unwind the stack */
	ldo	192(%sp),%sp
	/* Retore callers rp */
        ldw -20(%sp),%rp
	/* Return */
	bv,n	0(%r2)
        .EXIT
        .PROCEND
	cfi_endproc
	.size   _dl_runtime_profile, . - _dl_runtime_profile

