/* Machine-dependent definitions for profiling support.  AVR32 version.
   Copyright (C) 1996, 1997, 1998 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, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#define mcount_internal __mcount_internal

#define _MCOUNT_DECL(frompc, selfpc) \
static void __attribute((used)) mcount_internal(unsigned long frompc, unsigned long selfpc)

/*
 * This mcount implementation expects to get called after the prologue
 * has been run. It also expects that r7 contains a valid frame
 * pointer.
 *
 * When profiling, the compiler should generate something like this at
 * each function entry:
 *
 *	pushm	r0-r7,lr	// lr mandatory, others optional
 *	mov	r7, sp
 *	// rest of prologue goes here
 *	mcall	pc[.LC1 - .]
 *      // rest of function goes here
 * .LC1:
 *	.long	mcount
 *
 * or for PIC:
 *
 *	pushm	r0-r7,lr
 *	mov	r7, sp
 *	// rest of prologue goes here
 *	lddpc	r0, .LC1
 * .L1: rsub	r0, pc
 *	mcall	r0[mcount@GOT]
 *	// rest of function goes here
 * .LC1:
 *	.long	.L1 - _GLOBAL_OFFSET_TABLE_
 *
 * This way, when mcount() is called, r7 points to the calling
 * function's return address. It is guaranteed that calling mcount
 * will clobber no registers except LR, which is unavoidable.
 */
#define MCOUNT asm(				\
	"	.align	4\n"			\
	"	.global	_mcount\n"		\
	"	.type	_mcount,@function\n"	\
	"_mcount:\n"				\
	"	pushm	r8-r12,lr\n"		\
	"	mov	r11, lr\n"		\
	"	ld.w	r12, r7[0]\n"		\
	"	rcall	__mcount_internal\n"	\
	"	popm	r8-r12,pc\n"		\
	"	.size	_mcount, . - _mcount\n"	\
	"	.weak	mcount\n"		\
	"	mcount = _mcount");
