summaryrefslogtreecommitdiffstats
path: root/arch/sh/lib/mcount.S
blob: cb87ef580b314d5fc56c6f970d19e5ab7de8b282 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/*
 * arch/sh/lib/mcount.S
 *
 *  Copyright (C) 2008  Paul Mundt
 *  Copyright (C) 2008, 2009  Matt Fleming
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 */
#include <asm/ftrace.h>

#define MCOUNT_ENTER()		\
	mov.l	r4, @-r15;	\
	mov.l	r5, @-r15;	\
	mov.l	r6, @-r15;	\
	mov.l	r7, @-r15;	\
	sts.l	pr, @-r15;	\
				\
	mov.l	@(20,r15),r4;	\
	sts	pr, r5

#define MCOUNT_LEAVE()		\
	lds.l	@r15+, pr;	\
	mov.l	@r15+, r7;	\
	mov.l	@r15+, r6;	\
	mov.l	@r15+, r5;	\
	rts;			\
	 mov.l	@r15+, r4

	.align 2
	.globl	_mcount
	.type	_mcount,@function
	.globl	mcount
	.type	mcount,@function
_mcount:
mcount:
#ifndef CONFIG_DYNAMIC_FTRACE
	mov.l	.Lfunction_trace_stop, r0
	mov.l	@r0, r0
	tst	r0, r0
	bf	ftrace_stub
#endif
	MCOUNT_ENTER()

#ifdef CONFIG_DYNAMIC_FTRACE
	.globl	mcount_call
mcount_call:
	mov.l	.Lftrace_stub, r6
#else
	mov.l	.Lftrace_trace_function, r6
	mov.l	ftrace_stub, r7
	cmp/eq	r6, r7
	bt	skip_trace
	mov.l	@r6, r6
#endif

	jsr	@r6
	 nop

skip_trace:
	MCOUNT_LEAVE()

	.align 2
.Lftrace_trace_function:
	.long	ftrace_trace_function

#ifdef CONFIG_DYNAMIC_FTRACE
	.globl ftrace_caller
ftrace_caller:
	mov.l	.Lfunction_trace_stop, r0
	mov.l	@r0, r0
	tst	r0, r0
	bf	ftrace_stub
	
	MCOUNT_ENTER()

	.globl ftrace_call
ftrace_call:
	mov.l	.Lftrace_stub, r6
	jsr	@r6
	 nop

	MCOUNT_LEAVE()
#endif /* CONFIG_DYNAMIC_FTRACE */

/*
 * NOTE: From here on the locations of the .Lftrace_stub label and
 * ftrace_stub itself are fixed. Adding additional data here will skew
 * the displacement for the memory table and break the block replacement.
 * Place new labels either after the ftrace_stub body, or before
 * ftrace_caller. You have been warned.
 */
	.align 2
.Lftrace_stub:
	.long	ftrace_stub

	.globl	ftrace_stub
ftrace_stub:
	rts
	 nop

	.align 2
.Lfunction_trace_stop:
	.long	function_trace_stop