• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/**
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "arch/asm_support.h"
17
18.extern InvokeInterpreter
19
20.global DeoptimizeAfterCFrame
21.type DeoptimizeAfterCFrame, %function
22DeoptimizeAfterCFrame:
23    CFI_STARTPROC
24
25    // Parameters:
26    // r0 - thread
27    // r1 - pc of the entry
28    // r2 - pointer to interpreter Frame
29    // r3 - pointer to cframe origin
30    // r4(slot0) - last restored interpreter Frame
31
32    // Morph CFrame into C2I bridge frame
33    // FROM         TO
34    //  lr          lr
35    //  fp <----    COMPILED_CODE_TO_INTERPRETER_BRIDGE
36    //  method      fp <----
37
38    CFI_DEF_CFA(r3, (2 * 4))
39    CFI_REL_OFFSET(lr, 4)
40    CFI_REL_OFFSET(fp, 0)
41    CFI_REL_OFFSET(THREAD_REG, -((CFRAME_CALLEE_REGS_START_SLOT + 0) * 4))
42    CFI_REL_OFFSET(r9,  -((CFRAME_CALLEE_REGS_START_SLOT + 1) * 4))
43    CFI_REL_OFFSET(r8,  -((CFRAME_CALLEE_REGS_START_SLOT + 2) * 4))
44    CFI_REL_OFFSET(r7,  -((CFRAME_CALLEE_REGS_START_SLOT + 3) * 4))
45    CFI_REL_OFFSET(r6,  -((CFRAME_CALLEE_REGS_START_SLOT + 4) * 4))
46    CFI_REL_OFFSET(r5,  -((CFRAME_CALLEE_REGS_START_SLOT + 5) * 4))
47    CFI_REL_OFFSET(r4,  -((CFRAME_CALLEE_REGS_START_SLOT + 6) * 4))
48    ldr r4, [sp]
49
50    sub sp, r3, #((CFRAME_CALLEE_REGS_START_SLOT * 4) + CALLEE_SAVED_SIZE)
51
52    ldr r5, [r3], #-4
53    CFI_ADJUST_CFA_OFFSET(4)
54    mov r6, #COMPILED_CODE_TO_INTERPRETER_BRIDGE
55    stm r3, {r5, r6}
56    CFI_REL_OFFSET(fp, 0)
57
58    mov fp, r3
59    CFI_DEF_CFA_REGISTER(fp)
60
61    // Set IFrame's prev_frame to this C2I bridge frame
62    str r3, [r4, #FRAME_PREV_FRAME_OFFSET]
63
64    BOUNDARY_FRAME_SLOT = ((CFRAME_HEADER_SIZE - 3) + 1)
65
66    // Copy callee saved registers from cframe into boundary frame.
67    sub r12, r3, #((CFRAME_CALLEE_REGS_START_SLOT - 1) * 4 - 4)
68    sub r11, r3, #((BOUNDARY_FRAME_SLOT - 1) * 4)
69
70    // Scalar
71    ldr r10, [r12, #-4]!
72    str r10, [r11, #-4]!
73    CFI_REL_OFFSET(r10, -((BOUNDARY_FRAME_SLOT + 0) * 4))
74    ldr r10, [r12, #-4]!
75    str r10, [r11, #-4]!
76    CFI_REL_OFFSET(r9, -((BOUNDARY_FRAME_SLOT + 1) * 4))
77    ldr r10, [r12, #-4]!
78    str r10, [r11, #-4]!
79    CFI_REL_OFFSET(r8, -((BOUNDARY_FRAME_SLOT + 2) * 4))
80    ldr r10, [r12, #-4]!
81    str r10, [r11, #-4]!
82    CFI_REL_OFFSET(r7, -((BOUNDARY_FRAME_SLOT + 3) * 4))
83    ldr r10, [r12, #-4]!
84    str r10, [r11, #-4]!
85    CFI_REL_OFFSET(r6, -((BOUNDARY_FRAME_SLOT + 4) * 4))
86    ldr r10, [r12, #-4]!
87    str r10, [r11, #-4]!
88    CFI_REL_OFFSET(r5, -((BOUNDARY_FRAME_SLOT + 5) * 4))
89    ldr r10, [r12, #-4]!
90    str r10, [r11, #-4]!
91    CFI_REL_OFFSET(r4, -((BOUNDARY_FRAME_SLOT + 6) * 4))
92    // Vector (use 32-bit)
93    ldr r10, [r12, #-4]!
94    str r10, [r11, #-4]!
95    CFI_REL_OFFSET(s31, -((BOUNDARY_FRAME_SLOT + 7) * 4))
96    ldr r10, [r12, #-4]!
97    str r10, [r11, #-4]!
98    CFI_REL_OFFSET(s30, -((BOUNDARY_FRAME_SLOT + 8) * 4))
99    ldr r10, [r12, #-4]!
100    str r10, [r11, #-4]!
101    CFI_REL_OFFSET(s29, -((BOUNDARY_FRAME_SLOT + 9) * 4))
102    ldr r10, [r12, #-4]!
103    str r10, [r11, #-4]!
104    CFI_REL_OFFSET(s28, -((BOUNDARY_FRAME_SLOT + 10) * 4))
105    ldr r10, [r12, #-4]!
106    str r10, [r11, #-4]!
107    CFI_REL_OFFSET(s27, -((BOUNDARY_FRAME_SLOT + 11) * 4))
108    ldr r10, [r12, #-4]!
109    str r10, [r11, #-4]!
110    CFI_REL_OFFSET(s26, -((BOUNDARY_FRAME_SLOT + 12) * 4))
111    ldr r10, [r12, #-4]!
112    str r10, [r11, #-4]!
113    CFI_REL_OFFSET(s25, -((BOUNDARY_FRAME_SLOT + 13) * 4))
114    ldr r10, [r12, #-4]!
115    str r10, [r11, #-4]!
116    CFI_REL_OFFSET(s24, -((BOUNDARY_FRAME_SLOT + 14) * 4))
117    ldr r10, [r12, #-4]!
118    str r10, [r11, #-4]!
119    CFI_REL_OFFSET(s23, -((BOUNDARY_FRAME_SLOT + 15) * 4))
120    ldr r10, [r12, #-4]!
121    str r10, [r11, #-4]!
122    CFI_REL_OFFSET(s22, -((BOUNDARY_FRAME_SLOT + 16) * 4))
123    ldr r10, [r12, #-4]!
124    str r10, [r11, #-4]!
125    CFI_REL_OFFSET(s21, -((BOUNDARY_FRAME_SLOT + 17) * 4))
126    ldr r10, [r12, #-4]!
127    str r10, [r11, #-4]!
128    CFI_REL_OFFSET(s20, -((BOUNDARY_FRAME_SLOT + 18) * 4))
129    ldr r10, [r12, #-4]!
130    str r10, [r11, #-4]!
131    CFI_REL_OFFSET(s19, -((BOUNDARY_FRAME_SLOT + 19) * 4))
132    ldr r10, [r12, #-4]!
133    str r10, [r11, #-4]!
134    CFI_REL_OFFSET(s18, -((BOUNDARY_FRAME_SLOT + 20) * 4))
135    ldr r10, [r12, #-4]!
136    str r10, [r11, #-4]!
137    CFI_REL_OFFSET(s17, -((BOUNDARY_FRAME_SLOT + 21) * 4))
138    ldr r10, [r12, #-4]!
139    str r10, [r11, #-4]!
140    CFI_REL_OFFSET(s16, -((BOUNDARY_FRAME_SLOT + 22) * 4))
141    // Save used registers
142    str r3, [sp, #-4]!
143    str r2, [sp, #-4]!
144    str r1, [sp, #-4]!
145    str r0, [sp, #-4]!
146    mov r3, r4
147
148    // Arguments are already lay in registers, because signature of DeoptimizeAfterCFrame is similar to InvokeInterpreter
149    blx InvokeInterpreter
150    // r0, r1 - return values
151
152    // Restore used registers, but not r0, r1 which holds result of the invoked method and should be survive to the end
153    // So we use r4 instead of r0 for restoring THREAD_REG
154    ldr r4, [sp], #4
155    add sp, sp, #4
156    ldrd r2, r3, [sp], #8
157
158    // Restore stack pointer so that it points to COMPILED_CODE_TO_INTERPRETER_BRIDGE
159    sub sp, r3, #4
160
161    // Restore callee saved registers
162    sub r3, r3, #((BOUNDARY_FRAME_SLOT - 1) * 4)
163
164    ldr r10, [r3, #-4]!
165    ldrd r8, r9, [r3, #-8]!
166    CFI_RESTORE(r9)
167    CFI_RESTORE(r8)
168    ldrd r6, r7, [r3, #-8]!
169    CFI_RESTORE(r7)
170    CFI_RESTORE(r6)
171    // THREAD_REG is r10, but we can't remove `ldr r10, [r3, #-4]!` because we can change number of the THREAD_REG
172    // !NOTE fix this code if THREAD_REG will be change to r4 or r5
173    mov THREAD_REG, r4
174    CFI_RESTORE(THREAD_REG)
175
176    ldrd r4, r5, [r3, #-8]!
177    CFI_RESTORE(r5)
178    CFI_RESTORE(r4)
179
180#ifndef PANDA_TARGET_ARM32_ABI_SOFT
181    vldr d15, [r3, #-8]
182    CFI_RESTORE(d15)
183    vldr d14, [r3, #-16]
184    CFI_RESTORE(d14)
185    vldr d13, [r3, #-24]
186    CFI_RESTORE(d13)
187    vldr d12, [r3, #-32]
188    CFI_RESTORE(d12)
189    vldr d11, [r3, #-40]
190    CFI_RESTORE(d11)
191    vldr d10, [r3, #-48]
192    CFI_RESTORE(d10)
193    vldr d9, [r3, #-56]
194    CFI_RESTORE(d9)
195    vldr d8, [r3, #-64]
196    CFI_RESTORE(d8)
197
198    vmov.f64 d0, r0, r1
199#endif
200
201    ldr fp, [sp, #4]
202    CFI_RESTORE(fp)
203    CFI_DEF_CFA(sp, (4 * 4))
204    ldr lr, [sp, #12]
205    CFI_RESTORE(lr)
206    add sp, sp, #16
207    CFI_ADJUST_CFA_OFFSET(-(4 * 4))
208    bx lr
209    CFI_ENDPROC
210
211.global DeoptimizeAfterIFrame
212.type DeoptimizeAfterIFrame, %function
213DeoptimizeAfterIFrame:
214    CFI_STARTPROC
215
216    // Parameters:
217    // r0 - thread
218    // r1 - pc of the entry
219    // r2 - pointer to interpreter Frame
220    // r3 - pointer to cframe origin
221    // r4(slot0) - last restored interpreter Frame
222    // load num_inlined_methods from stack
223
224    CFI_DEF_CFA(r3, (2 * 4))
225    CFI_REL_OFFSET(lr, 4)
226    CFI_REL_OFFSET(fp, 0)
227    CFI_REL_OFFSET(r10, -((CFRAME_CALLEE_REGS_START_SLOT + 0) * 4))
228    CFI_REL_OFFSET(r9,  -((CFRAME_CALLEE_REGS_START_SLOT + 1) * 4))
229    CFI_REL_OFFSET(r8,  -((CFRAME_CALLEE_REGS_START_SLOT + 2) * 4))
230    CFI_REL_OFFSET(r7,  -((CFRAME_CALLEE_REGS_START_SLOT + 3) * 4))
231    CFI_REL_OFFSET(r6,  -((CFRAME_CALLEE_REGS_START_SLOT + 4) * 4))
232    CFI_REL_OFFSET(r5,  -((CFRAME_CALLEE_REGS_START_SLOT + 5) * 4))
233    CFI_REL_OFFSET(r4,  -((CFRAME_CALLEE_REGS_START_SLOT + 6) * 4))
234
235    ldr r4, [sp]
236
237    // Restore fp by pointer to the I2C boundary frame
238    // Restore return address, so after interperter finish its work it returns to the I2C bridge
239    mov fp, r3
240    CFI_DEF_CFA_REGISTER(fp)
241
242    // Restore stack pointer to the beginning of the cframe
243    mov sp, fp
244
245    // save num_inlined_methods to new stack
246    str r4, [sp, #-4]!
247
248    // Restore callee saved registers
249    sub r3, r3, #((CFRAME_CALLEE_REGS_START_SLOT * 4) - 4)
250    ldr r10, [r3, #-4]!
251    CFI_RESTORE(r10)
252    ldrd r8, r9, [r3, #-8]!
253    CFI_RESTORE(r9)
254    CFI_RESTORE(r8)
255    ldrd r6, r7, [r3, #-8]!
256    CFI_RESTORE(r7)
257    CFI_RESTORE(r6)
258    ldrd r4, r5, [r3, #-8]!
259    CFI_RESTORE(r5)
260    CFI_RESTORE(r4)
261
262#ifndef PANDA_TARGET_ARM32_ABI_SOFT
263    vldr d15, [r3, #-8]
264    CFI_RESTORE(d15)
265    vldr d14, [r3, #-16]
266    CFI_RESTORE(d14)
267    vldr d13, [r3, #-24]
268    CFI_RESTORE(d13)
269    vldr d12, [r3, #-32]
270    CFI_RESTORE(d12)
271    vldr d11, [r3, #-40]
272    CFI_RESTORE(d11)
273    vldr d10, [r3, #-48]
274    CFI_RESTORE(d10)
275    vldr d9, [r3, #-56]
276    CFI_RESTORE(d9)
277    vldr d8, [r3, #-64]
278    CFI_RESTORE(d8)
279#endif
280
281    // load num_inlined_methods from new stack
282    ldr r3, [sp], #4
283
284    bl InvokeInterpreter
285
286#ifndef PANDA_TARGET_ARM32_ABI_SOFT
287    // InvokeInterpreter returns int64 value, but result can be double, so we copy value to vector register
288    vmov.f64 d0, r0, r1
289#endif
290
291    pop {fp, lr}
292    CFI_RESTORE(lr)
293    CFI_RESTORE(fp)
294    CFI_DEF_CFA(sp, 0)
295    bx lr
296    CFI_ENDPROC
297
298.global DropCompiledFrameAndReturn
299.type DropCompiledFrameAndReturn, %function
300DropCompiledFrameAndReturn:
301    CFI_STARTPROC
302
303    // r0 - pointer to cframe origin
304    CFI_DEF_CFA(r0, (2 * 4))
305    CFI_REL_OFFSET(lr, 4)
306    CFI_REL_OFFSET(fp, 0)
307    CFI_REL_OFFSET(r10, -((CFRAME_CALLEE_REGS_START_SLOT + 0) * 4))
308    CFI_REL_OFFSET(r9,  -((CFRAME_CALLEE_REGS_START_SLOT + 1) * 4))
309    CFI_REL_OFFSET(r8,  -((CFRAME_CALLEE_REGS_START_SLOT + 2) * 4))
310    CFI_REL_OFFSET(r7,  -((CFRAME_CALLEE_REGS_START_SLOT + 3) * 4))
311    CFI_REL_OFFSET(r6,  -((CFRAME_CALLEE_REGS_START_SLOT + 4) * 4))
312    CFI_REL_OFFSET(r5,  -((CFRAME_CALLEE_REGS_START_SLOT + 5) * 4))
313    CFI_REL_OFFSET(r4,  -((CFRAME_CALLEE_REGS_START_SLOT + 6) * 4))
314
315    mov fp, r0
316    CFI_DEF_CFA_REGISTER(fp)
317
318    // Restore callee saved registers from dropped CFrame
319    sub r0, r0, #((CFRAME_CALLEE_REGS_START_SLOT * 4) - 4)
320    ldr r10, [r0, #-4]!
321    CFI_RESTORE(r10)
322    ldrd r8, r9, [r0, #-8]!
323    CFI_RESTORE(r9)
324    CFI_RESTORE(r8)
325    ldrd r6, r7, [r0, #-8]!
326    CFI_RESTORE(r7)
327    CFI_RESTORE(r6)
328    ldrd r4, r5, [r0, #-8]!
329    CFI_RESTORE(r5)
330    CFI_RESTORE(r4)
331
332#ifndef PANDA_TARGET_ARM32_ABI_SOFT
333    vldr d15, [r0, #-8]
334    CFI_RESTORE(d15)
335    vldr d14, [r0, #-16]
336    CFI_RESTORE(d14)
337    vldr d13, [r0, #-24]
338    CFI_RESTORE(d13)
339    vldr d12, [r0, #-32]
340    CFI_RESTORE(d12)
341    vldr d11, [r0, #-40]
342    CFI_RESTORE(d11)
343    vldr d10, [r0, #-48]
344    CFI_RESTORE(d10)
345    vldr d9, [r0, #-56]
346    CFI_RESTORE(d9)
347    vldr d8, [r0, #-64]
348    CFI_RESTORE(d8)
349#endif
350
351    // We need to clear return value, since it will be written to the IFrame's accumulator. Without this, it holds
352    // garbage and StackWalker verification might fail.
353    mov r0, #0
354    mov r1, #0
355
356    mov sp, fp
357    pop {fp, lr}
358    CFI_RESTORE(lr)
359    CFI_RESTORE(fp)
360    CFI_DEF_CFA(sp, 0)
361    bx lr
362    CFI_ENDPROC
363
364