Linux: Make __rseq_size useful for feature detection (bug 31965)
[glibc.git] / sysdeps / powerpc / powerpc32 / ppc-mcount.S
blob317e466b5f88e255b9cc6877c088e37cf3927fcd
1 /* PowerPC-specific implementation of profiling support.
2    Copyright (C) 1997-2024 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
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.
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.
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    <https://www.gnu.org/licenses/>.  */
19 /* This would be bad.  */
20 #ifdef PROF
21 #undef PROF
22 #endif
24 #include <sysdep.h>
26 /* We do profiling as described in the SYSV ELF ABI, except that glibc
27    _mcount manages its own counters.  The caller has put the address the
28    caller will return to in the usual place on the stack, 4(r1).  _mcount
29    is responsible for ensuring that when it returns no argument-passing
30    registers are disturbed, and that the LR is set back to (what the
31    caller sees as) 4(r1).
33    This is intended so that the following code can be inserted at the
34    front of any routine without changing the routine:
36         .data
37         mflr    r0
38         stw     r0,4(r1)
39         bl      _mcount
42 ENTRY(_mcount)
43 #if defined PIC && !defined SHARED
44 # define CALLER_LR_OFFSET 68
45         stwu    r1,-64(r1)
46         cfi_adjust_cfa_offset (64)
47         stw     r30, 48(r1)
48         cfi_rel_offset (r30, 48)
49 #else
50 # define CALLER_LR_OFFSET 52
51         stwu    r1,-48(r1)
52         cfi_adjust_cfa_offset (48)
53 #endif
54 /* We need to save the parameter-passing registers.  */
55         stw     r3, 12(r1)
56         stw     r4, 16(r1)
57         stw     r5, 20(r1)
58         stw     r6, 24(r1)
59         mflr    r4
60 #if defined PIC && !defined SHARED
61         bcl     20,31,0f
63         mflr    r30
64         addis   r30, r30, _GLOBAL_OFFSET_TABLE_-0b@ha
65         addi    r30, r30, _GLOBAL_OFFSET_TABLE_-0b@l
66 #endif
67         lwz     r3, CALLER_LR_OFFSET(r1)
68         mfcr    r5
69         stw     r7, 28(r1)
70         stw     r8, 32(r1)
71         stw     r9, 36(r1)
72         stw     r10,40(r1)
73         stw     r4, 44(r1)
74         cfi_rel_offset (lr, 44)
75         stw     r5,  8(r1)
76 #ifndef SHARED
77         bl      JUMPTARGET(__mcount_internal)
78 #else
79         bl      __mcount_internal@local
80 #endif
81  /* Restore the registers...  */
82         lwz     r6,  8(r1)
83         lwz     r0, 44(r1)
84         lwz     r3, 12(r1)
85         mtctr   r0
86         lwz     r4, 16(r1)
87         mtcrf   0xff,r6
88         lwz     r5, 20(r1)
89         lwz     r6, 24(r1)
90         lwz     r0, CALLER_LR_OFFSET(r1)
91         lwz     r7, 28(r1)
92         lwz     r8, 32(r1)
93         mtlr    r0
94         lwz     r9, 36(r1)
95         lwz     r10,40(r1)
96  /* ...unwind the stack frame, and return to your usual programming.  */
97 #if defined PIC && !defined SHARED
98         lwz     r30, 48(r1)
99         addi    r1,r1,64
100 #else
101         addi    r1,r1,48
102 #endif
103         bctr
104 END(_mcount)