160727d8bSWarner Losh /*-
2796df753SPedro F. Giffuni * SPDX-License-Identifier: MIT-CMU
3796df753SPedro F. Giffuni *
4f48649e5SPeter Grehan * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
5f48649e5SPeter Grehan * All rights reserved.
6f48649e5SPeter Grehan *
7f48649e5SPeter Grehan * Author: Chris G. Demetriou
8f48649e5SPeter Grehan *
9f48649e5SPeter Grehan * Permission to use, copy, modify and distribute this software and
10f48649e5SPeter Grehan * its documentation is hereby granted, provided that both the copyright
11f48649e5SPeter Grehan * notice and this permission notice appear in all copies of the
12f48649e5SPeter Grehan * software, derivative works or modified versions, and any portions
13f48649e5SPeter Grehan * thereof, and that both notices appear in supporting documentation.
14f48649e5SPeter Grehan *
15f48649e5SPeter Grehan * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
16f48649e5SPeter Grehan * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
17f48649e5SPeter Grehan * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
18f48649e5SPeter Grehan *
19f48649e5SPeter Grehan * Carnegie Mellon requests users of this software to return to
20f48649e5SPeter Grehan *
21f48649e5SPeter Grehan * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
22f48649e5SPeter Grehan * School of Computer Science
23f48649e5SPeter Grehan * Carnegie Mellon University
24f48649e5SPeter Grehan * Pittsburgh PA 15213-3890
25f48649e5SPeter Grehan *
26f48649e5SPeter Grehan * any improvements or extensions that they make and grant Carnegie the
27f48649e5SPeter Grehan * rights to redistribute these changes.
28f48649e5SPeter Grehan *
29f48649e5SPeter Grehan * from: NetBSD: profile.h,v 1.9 1997/04/06 08:47:37 cgd Exp
30f48649e5SPeter Grehan * from: FreeBSD: src/sys/alpha/include/profile.h,v 1.4 1999/12/29
31f48649e5SPeter Grehan */
32f48649e5SPeter Grehan
33f48649e5SPeter Grehan #ifndef _MACHINE_PROFILE_H_
34f48649e5SPeter Grehan #define _MACHINE_PROFILE_H_
35f48649e5SPeter Grehan
36590ccf8cSPeter Grehan #define _MCOUNT_DECL void __mcount
37f48649e5SPeter Grehan
38cfbcffa2SMarcel Moolenaar #define FUNCTION_ALIGNMENT 4
39f48649e5SPeter Grehan
40c3e289e1SNathan Whitehorn typedef __ptrdiff_t fptrdiff_t;
41f48649e5SPeter Grehan
42590ccf8cSPeter Grehan /*
43590ccf8cSPeter Grehan * The mcount trampoline macro, expanded in libc/gmon/mcount.c
44590ccf8cSPeter Grehan *
45590ccf8cSPeter Grehan * For PowerPC SVR4 ABI profiling, the compiler will insert
46590ccf8cSPeter Grehan * a data declaration and code sequence at the start of a routine of the form
47590ccf8cSPeter Grehan *
48590ccf8cSPeter Grehan * .function_mc: .data
49590ccf8cSPeter Grehan * .align 2
50590ccf8cSPeter Grehan * .long 0
51590ccf8cSPeter Grehan * .text
52590ccf8cSPeter Grehan *
53590ccf8cSPeter Grehan * function: mflr %r0
54590ccf8cSPeter Grehan * addis %r11,%r0, .function_mc@ha
55590ccf8cSPeter Grehan * stw %r0,4(%r1)
56590ccf8cSPeter Grehan * addi %r0,%r11, .function_mc@l
57590ccf8cSPeter Grehan * bl _mcount
58590ccf8cSPeter Grehan *
59590ccf8cSPeter Grehan * The link register is saved in the LR save word in the caller's
60590ccf8cSPeter Grehan * stack frame, r0 is set up to point to the allocated longword,
61590ccf8cSPeter Grehan * and control is transferred to _mcount.
62590ccf8cSPeter Grehan *
63590ccf8cSPeter Grehan * On return from _mcount, the routine should function as it would
64590ccf8cSPeter Grehan * with no profiling so _mcount must restore register state to that upon
65590ccf8cSPeter Grehan * entry. Any routine called by the _mcount trampoline will save
66590ccf8cSPeter Grehan * callee-save registers, so _mcount must make sure it saves volatile
67590ccf8cSPeter Grehan * registers that may have state after it returns i.e. parameter registers.
68590ccf8cSPeter Grehan *
69590ccf8cSPeter Grehan * The FreeBSD libc mcount routine ignores the r0 longword pointer, but
70590ccf8cSPeter Grehan * instead requires as parameters the current PC and called PC. The current
71590ccf8cSPeter Grehan * PC is obtained from the link register, as a result of "bl _mcount" in
72590ccf8cSPeter Grehan * the stub, while the caller's PC is obtained from the LR save word.
73590ccf8cSPeter Grehan *
74590ccf8cSPeter Grehan * On return from libc mcount, the return is done indirectly with the
75590ccf8cSPeter Grehan * ctr register rather than the link register, to allow the link register
76590ccf8cSPeter Grehan * to be restored to what it was on entry to the profiled routine.
77590ccf8cSPeter Grehan */
78590ccf8cSPeter Grehan
79fd6820bbSNathan Whitehorn #if defined(__powerpc64__)
80fd6820bbSNathan Whitehorn
81fd6820bbSNathan Whitehorn #if !defined(_CALL_ELF) || _CALL_ELF == 1
82fd6820bbSNathan Whitehorn #define MCOUNT_PREAMBLE \
83c3e289e1SNathan Whitehorn " .align 2 \n" \
84c3e289e1SNathan Whitehorn " .globl _mcount \n" \
85c3e289e1SNathan Whitehorn " .section \".opd\",\"aw\" \n" \
86c3e289e1SNathan Whitehorn " .align 3 \n" \
87c3e289e1SNathan Whitehorn "_mcount: \n" \
8879c77d72SNathan Whitehorn " .quad .L._mcount,.TOC.@tocbase,0\n" \
89c3e289e1SNathan Whitehorn " .previous \n" \
9051a6f57eSNathan Whitehorn " .size _mcount,24 \n" \
9179c77d72SNathan Whitehorn " .type _mcount,@function \n" \
92c3e289e1SNathan Whitehorn " .align 4 \n" \
93fd6820bbSNathan Whitehorn ".L._mcount: \n"
94fd6820bbSNathan Whitehorn #else
95fd6820bbSNathan Whitehorn #define MCOUNT_PREAMBLE \
96fd6820bbSNathan Whitehorn " .globl _mcount \n" \
97fd6820bbSNathan Whitehorn " .type _mcount,@function \n" \
98fd6820bbSNathan Whitehorn " .align 4 \n" \
99fd6820bbSNathan Whitehorn "_mcount: \n"
100fd6820bbSNathan Whitehorn #endif
101fd6820bbSNathan Whitehorn
102fd6820bbSNathan Whitehorn #define MCOUNT \
103fd6820bbSNathan Whitehorn __asm( MCOUNT_PREAMBLE \
10479c77d72SNathan Whitehorn " stdu %r1,-(288+128)(%r1) \n" \
105c3e289e1SNathan Whitehorn " std %r3,48(%r1) \n" \
106c3e289e1SNathan Whitehorn " std %r4,56(%r1) \n" \
107c3e289e1SNathan Whitehorn " std %r5,64(%r1) \n" \
108c3e289e1SNathan Whitehorn " std %r6,72(%r1) \n" \
109c3e289e1SNathan Whitehorn " std %r7,80(%r1) \n" \
110c3e289e1SNathan Whitehorn " std %r8,88(%r1) \n" \
111c3e289e1SNathan Whitehorn " std %r9,96(%r1) \n" \
112c3e289e1SNathan Whitehorn " std %r10,104(%r1) \n" \
113c3e289e1SNathan Whitehorn " mflr %r4 \n" \
114c3e289e1SNathan Whitehorn " std %r4,112(%r1) \n" \
115c3e289e1SNathan Whitehorn " ld %r3,0(%r1) \n" \
116c3e289e1SNathan Whitehorn " ld %r3,0(%r3) \n" \
117c3e289e1SNathan Whitehorn " ld %r3,16(%r3) \n" \
11879c77d72SNathan Whitehorn " bl __mcount \n" \
119c3e289e1SNathan Whitehorn " nop \n" \
120c3e289e1SNathan Whitehorn " ld %r4,112(%r1) \n" \
121c3e289e1SNathan Whitehorn " mtlr %r4 \n" \
122c3e289e1SNathan Whitehorn " ld %r3,48(%r1) \n" \
123c3e289e1SNathan Whitehorn " ld %r4,56(%r1) \n" \
124c3e289e1SNathan Whitehorn " ld %r5,64(%r1) \n" \
125c3e289e1SNathan Whitehorn " ld %r6,72(%r1) \n" \
126c3e289e1SNathan Whitehorn " ld %r7,80(%r1) \n" \
127c3e289e1SNathan Whitehorn " ld %r8,88(%r1) \n" \
128c3e289e1SNathan Whitehorn " ld %r9,96(%r1) \n" \
129c3e289e1SNathan Whitehorn " ld %r10,104(%r1) \n" \
13079c77d72SNathan Whitehorn " addi %r1,%r1,(288+128) \n" \
131c3e289e1SNathan Whitehorn " blr \n");
132c3e289e1SNathan Whitehorn #else
133c3e289e1SNathan Whitehorn
134294246bbSEd Maste #ifdef PIC
135590ccf8cSPeter Grehan #define _PLT "@plt"
136590ccf8cSPeter Grehan #else
137590ccf8cSPeter Grehan #define _PLT
138590ccf8cSPeter Grehan #endif
139590ccf8cSPeter Grehan
140f48649e5SPeter Grehan #define MCOUNT \
141590ccf8cSPeter Grehan __asm( " .globl _mcount \n" \
142590ccf8cSPeter Grehan " .type _mcount,@function \n" \
143dc9d1684SMarcel Moolenaar " .align 4 \n" \
144590ccf8cSPeter Grehan "_mcount: \n" \
145dc9d1684SMarcel Moolenaar " stwu %r1,-64(%r1) \n" \
146dc9d1684SMarcel Moolenaar " stw %r3,16(%r1) \n" \
147dc9d1684SMarcel Moolenaar " stw %r4,20(%r1) \n" \
148590ccf8cSPeter Grehan " stw %r5,24(%r1) \n" \
149590ccf8cSPeter Grehan " stw %r6,28(%r1) \n" \
150590ccf8cSPeter Grehan " stw %r7,32(%r1) \n" \
151590ccf8cSPeter Grehan " stw %r8,36(%r1) \n" \
152590ccf8cSPeter Grehan " stw %r9,40(%r1) \n" \
153590ccf8cSPeter Grehan " stw %r10,44(%r1) \n" \
154dc9d1684SMarcel Moolenaar " mflr %r4 \n" \
155dc9d1684SMarcel Moolenaar " stw %r4,48(%r1) \n" \
156590ccf8cSPeter Grehan " lwz %r3,68(%r1) \n" \
157dc9d1684SMarcel Moolenaar " bl __mcount" _PLT " \n" \
158dc9d1684SMarcel Moolenaar " lwz %r3,68(%r1) \n" \
159dc9d1684SMarcel Moolenaar " mtlr %r3 \n" \
160590ccf8cSPeter Grehan " lwz %r4,48(%r1) \n" \
161dc9d1684SMarcel Moolenaar " mtctr %r4 \n" \
162dc9d1684SMarcel Moolenaar " lwz %r3,16(%r1) \n" \
163590ccf8cSPeter Grehan " lwz %r4,20(%r1) \n" \
164590ccf8cSPeter Grehan " lwz %r5,24(%r1) \n" \
165590ccf8cSPeter Grehan " lwz %r6,28(%r1) \n" \
166590ccf8cSPeter Grehan " lwz %r7,32(%r1) \n" \
167590ccf8cSPeter Grehan " lwz %r8,36(%r1) \n" \
168590ccf8cSPeter Grehan " lwz %r9,40(%r1) \n" \
169590ccf8cSPeter Grehan " lwz %r10,44(%r1) \n" \
170dc9d1684SMarcel Moolenaar " addi %r1,%r1,64 \n" \
171dc9d1684SMarcel Moolenaar " bctr \n" \
172590ccf8cSPeter Grehan "_mcount_end: \n" \
173590ccf8cSPeter Grehan " .size _mcount,_mcount_end-_mcount");
174c3e289e1SNathan Whitehorn #endif
175590ccf8cSPeter Grehan
176f48649e5SPeter Grehan #ifdef _KERNEL
177dc9d1684SMarcel Moolenaar #define MCOUNT_ENTER(s) s = intr_disable()
178dc9d1684SMarcel Moolenaar #define MCOUNT_EXIT(s) intr_restore(s)
179dc9d1684SMarcel Moolenaar #define MCOUNT_DECL(s) register_t s;
1800f2fe153SMarcel Moolenaar
181dc9d1684SMarcel Moolenaar #ifndef COMPILING_LINT
182dc9d1684SMarcel Moolenaar #ifdef AIM
183dc9d1684SMarcel Moolenaar #include <machine/trap.h>
184dc9d1684SMarcel Moolenaar #define __PROFILE_VECTOR_BASE EXC_RST
185dc9d1684SMarcel Moolenaar #define __PROFILE_VECTOR_TOP (EXC_LAST + 0x100)
186dc9d1684SMarcel Moolenaar #endif /* AIM */
18717f4cae4SRafal Jaworowski #if defined(BOOKE)
188dc9d1684SMarcel Moolenaar extern char interrupt_vector_base[];
189dc9d1684SMarcel Moolenaar extern char interrupt_vector_top[];
190dc9d1684SMarcel Moolenaar #define __PROFILE_VECTOR_BASE (uintfptr_t)interrupt_vector_base
191dc9d1684SMarcel Moolenaar #define __PROFILE_VECTOR_TOP (uintfptr_t)interrupt_vector_top
192*889d304bSJustin Hibbits #endif /* BOOKE_E500 */
19317f4cae4SRafal Jaworowski
194dc9d1684SMarcel Moolenaar #endif /* !COMPILING_LINT */
195dc9d1684SMarcel Moolenaar
196dc9d1684SMarcel Moolenaar #ifndef __PROFILE_VECTOR_BASE
197dc9d1684SMarcel Moolenaar #define __PROFILE_VECTOR_BASE 0
198dc9d1684SMarcel Moolenaar #endif
199dc9d1684SMarcel Moolenaar #ifndef __PROFILE_VECTOR_TOP
200dc9d1684SMarcel Moolenaar #define __PROFILE_VECTOR_TOP 1
201dc9d1684SMarcel Moolenaar #endif
202dc9d1684SMarcel Moolenaar
203dc9d1684SMarcel Moolenaar static __inline void
powerpc_profile_interrupt(void)204dc9d1684SMarcel Moolenaar powerpc_profile_interrupt(void)
205dc9d1684SMarcel Moolenaar {
206dc9d1684SMarcel Moolenaar }
207dc9d1684SMarcel Moolenaar
208dc9d1684SMarcel Moolenaar static __inline void
powerpc_profile_userspace(void)209dc9d1684SMarcel Moolenaar powerpc_profile_userspace(void)
210dc9d1684SMarcel Moolenaar {
211dc9d1684SMarcel Moolenaar }
2120f2fe153SMarcel Moolenaar
2130f2fe153SMarcel Moolenaar #define MCOUNT_FROMPC_USER(pc) \
214dc9d1684SMarcel Moolenaar ((pc < (uintfptr_t)VM_MAXUSER_ADDRESS) ? \
215dc9d1684SMarcel Moolenaar (uintfptr_t)powerpc_profile_userspace : pc)
2160f2fe153SMarcel Moolenaar
2170f2fe153SMarcel Moolenaar #define MCOUNT_FROMPC_INTR(pc) \
218dc9d1684SMarcel Moolenaar ((pc >= __PROFILE_VECTOR_BASE && \
219dc9d1684SMarcel Moolenaar pc < __PROFILE_VECTOR_TOP) ? \
220dc9d1684SMarcel Moolenaar (uintfptr_t)powerpc_profile_interrupt : ~0U)
2210f2fe153SMarcel Moolenaar
222dc9d1684SMarcel Moolenaar void __mcount(uintfptr_t frompc, uintfptr_t selfpc);
22389ec08eeSJoseph Koshy
22489ec08eeSJoseph Koshy #else /* !_KERNEL */
22589ec08eeSJoseph Koshy
226c3e289e1SNathan Whitehorn #ifdef __powerpc64__
227c3e289e1SNathan Whitehorn typedef u_long uintfptr_t;
228c3e289e1SNathan Whitehorn #else
22989ec08eeSJoseph Koshy typedef u_int uintfptr_t;
230c3e289e1SNathan Whitehorn #endif
23189ec08eeSJoseph Koshy
23289ec08eeSJoseph Koshy #endif /* _KERNEL */
233f48649e5SPeter Grehan
234f48649e5SPeter Grehan #endif /* !_MACHINE_PROFILE_H_ */
235