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