1//===----------------------Hexagon builtin routine ------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9// Functions that implement common sequences in function prologues and epilogues
10// used to save code size
11
12	.macro FUNCTION_BEGIN name
13	.p2align 2
14        .section .text.\name,"ax",@progbits
15	.globl \name
16	.type  \name, @function
17\name:
18	.endm
19
20	.macro FUNCTION_END name
21	.size  \name, . - \name
22	.endm
23
24	.macro FALLTHROUGH_TAIL_CALL name0 name1
25	.p2align 2
26	.size \name0, . - \name0
27	.globl \name1
28	.type \name1, @function
29\name1:
30	.endm
31
32
33
34
35// Save r17:16 at fp+#-8, r19:18 at fp+#-16, r21:20 at fp+#-24, r23:22 at
36// fp+#-32, r25:24 at fp+#-40, and r27:26 at fp+#-48.
37// The compiler knows that the __save_* functions clobber LR.  No other
38// registers should be used without informing the compiler.
39
40FUNCTION_BEGIN __save_r16_through_r27
41        {
42                memd(fp+#-48) = r27:26
43                memd(fp+#-40) = r25:24
44        }
45        {
46                memd(fp+#-32) = r23:22
47                memd(fp+#-24) = r21:20
48        }
49        {
50                memd(fp+#-16) = r19:18
51                memd(fp+#-8) = r17:16
52                jumpr lr
53        }
54FUNCTION_END __save_r16_through_r27
55
56FUNCTION_BEGIN __save_r16_through_r25
57        {
58                memd(fp+#-40) = r25:24
59                memd(fp+#-32) = r23:22
60        }
61        {
62                memd(fp+#-24) = r21:20
63                memd(fp+#-16) = r19:18
64        }
65        {
66                memd(fp+#-8) = r17:16
67                jumpr lr
68        }
69FUNCTION_END __save_r16_through_r25
70
71FUNCTION_BEGIN __save_r16_through_r23
72        {
73                memd(fp+#-32) = r23:22
74                memd(fp+#-24) = r21:20
75        }
76        {
77                memd(fp+#-16) = r19:18
78                memd(fp+#-8) = r17:16
79                jumpr lr
80        }
81FUNCTION_END __save_r16_through_r23
82
83FUNCTION_BEGIN __save_r16_through_r21
84        {
85                memd(fp+#-24) = r21:20
86                memd(fp+#-16) = r19:18
87        }
88        {
89                memd(fp+#-8) = r17:16
90                jumpr lr
91        }
92FUNCTION_END __save_r16_through_r21
93
94FUNCTION_BEGIN __save_r16_through_r19
95        {
96                memd(fp+#-16) = r19:18
97                memd(fp+#-8) = r17:16
98                jumpr lr
99        }
100FUNCTION_END __save_r16_through_r19
101
102FUNCTION_BEGIN __save_r16_through_r17
103        {
104                memd(fp+#-8) = r17:16
105                jumpr lr
106        }
107FUNCTION_END __save_r16_through_r17
108
109// For each of the *_before_tailcall functions, jumpr lr is executed in parallel
110// with deallocframe.  That way, the return gets the old value of lr, which is
111// where these functions need to return, and at the same time, lr gets the value
112// it needs going into the tail call.
113
114
115FUNCTION_BEGIN __restore_r16_through_r27_and_deallocframe_before_tailcall
116                r27:26 = memd(fp+#-48)
117        {
118                r25:24 = memd(fp+#-40)
119                r23:22 = memd(fp+#-32)
120        }
121        {
122                r21:20 = memd(fp+#-24)
123                r19:18 = memd(fp+#-16)
124        }
125        {
126                r17:16 = memd(fp+#-8)
127                deallocframe
128                jumpr lr
129        }
130FUNCTION_END __restore_r16_through_r27_and_deallocframe_before_tailcall
131
132FUNCTION_BEGIN __restore_r16_through_r25_and_deallocframe_before_tailcall
133        {
134                r25:24 = memd(fp+#-40)
135                r23:22 = memd(fp+#-32)
136        }
137        {
138                r21:20 = memd(fp+#-24)
139                r19:18 = memd(fp+#-16)
140        }
141        {
142                r17:16 = memd(fp+#-8)
143                deallocframe
144                jumpr lr
145        }
146FUNCTION_END __restore_r16_through_r25_and_deallocframe_before_tailcall
147
148FUNCTION_BEGIN __restore_r16_through_r23_and_deallocframe_before_tailcall
149        {
150                r23:22 = memd(fp+#-32)
151                r21:20 = memd(fp+#-24)
152        }
153                r19:18 = memd(fp+#-16)
154        {
155                r17:16 = memd(fp+#-8)
156                deallocframe
157                jumpr lr
158        }
159FUNCTION_END __restore_r16_through_r23_and_deallocframe_before_tailcall
160
161
162FUNCTION_BEGIN __restore_r16_through_r21_and_deallocframe_before_tailcall
163        {
164                r21:20 = memd(fp+#-24)
165                r19:18 = memd(fp+#-16)
166        }
167        {
168                r17:16 = memd(fp+#-8)
169                deallocframe
170                jumpr lr
171        }
172FUNCTION_END __restore_r16_through_r19_and_deallocframe_before_tailcall
173
174FUNCTION_BEGIN __restore_r16_through_r19_and_deallocframe_before_tailcall
175                r19:18 = memd(fp+#-16)
176        {
177                r17:16 = memd(fp+#-8)
178                deallocframe
179                jumpr lr
180        }
181FUNCTION_END __restore_r16_through_r19_and_deallocframe_before_tailcall
182
183FUNCTION_BEGIN __restore_r16_through_r17_and_deallocframe_before_tailcall
184        {
185                r17:16 = memd(fp+#-8)
186                deallocframe
187                jumpr lr
188        }
189FUNCTION_END __restore_r16_through_r17_and_deallocframe_before_tailcall
190
191
192FUNCTION_BEGIN __restore_r16_through_r27_and_deallocframe
193                r27:26 = memd(fp+#-48)
194        {
195                r25:24 = memd(fp+#-40)
196                r23:22 = memd(fp+#-32)
197        }
198        {
199                r21:20 = memd(fp+#-24)
200                r19:18 = memd(fp+#-16)
201        }
202	{
203		r17:16 = memd(fp+#-8)
204		dealloc_return
205	}
206FUNCTION_END __restore_r16_through_r27_and_deallocframe
207
208FUNCTION_BEGIN __restore_r16_through_r25_and_deallocframe
209        {
210                r25:24 = memd(fp+#-40)
211                r23:22 = memd(fp+#-32)
212        }
213        {
214                r21:20 = memd(fp+#-24)
215                r19:18 = memd(fp+#-16)
216        }
217	{
218		r17:16 = memd(fp+#-8)
219		dealloc_return
220	}
221FUNCTION_END __restore_r16_through_r25_and_deallocframe
222
223FUNCTION_BEGIN __restore_r16_through_r23_and_deallocframe
224        {
225                r23:22 = memd(fp+#-32)
226        }
227        {
228                r21:20 = memd(fp+#-24)
229                r19:18 = memd(fp+#-16)
230        }
231	{
232		r17:16 = memd(fp+#-8)
233		dealloc_return
234	}
235FUNCTION_END __restore_r16_through_r23_and_deallocframe
236
237FUNCTION_BEGIN __restore_r16_through_r21_and_deallocframe
238        {
239                r21:20 = memd(fp+#-24)
240                r19:18 = memd(fp+#-16)
241        }
242	{
243		r17:16 = memd(fp+#-8)
244		dealloc_return
245	}
246FUNCTION_END __restore_r16_through_r21_and_deallocframe
247
248FUNCTION_BEGIN __restore_r16_through_r19_and_deallocframe
249	{
250                r19:18 = memd(fp+#-16)
251		r17:16 = memd(fp+#-8)
252        }
253        {
254		dealloc_return
255	}
256FUNCTION_END __restore_r16_through_r19_and_deallocframe
257
258FUNCTION_BEGIN __restore_r16_through_r17_and_deallocframe
259	{
260		r17:16 = memd(fp+#-8)
261		dealloc_return
262	}
263FUNCTION_END __restore_r16_through_r17_and_deallocframe
264
265FUNCTION_BEGIN __deallocframe
266        dealloc_return
267FUNCTION_END __deallocframe
268