1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: 2026 The Ebitengine Authors
3
4//go:build !cgo && linux
5
6#include "textflag.h"
7#include "go_asm.h"
8#include "abi_ppc64x.h"
9
10// These trampolines map the C ABI to Go ABI and call into the Go equivalent functions.
11
12TEXT x_cgo_init_trampoline(SB), NOSPLIT, $0-0
13 MOVD ·x_cgo_init_call(SB), R12
14 MOVD (R12), R12
15 MOVD R12, CTR
16 CALL CTR
17 RET
18
19TEXT x_cgo_thread_start_trampoline(SB), NOSPLIT, $0-0
20 MOVD ·x_cgo_thread_start_call(SB), R12
21 MOVD (R12), R12
22 MOVD R12, CTR
23 CALL CTR
24 RET
25
26TEXT x_cgo_setenv_trampoline(SB), NOSPLIT, $0-0
27 MOVD ·x_cgo_setenv_call(SB), R12
28 MOVD (R12), R12
29 MOVD R12, CTR
30 CALL CTR
31 RET
32
33TEXT x_cgo_unsetenv_trampoline(SB), NOSPLIT, $0-0
34 MOVD ·x_cgo_unsetenv_call(SB), R12
35 MOVD (R12), R12
36 MOVD R12, CTR
37 CALL CTR
38 RET
39
40TEXT x_cgo_notify_runtime_init_done_trampoline(SB), NOSPLIT, $0-0
41 CALL ·x_cgo_notify_runtime_init_done(SB)
42 RET
43
44TEXT x_cgo_bindm_trampoline(SB), NOSPLIT, $0-0
45 CALL ·x_cgo_bindm(SB)
46 RET
47
48// func setg_trampoline(setg uintptr, g uintptr)
49TEXT ·setg_trampoline(SB), NOSPLIT, $16-16
50 MOVD R31, 8(R1) // save R31 (load_g clobbers it)
51
52 MOVD setg+0(FP), R12
53 MOVD newg+8(FP), R3
54
55 MOVD R12, CTR
56 CALL CTR
57
58 CALL runtime·load_g(SB)
59
60 MOVD 8(R1), R31
61 XOR R0, R0, R0
62 RET
63
64TEXT threadentry_trampoline(SB), NOSPLIT|NOFRAME, $0-0
65 // Called from C (pthread_create). Must save all C callee-saved registers.
66 // Uses NOFRAME for proper ELFv2 backchain via MOVDU.
67 MOVD LR, R0
68 MOVD R0, 16(R1)
69 MOVW CR, R0
70 MOVD R0, 8(R1)
71
72 MOVDU R1, -320(R1)
73
74 SAVE_GPR(32)
75 SAVE_FPR(32+SAVE_GPR_SIZE)
76
77 MOVD $0, R0
78
79 MOVD ·threadentry_call(SB), R12
80 MOVD (R12), R12
81 MOVD R12, CTR
82 CALL CTR
83
84 RESTORE_FPR(32+SAVE_GPR_SIZE)
85 RESTORE_GPR(32)
86
87 ADD $320, R1
88
89 MOVD 16(R1), R0
90 MOVD R0, LR
91 MOVD 8(R1), R0
92 MOVW R0, CR
93 RET
94
95TEXT ·call5(SB), NOSPLIT|NOFRAME, $0-56
96 MOVD LR, R20
97 MOVW CR, R21
98
99 // Load arguments from Go stack into C argument registers
100 // Go placed args at 32(R1), 40(R1), etc.
101 MOVD 32(R1), R12 // fn
102 MOVD 40(R1), R3 // a1 → first C arg
103 MOVD 48(R1), R4 // a2 → second C arg
104 MOVD 56(R1), R5 // a3 → third C arg
105 MOVD 64(R1), R6 // a4 → fourth C arg
106 MOVD 72(R1), R7 // a5 → fifth C arg
107
108 MOVDU R1, -32(R1)
109
110 MOVD R12, CTR
111 CALL CTR
112
113 // Store return value
114 // After MOVDU -32, original 80(R1) is now at 80+32=112(R1)
115 MOVD R3, (80+32)(R1)
116
117 // Deallocate frame
118 ADD $32, R1
119
120 // Clear R0 before returning to Go code.
121 // Go uses R0 as a constant 0 register for things like "std r0,X(r1)"
122 // to zero stack locations. C functions may leave garbage in R0.
123 XOR R0, R0, R0
124
125 // Restore LR/CR from non-volatile registers
126 MOVD R20, LR
127 MOVW R21, CR
128 RET