Blame sysdeps/powerpc/powerpc32/ppc-mcount.S

Packit 6c4009
/* PowerPC-specific implementation of profiling support.
Packit 6c4009
   Copyright (C) 1997-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
/* This would be bad.  */
Packit 6c4009
#ifdef PROF
Packit 6c4009
#undef PROF
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#include <sysdep.h>
Packit 6c4009
Packit 6c4009
/* We do profiling as described in the SYSV ELF ABI, except that glibc
Packit 6c4009
   _mcount manages its own counters.  The caller has put the address the
Packit 6c4009
   caller will return to in the usual place on the stack, 4(r1).  _mcount
Packit 6c4009
   is responsible for ensuring that when it returns no argument-passing
Packit 6c4009
   registers are disturbed, and that the LR is set back to (what the
Packit 6c4009
   caller sees as) 4(r1).
Packit 6c4009
Packit 6c4009
   This is intended so that the following code can be inserted at the
Packit 6c4009
   front of any routine without changing the routine:
Packit 6c4009
Packit 6c4009
	.data
Packit 6c4009
	mflr	r0
Packit 6c4009
	stw	r0,4(r1)
Packit 6c4009
	bl	_mcount
Packit 6c4009
*/
Packit 6c4009
Packit 6c4009
ENTRY(_mcount)
Packit 6c4009
#if defined PIC && !defined SHARED
Packit 6c4009
# define CALLER_LR_OFFSET 68
Packit 6c4009
	stwu	r1,-64(r1)
Packit 6c4009
	cfi_adjust_cfa_offset (64)
Packit 6c4009
	stw	r30, 48(r1)
Packit 6c4009
	cfi_rel_offset (r30, 48)
Packit 6c4009
#else
Packit 6c4009
# define CALLER_LR_OFFSET 52
Packit 6c4009
	stwu	r1,-48(r1)
Packit 6c4009
	cfi_adjust_cfa_offset (48)
Packit 6c4009
#endif
Packit 6c4009
/* We need to save the parameter-passing registers.  */
Packit 6c4009
	stw	r3, 12(r1)
Packit 6c4009
	stw	r4, 16(r1)
Packit 6c4009
	stw	r5, 20(r1)
Packit 6c4009
	stw	r6, 24(r1)
Packit 6c4009
	mflr	r4
Packit 6c4009
#if defined PIC && !defined SHARED
Packit 6c4009
	bcl	20,31,0f
Packit 6c4009
0:
Packit 6c4009
	mflr	r30
Packit 6c4009
	addis	r30, r30, _GLOBAL_OFFSET_TABLE_-0b@ha
Packit 6c4009
	addi	r30, r30, _GLOBAL_OFFSET_TABLE_-0b@l
Packit 6c4009
#endif
Packit 6c4009
	lwz	r3, CALLER_LR_OFFSET(r1)
Packit 6c4009
	mfcr	r5
Packit 6c4009
	stw	r7, 28(r1)
Packit 6c4009
	stw	r8, 32(r1)
Packit 6c4009
	stw	r9, 36(r1)
Packit 6c4009
	stw	r10,40(r1)
Packit 6c4009
	stw	r4, 44(r1)
Packit 6c4009
	cfi_rel_offset (lr, 44)
Packit 6c4009
	stw	r5,  8(r1)
Packit 6c4009
#ifndef SHARED
Packit 6c4009
	bl	JUMPTARGET(__mcount_internal)
Packit 6c4009
#else
Packit 6c4009
	bl	__mcount_internal@local
Packit 6c4009
#endif
Packit 6c4009
 /* Restore the registers...  */
Packit 6c4009
	lwz     r6,  8(r1)
Packit 6c4009
	lwz	r0, 44(r1)
Packit 6c4009
	lwz	r3, 12(r1)
Packit 6c4009
	mtctr	r0
Packit 6c4009
	lwz	r4, 16(r1)
Packit 6c4009
	mtcrf	0xff,r6
Packit 6c4009
	lwz	r5, 20(r1)
Packit 6c4009
	lwz	r6, 24(r1)
Packit 6c4009
	lwz	r0, CALLER_LR_OFFSET(r1)
Packit 6c4009
	lwz	r7, 28(r1)
Packit 6c4009
	lwz	r8, 32(r1)
Packit 6c4009
	mtlr	r0
Packit 6c4009
	lwz	r9, 36(r1)
Packit 6c4009
	lwz	r10,40(r1)
Packit 6c4009
 /* ...unwind the stack frame, and return to your usual programming.  */
Packit 6c4009
#if defined PIC && !defined SHARED
Packit 6c4009
	lwz	r30, 48(r1)
Packit 6c4009
	addi	r1,r1,64
Packit 6c4009
#else
Packit 6c4009
	addi	r1,r1,48
Packit 6c4009
#endif
Packit 6c4009
	bctr
Packit 6c4009
END(_mcount)