• 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#include "arch/aarch64/helpers_aarch64.S"
18#include "shorty_values.h"
19
20.extern InvokeInterpreter
21
22.macro CFRAME_COPY_LR fpreg
23    ldr lr, [\fpreg, #(-CFRAME_FLAGS_SLOT * 8)]
24    tst lr, #CFRAME_KIND_OSR
25    beq 1f
26    ldr lr, [\fpreg, #(-(CFRAME_LOCALS_START_SLOT + 2) * 8)]
27    str lr, [\fpreg, #(-CFRAME_LR_SLOT * 8)]
281:
29.endm
30
31.macro CFRAME_GET_LR fpreg
32    ldr lr, [\fpreg, #(-CFRAME_FLAGS_SLOT * 8)]
33    tst lr, #CFRAME_KIND_OSR
34    bne 1f
35    ldr lr, [\fpreg, #(-CFRAME_LR_SLOT * 8)]
36    b 2f
371:
38    ldr lr, [\fpreg, #(-(CFRAME_LOCALS_START_SLOT + 2) * 8)]
392:
40.endm
41
42.macro RESTORE_CALLEE_REGISTERS basereg
43    ldp x27, x28, [\basereg, #-16]!
44    ldp x25, x26, [\basereg, #-16]!
45    ldp x23, x24, [\basereg, #-16]!
46    ldp x21, x22, [\basereg, #-16]!
47    ldp x19, x20, [\basereg, #-16]!
48    ldp d14, d15, [\basereg, #-16]!
49    ldp d12, d13, [\basereg, #-16]!
50    ldp d10, d11, [\basereg, #-16]!
51    ldp d8,  d9,  [\basereg, #-16]!
52.endm
53
54// ============================================================================
55
56.global DeoptimizeAfterCFrame
57.type DeoptimizeAfterCFrame, %function
58DeoptimizeAfterCFrame:
59    CFI_STARTPROC
60
61    // Parameters:
62    // x0 - thread
63    // x1 - pc of the entry
64    // x2 - pointer to interpreter Frame
65    // x3 - pointer to cframe origin
66    // x4 - last restored interpreter Frame
67    // x5 - pointer to a callee-saved registers buffer from StackWalker
68
69    CFI_DEF_CFA(x3, (2 * 8))
70    CFI_REL_OFFSET(lr, 8)
71    CFI_REL_OFFSET(fp, 0)
72    CFI_REL_OFFSET(x28, -((CFRAME_CALLEE_REGS_START_SLOT + 0) * 8))
73    CFI_REL_OFFSET(x27, -((CFRAME_CALLEE_REGS_START_SLOT + 1) * 8))
74    CFI_REL_OFFSET(x26, -((CFRAME_CALLEE_REGS_START_SLOT + 2) * 8))
75    CFI_REL_OFFSET(x25, -((CFRAME_CALLEE_REGS_START_SLOT + 3) * 8))
76    CFI_REL_OFFSET(x24, -((CFRAME_CALLEE_REGS_START_SLOT + 4) * 8))
77    CFI_REL_OFFSET(x23, -((CFRAME_CALLEE_REGS_START_SLOT + 5) * 8))
78    CFI_REL_OFFSET(x22, -((CFRAME_CALLEE_REGS_START_SLOT + 6) * 8))
79    CFI_REL_OFFSET(x21, -((CFRAME_CALLEE_REGS_START_SLOT + 7) * 8))
80    CFI_REL_OFFSET(x20, -((CFRAME_CALLEE_REGS_START_SLOT + 8) * 8))
81    CFI_REL_OFFSET(x19, -((CFRAME_CALLEE_REGS_START_SLOT + 9) * 8))
82    CFI_REL_OFFSET(d15, -((CFRAME_CALLEE_REGS_START_SLOT + 10) * 8))
83    CFI_REL_OFFSET(d14, -((CFRAME_CALLEE_REGS_START_SLOT + 11) * 8))
84    CFI_REL_OFFSET(d13, -((CFRAME_CALLEE_REGS_START_SLOT + 12) * 8))
85    CFI_REL_OFFSET(d12, -((CFRAME_CALLEE_REGS_START_SLOT + 13) * 8))
86    CFI_REL_OFFSET(d11, -((CFRAME_CALLEE_REGS_START_SLOT + 14) * 8))
87    CFI_REL_OFFSET(d10, -((CFRAME_CALLEE_REGS_START_SLOT + 15) * 8))
88    CFI_REL_OFFSET(d9, -((CFRAME_CALLEE_REGS_START_SLOT + 16) * 8))
89    CFI_REL_OFFSET(d8, -((CFRAME_CALLEE_REGS_START_SLOT + 17) * 8))
90
91    // Morph CFrame into C2I bridge frame
92    // FROM         TO
93    //  lr          lr
94    //  fp <----    COMPILED_CODE_TO_INTERPRETER_BRIDGE
95    //  method      fp <----
96    sub sp, x3, #(((CFRAME_HEADER_SIZE - 2) * 8) + CALLEE_SAVED_SIZE)
97    ldr x7, [x3]
98    mov x8, #COMPILED_CODE_TO_INTERPRETER_BRIDGE
99    stp x7, x8, [x3, #-8]!
100    CFI_ADJUST_CFA_OFFSET(8)
101    CFI_REL_OFFSET(fp, 0)
102
103    mov fp, x3
104    CFI_DEF_CFA_REGISTER(fp)
105
106    // Set last IFrame's prev_frame to this C2I bridge frame
107    str x3, [x4, #FRAME_PREV_FRAME_OFFSET]
108
109    BOUNDARY_FRAME_SLOT = ((CFRAME_HEADER_SIZE - 3) + 1)
110
111    // Copy callee saved registers from StackWalker into boundary frame.
112    // Note, we do not preserve x5 (holding a pointer to a callee-saved
113    // registers buffer from StackWalker) as it is not needed later on.
114    sub x17, x3, #((BOUNDARY_FRAME_SLOT - 1) * 8)
115    ldp x14, x15, [x5, #-16]!
116    stp x14, x15, [x17, #-16]!
117    CFI_REL_OFFSET(x28, -((BOUNDARY_FRAME_SLOT + 0) * 8))
118    CFI_REL_OFFSET(x27, -((BOUNDARY_FRAME_SLOT + 1) * 8))
119    ldp x14, x15, [x5, #-16]!
120    stp x14, x15, [x17, #-16]!
121    CFI_REL_OFFSET(x26, -((BOUNDARY_FRAME_SLOT + 2) * 8))
122    CFI_REL_OFFSET(x25, -((BOUNDARY_FRAME_SLOT + 3) * 8))
123    ldp x14, x15, [x5, #-16]!
124    stp x14, x15, [x17, #-16]!
125    CFI_REL_OFFSET(x24, -((BOUNDARY_FRAME_SLOT + 4) * 8))
126    CFI_REL_OFFSET(x23, -((BOUNDARY_FRAME_SLOT + 5) * 8))
127    ldp x14, x15, [x5, #-16]!
128    stp x14, x15, [x17, #-16]!
129    CFI_REL_OFFSET(x22, -((BOUNDARY_FRAME_SLOT + 6) * 8))
130    CFI_REL_OFFSET(x21, -((BOUNDARY_FRAME_SLOT + 7) * 8))
131    ldp x14, x15, [x5, #-16]!
132    stp x14, x15, [x17, #-16]!
133    CFI_REL_OFFSET(x20, -((BOUNDARY_FRAME_SLOT + 8) * 8))
134    CFI_REL_OFFSET(x19, -((BOUNDARY_FRAME_SLOT + 9) * 8))
135    ldp x14, x15, [x5, #-16]!
136    stp x14, x15, [x17, #-16]!
137    CFI_REL_OFFSET(d15, -((BOUNDARY_FRAME_SLOT + 10) * 8))
138    CFI_REL_OFFSET(d14, -((BOUNDARY_FRAME_SLOT + 11) * 8))
139    ldp x14, x15, [x5, #-16]!
140    stp x14, x15, [x17, #-16]!
141    CFI_REL_OFFSET(d13, -((BOUNDARY_FRAME_SLOT + 12) * 8))
142    CFI_REL_OFFSET(d12, -((BOUNDARY_FRAME_SLOT + 13) * 8))
143    ldp x14, x15, [x5, #-16]!
144    stp x14, x15, [x17, #-16]!
145    CFI_REL_OFFSET(d11, -((BOUNDARY_FRAME_SLOT + 14) * 8))
146    CFI_REL_OFFSET(d10, -((BOUNDARY_FRAME_SLOT + 15) * 8))
147    ldp x14, x15, [x5, #-16]!
148    stp x14, x15, [x17, #-16]!
149    CFI_REL_OFFSET(d9, -((BOUNDARY_FRAME_SLOT + 16) * 8))
150    CFI_REL_OFFSET(d8, -((BOUNDARY_FRAME_SLOT + 17) * 8))
151
152    ASSERT_REGS_CMP sp, x17, eq
153
154    // Save used registers
155    stp x0, x1, [sp, #-16]!
156    stp x2, x3, [sp, #-16]!
157
158    mov x3, x4
159    // Arguments are already lie in the registers, because signature of DeoptimizeAfterCFrame is similar to InvokeInterpreter
160    bl InvokeInterpreter
161
162    // Restore used registers, but not x0 which holds result of the invoked method and should survive to the end
163    // So we use r7 instead of r0 for restoring THRED_REG
164    ldp x2, x3, [sp], #16
165    ldp x7, x1, [sp], #16
166
167    // Restore callee saved registers
168    sub x3, x3, #((BOUNDARY_FRAME_SLOT - 1) * 8)
169    RESTORE_CALLEE_REGISTERS x3
170    CFI_RESTORE(x28)
171    CFI_RESTORE(x27)
172    CFI_RESTORE(x26)
173    CFI_RESTORE(x25)
174    CFI_RESTORE(x24)
175    CFI_RESTORE(x23)
176    CFI_RESTORE(x22)
177    CFI_RESTORE(x21)
178    CFI_RESTORE(x20)
179    CFI_RESTORE(x19)
180    CFI_RESTORE(d15)
181    CFI_RESTORE(d14)
182    CFI_RESTORE(d13)
183    CFI_RESTORE(d12)
184    CFI_RESTORE(d11)
185    CFI_RESTORE(d10)
186    CFI_RESTORE(d9)
187    CFI_RESTORE(d8)
188
189    # Restore stack pointer
190    add sp, sp, #(((CFRAME_HEADER_SIZE - 2) * 8) + CALLEE_SAVED_SIZE)
191
192    ldr fp, [sp, #-8]
193    CFI_RESTORE(fp)
194    CFI_DEF_CFA(sp, (2 * 8))
195    ldr lr, [sp, #8]
196    CFI_RESTORE(lr)
197    add sp, sp, #16
198    CFI_ADJUST_CFA_OFFSET(-(2 * 8))
199    mov THREAD_REG, x7
200    CFI_RESTORE(THREAD_REG)
201    fmov d0, x0
202    ret
203    CFI_ENDPROC
204
205
206.global DeoptimizeAfterIFrame
207.type DeoptimizeAfterIFrame, %function
208DeoptimizeAfterIFrame:
209    CFI_STARTPROC
210    CFI_DEF_CFA(sp, 0)
211#ifndef NDEBUG
212    stp fp, lr, [sp, #-16]!
213    CFI_ADJUST_CFA_OFFSET(2 * 8)
214    CFI_REL_OFFSET(lr, 8)
215#endif
216
217    // Parameters:
218    // x0 - thread
219    // x1 - pc of the entry
220    // x2 - pointer to interpreter Frame
221    // x3 - pointer to cframe origin
222    // x4 - last restored interpreter Frame
223    // x5 - pointer to a callee-saved registers buffer from StackWalker
224
225    CFRAME_COPY_LR x3
226
227    CFI_DEF_CFA(x3, (2 * 8))
228    CFI_REL_OFFSET(lr, 8)
229    CFI_REL_OFFSET(fp, 0)
230    CFI_REL_OFFSET(x28, -((CFRAME_CALLEE_REGS_START_SLOT + 0) * 8))
231    CFI_REL_OFFSET(x27, -((CFRAME_CALLEE_REGS_START_SLOT + 1) * 8))
232    CFI_REL_OFFSET(x26, -((CFRAME_CALLEE_REGS_START_SLOT + 2) * 8))
233    CFI_REL_OFFSET(x25, -((CFRAME_CALLEE_REGS_START_SLOT + 3) * 8))
234    CFI_REL_OFFSET(x24, -((CFRAME_CALLEE_REGS_START_SLOT + 4) * 8))
235    CFI_REL_OFFSET(x23, -((CFRAME_CALLEE_REGS_START_SLOT + 5) * 8))
236    CFI_REL_OFFSET(x22, -((CFRAME_CALLEE_REGS_START_SLOT + 6) * 8))
237    CFI_REL_OFFSET(x21, -((CFRAME_CALLEE_REGS_START_SLOT + 7) * 8))
238    CFI_REL_OFFSET(x20, -((CFRAME_CALLEE_REGS_START_SLOT + 8) * 8))
239    CFI_REL_OFFSET(x19, -((CFRAME_CALLEE_REGS_START_SLOT + 9) * 8))
240    CFI_REL_OFFSET(d15, -((CFRAME_CALLEE_REGS_START_SLOT + 10) * 8))
241    CFI_REL_OFFSET(d14, -((CFRAME_CALLEE_REGS_START_SLOT + 11) * 8))
242    CFI_REL_OFFSET(d13, -((CFRAME_CALLEE_REGS_START_SLOT + 12) * 8))
243    CFI_REL_OFFSET(d12, -((CFRAME_CALLEE_REGS_START_SLOT + 13) * 8))
244    CFI_REL_OFFSET(d11, -((CFRAME_CALLEE_REGS_START_SLOT + 14) * 8))
245    CFI_REL_OFFSET(d10, -((CFRAME_CALLEE_REGS_START_SLOT + 15) * 8))
246    CFI_REL_OFFSET(d9, -((CFRAME_CALLEE_REGS_START_SLOT + 16) * 8))
247    CFI_REL_OFFSET(d8, -((CFRAME_CALLEE_REGS_START_SLOT + 17) * 8))
248
249    // Restore fp by pointer to the I2C boundary frame
250    mov fp, x3
251    CFI_DEF_CFA_REGISTER(fp)
252
253    // Restore return address, so after interperter finished, it returns to the I2C bridge
254
255    // Restore callee saved registers
256    RESTORE_CALLEE_REGISTERS x5
257    CFI_RESTORE(x28)
258    CFI_RESTORE(x27)
259    CFI_RESTORE(x26)
260    CFI_RESTORE(x25)
261    CFI_RESTORE(x24)
262    CFI_RESTORE(x23)
263    CFI_RESTORE(x22)
264    CFI_RESTORE(x21)
265    CFI_RESTORE(x20)
266    CFI_RESTORE(x19)
267    CFI_RESTORE(d15)
268    CFI_RESTORE(d14)
269    CFI_RESTORE(d13)
270    CFI_RESTORE(d12)
271    CFI_RESTORE(d11)
272    CFI_RESTORE(d10)
273    CFI_RESTORE(d9)
274    CFI_RESTORE(d8)
275
276    // Restore stack pointer to the beginning of the cframe
277    mov sp, fp
278
279    mov x3, x4
280    bl InvokeInterpreter
281    // InvokeInterpreter returns int64 value, but result can be double, so we copy value to vector register
282    fmov d0, x0
283
284    ldp fp, lr, [sp], #16
285    CFI_RESTORE(fp)
286    CFI_RESTORE(lr)
287    CFI_DEF_CFA(sp, 0)
288    ret
289    CFI_ENDPROC
290
291
292.global DropCompiledFrameAndReturn
293.type DropCompiledFrameAndReturn, %function
294DropCompiledFrameAndReturn:
295    CFI_STARTPROC
296    CFI_DEF_CFA(sp, 0)
297#ifndef NDEBUG
298    stp fp, lr, [sp, #-16]!
299    CFI_ADJUST_CFA_OFFSET(2 * 8)
300    CFI_REL_OFFSET(lr, 8)
301#endif
302
303    // x0 - pointer to cframe origin
304    // x1 - pointer to a callee-saved registers buffer from StackWalker
305    CFRAME_GET_LR x0
306
307    CFI_DEF_CFA(x0, (2 * 8))
308    CFI_RESTORE(lr)
309    CFI_REL_OFFSET(fp, 0)
310    CFI_REL_OFFSET(x28, -((CFRAME_CALLEE_REGS_START_SLOT + 0) * 8))
311    CFI_REL_OFFSET(x27, -((CFRAME_CALLEE_REGS_START_SLOT + 1) * 8))
312    CFI_REL_OFFSET(x26, -((CFRAME_CALLEE_REGS_START_SLOT + 2) * 8))
313    CFI_REL_OFFSET(x25, -((CFRAME_CALLEE_REGS_START_SLOT + 3) * 8))
314    CFI_REL_OFFSET(x24, -((CFRAME_CALLEE_REGS_START_SLOT + 4) * 8))
315    CFI_REL_OFFSET(x23, -((CFRAME_CALLEE_REGS_START_SLOT + 5) * 8))
316    CFI_REL_OFFSET(x22, -((CFRAME_CALLEE_REGS_START_SLOT + 6) * 8))
317    CFI_REL_OFFSET(x21, -((CFRAME_CALLEE_REGS_START_SLOT + 7) * 8))
318    CFI_REL_OFFSET(x20, -((CFRAME_CALLEE_REGS_START_SLOT + 8) * 8))
319    CFI_REL_OFFSET(x19, -((CFRAME_CALLEE_REGS_START_SLOT + 9) * 8))
320    CFI_REL_OFFSET(d15, -((CFRAME_CALLEE_REGS_START_SLOT + 10) * 8))
321    CFI_REL_OFFSET(d14, -((CFRAME_CALLEE_REGS_START_SLOT + 11) * 8))
322    CFI_REL_OFFSET(d13, -((CFRAME_CALLEE_REGS_START_SLOT + 12) * 8))
323    CFI_REL_OFFSET(d12, -((CFRAME_CALLEE_REGS_START_SLOT + 13) * 8))
324    CFI_REL_OFFSET(d11, -((CFRAME_CALLEE_REGS_START_SLOT + 14) * 8))
325    CFI_REL_OFFSET(d10, -((CFRAME_CALLEE_REGS_START_SLOT + 15) * 8))
326    CFI_REL_OFFSET(d9, -((CFRAME_CALLEE_REGS_START_SLOT + 16) * 8))
327    CFI_REL_OFFSET(d8, -((CFRAME_CALLEE_REGS_START_SLOT + 17) * 8))
328
329    mov fp, x0
330    CFI_DEF_CFA_REGISTER(fp)
331
332    // Restore callee saved registers
333    RESTORE_CALLEE_REGISTERS x1
334    CFI_RESTORE(x28)
335    CFI_RESTORE(x27)
336    CFI_RESTORE(x26)
337    CFI_RESTORE(x25)
338    CFI_RESTORE(x24)
339    CFI_RESTORE(x23)
340    CFI_RESTORE(x22)
341    CFI_RESTORE(x21)
342    CFI_RESTORE(x20)
343    CFI_RESTORE(x19)
344    CFI_RESTORE(d15)
345    CFI_RESTORE(d14)
346    CFI_RESTORE(d13)
347    CFI_RESTORE(d12)
348    CFI_RESTORE(d11)
349    CFI_RESTORE(d10)
350    CFI_RESTORE(d9)
351    CFI_RESTORE(d8)
352
353    // We need to clear return value, since it will be written to the IFrame's accumulator. Without this, it holds
354    // garbage and StackWalker verification might fail.
355    mov x0, xzr
356
357    mov sp, fp
358    ldr fp, [sp], #16
359    CFI_RESTORE(fp)
360    CFI_DEF_CFA(sp, 0)
361    ret
362    CFI_ENDPROC
363