• 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
18.macro SAVE_CALLEE_GP_REGS base_reg, tmp_reg, offset
19    add \tmp_reg, \base_reg, #(\offset - CALLEE_REG0_OFFSET)
20    stm \tmp_reg, {r4-r10}
21    CFI_REL_OFFSET(r10, (\offset - CALLEE_REG0_OFFSET + 4*6))
22    CFI_REL_OFFSET(r9,  (\offset - CALLEE_REG0_OFFSET + 4*5))
23    CFI_REL_OFFSET(r8,  (\offset - CALLEE_REG0_OFFSET + 4*4))
24    CFI_REL_OFFSET(r7,  (\offset - CALLEE_REG0_OFFSET + 4*3))
25    CFI_REL_OFFSET(r6,  (\offset - CALLEE_REG0_OFFSET + 4*2))
26    CFI_REL_OFFSET(r5,  (\offset - CALLEE_REG0_OFFSET + 4*1))
27    CFI_REL_OFFSET(r4,  (\offset - CALLEE_REG0_OFFSET + 4*0))
28.endm
29
30.macro RESTORE_CALLEE_GP_REGS base_reg, tmp_reg, offset
31    add \tmp_reg, \base_reg, #(\offset - CALLEE_REG0_OFFSET)
32    ldm \tmp_reg, {r4-r10}
33    CFI_RESTORE(r10)
34    CFI_RESTORE(r9)
35    CFI_RESTORE(r8)
36    CFI_RESTORE(r7)
37    CFI_RESTORE(r6)
38    CFI_RESTORE(r5)
39    CFI_RESTORE(r4)
40.endm
41
42.macro SAVE_CALLEE_FP_REGS base_reg, tmp_reg, offset
43    add \tmp_reg, \base_reg, #(\offset - CALLEE_VREG0_OFFSET)
44    vstm \tmp_reg, {d8-d15}
45    CFI_REL_OFFSET(d15, (\offset - CALLEE_VREG0_OFFSET + 4*14))
46    CFI_REL_OFFSET(d14, (\offset - CALLEE_VREG0_OFFSET + 4*12))
47    CFI_REL_OFFSET(d13, (\offset - CALLEE_VREG0_OFFSET + 4*10))
48    CFI_REL_OFFSET(d12, (\offset - CALLEE_VREG0_OFFSET + 4*8))
49    CFI_REL_OFFSET(d11, (\offset - CALLEE_VREG0_OFFSET + 4*6))
50    CFI_REL_OFFSET(d10, (\offset - CALLEE_VREG0_OFFSET + 4*4))
51    CFI_REL_OFFSET(d9,  (\offset - CALLEE_VREG0_OFFSET + 4*2))
52    CFI_REL_OFFSET(d8,  (\offset - CALLEE_VREG0_OFFSET + 4*0))
53.endm
54
55.macro RESTORE_CALLEE_FP_REGS base_reg, tmp_reg, offset
56    add \tmp_reg, \base_reg, #(\offset - CALLEE_VREG0_OFFSET)
57    vldm \tmp_reg, {d8-d15}
58    CFI_RESTORE(d15)
59    CFI_RESTORE(d14)
60    CFI_RESTORE(d13)
61    CFI_RESTORE(d12)
62    CFI_RESTORE(d11)
63    CFI_RESTORE(d10)
64    CFI_RESTORE(d9)
65    CFI_RESTORE(d8)
66.endm
67
68.macro SAVE_CALLER_GP_REGS fp_reg, tmp_reg, paramsnum
69    add \tmp_reg, \fp_reg, #-CALLER_REG0_OFFSET+4*4
70.ifeq \paramsnum
71    stmdb \tmp_reg, {r0-r3}
72.endif
73.ifeq \paramsnum-1
74    stmdb \tmp_reg, {r1-r3}
75.endif
76.ifeq \paramsnum-2
77    stmdb \tmp_reg, {r2-r3}
78.endif
79.ifeq \paramsnum-3
80    str r3, [\tmp_reg, #-4]
81.endif
82.endm
83
84.macro RESTORE_CALLER_GP_REGS fp_reg, tmp_reg, ret_type
85    add \tmp_reg, \fp_reg, #-CALLER_REG0_OFFSET+4*4
86#ifdef PANDA_TARGET_ARM32_ABI_HARD
87.ifnc \ret_type,INTEGER
88#else
89.ifc \ret_type,VOID
90#endif
91    ldmdb \tmp_reg, {r0-r3}
92.else
93    // r0-r1 is 64-bit return value
94    ldmdb \tmp_reg, {r2-r3}
95.endif
96.endm
97
98.macro SAVE_CALLER_FP_REGS fp_reg, tmp_reg
99    add \tmp_reg, \fp_reg, #-CALLER_VREG0_OFFSET
100    vstm \tmp_reg, {d0-d7}
101.endm
102
103.macro RESTORE_CALLER_FP_REGS fp_reg, tmp_reg, ret_type
104    add \tmp_reg, \fp_reg, #-CALLER_VREG0_OFFSET+8*8
105#ifdef PANDA_TARGET_ARM32_ABI_HARD
106.ifnc \ret_type,FLOAT
107    vldmdb \tmp_reg!, {d0-d7}
108.else
109    vldmdb \tmp_reg!, {d1-d7}
110.endif
111#else
112    vldmdb \tmp_reg!, {d0-d7}
113#endif
114.endm
115
116.macro CHECK_NATIVE_EXCEPTION ret_type
117    ldr lr, [THREAD_REG, #MANAGED_THREAD_EXCEPTION_OFFSET]
118    cmp lr, #0
119
120    beq 3f
121    CFI_REMEMBER_STATE
122
123#ifdef PANDA_TARGET_ARM32_ABI_HARD
124.ifc \ret_type,INTEGER
125#else
126.ifnc \ret_type,VOID
127#endif
128    add lr, fp, #-CALLER_REG0_OFFSET
129    ldm lr, {r0-r1}
130.endif
131#ifdef PANDA_TARGET_ARM32_ABI_HARD
132.ifc \ret_type,FLOAT
133    add lr, fp, #-CALLER_VREG0_OFFSET
134    vldr d0, [lr]
135.endif
136#endif
137
138    ldr lr, [sp, #(BRIDGE_FRAME_SIZE - 4)]
139    CFI_RESTORE(lr)
140
141    add sp, sp, #BRIDGE_FRAME_SIZE
142    CFI_ADJUST_CFA_OFFSET(-BRIDGE_FRAME_SIZE)
143
144    b ThrowNativeExceptionBridge
145    CFI_RESTORE_STATE
146
1473:
148    ldr lr, [sp, #(BRIDGE_FRAME_SIZE - 4)]
149    CFI_RESTORE(lr)
150
151    add sp, sp, #BRIDGE_FRAME_SIZE
152    CFI_ADJUST_CFA_OFFSET(-BRIDGE_FRAME_SIZE)
153.endm
154
155.macro BRIDGE_SELECTOR name, notcompiled_entry, compiled_entry
156.global \name
157.type \name, %function
158\name:
159    ldrb r12, [THREAD_REG, #MANAGED_THREAD_FRAME_KIND_OFFSET]
160    tst r12, r12
161    bne \compiled_entry
162    b \notcompiled_entry
163.endm
164
165
166.macro RUNTIME_CALL_CHECKER name, entry
167.global \name
168.type \name, %function
169\name:
170      CFI_STARTPROC
171      CFI_DEF_CFA(sp, 0)
172
173      ldr r12, [THREAD_REG, #MANAGED_THREAD_RUNTIME_CALL_ENABLED_OFFSET]
174
175      sub sp, sp, #8
176      CFI_ADJUST_CFA_OFFSET(8)
177
178      stm sp, {r12, lr}
179      CFI_REL_OFFSET(lr, -4)
180
181      mov r12, #0
182      str r12, [THREAD_REG, #MANAGED_THREAD_RUNTIME_CALL_ENABLED_OFFSET]
183
184      bl \entry
185
186      ldm sp, {r12, lr}
187      CFI_RESTORE(lr)
188
189      add sp, sp, #8
190      CFI_ADJUST_CFA_OFFSET(-8)
191
192      str r12, [THREAD_REG, #MANAGED_THREAD_RUNTIME_CALL_ENABLED_OFFSET]
193
194      bx lr
195      CFI_ENDPROC
196.endm
197
198.macro CALL_RUNTIME mode, entry, paramsnum, ret_type
199      sub sp, sp, #BRIDGE_FRAME_SIZE
200      CFI_ADJUST_CFA_OFFSET(BRIDGE_FRAME_SIZE)
201
202      // Setup BoundaryFrame
203      str lr, [sp, #(BRIDGE_FRAME_SIZE - 1 * 4)]     // Bridge frame, slot 1 = npc = LR (the StackMap stays just after the bridge call)
204      CFI_REL_OFFSET(lr, (BRIDGE_FRAME_SIZE - 1 * 4))
205      str lr, [THREAD_REG, #MANAGED_THREAD_NATIVE_PC_OFFSET] // ManagedThread.npc update
206      mov lr, #COMPILED_CODE_TO_INTERPRETER_BRIDGE
207      str lr, [sp, #(BRIDGE_FRAME_SIZE - 2 * 4)]     // Bridge frame, slot 2 = COMPILED_CODE_TO_INTERPRETER_BRIDGE flag
208      str fp, [sp, #(BRIDGE_FRAME_SIZE - 3 * 4)]    // Bridge frame, slot 3 = parent frame pointer
209      CFI_REL_OFFSET(fp, (BRIDGE_FRAME_SIZE - 3 * 4))
210      add lr, sp, #(BRIDGE_FRAME_SIZE - 3 * 4)
211      str lr, [THREAD_REG, #MANAGED_THREAD_FRAME_OFFSET]    // ManagedThread._frame = this boundary frame
212
213      SAVE_CALLEE_GP_REGS sp, lr, BRIDGE_FRAME_SIZE
214#ifndef PANDA_TARGET_ARM32_ABI_SOFT
215      // StackWalker requires callee-saved FP registers to be saved unconditionally in the runtime bridge
216      SAVE_CALLEE_FP_REGS sp, lr, BRIDGE_FRAME_SIZE
217#endif
218
219.if \mode != RUNTIME_MODE_SLOW_PATH
220      SAVE_CALLER_GP_REGS fp, lr, \paramsnum
221.endif
222
223#ifndef PANDA_TARGET_ARM32_ABI_SOFT
224      ldr r4, [fp, #(-CFRAME_FLAGS_SLOT * 4)]
225      tst r4, #CFRAME_HAS_FLOAT_REGS_FLAG_MASK
226      beq 1f
227
228      SAVE_CALLER_FP_REGS fp, lr
2291:
230#endif
231
232      bl \entry
233
234      // State restore
235      str fp, [THREAD_REG, #MANAGED_THREAD_FRAME_OFFSET]
236
237#ifndef PANDA_TARGET_ARM32_ABI_SOFT
238      tst r4, #CFRAME_HAS_FLOAT_REGS_FLAG_MASK
239      beq 2f
240
241      RESTORE_CALLEE_FP_REGS sp, lr, BRIDGE_FRAME_SIZE
242      RESTORE_CALLER_FP_REGS fp, lr, \ret_type
2432:
244#endif
245
246      RESTORE_CALLEE_GP_REGS sp, lr, BRIDGE_FRAME_SIZE
247      RESTORE_CALLER_GP_REGS fp, lr, \ret_type
248
249      CHECK_NATIVE_EXCEPTION \ret_type
250.endm
251
252.macro ENTRYPOINT name, entry, paramsnum, ret_type
253.global \name
254.type \name, %function
255\name:
256      CFI_STARTPROC
257      CFI_DEF_CFA(sp, 0)
258
259      CALL_RUNTIME RUNTIME_MODE_DEFAULT, \entry, \paramsnum, \ret_type
260      bx lr
261      CFI_ENDPROC
262.endm
263
264// Unused for 32-bit arm
265.macro ENTRYPOINT_ODD_SAVED name, entry, paramsnum, ret_type
266      ENTRYPOINT \name, \entry, \paramsnum, \ret_type
267.endm
268
269.macro ENTRYPOINT_SLOW_PATH name, entry, paramsnum, ret_type
270.global \name
271.type \name, %function
272\name:
273    CFI_STARTPROC
274    CFI_DEF_CFA(sp, 0)
275
276    CALL_RUNTIME RUNTIME_MODE_SLOW_PATH, \entry, \paramsnum, \ret_type
277    bx lr
278    CFI_ENDPROC
279.endm
280
281.macro MethodEntrypointStub name, entry, notcompiled
282.global \name
283.type \name, %function
284\name:
285    CFI_STARTPROC
286    CFI_DEF_CFA(sp, 0)
287
288    // If the caller is not a compiled method, we need to call \entry
289    // and return back after its execution
290    ldrb r1, [THREAD_REG, #MANAGED_THREAD_FRAME_KIND_OFFSET]
291    tst r1, r1
292    beq .L\notcompiled
293    CFI_REMEMBER_STATE
294
295    str lr, [sp, #-4]
296    CFI_REL_OFFSET(lr, -4)
297    str lr, [THREAD_REG, #MANAGED_THREAD_NATIVE_PC_OFFSET]
298    mov lr, #COMPILED_CODE_TO_INTERPRETER_BRIDGE
299    str lr, [sp, #-8]
300    str fp, [sp, #-12]
301    CFI_REL_OFFSET(fp, -12)
302    sub lr, sp, #12
303    str lr, [THREAD_REG, #MANAGED_THREAD_FRAME_OFFSET]
304    sub sp, sp, #16
305    CFI_ADJUST_CFA_OFFSET(16)
306
307    push {r4 - r10}
308    CFI_ADJUST_CFA_OFFSET(28)
309    CFI_REL_OFFSET(r10, (6 * 4))
310    CFI_REL_OFFSET(r9,  (5 * 4))
311    CFI_REL_OFFSET(r8,  (4 * 4))
312    CFI_REL_OFFSET(r7,  (3 * 4))
313    CFI_REL_OFFSET(r6,  (2 * 4))
314    CFI_REL_OFFSET(r5,  (1 * 4))
315    CFI_REL_OFFSET(r4,  (0 * 4))
316
317#ifndef PANDA_TARGET_ARM32_ABI_SOFT
318    vpush {d8 - d15}
319    CFI_ADJUST_CFA_OFFSET(64)
320    CFI_REL_OFFSET(d15, (14 * 4))
321    CFI_REL_OFFSET(d14, (12 * 4))
322    CFI_REL_OFFSET(d13, (10 * 4))
323    CFI_REL_OFFSET(d12, (8 * 4))
324    CFI_REL_OFFSET(d11, (6 * 4))
325    CFI_REL_OFFSET(d10, (4 * 4))
326    CFI_REL_OFFSET(d9,  (2 * 4))
327    CFI_REL_OFFSET(d8,  (0 * 4))
328#endif
329
330    // align to 8
331    sub sp, sp, #4
332
333    bl \entry
334    // we're not going to return back here
335
336.L\notcompiled:
337    CFI_RESTORE_STATE
338    CFI_DEF_CFA(sp, 0)
339    str lr, [sp, #-4]
340    CFI_REL_OFFSET(lr, -(1 * 4))
341    sub sp, sp, #8
342    CFI_ADJUST_CFA_OFFSET(2 * 4)
343    bl \entry
344    add sp, sp, #8
345    CFI_ADJUST_CFA_OFFSET(-(2 * 4))
346    ldr lr, [sp, #-4]
347    CFI_RESTORE(lr)
348    bx lr
349    CFI_ENDPROC
350.endm
351
352#include "entrypoints_gen.S"
353#include "entrypoints_bridge_asm_macro.inl"
354
355MethodEntrypointStub AbstractMethodStub AbstractMethodErrorEntrypoint ame_not_compiled
356
357MethodEntrypointStub DefaultConflictMethodStub IncompatibleClassChangeErrorForMethodConflictEntrypoint icce_not_compiled
358