1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: 2026 The Ebitengine Authors
3
4//go:build !cgo && (freebsd || linux)
5
6#include "textflag.h"
7#include "go_asm.h"
8
9// These trampolines map the gcc ABI to Go ABI0 and then call into the Go equivalent functions.
10// On ARM32, Go ABI0 uses stack-based calling convention.
11// Arguments are placed on the stack starting at 4(SP) after the prologue.
12
13TEXT x_cgo_init_trampoline(SB), NOSPLIT, $8-0
14 MOVW R0, 4(R13)
15 MOVW R1, 8(R13)
16 MOVW ·x_cgo_init_call(SB), R12
17 MOVW (R12), R12
18 CALL (R12)
19 RET
20
21TEXT x_cgo_thread_start_trampoline(SB), NOSPLIT, $8-0
22 MOVW R0, 4(R13)
23 MOVW ·x_cgo_thread_start_call(SB), R12
24 MOVW (R12), R12
25 CALL (R12)
26 RET
27
28TEXT x_cgo_setenv_trampoline(SB), NOSPLIT, $8-0
29 MOVW R0, 4(R13)
30 MOVW ·x_cgo_setenv_call(SB), R12
31 MOVW (R12), R12
32 CALL (R12)
33 RET
34
35TEXT x_cgo_unsetenv_trampoline(SB), NOSPLIT, $8-0
36 MOVW R0, 4(R13)
37 MOVW ·x_cgo_unsetenv_call(SB), R12
38 MOVW (R12), R12
39 CALL (R12)
40 RET
41
42TEXT x_cgo_notify_runtime_init_done_trampoline(SB), NOSPLIT, $0-0
43 CALL ·x_cgo_notify_runtime_init_done(SB)
44 RET
45
46TEXT x_cgo_bindm_trampoline(SB), NOSPLIT, $0
47 CALL ·x_cgo_bindm(SB)
48 RET
49
50// func setg_trampoline(setg uintptr, g uintptr)
51TEXT ·setg_trampoline(SB), NOSPLIT, $0-8
52 MOVW G+4(FP), R0
53 MOVW setg+0(FP), R12
54 BL (R12)
55 RET
56
57TEXT threadentry_trampoline(SB), NOSPLIT, $104-0
58 // Save C callee-saved registers at C-to-Go boundary.
59 // See crosscall2 in asm_arm.s.
60 // ARM AAPCS callee-saved: R4-R11 (includes g=R10), D8-D15.
61 // LR is saved/restored by the Go-managed frame prologue/epilogue.
62 MOVW R0, 4(R13) // arg for threadentry_call
63
64 MOVW R4, 8(R13)
65 MOVW R5, 12(R13)
66 MOVW R6, 16(R13)
67 MOVW R7, 20(R13)
68 MOVW R8, 24(R13)
69 MOVW R9, 28(R13)
70 MOVW g, 32(R13) // R10
71 MOVW R11, 36(R13)
72
73 // Skip floating point registers if runtime.goarmsoftfp!=0.
74 MOVB runtime·goarmsoftfp(SB), R11
75 CMP $0, R11
76 BNE skipfpsave
77 MOVD F8, 40(R13)
78 MOVD F9, 48(R13)
79 MOVD F10, 56(R13)
80 MOVD F11, 64(R13)
81 MOVD F12, 72(R13)
82 MOVD F13, 80(R13)
83 MOVD F14, 88(R13)
84 MOVD F15, 96(R13)
85
86skipfpsave:
87 MOVW ·threadentry_call(SB), R12
88 MOVW (R12), R12
89 CALL (R12)
90
91 MOVB runtime·goarmsoftfp(SB), R11
92 CMP $0, R11
93 BNE skipfprest
94 MOVD 40(R13), F8
95 MOVD 48(R13), F9
96 MOVD 56(R13), F10
97 MOVD 64(R13), F11
98 MOVD 72(R13), F12
99 MOVD 80(R13), F13
100 MOVD 88(R13), F14
101 MOVD 96(R13), F15
102
103skipfprest:
104 MOVW 8(R13), R4
105 MOVW 12(R13), R5
106 MOVW 16(R13), R6
107 MOVW 20(R13), R7
108 MOVW 24(R13), R8
109 MOVW 28(R13), R9
110 MOVW 32(R13), g
111 MOVW 36(R13), R11
112
113 RET
114
115TEXT ·call5(SB), NOSPLIT, $8-28
116 MOVW fn+0(FP), R12
117 MOVW a1+4(FP), R0
118 MOVW a2+8(FP), R1
119 MOVW a3+12(FP), R2
120 MOVW a4+16(FP), R3
121 MOVW a5+20(FP), R4
122
123 // Store 5th arg below SP (in local frame area)
124 MOVW R4, arg5-8(SP)
125
126 // Align SP to 8 bytes for call (required by ARM AAPCS)
127 SUB $8, R13
128 CALL (R12)
129 ADD $8, R13
130 MOVW R0, r1+24(FP)
131 RET