]>
Commit | Line | Data |
---|---|---|
e156dabc | 1 | /* Record the register state before and after a variant PCS call. |
dff8da6b | 2 | Copyright (C) 2020-2024 Free Software Foundation, Inc. |
e156dabc SN |
3 | |
4 | This file is part of the GNU C Library. | |
5 | ||
6 | The GNU C Library is free software; you can redistribute it and/or | |
7 | modify it under the terms of the GNU Lesser General Public License as | |
8 | published by the Free Software Foundation; either version 2.1 of the | |
9 | License, or (at your option) any later version. | |
10 | ||
11 | The GNU C Library is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | Lesser General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU Lesser General Public | |
17 | License along with the GNU C Library. If not, see | |
18 | <https://www.gnu.org/licenses/>. */ | |
19 | ||
20 | .variant_pcs vpcs_call | |
21 | .global vpcs_call | |
22 | .type vpcs_call, %function | |
23 | vpcs_call: | |
24 | .cfi_startproc | |
25 | hint 34 /* bti c. */ | |
26 | ||
27 | /* Save register state to *x0. */ | |
28 | stp x0, x1, [x0] | |
29 | stp x2, x3, [x0, 16] | |
30 | stp x4, x5, [x0, 32] | |
31 | stp x6, x7, [x0, 48] | |
32 | stp x8, x9, [x0, 64] | |
33 | stp x10, x11, [x0, 80] | |
34 | stp x12, x13, [x0, 96] | |
35 | stp x14, x15, [x0, 112] | |
36 | stp x16, x17, [x0, 128] | |
37 | stp x18, x19, [x0, 144] | |
38 | stp x20, x21, [x0, 160] | |
39 | stp x22, x23, [x0, 176] | |
40 | stp x24, x25, [x0, 192] | |
41 | stp x26, x27, [x0, 208] | |
42 | stp x28, x29, [x0, 224] | |
43 | mov x1, sp | |
44 | stp x30, x1, [x0, 240] | |
45 | stp q0, q1, [x0, 256] | |
46 | stp q2, q3, [x0, 288] | |
47 | stp q4, q5, [x0, 320] | |
48 | stp q6, q7, [x0, 352] | |
49 | stp q8, q9, [x0, 384] | |
50 | stp q10, q11, [x0, 416] | |
51 | stp q12, q13, [x0, 448] | |
52 | stp q14, q15, [x0, 480] | |
53 | stp q16, q17, [x0, 512] | |
54 | stp q18, q19, [x0, 544] | |
55 | stp q20, q21, [x0, 576] | |
56 | stp q22, q23, [x0, 608] | |
57 | stp q24, q25, [x0, 640] | |
58 | stp q26, q27, [x0, 672] | |
59 | stp q28, q29, [x0, 704] | |
60 | stp q30, q31, [x0, 736] | |
61 | ret | |
62 | .cfi_endproc | |
63 | .size vpcs_call, .-vpcs_call | |
64 | ||
65 | .global vpcs_call_regs | |
66 | .type vpcs_call_regs, %function | |
67 | vpcs_call_regs: | |
68 | .cfi_startproc | |
69 | hint 34 /* bti c. */ | |
70 | ||
71 | stp x29, x30, [sp, -160]! | |
72 | mov x29, sp | |
73 | ||
74 | /* Save callee-saved registers. */ | |
75 | stp x19, x20, [sp, 16] | |
76 | stp x21, x22, [sp, 32] | |
77 | stp x23, x24, [sp, 48] | |
78 | stp x25, x26, [sp, 64] | |
79 | stp x27, x28, [sp, 80] | |
80 | stp d8, d9, [sp, 96] | |
81 | stp d10, d11, [sp, 112] | |
82 | stp d12, d13, [sp, 128] | |
83 | stp d14, d15, [sp, 144] | |
84 | ||
85 | /* Initialize most registers from *x1, and save x0, x1, x29, x30, | |
86 | and sp (== x29), so *x1 contains the register state. */ | |
87 | stp x0, x1, [x1] | |
88 | str x29, [x1, 232] | |
89 | ldp x2, x3, [x1, 16] | |
90 | ldp x4, x5, [x1, 32] | |
91 | ldp x6, x7, [x1, 48] | |
92 | ldp x8, x9, [x1, 64] | |
93 | ldp x10, x11, [x1, 80] | |
94 | ldp x12, x13, [x1, 96] | |
95 | ldp x14, x15, [x1, 112] | |
96 | ldp x16, x17, [x1, 128] | |
97 | ldp x18, x19, [x1, 144] | |
98 | ldp x20, x21, [x1, 160] | |
99 | ldp x22, x23, [x1, 176] | |
100 | ldp x24, x25, [x1, 192] | |
101 | ldp x26, x27, [x1, 208] | |
102 | ldr x28, [x1, 224] | |
103 | /* Skip x29, x30, sp. */ | |
104 | ldp q0, q1, [x1, 256] | |
105 | ldp q2, q3, [x1, 288] | |
106 | ldp q4, q5, [x1, 320] | |
107 | ldp q6, q7, [x1, 352] | |
108 | ldp q8, q9, [x1, 384] | |
109 | ldp q10, q11, [x1, 416] | |
110 | ldp q12, q13, [x1, 448] | |
111 | ldp q14, q15, [x1, 480] | |
112 | ldp q16, q17, [x1, 512] | |
113 | ldp q18, q19, [x1, 544] | |
114 | ldp q20, q21, [x1, 576] | |
115 | ldp q22, q23, [x1, 608] | |
116 | ldp q24, q25, [x1, 640] | |
117 | ldp q26, q27, [x1, 672] | |
118 | ldp q28, q29, [x1, 704] | |
119 | ldp q30, q31, [x1, 736] | |
120 | ||
121 | /* Emulate a BL using B, but save x30 before the branch. */ | |
122 | adr x30, .L_return_addr | |
123 | stp x30, x29, [x1, 240] | |
124 | b vpcs_call | |
125 | .L_return_addr: | |
126 | ||
127 | /* Restore callee-saved registers. */ | |
128 | ldp x19, x20, [sp, 16] | |
129 | ldp x21, x22, [sp, 32] | |
130 | ldp x23, x24, [sp, 48] | |
131 | ldp x25, x26, [sp, 64] | |
132 | ldp x27, x28, [sp, 80] | |
133 | ldp d8, d9, [sp, 96] | |
134 | ldp d10, d11, [sp, 112] | |
135 | ldp d12, d13, [sp, 128] | |
136 | ldp d14, d15, [sp, 144] | |
137 | ||
138 | ldp x29, x30, [sp], 160 | |
139 | ret | |
140 | .cfi_endproc | |
141 | .size vpcs_call_regs, .-vpcs_call_regs |