1 // SPDX-License-Identifier: Apache-2.0
2 // SPDX-FileCopyrightText: 2023 The Ebitengine Authors
3 4 //go:build darwin || freebsd || linux || netbsd
5 6 #include "textflag.h"
7 #include "go_asm.h"
8 #include "funcdata.h"
9 #include "abi_arm64.h"
10 11 TEXT 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 FSTPD (F0, F1), (0*8)(R14)
21 FSTPD (F2, F3), (2*8)(R14)
22 FSTPD (F4, F5), (4*8)(R14)
23 FSTPD (F6, F7), (6*8)(R14)
24 STP (R0, R1), (8*8)(R14)
25 STP (R2, R3), (10*8)(R14)
26 STP (R4, R5), (12*8)(R14)
27 STP (R6, R7), (14*8)(R14)
28 29 // Adjust SP by frame size.
30 SUB $(26*8), RSP
31 32 // It is important to save R27 because the go assembler
33 // uses it for move instructions for a variable.
34 // This line:
35 // MOVD ·callbackWrap_call(SB), R0
36 // Creates the instructions:
37 // ADRP 14335(PC), R27
38 // MOVD 388(27), R0
39 // R27 is a callee saved register so we are responsible
40 // for ensuring its value doesn't change. So save it and
41 // restore it at the end of this function.
42 // R30 is the link register. crosscall2 doesn't save it
43 // so it's saved here.
44 STP (R27, R30), 0(RSP)
45 46 // Create a struct callbackArgs on our stack.
47 MOVD $(callbackArgs__size)(RSP), R13
48 MOVD R12, callbackArgs_index(R13) // callback index
49 MOVD R14, callbackArgs_args(R13) // address of args vector
50 MOVD ZR, callbackArgs_result(R13) // result
51 52 // Move parameters into registers
53 // Get the ABIInternal function pointer
54 // without <ABIInternal> by using a closure.
55 MOVD ·callbackWrap_call(SB), R0
56 MOVD (R0), R0 // fn unsafe.Pointer
57 MOVD R13, R1 // frame (&callbackArgs{...})
58 MOVD $0, R3 // ctxt uintptr
59 60 BL crosscall2(SB)
61 62 // Get callback result.
63 MOVD $(callbackArgs__size)(RSP), R13
64 MOVD callbackArgs_result(R13), R0
65 66 // Restore LR and R27
67 LDP 0(RSP), (R27, R30)
68 ADD $(26*8), RSP
69 70 RET
71