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