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: stable/11/sys/mips/include/profile.h 352083 2019-09-09 17:37:52Z kevans $
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 \
47352083Skevans	__asm(".text;"			\
48352083Skevans	".globl _mcount;"		\
49178172Simp	".type _mcount,@function;"	\
50178172Simp	"_mcount:;"			\
51178172Simp	".set noreorder;"		\
52178172Simp	".set noat;"			\
53178172Simp	".cpload $25;"			\
54178172Simp	".cprestore 4;"			\
55178172Simp	"sw $4,8($29);"			\
56178172Simp	"sw $5,12($29);"		\
57178172Simp	"sw $6,16($29);"		\
58178172Simp	"sw $7,20($29);"		\
59178172Simp	"sw $1,0($29);"			\
60178172Simp	"sw $31,4($29);"		\
61178172Simp	"move $5,$31;"			\
62178172Simp	"jal ___mcount;"		\
63178172Simp	"move $4,$1;"			\
64178172Simp	"lw $4,8($29);"			\
65178172Simp	"lw $5,12($29);"		\
66178172Simp	"lw $6,16($29);"		\
67178172Simp	"lw $7,20($29);"		\
68178172Simp	"lw $31,4($29);"		\
69178172Simp	"lw $1,0($29);"			\
70178172Simp	"addu $29,$29,8;"		\
71178172Simp	"j $31;"			\
72178172Simp	"move $31,$1;"			\
73178172Simp	".set reorder;"			\
74178172Simp	".set at");
75178172Simp
76178172Simp#ifdef _KERNEL
77178172Simp/*
78178172Simp * The following two macros do splhigh and splx respectively.
79178172Simp * They have to be defined this way because these are real
80178172Simp * functions on the MIPS, and we do not want to invoke mcount
81178172Simp * recursively.
82178172Simp */
83178172Simp
84178172Simp#define	MCOUNT_DECL(s)	u_long s;
85178172Simp#ifdef SMP
86178172Simpextern int	mcount_lock;
87178172Simp#define	MCOUNT_ENTER(s)	{					\
88206717Sjmallett	s = intr_disable();					\
89178172Simp	while (!atomic_cmpset_acq_int(&mcount_lock, 0, 1))	\
90178172Simp		/* nothing */ ;					\
91178172Simp}
92178172Simp#define	MCOUNT_EXIT(s)	{					\
93178172Simp	atomic_store_rel_int(&mcount_lock, 0);			\
94206717Sjmallett	intr_restore(s);						\
95178172Simp}
96178172Simp#else
97206717Sjmallett#define	MCOUNT_ENTER(s)	{ s = intr_disable(); }
98206717Sjmallett#define	MCOUNT_EXIT(s)	(intr_restore(s))
99178172Simp#endif
100178172Simp
101178172Simp/* REVISIT for mips */
102178172Simp/*
103178172Simp * Config generates something to tell the compiler to align functions on 16
104178172Simp * byte boundaries.  A strict alignment is good for keeping the tables small.
105178172Simp */
106178172Simp#define	FUNCTION_ALIGNMENT	16
107178172Simp
108178172Simp#ifdef GUPROF
109178172Simpstruct gmonparam;
110178172Simpvoid	stopguprof __P((struct gmonparam *p));
111178172Simp#else
112178172Simp#define	stopguprof(p)
113178172Simp#endif /* GUPROF */
114178172Simp
115178172Simp#else	/* !_KERNEL */
116178172Simp
117178172Simp#define	FUNCTION_ALIGNMENT	4
118178172Simp
119210606Sjchandra#ifdef __mips_n64
120210606Sjchandratypedef u_long	uintfptr_t;
121210606Sjchandra#else
122210606Sjchandratypedef u_int	uintfptr_t;
123210606Sjchandra#endif
124178172Simp
125178172Simp#endif /* _KERNEL */
126178172Simp
127178172Simp/*
128178172Simp * An unsigned integral type that can hold non-negative difference between
129178172Simp * function pointers.
130178172Simp */
131210606Sjchandra#ifdef __mips_n64
132210606Sjchandratypedef u_long	fptrdiff_t;
133210606Sjchandra#else
134178172Simptypedef u_int	fptrdiff_t;
135210606Sjchandra#endif
136178172Simp
137178172Simp#ifdef _KERNEL
138178172Simp
139178172Simpvoid	mcount(uintfptr_t frompc, uintfptr_t selfpc);
140178172Simp
141178172Simp#ifdef GUPROF
142178172Simpstruct gmonparam;
143178172Simp
144178172Simpvoid	nullfunc_loop_profiled(void);
145178172Simpvoid	nullfunc_profiled(void);
146178172Simpvoid	startguprof(struct gmonparam *p);
147178172Simpvoid	stopguprof(struct gmonparam *p);
148178172Simp#else
149178172Simp#define	startguprof(p)
150178172Simp#define	stopguprof(p)
151178172Simp#endif /* GUPROF */
152178172Simp
153178172Simp#else /* !_KERNEL */
154178172Simp
155178172Simp#include <sys/cdefs.h>
156178172Simp
157178172Simp__BEGIN_DECLS
158178172Simp#ifdef __GNUC__
159178172Simp#ifdef __ELF__
160178172Simpvoid	mcount(void) __asm(".mcount");
161178172Simp#else
162178172Simpvoid	mcount(void) __asm("mcount");
163178172Simp#endif
164178172Simp#endif
165178172Simpvoid	_mcount(uintfptr_t frompc, uintfptr_t selfpc);
166178172Simp__END_DECLS
167178172Simp
168178172Simp#endif /* _KERNEL */
169178172Simp
170178172Simp#ifdef GUPROF
171178172Simp/* XXX doesn't quite work outside kernel yet. */
172178172Simpextern int	cputime_bias;
173178172Simp
174178172Simp__BEGIN_DECLS
175178172Simpint	cputime(void);
176178172Simpvoid	empty_loop(void);
177178172Simpvoid	mexitcount(uintfptr_t selfpc);
178178172Simpvoid	nullfunc(void);
179178172Simpvoid	nullfunc_loop(void);
180178172Simp__END_DECLS
181178172Simp#endif
182178172Simp
183178172Simp#endif /* !_MACHINE_PROFILE_H_ */
184