1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: 2023 The Ebitengine Authors
3
4//go:build darwin || (!cgo && linux)
5
6#include "textflag.h"
7#include "go_asm.h"
8#include "funcdata.h"
9#include "internal/abi/abi_arm64.h"
10
11TEXT callbackasm1(SB), NOSPLIT|NOFRAME, $0
12 NO_LOCAL_POINTERS
13
14 // On entry, the trampoline in zcallback_darwin_arm64.s left
15 // the callback index in R12 (which is volatile in the C ABI).
16
17 // Save callback register arguments R0-R7 and F0-F7.
18 // We do this at the top of the frame so they're contiguous with stack arguments.
19 SUB $(16*8), RSP, R14
20 FMOVD F0, (0*8)(R14)
21 FMOVD F1, (1*8)(R14)
22 FMOVD F2, (2*8)(R14)
23 FMOVD F3, (3*8)(R14)
24 FMOVD F4, (4*8)(R14)
25 FMOVD F5, (5*8)(R14)
26 FMOVD F6, (6*8)(R14)
27 FMOVD F7, (7*8)(R14)
28 STP (R0, R1), (8*8)(R14)
29 STP (R2, R3), (10*8)(R14)
30 STP (R4, R5), (12*8)(R14)
31 STP (R6, R7), (14*8)(R14)
32
33 // Adjust SP by frame size.
34 // crosscall2 clobbers FP in the frame record so only save/restore SP.
35 SUB $(28*8), RSP
36 MOVD R30, (RSP)
37
38 // Create a struct callbackArgs on our stack.
39 ADD $(callbackArgs__size + 3*8), RSP, R13
40 MOVD R12, callbackArgs_index(R13) // callback index
41 MOVD R14, R0
42 MOVD R0, callbackArgs_args(R13) // address of args vector
43 MOVD $0, R0
44 MOVD R0, callbackArgs_result(R13) // result
45
46 // Move parameters into registers
47 // Get the ABIInternal function pointer
48 // without <ABIInternal> by using a closure.
49 MOVD ·callbackWrap_call(SB), R0
50 MOVD (R0), R0 // fn unsafe.Pointer
51 MOVD R13, R1 // frame (&callbackArgs{...})
52 MOVD $0, R3 // ctxt uintptr
53
54 BL crosscall2(SB)
55
56 // Get callback result.
57 ADD $(callbackArgs__size + 3*8), RSP, R13
58 MOVD callbackArgs_result(R13), R0
59
60 // Restore SP
61 MOVD (RSP), R30
62 ADD $(28*8), RSP
63
64 RET