// Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
// This source file is part of the Cangjie project, licensed under Apache-2.0
// with Runtime Library Exception.
//
// See https://cangjie-lang.cn/pages/LICENSE for license information.
// stub need to be 16-byte aligned, so we should use (8 * even numbers)
#define HandleSafepointStubFrameSize (264)
#define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off
#define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off
#define cfi_restore(reg) .cfi_restore reg
#define cfi_def_cfa_register(reg) .cfi_def_cfa_register reg
.text
.align 2
.global CJ_MCC_HandleSafepoint
.type CJ_MCC_HandleSafepoint, %function
CJ_MCC_HandleSafepoint:
.cfi_startproc
// save callee registers
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
pushq %rax
cfi_rel_offset (%rax, -8)
pushq %rbx
cfi_rel_offset (%rbx, -16)
pushq %rcx
cfi_rel_offset (%rcx, -24)
pushq %rdx
cfi_rel_offset (%rdx, -32)
pushq %rdi
cfi_rel_offset (%rdi, -40)
pushq %rsi
cfi_rel_offset (%rsi, -48)
pushq %rsp
cfi_rel_offset (%rsp, -56)
pushq %r8
cfi_rel_offset (%r8, -64)
pushq %r9
cfi_rel_offset (%r9, -72)
pushq %r10
cfi_rel_offset (%r10, -80)
pushq %r11
cfi_rel_offset (%r11, -88)
pushq %r12
cfi_rel_offset (%r12, -96)
pushq %r13
cfi_rel_offset (%r13, -104)
pushq %r14
cfi_rel_offset (%r14, -112)
pushq %r15
cfi_rel_offset (%r15, -120)
// Need to ensure 16-bit alignment
subq $HandleSafepointStubFrameSize, %rsp
movapd %xmm0, 0(%rsp)
movapd %xmm1, 16(%rsp)
movapd %xmm2, 32(%rsp)
movapd %xmm3, 48(%rsp)
movapd %xmm4, 64(%rsp)
movapd %xmm5, 80(%rsp)
movapd %xmm6, 96(%rsp)
movapd %xmm7, 112(%rsp)
movapd %xmm8, 128(%rsp)
movapd %xmm9, 144(%rsp)
movapd %xmm10, 160(%rsp)
movapd %xmm11, 176(%rsp)
movapd %xmm12, 192(%rsp)
movapd %xmm13, 208(%rsp)
movapd %xmm14, 224(%rsp)
movapd %xmm15, 240(%rsp)
movq %rbp, %rsi
movq %r15, %rcx
movq $3, %rdx
leaq 13(%rip), %rdi // rdi is addr of unwindPCForSafepointHandlerStub
callq MRT_UpdateUwContext@PLT
// call safepoint handler
movq %r15, %rdi
callq HandleSafepoint@PLT
.global unwindPCForSafepointHandlerStub
unwindPCForSafepointHandlerStub:
callq MRT_GetThreadLocalData@PLT
movq %rax, %r15
movq %rax, %rdi
callq MRT_DeleteC2NContext@PLT
// restore callee registers
movapd 0(%rsp), %xmm0
movapd 16(%rsp), %xmm1
movapd 32(%rsp), %xmm2
movapd 48(%rsp), %xmm3
movapd 64(%rsp), %xmm4
movapd 80(%rsp), %xmm5
movapd 96(%rsp), %xmm6
movapd 112(%rsp), %xmm7
movapd 128(%rsp), %xmm8
movapd 144(%rsp), %xmm9
movapd 160(%rsp), %xmm10
movapd 176(%rsp), %xmm11
movapd 192(%rsp), %xmm12
movapd 208(%rsp), %xmm13
movapd 224(%rsp), %xmm14
movapd 240(%rsp), %xmm15
// Need to ensure 16-bit alignment
addq $HandleSafepointStubFrameSize, %rsp
// do not popq %r15
popq %rax
cfi_restore (%rax)
popq %r14
cfi_restore (%r14)
popq %r13
cfi_restore (%r13)
popq %r12
cfi_restore (%r12)
popq %r11
cfi_restore (%r11)
popq %r10
cfi_restore (%r10)
popq %r9
cfi_restore (%r9)
popq %r8
cfi_restore (%r8)
popq %rsp
cfi_restore (%rsp)
popq %rsi
cfi_restore (%rsi)
popq %rdi
cfi_restore (%rdi)
popq %rdx
cfi_restore (%rdx)
popq %rcx
cfi_restore (%rcx)
popq %rbx
cfi_restore (%rbx)
popq %rax
cfi_restore (%rax)
popq %rbp
cfi_restore (%rbp)
.cfi_def_cfa %rsp, 8
retq
.cfi_endproc
.size CJ_MCC_HandleSafepoint, .-CJ_MCC_HandleSafepoint