GNU Linux-libre 5.4.274-gnu1
[releases.git] / arch / csky / abiv2 / mcount.S
1 /* SPDX-License-Identifier: GPL-2.0 */
2 // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
3
4 #include <linux/linkage.h>
5 #include <asm/ftrace.h>
6
7 /*
8  * csky-gcc with -pg will put the following asm after prologue:
9  *      push    r15
10  *      jsri    _mcount
11  *
12  * stack layout after mcount_enter in _mcount():
13  *
14  * current sp => 0:+-------+
15  *                 | a0-a3 | -> must save all argument regs
16  *             +16:+-------+
17  *                 | lr    | -> _mcount lr (instrumente function's pc)
18  *             +20:+-------+
19  *                 | fp=r8 | -> instrumented function fp
20  *             +24:+-------+
21  *                 | plr   | -> instrumented function lr (parent's pc)
22  *                 +-------+
23  */
24
25 .macro mcount_enter
26         subi    sp, 24
27         stw     a0, (sp, 0)
28         stw     a1, (sp, 4)
29         stw     a2, (sp, 8)
30         stw     a3, (sp, 12)
31         stw     lr, (sp, 16)
32         stw     r8, (sp, 20)
33 .endm
34
35 .macro mcount_exit
36         ldw     a0, (sp, 0)
37         ldw     a1, (sp, 4)
38         ldw     a2, (sp, 8)
39         ldw     a3, (sp, 12)
40         ldw     t1, (sp, 16)
41         ldw     r8, (sp, 20)
42         ldw     lr, (sp, 24)
43         addi    sp, 28
44         jmp     t1
45 .endm
46
47 .macro save_return_regs
48         subi    sp, 16
49         stw     a0, (sp, 0)
50         stw     a1, (sp, 4)
51         stw     a2, (sp, 8)
52         stw     a3, (sp, 12)
53 .endm
54
55 .macro restore_return_regs
56         mov     lr, a0
57         ldw     a0, (sp, 0)
58         ldw     a1, (sp, 4)
59         ldw     a2, (sp, 8)
60         ldw     a3, (sp, 12)
61         addi    sp, 16
62 .endm
63
64 .macro nop32_stub
65         nop32
66         nop32
67         nop32
68 .endm
69
70 ENTRY(ftrace_stub)
71         jmp     lr
72 END(ftrace_stub)
73
74 #ifndef CONFIG_DYNAMIC_FTRACE
75 ENTRY(_mcount)
76         mcount_enter
77
78         /* r26 is link register, only used with jsri translation */
79         lrw     r26, ftrace_trace_function
80         ldw     r26, (r26, 0)
81         lrw     a1, ftrace_stub
82         cmpne   r26, a1
83         bf      skip_ftrace
84
85         mov     a0, lr
86         subi    a0, 4
87         ldw     a1, (sp, 24)
88
89         jsr     r26
90
91 #ifndef CONFIG_FUNCTION_GRAPH_TRACER
92 skip_ftrace:
93         mcount_exit
94 #else
95 skip_ftrace:
96         lrw     a0, ftrace_graph_return
97         ldw     a0, (a0, 0)
98         lrw     a1, ftrace_stub
99         cmpne   a0, a1
100         bt      ftrace_graph_caller
101
102         lrw     a0, ftrace_graph_entry
103         ldw     a0, (a0, 0)
104         lrw     a1, ftrace_graph_entry_stub
105         cmpne   a0, a1
106         bt      ftrace_graph_caller
107
108         mcount_exit
109 #endif
110 END(_mcount)
111 #else /* CONFIG_DYNAMIC_FTRACE */
112 ENTRY(_mcount)
113         mov     t1, lr
114         ldw     lr, (sp, 0)
115         addi    sp, 4
116         jmp     t1
117 ENDPROC(_mcount)
118
119 ENTRY(ftrace_caller)
120         mcount_enter
121
122         ldw     a0, (sp, 16)
123         subi    a0, 4
124         ldw     a1, (sp, 24)
125
126         nop
127 GLOBAL(ftrace_call)
128         nop32_stub
129
130 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
131         nop
132 GLOBAL(ftrace_graph_call)
133         nop32_stub
134 #endif
135
136         mcount_exit
137 ENDPROC(ftrace_caller)
138 #endif /* CONFIG_DYNAMIC_FTRACE */
139
140 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
141 ENTRY(ftrace_graph_caller)
142         mov     a0, sp
143         addi    a0, 24
144         ldw     a1, (sp, 16)
145         subi    a1, 4
146         mov     a2, r8
147         lrw     r26, prepare_ftrace_return
148         jsr     r26
149         mcount_exit
150 END(ftrace_graph_caller)
151
152 ENTRY(return_to_handler)
153         save_return_regs
154         mov     a0, r8
155         jsri    ftrace_return_to_handler
156         restore_return_regs
157         jmp     lr
158 END(return_to_handler)
159 #endif