]> git.ipfire.org Git - thirdparty/glibc.git/blob - ports/sysdeps/arm/arm-mcount.S
8162be24830f77e513631d83b13d115bbdaa858a
[thirdparty/glibc.git] / ports / sysdeps / arm / arm-mcount.S
1 /* Implementation of profiling support. ARM EABI version.
2 Copyright (C) 2008-2013 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library. If not, see
17 <http://www.gnu.org/licenses/>. */
18
19 /* Don't call mcount when calling mcount... */
20 #undef PROF
21
22 #include <sysdep.h>
23
24
25 #ifdef __thumb2__
26 .thumb
27 #endif
28 .syntax unified
29
30
31 /* Use an assembly stub with a special ABI. The calling lr has been
32 pushed to the stack (which will be misaligned). We should preserve
33 all registers except ip and pop a word off the stack.
34
35 NOTE: This assumes mcount_internal does not clobber any non-core
36 (coprocessor) registers. Currently this is true, but may require
37 additional attention in the future.
38
39 The calling sequence looks something like:
40 func:
41 push {lr}
42 bl __gnu_mcount_nc
43 <function body>
44 */
45
46 ENTRY(__gnu_mcount_nc)
47 push {r0, r1, r2, r3, lr}
48 cfi_adjust_cfa_offset (20)
49 cfi_rel_offset (r0, 0)
50 cfi_rel_offset (r1, 4)
51 cfi_rel_offset (r2, 8)
52 cfi_rel_offset (r3, 12)
53 cfi_rel_offset (lr, 16)
54 bic r1, lr, #1
55 ldr r0, [sp, #20]
56 bl __mcount_internal
57 pop {r0, r1, r2, r3, ip, lr}
58 cfi_adjust_cfa_offset (-24)
59 cfi_restore (r0)
60 cfi_restore (r1)
61 cfi_restore (r2)
62 cfi_restore (r3)
63 cfi_register (lr, ip)
64 bx ip
65 END(__gnu_mcount_nc)
66
67
68 /* Provide old mcount for backwards compatibility. This requires
69 code be compiled with APCS frame pointers. */
70
71 ENTRY(_mcount)
72 push {r0, r1, r2, r3, fp, lr}
73 cfi_adjust_cfa_offset (24)
74 cfi_rel_offset (r0, 0)
75 cfi_rel_offset (r1, 4)
76 cfi_rel_offset (r2, 8)
77 cfi_rel_offset (r3, 12)
78 cfi_rel_offset (fp, 16)
79 cfi_rel_offset (lr, 20)
80 movs r0, fp
81 ittt ne
82 sfi_breg r0, \
83 ldrne r0, [\B, #-4]
84 movsne r1, lr
85 blne __mcount_internal
86 #if defined (__ARM_ARCH_4T__) && defined (__THUMB_INTERWORK__)
87 pop {r0, r1, r2, r3, fp, lr}
88 cfi_adjust_cfa_offset (-24)
89 cfi_restore (r0)
90 cfi_restore (r1)
91 cfi_restore (r2)
92 cfi_restore (r3)
93 cfi_restore (fp)
94 cfi_restore (lr)
95 bx lr
96 #else
97 pop {r0, r1, r2, r3, fp, pc}
98 #endif
99 END(_mcount)
100
101 /* The canonical name for the function is `_mcount' in both C and asm,
102 but some old asm code might assume it's `mcount'. */
103 #undef mcount
104 weak_alias (_mcount, mcount)