1/*-
  2 * SPDX-License-Identifier: BSD-3-Clause
  3 *
  4 * Copyright (c) 1992, 1993
  5 *	The Regents of the University of California.  All rights reserved.
  6 *
  7 * Redistribution and use in source and binary forms, with or without
  8 * modification, are permitted provided that the following conditions
  9 * are met:
 10 * 1. Redistributions of source code must retain the above copyright
 11 *    notice, this list of conditions and the following disclaimer.
 12 * 2. Redistributions in binary form must reproduce the above copyright
 13 *    notice, this list of conditions and the following disclaimer in the
 14 *    documentation and/or other materials provided with the distribution.
 15 * 3. Neither the name of the University nor the names of its contributors
 16 *    may be used to endorse or promote products derived from this software
 17 *    without specific prior written permission.
 18 *
 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 29 * SUCH DAMAGE.
 30 *
 31 *	@(#)profile.h	8.1 (Berkeley) 6/11/93
 32 */
 33
 34#ifdef __i386__
 35#include <i386/profile.h>
 36#else /* !__i386__ */
 37
 38#ifndef _MACHINE_PROFILE_H_
 39#define	_MACHINE_PROFILE_H_
 40
 41#ifndef _KERNEL
 42
 43#include <sys/cdefs.h>
 44
 45#define	FUNCTION_ALIGNMENT	4
 46
 47#define	_MCOUNT_DECL \
 48static void _mcount(uintfptr_t frompc, uintfptr_t selfpc) __used; \
 49static void _mcount
 50
 51#define	MCOUNT __asm("			\n\
 52	.text				\n\
 53	.p2align 4,0x90			\n\
 54	.globl	.mcount			\n\
 55	.type	.mcount,@function	\n\
 56.mcount:				\n\
 57	pushq	%rdi			\n\
 58	pushq	%rsi			\n\
 59	pushq	%rdx			\n\
 60	pushq	%rcx			\n\
 61	pushq	%r8			\n\
 62	pushq	%r9			\n\
 63	pushq	%rax			\n\
 64	movq	8(%rbp),%rdi		\n\
 65	movq	7*8(%rsp),%rsi		\n\
 66	call	_mcount			\n\
 67	popq	%rax			\n\
 68	popq	%r9			\n\
 69	popq	%r8			\n\
 70	popq	%rcx			\n\
 71	popq	%rdx			\n\
 72	popq	%rsi			\n\
 73	popq	%rdi			\n\
 74	ret				\n\
 75	.size	.mcount, . - .mcount");
 76#if 0
 77/*
 78 * We could use this, except it doesn't preserve the registers that were
 79 * being passed with arguments to the function that we were inserted
 80 * into.  I've left it here as documentation of what the code above is
 81 * supposed to do.
 82 */
 83#define	MCOUNT								\
 84void									\
 85mcount()								\
 86{									\
 87	uintfptr_t selfpc, frompc;					\
 88	/*								\
 89	 * Find the return address for mcount,				\
 90	 * and the return address for mcount's caller.			\
 91	 *								\
 92	 * selfpc = pc pushed by call to mcount				\
 93	 */								\
 94	__asm("movq 8(%%rbp),%0" : "=r" (selfpc));			\
 95	/*								\
 96	 * frompc = pc pushed by call to mcount's caller.		\
 97	 * The caller's stack frame has already been built, so %rbp is	\
 98	 * the caller's frame pointer.  The caller's raddr is in the	\
 99	 * caller's frame following the caller's caller's frame pointer.\
100	 */								\
101	__asm("movq (%%rbp),%0" : "=r" (frompc));			\
102	frompc = ((uintfptr_t *)frompc)[1];				\
103	_mcount(frompc, selfpc);					\
104}
105#endif
106
107typedef	u_long	uintfptr_t;
108
109/*
110 * An unsigned integral type that can hold non-negative difference between
111 * function pointers.
112 */
113typedef	u_long	fptrdiff_t;
114
115__BEGIN_DECLS
116void	mcount(void) __asm(".mcount");
117__END_DECLS
118
119#endif /* !_KERNEL */
120
121#endif /* !_MACHINE_PROFILE_H_ */
122
123#endif /* __i386__ */