Merge tag 'locks-v3.16-2' of git://git.samba.org/jlayton/linux
[linux/fpc-iii.git] / arch / tile / kernel / mcount_64.S
blob70d7bb0c4d8f0741a9c4cf8727f3089fe7eab40c
1 /*
2  * Copyright 2012 Tilera Corporation. All Rights Reserved.
3  *
4  *   This program is free software; you can redistribute it and/or
5  *   modify it under the terms of the GNU General Public License
6  *   as published by the Free Software Foundation, version 2.
7  *
8  *   This program is distributed in the hope that it will be useful, but
9  *   WITHOUT ANY WARRANTY; without even the implied warranty of
10  *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11  *   NON INFRINGEMENT.  See the GNU General Public License for
12  *   more details.
13  *
14  * TILE-Gx specific __mcount support
15  */
17 #include <linux/linkage.h>
18 #include <asm/ftrace.h>
20 #define REGSIZE 8
22         .text
23         .global __mcount
25         .macro  MCOUNT_SAVE_REGS
26         addli   sp, sp, -REGSIZE
27         {
28          st     sp, lr
29          addli  r29, sp, - (12 * REGSIZE)
30         }
31         {
32          addli  sp, sp, - (13 * REGSIZE)
33          st     r29, sp
34         }
35         addli   r29, r29, REGSIZE
36         { st    r29, r0; addli  r29, r29, REGSIZE }
37         { st    r29, r1; addli  r29, r29, REGSIZE }
38         { st    r29, r2; addli  r29, r29, REGSIZE }
39         { st    r29, r3; addli  r29, r29, REGSIZE }
40         { st    r29, r4; addli  r29, r29, REGSIZE }
41         { st    r29, r5; addli  r29, r29, REGSIZE }
42         { st    r29, r6; addli  r29, r29, REGSIZE }
43         { st    r29, r7; addli  r29, r29, REGSIZE }
44         { st    r29, r8; addli  r29, r29, REGSIZE }
45         { st    r29, r9; addli  r29, r29, REGSIZE }
46         { st    r29, r10; addli r29, r29, REGSIZE }
47         .endm
49         .macro  MCOUNT_RESTORE_REGS
50         addli   r29, sp, (2 * REGSIZE)
51         { ld    r0, r29; addli  r29, r29, REGSIZE }
52         { ld    r1, r29; addli  r29, r29, REGSIZE }
53         { ld    r2, r29; addli  r29, r29, REGSIZE }
54         { ld    r3, r29; addli  r29, r29, REGSIZE }
55         { ld    r4, r29; addli  r29, r29, REGSIZE }
56         { ld    r5, r29; addli  r29, r29, REGSIZE }
57         { ld    r6, r29; addli  r29, r29, REGSIZE }
58         { ld    r7, r29; addli  r29, r29, REGSIZE }
59         { ld    r8, r29; addli  r29, r29, REGSIZE }
60         { ld    r9, r29; addli  r29, r29, REGSIZE }
61         { ld    r10, r29; addli lr, sp, (13 * REGSIZE) }
62         { ld    lr, lr;  addli  sp, sp, (14 * REGSIZE) }
63         .endm
65         .macro  RETURN_BACK
66         { move  r12, lr; move   lr, r10 }
67         jrp     r12
68         .endm
70 #ifdef CONFIG_DYNAMIC_FTRACE
72         .align  64
73 STD_ENTRY(__mcount)
74 __mcount:
75         j       ftrace_stub
76 STD_ENDPROC(__mcount)
78         .align  64
79 STD_ENTRY(ftrace_caller)
80         moveli  r11, hw2_last(function_trace_stop)
81         { shl16insli    r11, r11, hw1(function_trace_stop); move r12, lr }
82         { shl16insli    r11, r11, hw0(function_trace_stop); move lr, r10 }
83         ld      r11, r11
84         beqz    r11, 1f
85         jrp     r12
88         { move  r10, lr; move   lr, r12 }
89         MCOUNT_SAVE_REGS
91         /* arg1: self return address */
92         /* arg2: parent's return address */
93         { move  r0, lr; move    r1, r10 }
95         .global ftrace_call
96 ftrace_call:
97         /*
98          * a placeholder for the call to a real tracing function, i.e.
99          * ftrace_trace_function()
100          */
101         nop
103 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
104         .global ftrace_graph_call
105 ftrace_graph_call:
106         /*
107          * a placeholder for the call to a real tracing function, i.e.
108          * ftrace_graph_caller()
109          */
110         nop
111 #endif
112         MCOUNT_RESTORE_REGS
113         .global ftrace_stub
114 ftrace_stub:
115         RETURN_BACK
116 STD_ENDPROC(ftrace_caller)
118 #else /* ! CONFIG_DYNAMIC_FTRACE */
120         .align  64
121 STD_ENTRY(__mcount)
122         moveli  r11, hw2_last(function_trace_stop)
123         { shl16insli    r11, r11, hw1(function_trace_stop); move r12, lr }
124         { shl16insli    r11, r11, hw0(function_trace_stop); move lr, r10 }
125         ld      r11, r11
126         beqz    r11, 1f
127         jrp     r12
130         { move  r10, lr; move   lr, r12 }
131         {
132          moveli r11, hw2_last(ftrace_trace_function)
133          moveli r13, hw2_last(ftrace_stub)
134         }
135         {
136          shl16insli     r11, r11, hw1(ftrace_trace_function)
137          shl16insli     r13, r13, hw1(ftrace_stub)
138         }
139         {
140          shl16insli     r11, r11, hw0(ftrace_trace_function)
141          shl16insli     r13, r13, hw0(ftrace_stub)
142         }
144         ld      r11, r11
145         sub     r14, r13, r11
146         bnez    r14, static_trace
148 #ifdef  CONFIG_FUNCTION_GRAPH_TRACER
149         moveli  r15, hw2_last(ftrace_graph_return)
150         shl16insli      r15, r15, hw1(ftrace_graph_return)
151         shl16insli      r15, r15, hw0(ftrace_graph_return)
152         ld      r15, r15
153         sub     r15, r15, r13
154         bnez    r15, ftrace_graph_caller
156         {
157          moveli r16, hw2_last(ftrace_graph_entry)
158          moveli r17, hw2_last(ftrace_graph_entry_stub)
159         }
160         {
161          shl16insli     r16, r16, hw1(ftrace_graph_entry)
162          shl16insli     r17, r17, hw1(ftrace_graph_entry_stub)
163         }
164         {
165          shl16insli     r16, r16, hw0(ftrace_graph_entry)
166          shl16insli     r17, r17, hw0(ftrace_graph_entry_stub)
167         }
168         ld      r16, r16
169         sub     r17, r16, r17
170         bnez    r17, ftrace_graph_caller
172 #endif
173         RETURN_BACK
175 static_trace:
176         MCOUNT_SAVE_REGS
178         /* arg1: self return address */
179         /* arg2: parent's return address */
180         { move  r0, lr; move    r1, r10 }
182         /* call ftrace_trace_function() */
183         jalr    r11
185         MCOUNT_RESTORE_REGS
187         .global ftrace_stub
188 ftrace_stub:
189         RETURN_BACK
190 STD_ENDPROC(__mcount)
192 #endif  /* ! CONFIG_DYNAMIC_FTRACE */
194 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
196 STD_ENTRY(ftrace_graph_caller)
197 ftrace_graph_caller:
198 #ifndef CONFIG_DYNAMIC_FTRACE
199         MCOUNT_SAVE_REGS
200 #endif
202         /* arg1: Get the location of the parent's return address */
203         addi    r0, sp, 12 * REGSIZE
204         /* arg2: Get self return address */
205         move    r1, lr
207         jal prepare_ftrace_return
209         MCOUNT_RESTORE_REGS
210         RETURN_BACK
211 STD_ENDPROC(ftrace_graph_caller)
213         .global return_to_handler
214 return_to_handler:
215         MCOUNT_SAVE_REGS
217         jal     ftrace_return_to_handler
218         /* restore the real parent address */
219         move    r11, r0
221         MCOUNT_RESTORE_REGS
222         jr      r11
224 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */