1 | /* Machine-specific calling sequence for `mcount' profiling function. alpha |
2 | Copyright (C) 1995-2022 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 | <https://www.gnu.org/licenses/>. */ |
18 | |
19 | /* Assembly stub to invoke _mcount(). Compiler generated code calls |
20 | this stub after executing a function's prologue and without saving any |
21 | registers. It is therefore necessary to preserve a0..a5 as they may |
22 | contain function arguments. To work correctly with frame- less |
23 | functions, it is also necessary to preserve ra. Finally, division |
24 | routines are invoked with a special calling convention and the |
25 | compiler treats those calls as if they were instructions. In |
26 | particular, it doesn't save any of the temporary registers (caller |
27 | saved registers). It is therefore necessary to preserve all |
28 | caller-saved registers as well. |
29 | |
30 | Upon entering _mcount, register $at holds the return address and ra |
31 | holds the return address of the function's caller (selfpc and frompc, |
32 | respectively in gmon.c language...). */ |
33 | |
34 | #include <sysdep.h> |
35 | |
36 | .set noat |
37 | .set noreorder |
38 | |
39 | LEAF(_mcount, 0xb0) |
40 | subq sp, 0xb0, sp |
41 | .prologue 0 |
42 | stq a0, 0x00(sp) |
43 | mov ra, a0 # a0 = caller-pc |
44 | stq a1, 0x08(sp) |
45 | mov $at, a1 # a1 = self-pc |
46 | stq $at, 0x10(sp) |
47 | |
48 | stq a2, 0x18(sp) |
49 | stq a3, 0x20(sp) |
50 | stq a4, 0x28(sp) |
51 | stq a5, 0x30(sp) |
52 | stq ra, 0x38(sp) |
53 | stq gp, 0x40(sp) |
54 | |
55 | br gp, 1f |
56 | 1: ldgp gp, 0(gp) |
57 | |
58 | stq t0, 0x48(sp) |
59 | stq t1, 0x50(sp) |
60 | stq t2, 0x58(sp) |
61 | stq t3, 0x60(sp) |
62 | stq t4, 0x68(sp) |
63 | stq t5, 0x70(sp) |
64 | stq t6, 0x78(sp) |
65 | |
66 | stq t7, 0x80(sp) |
67 | stq t8, 0x88(sp) |
68 | stq t9, 0x90(sp) |
69 | stq t10, 0x98(sp) |
70 | stq t11, 0xa0(sp) |
71 | stq v0, 0xa8(sp) |
72 | |
73 | jsr ra, __mcount |
74 | |
75 | ldq a0, 0x00(sp) |
76 | ldq a1, 0x08(sp) |
77 | ldq $at, 0x10(sp) # restore self-pc |
78 | ldq a2, 0x18(sp) |
79 | ldq a3, 0x20(sp) |
80 | ldq a4, 0x28(sp) |
81 | ldq a5, 0x30(sp) |
82 | ldq ra, 0x38(sp) |
83 | ldq gp, 0x40(sp) |
84 | mov $at, pv # make pv point to return address |
85 | ldq t0, 0x48(sp) # this is important under OSF/1 to |
86 | ldq t1, 0x50(sp) # ensure that the code that we return |
87 | ldq t2, 0x58(sp) # can correctly compute its gp |
88 | ldq t3, 0x60(sp) |
89 | ldq t4, 0x68(sp) |
90 | ldq t5, 0x70(sp) |
91 | ldq t6, 0x78(sp) |
92 | ldq t7, 0x80(sp) |
93 | ldq t8, 0x88(sp) |
94 | ldq t9, 0x90(sp) |
95 | ldq t10, 0x98(sp) |
96 | ldq t11, 0xa0(sp) |
97 | ldq v0, 0xa8(sp) |
98 | |
99 | addq sp, 0xb0, sp |
100 | ret zero,($at),1 |
101 | |
102 | END(_mcount) |
103 | |
104 | weak_alias (_mcount, mcount) |
105 | |