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