1 | /* Record the register state before and after a variant PCS call. |
2 | Copyright (C) 2020-2024 Free Software Foundation, Inc. |
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 |
142 | |