1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: 2025 The Ebitengine Authors
3
4//go:build linux
5
6#include "textflag.h"
7#include "go_asm.h"
8#include "funcdata.h"
9
10#define STACK_SIZE 208
11#define PTR_ADDRESS (STACK_SIZE - 8)
12
13// syscallX calls a function in libc on behalf of the syscall package.
14// syscallX takes a pointer to a struct like:
15// struct {
16// fn uintptr
17// a1 uintptr
18// a2 uintptr
19// a3 uintptr
20// a4 uintptr
21// a5 uintptr
22// a6 uintptr
23// a7 uintptr
24// a8 uintptr
25// a9 uintptr
26// a10 uintptr
27// a11 uintptr
28// a12 uintptr
29// a13 uintptr
30// a14 uintptr
31// a15 uintptr
32// r1 uintptr
33// r2 uintptr
34// err uintptr
35// }
36// syscallX must be called on the g0 stack with the
37// C calling convention (use libcCall).
38GLOBL ·syscallXABI0(SB), NOPTR|RODATA, $8
39DATA ·syscallXABI0(SB)/8, $syscallX(SB)
40TEXT syscallX(SB), NOSPLIT, $0
41 // push structure pointer
42 SUBV $STACK_SIZE, R3
43 MOVV R4, PTR_ADDRESS(R3)
44 MOVV R4, R13
45
46 MOVD syscallArgs_f1(R13), F0 // f1
47 MOVD syscallArgs_f2(R13), F1 // f2
48 MOVD syscallArgs_f3(R13), F2 // f3
49 MOVD syscallArgs_f4(R13), F3 // f4
50 MOVD syscallArgs_f5(R13), F4 // f5
51 MOVD syscallArgs_f6(R13), F5 // f6
52 MOVD syscallArgs_f7(R13), F6 // f7
53 MOVD syscallArgs_f8(R13), F7 // f8
54
55 MOVV syscallArgs_a1(R13), R4 // a1
56 MOVV syscallArgs_a2(R13), R5 // a2
57 MOVV syscallArgs_a3(R13), R6 // a3
58 MOVV syscallArgs_a4(R13), R7 // a4
59 MOVV syscallArgs_a5(R13), R8 // a5
60 MOVV syscallArgs_a6(R13), R9 // a6
61 MOVV syscallArgs_a7(R13), R10 // a7
62 MOVV syscallArgs_a8(R13), R11 // a8
63
64 // push a9-a15 onto stack
65 MOVV syscallArgs_a9(R13), R12
66 MOVV R12, 0(R3)
67 MOVV syscallArgs_a10(R13), R12
68 MOVV R12, 8(R3)
69 MOVV syscallArgs_a11(R13), R12
70 MOVV R12, 16(R3)
71 MOVV syscallArgs_a12(R13), R12
72 MOVV R12, 24(R3)
73 MOVV syscallArgs_a13(R13), R12
74 MOVV R12, 32(R3)
75 MOVV syscallArgs_a14(R13), R12
76 MOVV R12, 40(R3)
77 MOVV syscallArgs_a15(R13), R12
78 MOVV R12, 48(R3)
79 MOVV syscallArgs_a16(R13), R12
80 MOVV R12, 56(R3)
81 MOVV syscallArgs_a17(R13), R12
82 MOVV R12, 64(R3)
83 MOVV syscallArgs_a18(R13), R12
84 MOVV R12, 72(R3)
85 MOVV syscallArgs_a19(R13), R12
86 MOVV R12, 80(R3)
87 MOVV syscallArgs_a20(R13), R12
88 MOVV R12, 88(R3)
89 MOVV syscallArgs_a21(R13), R12
90 MOVV R12, 96(R3)
91 MOVV syscallArgs_a22(R13), R12
92 MOVV R12, 104(R3)
93 MOVV syscallArgs_a23(R13), R12
94 MOVV R12, 112(R3)
95 MOVV syscallArgs_a24(R13), R12
96 MOVV R12, 120(R3)
97 MOVV syscallArgs_a25(R13), R12
98 MOVV R12, 128(R3)
99 MOVV syscallArgs_a26(R13), R12
100 MOVV R12, 136(R3)
101 MOVV syscallArgs_a27(R13), R12
102 MOVV R12, 144(R3)
103 MOVV syscallArgs_a28(R13), R12
104 MOVV R12, 152(R3)
105 MOVV syscallArgs_a29(R13), R12
106 MOVV R12, 160(R3)
107 MOVV syscallArgs_a30(R13), R12
108 MOVV R12, 168(R3)
109 MOVV syscallArgs_a31(R13), R12
110 MOVV R12, 176(R3)
111 MOVV syscallArgs_a32(R13), R12
112 MOVV R12, 184(R3)
113
114 MOVV syscallArgs_fn(R13), R12
115 JAL (R12)
116
117 // pop structure pointer
118 MOVV PTR_ADDRESS(R3), R13
119 ADDV $STACK_SIZE, R3
120
121 // save R4, R5
122 MOVV R4, syscallArgs_a1(R13)
123 MOVV R5, syscallArgs_a2(R13)
124
125 // save f0-f3
126 MOVD F0, syscallArgs_f1(R13)
127 MOVD F1, syscallArgs_f2(R13)
128 MOVD F2, syscallArgs_f3(R13)
129 MOVD F3, syscallArgs_f4(R13)
130 RET