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