1178172Simp/*	$OpenBSD: profile.h,v 1.2 1999/01/27 04:46:05 imp Exp $ */
2178172Simp/*-
3178172Simp * Copyright (c) 1992, 1993
4178172Simp *	The Regents of the University of California.  All rights reserved.
5178172Simp *
6178172Simp * This code is derived from software contributed to Berkeley by
7178172Simp * Ralph Campbell.
8178172Simp *
9178172Simp * Redistribution and use in source and binary forms, with or without
10178172Simp * modification, are permitted provided that the following conditions
11178172Simp * are met:
12178172Simp * 1. Redistributions of source code must retain the above copyright
13178172Simp *    notice, this list of conditions and the following disclaimer.
14178172Simp * 2. Redistributions in binary form must reproduce the above copyright
15178172Simp *    notice, this list of conditions and the following disclaimer in the
16178172Simp *    documentation and/or other materials provided with the distribution.
17178172Simp * 4. Neither the name of the University nor the names of its contributors
18178172Simp *    may be used to endorse or promote products derived from this software
19178172Simp *    without specific prior written permission.
20178172Simp *
21178172Simp * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22178172Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23178172Simp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24178172Simp * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25178172Simp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26178172Simp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27178172Simp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28178172Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29178172Simp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30178172Simp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31178172Simp * SUCH DAMAGE.
32178172Simp *
33178172Simp *	from: @(#)profile.h	8.1 (Berkeley) 6/10/93
34178172Simp *	JNPR: profile.h,v 1.4 2006/12/02 09:53:41 katta
35178172Simp * $FreeBSD: releng/10.3/sys/mips/include/profile.h 210606 2010-07-29 14:04:29Z jchandra $
36178172Simp */
37178172Simp#ifndef _MACHINE_PROFILE_H_
38178172Simp#define	_MACHINE_PROFILE_H_
39178172Simp
40178172Simp#define	_MCOUNT_DECL void ___mcount
41178172Simp
42178172Simp/*XXX The cprestore instruction is a "dummy" to shut up as(1). */
43178172Simp
44202031Simp/*XXX This is not MIPS64 safe. */
45202031Simp
46178172Simp#define	MCOUNT \
47178172Simp	__asm(".globl _mcount;"		\
48178172Simp	".type _mcount,@function;"	\
49178172Simp	"_mcount:;"			\
50178172Simp	".set noreorder;"		\
51178172Simp	".set noat;"			\
52178172Simp	".cpload $25;"			\
53178172Simp	".cprestore 4;"			\
54178172Simp	"sw $4,8($29);"			\
55178172Simp	"sw $5,12($29);"		\
56178172Simp	"sw $6,16($29);"		\
57178172Simp	"sw $7,20($29);"		\
58178172Simp	"sw $1,0($29);"			\
59178172Simp	"sw $31,4($29);"		\
60178172Simp	"move $5,$31;"			\
61178172Simp	"jal ___mcount;"		\
62178172Simp	"move $4,$1;"			\
63178172Simp	"lw $4,8($29);"			\
64178172Simp	"lw $5,12($29);"		\
65178172Simp	"lw $6,16($29);"		\
66178172Simp	"lw $7,20($29);"		\
67178172Simp	"lw $31,4($29);"		\
68178172Simp	"lw $1,0($29);"			\
69178172Simp	"addu $29,$29,8;"		\
70178172Simp	"j $31;"			\
71178172Simp	"move $31,$1;"			\
72178172Simp	".set reorder;"			\
73178172Simp	".set at");
74178172Simp
75178172Simp#ifdef _KERNEL
76178172Simp/*
77178172Simp * The following two macros do splhigh and splx respectively.
78178172Simp * They have to be defined this way because these are real
79178172Simp * functions on the MIPS, and we do not want to invoke mcount
80178172Simp * recursively.
81178172Simp */
82178172Simp
83178172Simp#define	MCOUNT_DECL(s)	u_long s;
84178172Simp#ifdef SMP
85178172Simpextern int	mcount_lock;
86178172Simp#define	MCOUNT_ENTER(s)	{					\
87206717Sjmallett	s = intr_disable();					\
88178172Simp	while (!atomic_cmpset_acq_int(&mcount_lock, 0, 1))	\
89178172Simp		/* nothing */ ;					\
90178172Simp}
91178172Simp#define	MCOUNT_EXIT(s)	{					\
92178172Simp	atomic_store_rel_int(&mcount_lock, 0);			\
93206717Sjmallett	intr_restore(s);						\
94178172Simp}
95178172Simp#else
96206717Sjmallett#define	MCOUNT_ENTER(s)	{ s = intr_disable(); }
97206717Sjmallett#define	MCOUNT_EXIT(s)	(intr_restore(s))
98178172Simp#endif
99178172Simp
100178172Simp/* REVISIT for mips */
101178172Simp/*
102178172Simp * Config generates something to tell the compiler to align functions on 16
103178172Simp * byte boundaries.  A strict alignment is good for keeping the tables small.
104178172Simp */
105178172Simp#define	FUNCTION_ALIGNMENT	16
106178172Simp
107178172Simp#ifdef GUPROF
108178172Simpstruct gmonparam;
109178172Simpvoid	stopguprof __P((struct gmonparam *p));
110178172Simp#else
111178172Simp#define	stopguprof(p)
112178172Simp#endif /* GUPROF */
113178172Simp
114178172Simp#else	/* !_KERNEL */
115178172Simp
116178172Simp#define	FUNCTION_ALIGNMENT	4
117178172Simp
118210606Sjchandra#ifdef __mips_n64
119210606Sjchandratypedef u_long	uintfptr_t;
120210606Sjchandra#else
121210606Sjchandratypedef u_int	uintfptr_t;
122210606Sjchandra#endif
123178172Simp
124178172Simp#endif /* _KERNEL */
125178172Simp
126178172Simp/*
127178172Simp * An unsigned integral type that can hold non-negative difference between
128178172Simp * function pointers.
129178172Simp */
130210606Sjchandra#ifdef __mips_n64
131210606Sjchandratypedef u_long	fptrdiff_t;
132210606Sjchandra#else
133178172Simptypedef u_int	fptrdiff_t;
134210606Sjchandra#endif
135178172Simp
136178172Simp#ifdef _KERNEL
137178172Simp
138178172Simpvoid	mcount(uintfptr_t frompc, uintfptr_t selfpc);
139178172Simp
140178172Simp#ifdef GUPROF
141178172Simpstruct gmonparam;
142178172Simp
143178172Simpvoid	nullfunc_loop_profiled(void);
144178172Simpvoid	nullfunc_profiled(void);
145178172Simpvoid	startguprof(struct gmonparam *p);
146178172Simpvoid	stopguprof(struct gmonparam *p);
147178172Simp#else
148178172Simp#define	startguprof(p)
149178172Simp#define	stopguprof(p)
150178172Simp#endif /* GUPROF */
151178172Simp
152178172Simp#else /* !_KERNEL */
153178172Simp
154178172Simp#include <sys/cdefs.h>
155178172Simp
156178172Simp__BEGIN_DECLS
157178172Simp#ifdef __GNUC__
158178172Simp#ifdef __ELF__
159178172Simpvoid	mcount(void) __asm(".mcount");
160178172Simp#else
161178172Simpvoid	mcount(void) __asm("mcount");
162178172Simp#endif
163178172Simp#endif
164178172Simpvoid	_mcount(uintfptr_t frompc, uintfptr_t selfpc);
165178172Simp__END_DECLS
166178172Simp
167178172Simp#endif /* _KERNEL */
168178172Simp
169178172Simp#ifdef GUPROF
170178172Simp/* XXX doesn't quite work outside kernel yet. */
171178172Simpextern int	cputime_bias;
172178172Simp
173178172Simp__BEGIN_DECLS
174178172Simpint	cputime(void);
175178172Simpvoid	empty_loop(void);
176178172Simpvoid	mexitcount(uintfptr_t selfpc);
177178172Simpvoid	nullfunc(void);
178178172Simpvoid	nullfunc_loop(void);
179178172Simp__END_DECLS
180178172Simp#endif
181178172Simp
182178172Simp#endif /* !_MACHINE_PROFILE_H_ */
183