• 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 "asm_defines.h"
17
18.macro SAVE_CALLEE_GP_REGS base_reg, offset
19    stp x27, x28, [\base_reg, #(\offset - CALLEE_REG0_OFFSET + 8*8)]
20    CFI_REL_OFFSET(x28, (\offset - CALLEE_REG0_OFFSET + 8*9))
21    CFI_REL_OFFSET(x27, (\offset - CALLEE_REG0_OFFSET + 8*8))
22    stp x25, x26, [\base_reg, #(\offset - CALLEE_REG0_OFFSET + 8*6)]
23    CFI_REL_OFFSET(x26, (\offset - CALLEE_REG0_OFFSET + 8*7))
24    CFI_REL_OFFSET(x25, (\offset - CALLEE_REG0_OFFSET + 8*6))
25    stp x23, x24, [\base_reg, #(\offset - CALLEE_REG0_OFFSET + 8*4)]
26    CFI_REL_OFFSET(x24, (\offset - CALLEE_REG0_OFFSET + 8*5))
27    CFI_REL_OFFSET(x23, (\offset - CALLEE_REG0_OFFSET + 8*4))
28    stp x21, x22, [\base_reg, #(\offset - CALLEE_REG0_OFFSET + 8*2)]
29    CFI_REL_OFFSET(x22, (\offset - CALLEE_REG0_OFFSET + 8*3))
30    CFI_REL_OFFSET(x21, (\offset - CALLEE_REG0_OFFSET + 8*2))
31    stp x19, x20, [\base_reg, #(\offset - CALLEE_REG0_OFFSET)]
32    CFI_REL_OFFSET(x20, (\offset - CALLEE_REG0_OFFSET + 8*1))
33    CFI_REL_OFFSET(x19, (\offset - CALLEE_REG0_OFFSET + 8*0))
34.endm
35
36.macro RESTORE_CALLEE_GP_REGS base_reg, offset
37    ldp x27, x28, [\base_reg, #(\offset - CALLEE_REG0_OFFSET + 8*8)]
38    CFI_RESTORE(x28)
39    CFI_RESTORE(x27)
40    ldp x25, x26, [\base_reg, #(\offset - CALLEE_REG0_OFFSET + 8*6)]
41    CFI_RESTORE(x26)
42    CFI_RESTORE(x25)
43    ldp x23, x24, [\base_reg, #(\offset - CALLEE_REG0_OFFSET + 8*4)]
44    CFI_RESTORE(x24)
45    CFI_RESTORE(x23)
46    ldp x21, x22, [\base_reg, #(\offset - CALLEE_REG0_OFFSET + 8*2)]
47    CFI_RESTORE(x22)
48    CFI_RESTORE(x21)
49    ldp x19, x20, [\base_reg, #(\offset - CALLEE_REG0_OFFSET)]
50    CFI_RESTORE(x20)
51    CFI_RESTORE(x19)
52.endm
53
54.macro SAVE_CALLEE_FP_REGS base_reg, offset
55    stp d14, d15, [\base_reg, #(\offset - CALLEE_VREG0_OFFSET + 8*6)]
56    CFI_REL_OFFSET(d15, (\offset - CALLEE_VREG0_OFFSET + 8*7))
57    CFI_REL_OFFSET(d14, (\offset - CALLEE_VREG0_OFFSET + 8*6))
58    stp d12, d13, [\base_reg, #(\offset - CALLEE_VREG0_OFFSET + 8*4)]
59    CFI_REL_OFFSET(d13, (\offset - CALLEE_VREG0_OFFSET + 8*5))
60    CFI_REL_OFFSET(d12, (\offset - CALLEE_VREG0_OFFSET + 8*4))
61    stp d10, d11, [\base_reg, #(\offset - CALLEE_VREG0_OFFSET + 8*2)]
62    CFI_REL_OFFSET(d11, (\offset - CALLEE_VREG0_OFFSET + 8*3))
63    CFI_REL_OFFSET(d10, (\offset - CALLEE_VREG0_OFFSET + 8*2))
64    stp d8, d9,   [\base_reg, #(\offset - CALLEE_VREG0_OFFSET)]
65    CFI_REL_OFFSET(d9,  (\offset - CALLEE_VREG0_OFFSET + 8*1))
66    CFI_REL_OFFSET(d8,  (\offset - CALLEE_VREG0_OFFSET + 8*0))
67.endm
68
69.macro RESTORE_CALLEE_FP_REGS base_reg, offset
70    ldp d14, d15, [\base_reg, #(\offset - CALLEE_VREG0_OFFSET + 8*6)]
71    CFI_RESTORE(d15)
72    CFI_RESTORE(d14)
73    ldp d12, d13, [\base_reg, #(\offset - CALLEE_VREG0_OFFSET + 8*4)]
74    CFI_RESTORE(d13)
75    CFI_RESTORE(d12)
76    ldp d10, d11, [\base_reg, #(\offset - CALLEE_VREG0_OFFSET + 8*2)]
77    CFI_RESTORE(d11)
78    CFI_RESTORE(d10)
79    ldp d8, d9,   [\base_reg, #(\offset - CALLEE_VREG0_OFFSET)]
80    CFI_RESTORE(d9)
81    CFI_RESTORE(d8)
82.endm
83
84.macro SAVE_CALLER_GP_REGS fp_reg, paramsnum, mode
85.if \mode != RUNTIME_MODE_STUB
86    // parameter holding registers are saved by the caller function
87.ifeq \paramsnum
88    stp x0,  x1,  [\fp_reg, #-CALLER_REG0_OFFSET+8*0]
89.endif
90.ifle \paramsnum-2
91    stp x2,  x3,  [\fp_reg, #-CALLER_REG0_OFFSET+8*2]
92.endif
93.ifle \paramsnum-4
94    stp x4,  x5,  [\fp_reg, #-CALLER_REG0_OFFSET+8*4]
95.endif
96.endif // \mode != RUNTIME_MODE_STUB
97
98    // Save caller saved regs
99    // first registers are stored by user of this macro or caller which uses them for arguments
100    stp x6,  x7,  [\fp_reg, #-CALLER_REG0_OFFSET+8*6]
101    stp x8,  x9,  [\fp_reg, #-CALLER_REG0_OFFSET+8*8]
102    stp x10, x11, [\fp_reg, #-CALLER_REG0_OFFSET+8*10]
103    stp x12, x13, [\fp_reg, #-CALLER_REG0_OFFSET+8*12]
104    stp x14, x15, [\fp_reg, #-CALLER_REG0_OFFSET+8*14]
105    stp x16, x17, [\fp_reg, #-CALLER_REG0_OFFSET+8*16]
106    str x18, [\fp_reg, #-CALLER_REG0_OFFSET+8*18]
107.endm
108
109.macro RESTORE_CALLER_GP_REGS fp_reg, tmp_reg, is_void
110.if \is_void == 1
111    ldp x0,  x1,  [\fp_reg, #-CALLER_REG0_OFFSET+8*0]
112.else
113    // do not load x0 here as it can overwrite the result value
114    add \tmp_reg, \fp_reg, #-CALLER_REG0_OFFSET
115    ldr x1,  [\tmp_reg, #8*1]
116.endif
117    ldp x2,  x3,  [\fp_reg, #-CALLER_REG0_OFFSET+8*2]
118    ldp x4,  x5,  [\fp_reg, #-CALLER_REG0_OFFSET+8*4]
119    ldp x6,  x7,  [\fp_reg, #-CALLER_REG0_OFFSET+8*6]
120    ldp x8,  x9,  [\fp_reg, #-CALLER_REG0_OFFSET+8*8]
121    ldp x10, x11, [\fp_reg, #-CALLER_REG0_OFFSET+8*10]
122    ldp x12, x13, [\fp_reg, #-CALLER_REG0_OFFSET+8*12]
123    ldp x14, x15, [\fp_reg, #-CALLER_REG0_OFFSET+8*14]
124    ldp x16, x17, [\fp_reg, #-CALLER_REG0_OFFSET+8*16]
125    ldr x18, [\fp_reg, #-CALLER_REG0_OFFSET+8*18]
126.endm
127
128.macro SAVE_CALLER_FP_REGS fp_reg, tmp_reg
129    add \tmp_reg, \fp_reg, #-CALLER_VREG0_OFFSET
130    stp d0, d1, [\tmp_reg]
131    stp d2, d3, [\tmp_reg, #8*2]
132    stp d4, d5, [\tmp_reg, #8*4]
133    stp d6, d7, [\tmp_reg, #8*6]
134    stp d16, d17, [\tmp_reg, #8*8]
135    stp d18, d19, [\tmp_reg, #8*10]
136    stp d20, d21, [\tmp_reg, #8*12]
137    stp d22, d23, [\tmp_reg, #8*14]
138    stp d24, d25, [\tmp_reg, #8*16]
139    stp d26, d27, [\tmp_reg, #8*18]
140    stp d28, d29, [\tmp_reg, #8*20]
141    stp d30, d31, [\tmp_reg, #8*22]
142.endm
143
144.macro RESTORE_CALLER_FP_REGS fp_reg, tmp_reg
145    add \tmp_reg, \fp_reg, #-CALLER_VREG0_OFFSET
146    ldp d0, d1, [\tmp_reg]
147    ldp d2, d3, [\tmp_reg, #8*2]
148    ldp d4, d5, [\tmp_reg, #8*4]
149    ldp d6, d7, [\tmp_reg, #8*6]
150    ldp d16, d17, [\tmp_reg, #8*8]
151    ldp d18, d19, [\tmp_reg, #8*10]
152    ldp d20, d21, [\tmp_reg, #8*12]
153    ldp d22, d23, [\tmp_reg, #8*14]
154    ldp d24, d25, [\tmp_reg, #8*16]
155    ldp d26, d27, [\tmp_reg, #8*18]
156    ldp d28, d29, [\tmp_reg, #8*20]
157    ldp d30, d31, [\tmp_reg, #8*22]
158.endm
159
160.macro CHECK_NATIVE_EXCEPTION is_void
161    ldr lr, [THREAD_REG, #MANAGED_THREAD_EXCEPTION_OFFSET]
162    cmp lr, 0
163
164    beq 1f
165    CFI_REMEMBER_STATE
166
167.if \is_void == 0
168    add lr, fp, #-CALLER_REG0_OFFSET
169    ldr x0, [lr]
170.endif
171
172    ldr lr, [sp, #(BRIDGE_FRAME_SIZE - 8)]
173    CFI_RESTORE(lr)
174
175    add sp, sp, #BRIDGE_FRAME_SIZE
176    CFI_ADJUST_CFA_OFFSET(-BRIDGE_FRAME_SIZE)
177
178    b ThrowNativeExceptionBridge
179    CFI_RESTORE_STATE
180
1811:
182    ldr lr, [sp, #(BRIDGE_FRAME_SIZE - 8)]
183    CFI_RESTORE(lr)
184
185    add sp, sp, #BRIDGE_FRAME_SIZE
186    CFI_ADJUST_CFA_OFFSET(-BRIDGE_FRAME_SIZE)
187.endm
188
189.macro CALL_RUNTIME mode, entry, paramsnum, is_void
190    sub sp, sp, #BRIDGE_FRAME_SIZE
191    CFI_ADJUST_CFA_OFFSET(BRIDGE_FRAME_SIZE)
192
193    // BoundaryFrame setup
194    str lr, [sp, #(BRIDGE_FRAME_SIZE - 8)]    // Bridge frame, slot 1 = npc = LR (the StackMap is just after the bridge call)
195    CFI_REL_OFFSET(lr, (BRIDGE_FRAME_SIZE - 1 * 8))
196    str lr, [THREAD_REG, #MANAGED_THREAD_NATIVE_PC_OFFSET]   // ManagedThread.npc update
197    mov lr, #COMPILED_CODE_TO_INTERPRETER_BRIDGE
198    str lr, [sp, #(BRIDGE_FRAME_SIZE - 16)] // Bridge frame, slot 2 = COMPILED_CODE_TO_INTERPRETER
199    str fp, [sp, #(BRIDGE_FRAME_SIZE - 24)] // Bridge frame, slot 3 = parent frame pointer
200    CFI_REL_OFFSET(fp, (BRIDGE_FRAME_SIZE - 3 * 8))
201    add lr, sp, #(BRIDGE_FRAME_SIZE - 24)
202    str lr, [THREAD_REG, #MANAGED_THREAD_FRAME_OFFSET]    // ManagedThread._frame = this boundary frame
203
204    SAVE_CALLEE_GP_REGS sp, BRIDGE_FRAME_SIZE
205    // StackWalker requires callee-saved FP registers to be saved unconditionally in the runtime bridge
206    SAVE_CALLEE_FP_REGS sp, BRIDGE_FRAME_SIZE
207
208.if \mode != RUNTIME_MODE_SLOW_PATH
209    SAVE_CALLER_GP_REGS fp, \paramsnum, \mode
210.endif
211
212    ldr x19, [fp, #(-CFRAME_FLAGS_SLOT * 8)]
213    tbz x19, #CFRAME_HAS_FLOAT_REGS_FLAG_BIT, 2f
214
215    SAVE_CALLER_FP_REGS fp, lr
216
2172:
218    // The call
219    bl \entry
220
221    // Restore previous state
222    str fp, [THREAD_REG, #MANAGED_THREAD_FRAME_OFFSET]
223
224    tbz x19, #CFRAME_HAS_FLOAT_REGS_FLAG_BIT, 3f
225
226    RESTORE_CALLEE_FP_REGS sp, BRIDGE_FRAME_SIZE
227    RESTORE_CALLER_FP_REGS fp, lr
228
2293:
230    RESTORE_CALLEE_GP_REGS sp, BRIDGE_FRAME_SIZE
231    RESTORE_CALLER_GP_REGS fp, lr, \is_void
232
233    CHECK_NATIVE_EXCEPTION \is_void
234.endm
235