1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: 2023 The Ebitengine Authors
3
4//go:build darwin || freebsd || linux
5
6#include "textflag.h"
7#include "go_asm.h"
8#include "funcdata.h"
9#include "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 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