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