• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/**
2 * Copyright (c) 2021-2024 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/amd64/helpers_amd64.S"
18
19.macro SAVE_CALLEE_GP_REGS base_reg, offset
20    movq %r15, (\offset - CALLEE_REG0_OFFSET + 8*4)(%\base_reg)
21    CFI_REL_OFFSET(r15, (\offset - CALLEE_REG0_OFFSET+8*4))
22    movq %r14, (\offset - CALLEE_REG0_OFFSET + 8*3)(%\base_reg)
23    CFI_REL_OFFSET(r14, (\offset - CALLEE_REG0_OFFSET+8*3))
24    movq %r13, (\offset - CALLEE_REG0_OFFSET + 8*2)(%\base_reg)
25    CFI_REL_OFFSET(r13, (\offset - CALLEE_REG0_OFFSET+8*2))
26    movq %r12, (\offset - CALLEE_REG0_OFFSET + 8*1)(%\base_reg)
27    CFI_REL_OFFSET(r12, (\offset - CALLEE_REG0_OFFSET+8*1))
28    movq %rbx, (\offset - CALLEE_REG0_OFFSET + 8*0)(%\base_reg)
29    CFI_REL_OFFSET(rbx, (\offset - CALLEE_REG0_OFFSET+8*0))
30.endm
31
32.macro RESTORE_CALLEE_GP_REGS base_reg, offset
33    movq (\offset - CALLEE_REG0_OFFSET + 8*4)(%\base_reg), %r15
34    CFI_RESTORE(r15)
35    movq (\offset - CALLEE_REG0_OFFSET + 8*3)(%\base_reg), %r14
36    CFI_RESTORE(r14)
37    movq (\offset - CALLEE_REG0_OFFSET + 8*2)(%\base_reg), %r13
38    CFI_RESTORE(r13)
39    movq (\offset - CALLEE_REG0_OFFSET + 8*1)(%\base_reg), %r12
40    CFI_RESTORE(r12)
41    movq (\offset - CALLEE_REG0_OFFSET + 8*0)(%\base_reg), %rbx
42    CFI_RESTORE(rbx)
43.endm
44
45.macro SAVE_CALLER_GP_REGS fp_reg, paramsnum, ret_type
46.ifnc \ret_type,INTEGER
47    movq %rax, (-CALLER_REG0_OFFSET + 0)(%\fp_reg)
48.endif
49.ifle \paramsnum-3
50    movq %rcx, (-CALLER_REG0_OFFSET + 8)(%\fp_reg)
51.endif
52.ifle \paramsnum-2
53    movq %rdx, (-CALLER_REG0_OFFSET + 16)(%\fp_reg)
54.endif
55    movq %r11, (-CALLER_REG0_OFFSET + 24)(%\fp_reg)
56    movq %r10, (-CALLER_REG0_OFFSET + 32)(%\fp_reg)
57.ifle \paramsnum-5
58    movq %r9, (-CALLER_REG0_OFFSET + 40)(%\fp_reg)
59.endif
60.ifle \paramsnum-1
61    movq %rsi, (-CALLER_REG0_OFFSET + 48)(%\fp_reg)
62.endif
63.ifeq \paramsnum
64    movq %rdi, (-CALLER_REG0_OFFSET + 56)(%\fp_reg)
65.endif
66.ifle \paramsnum-4
67    movq %r8, (-CALLER_REG0_OFFSET + 64)(%\fp_reg)
68.endif
69.endm
70
71.macro RESTORE_CALLER_GP_REGS fp_reg, ret_type
72.ifnc \ret_type,INTEGER
73    movq (-CALLER_REG0_OFFSET + 0)(%\fp_reg), %rax
74.endif
75    movq (-CALLER_REG0_OFFSET + 8)(%\fp_reg), %rcx
76    movq (-CALLER_REG0_OFFSET + 16)(%\fp_reg), %rdx
77    movq (-CALLER_REG0_OFFSET + 24)(%\fp_reg), %r11
78    movq (-CALLER_REG0_OFFSET + 32)(%\fp_reg), %r10
79    movq (-CALLER_REG0_OFFSET + 40)(%\fp_reg), %r9
80    movq (-CALLER_REG0_OFFSET + 48)(%\fp_reg), %rsi
81    movq (-CALLER_REG0_OFFSET + 56)(%\fp_reg), %rdi
82    movq (-CALLER_REG0_OFFSET + 64)(%\fp_reg), %r8
83.endm
84
85.macro SAVE_CALLER_FP_REGS fp_reg, ret_type
86.ifnc \ret_type,FLOAT
87    movsd %xmm0, (-CALLER_VREG0_OFFSET + 0)(%\fp_reg)
88.endif
89    movsd %xmm1, (-CALLER_VREG0_OFFSET + 8)(%\fp_reg)
90    movsd %xmm2, (-CALLER_VREG0_OFFSET + 16)(%\fp_reg)
91    movsd %xmm3, (-CALLER_VREG0_OFFSET + 24)(%\fp_reg)
92    movsd %xmm4, (-CALLER_VREG0_OFFSET + 32)(%\fp_reg)
93    movsd %xmm5, (-CALLER_VREG0_OFFSET + 40)(%\fp_reg)
94    movsd %xmm6, (-CALLER_VREG0_OFFSET + 48)(%\fp_reg)
95    movsd %xmm7, (-CALLER_VREG0_OFFSET + 56)(%\fp_reg)
96    movsd %xmm8, (-CALLER_VREG0_OFFSET + 64)(%\fp_reg)
97    movsd %xmm9, (-CALLER_VREG0_OFFSET + 72)(%\fp_reg)
98    movsd %xmm10, (-CALLER_VREG0_OFFSET + 80)(%\fp_reg)
99    movsd %xmm11, (-CALLER_VREG0_OFFSET + 88)(%\fp_reg)
100    movsd %xmm12, (-CALLER_VREG0_OFFSET + 96)(%\fp_reg)
101    movsd %xmm13, (-CALLER_VREG0_OFFSET + 104)(%\fp_reg)
102    movsd %xmm14, (-CALLER_VREG0_OFFSET + 112)(%\fp_reg)
103    movsd %xmm15, (-CALLER_VREG0_OFFSET + 120)(%\fp_reg)
104.endm
105
106.macro RESTORE_CALLER_FP_REGS fp_reg, ret_type
107.ifnc \ret_type,FLOAT
108    movsd (-CALLER_VREG0_OFFSET + 0)(%\fp_reg), %xmm0
109.endif
110    movsd (-CALLER_VREG0_OFFSET + 8)(%\fp_reg), %xmm1
111    movsd (-CALLER_VREG0_OFFSET + 16)(%\fp_reg), %xmm2
112    movsd (-CALLER_VREG0_OFFSET + 24)(%\fp_reg), %xmm3
113    movsd (-CALLER_VREG0_OFFSET + 32)(%\fp_reg), %xmm4
114    movsd (-CALLER_VREG0_OFFSET + 40)(%\fp_reg), %xmm5
115    movsd (-CALLER_VREG0_OFFSET + 48)(%\fp_reg), %xmm6
116    movsd (-CALLER_VREG0_OFFSET + 56)(%\fp_reg), %xmm7
117    movsd (-CALLER_VREG0_OFFSET + 64)(%\fp_reg), %xmm8
118    movsd (-CALLER_VREG0_OFFSET + 72)(%\fp_reg), %xmm9
119    movsd (-CALLER_VREG0_OFFSET + 80)(%\fp_reg), %xmm10
120    movsd (-CALLER_VREG0_OFFSET + 88)(%\fp_reg), %xmm11
121    movsd (-CALLER_VREG0_OFFSET + 96)(%\fp_reg), %xmm12
122    movsd (-CALLER_VREG0_OFFSET + 104)(%\fp_reg), %xmm13
123    movsd (-CALLER_VREG0_OFFSET + 112)(%\fp_reg), %xmm14
124    movsd (-CALLER_VREG0_OFFSET + 120)(%\fp_reg), %xmm15
125.endm
126
127.macro BRIDGE_SELECTOR name, notcompiled_entry, compiled_entry
128.global \name
129#ifdef PANDA_WITH_HIDDEN_SYMBOLS
130.hidden \name
131.hidden \notcompiled_entry
132.hidden \compiled_entry
133#else
134.protected \name
135.protected \notcompiled_entry
136.protected \compiled_entry
137#endif
138TYPE_FUNCTION(\name)
139\name:
140    movb MANAGED_THREAD_FRAME_KIND_OFFSET(%THREAD_REG), %r10b
141    testb %r10b, %r10b
142    jnz \compiled_entry
143    jmp \notcompiled_entry
144.endm
145
146.macro RUNTIME_CALL_CHECKER name, entry
147.global \name
148#ifdef PANDA_WITH_HIDDEN_SYMBOLS
149.hidden \name
150.hidden \entry
151#else
152.protected \name
153.protected \entry
154#endif
155TYPE_FUNCTION(\name)
156\name:
157    CFI_STARTPROC
158    CFI_DEF_CFA(rsp, 8)
159
160    pushq %r12
161    CFI_ADJUST_CFA_OFFSET(8)
162    CFI_REL_OFFSET(r12, 0)
163
164    movq MANAGED_THREAD_RUNTIME_CALL_ENABLED_OFFSET(%THREAD_REG), %r12
165
166    movq $0, MANAGED_THREAD_RUNTIME_CALL_ENABLED_OFFSET(%THREAD_REG)
167
168    call \entry
169
170    movq %r12, MANAGED_THREAD_RUNTIME_CALL_ENABLED_OFFSET(%THREAD_REG)
171    popq %r12
172    CFI_ADJUST_CFA_OFFSET(-8)
173    CFI_RESTORE(r12)
174
175    // return to the caller
176    retq
177    CFI_ENDPROC
178.endm
179
180.macro CALL_RUNTIME mode, entry, paramsnum, ret_type
181    subq $(BRIDGE_FRAME_SIZE - 8), %rsp
182    CFI_ADJUST_CFA_OFFSET((BRIDGE_FRAME_SIZE - 8))
183
184    SAVE_CALLEE_GP_REGS rsp, BRIDGE_FRAME_SIZE
185
186    // Bridge frame:
187    //   [1] native_pc = retaddr
188    //   [2] parent frame pointer
189    //   [3] COMPILED_CODE_TO_INTERPRETER_BRIDGE flag
190
191    // Bridge frame, slot 1 = npc = retaddr (StackMap stays just after the bridge call)
192    mov (BRIDGE_FRAME_SIZE - 1 * 8)(%rsp), %r14
193    // ManagedThread.npc update
194    mov %r14, MANAGED_THREAD_NATIVE_PC_OFFSET(%THREAD_REG)
195
196    // Bridge frame, slot 2 = COMPILED_CODE_TO_INTERPRETER_BRIDGE flag
197    movq $COMPILED_CODE_TO_INTERPRETER_BRIDGE, (BRIDGE_FRAME_SIZE - 2 * 8)(%rsp)
198    // Bridge frame, slot 3 = parent frame pointer
199    mov %rbp, (BRIDGE_FRAME_SIZE - 3 * 8)(%rsp)
200    CFI_REL_OFFSET(rbp, (BRIDGE_FRAME_SIZE - 3 * 8))
201
202    leaq (BRIDGE_FRAME_SIZE - 3 * 8)(%rsp), %r13
203    // ManagedThread._frame = this boundary frame
204    mov %r13, MANAGED_THREAD_FRAME_OFFSET(%THREAD_REG)
205
206.if \mode != RUNTIME_MODE_SLOW_PATH
207    SAVE_CALLER_GP_REGS rbp, \paramsnum, \ret_type
208.endif
209
210    movq (-CFRAME_FLAGS_SLOT * 8)(%rbp), %r12
211    testq $CFRAME_HAS_FLOAT_REGS_FLAG_MASK, %r12
212    jz 1f
213
214    SAVE_CALLER_FP_REGS rbp, \ret_type
215
2161:
217    // call to BoundaryFrame bridge
218    call \entry
219
220    // ManagedThread._frame = parent frame pointer
221    movq %rbp, MANAGED_THREAD_FRAME_OFFSET(%THREAD_REG)
222
223    RESTORE_CALLER_GP_REGS rbp, \ret_type
224
225    testq $CFRAME_HAS_FLOAT_REGS_FLAG_MASK, %r12
226    jz 2f
227
228    RESTORE_CALLER_FP_REGS rbp, \ret_type
229
2302:
231    RESTORE_CALLEE_GP_REGS rsp, BRIDGE_FRAME_SIZE
232
233    cmpq $0, MANAGED_THREAD_EXCEPTION_OFFSET(%THREAD_REG)
234    jz 3f
235    CFI_REMEMBER_STATE
236
237.ifc \ret_type,INTEGER
238    movq (-CALLER_REG0_OFFSET + 0)(%rbp), %rax
239.endif
240.ifc \ret_type,FLOAT
241    movsd (-CALLER_VREG0_OFFSET + 0)(%rbp), %xmm0
242.endif
243    addq $(BRIDGE_FRAME_SIZE - 8), %rsp
244    CFI_ADJUST_CFA_OFFSET(-(BRIDGE_FRAME_SIZE - 8))
245    jmp ThrowNativeExceptionBridge
246    CFI_RESTORE_STATE
247
2483:
249    addq $(BRIDGE_FRAME_SIZE - 8), %rsp
250    CFI_ADJUST_CFA_OFFSET(-(BRIDGE_FRAME_SIZE - 8))
251    // return to the caller
252.endm
253
254.macro ENTRYPOINT name, entry, paramsnum, ret_type
255.global \name
256#ifdef PANDA_WITH_HIDDEN_SYMBOLS
257.hidden \name
258.hidden \entry
259#else
260.protected \name
261.protected \entry
262#endif
263TYPE_FUNCTION(\name)
264\name:
265    CFI_STARTPROC
266    CFI_DEF_CFA(rsp, 8)
267
268    CALL_RUNTIME RUNTIME_MODE_DEFAULT, \entry, \paramsnum, \ret_type
269    retq
270    CFI_ENDPROC
271.endm
272
273// Unused for x86_64
274.macro ENTRYPOINT_ODD_SAVED name, entry, paramsnum, ret_type
275      ENTRYPOINT \name, \entry, \paramsnum, \ret_type
276.endm
277
278.macro ENTRYPOINT_SLOW_PATH name, entry, paramsnum, ret_type
279.global \name
280#ifdef PANDA_WITH_HIDDEN_SYMBOLS
281.hidden \name
282.hidden \entry
283#else
284.protected \name
285.protected \entry
286#endif
287TYPE_FUNCTION(\name)
288\name:
289    CFI_STARTPROC
290    CFI_DEF_CFA(rsp, 8)
291
292    CALL_RUNTIME RUNTIME_MODE_SLOW_PATH, \entry, \paramsnum, \ret_type
293    retq
294    CFI_ENDPROC
295.endm
296
297.macro MethodEntrypointStub name, entry, notcompiled
298.global \name
299#ifdef PANDA_WITH_HIDDEN_SYMBOLS
300.hidden \name
301.hidden \entry
302#else
303.protected \name
304.protected \entry
305#endif
306TYPE_FUNCTION(\name)
307\name:
308    CFI_STARTPROC
309    CFI_DEF_CFA(rsp, 8)
310
311    // If the caller is not a compiled method, we need to call \entry
312    // and return back after its execution
313    movb MANAGED_THREAD_FRAME_KIND_OFFSET(%THREAD_REG), %r9b
314    testb %r9b, %r9b
315    jz .L\notcompiled
316    CFI_REMEMBER_STATE
317
318    movq (%rsp), %rax
319    movq  %rax, MANAGED_THREAD_NATIVE_PC_OFFSET(%THREAD_REG)
320    movq  %rbp,  -0x10(%rsp)
321    CFI_REL_OFFSET(rbp, -(2 * 8))
322    movq $COMPILED_CODE_TO_INTERPRETER_BRIDGE, -0x8(%rsp)
323    lea -0x10(%rsp), %rax
324    movq %rax, MANAGED_THREAD_FRAME_OFFSET(%THREAD_REG)
325
326    movq %r15, -0x20(%rsp)
327    CFI_REL_OFFSET(r15, -(4 * 8))
328    movq %r14, -0x28(%rsp)
329    CFI_REL_OFFSET(r14, -(5 * 8))
330    movq %r13, -0x30(%rsp)
331    CFI_REL_OFFSET(r13, -(6 * 8))
332    movq %r12, -0x38(%rsp)
333    CFI_REL_OFFSET(r12, -(7 * 8))
334    movq %rbx, -0x40(%rsp)
335    CFI_REL_OFFSET(rbx, -(8 * 8))
336
337    // ------------- header
338    // %rsp        : ret addr
339    // %rsp -0x08  : $COMPILED_CODE_TO_INTERPRETER_BRIDGE
340    // %rsp -0x10  : frame pointer
341    // %rsp -0x18  : UNUSED
342    // ------------- callee-saved regs
343    // %rsp -0x20  : %r15
344    // %rsp -0x28  : %r14
345    // %rsp -0x30  : %r13
346    // %rsp -0x38  : %r12
347    // %rsp -0x40  : %rbx
348    // %rsp -0x48  : empty slot for alignment
349    subq $0x48, %rsp
350    CFI_ADJUST_CFA_OFFSET(9 * 8)
351
352    call \entry
353    // we're not going to return back here
354
355.L\notcompiled:
356    CFI_RESTORE_STATE
357    CFI_DEF_CFA(rsp, 8)
358    subq $0x8, %rsp
359    CFI_ADJUST_CFA_OFFSET(8)
360    call \entry
361    addq $0x8, %rsp
362    CFI_ADJUST_CFA_OFFSET(-8)
363    ret
364    CFI_ENDPROC
365.endm
366
367#include "entrypoints_gen.S"
368#include "entrypoints_bridge_asm_macro.inl"
369
370MethodEntrypointStub AbstractMethodStub AbstractMethodErrorEntrypoint ame_not_compiled
371
372MethodEntrypointStub DefaultConflictMethodStub IncompatibleClassChangeErrorForMethodConflictEntrypoint icce_not_compiled
373