1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: 2024 The Ebitengine Authors
3
4#include "stdint.h"
5
6#if defined(__x86_64__) || defined(__aarch64__)
7typedef int64_t GoInt;
8typedef uint64_t GoUint;
9#endif
10
11// Empty is empty
12struct Empty {};
13
14// NoStruct tests that an empty struct doesn't cause issues
15unsigned long NoStruct(struct Empty e) {
16 return 0xdeadbeef;
17}
18
19struct EmptyEmpty {
20 struct Empty x;
21};
22
23unsigned long EmptyEmpty(struct EmptyEmpty e) {
24 return 0xdeadbeef;
25}
26
27unsigned long EmptyEmptyWithReg(unsigned int x, struct EmptyEmpty e, unsigned int y) {
28 return (x << 16) | y;
29}
30
31// GreaterThan16Bytes is 24 bytes on 64 bit systems
32struct GreaterThan16Bytes {
33 long *x, *y, *z;
34};
35
36// GreaterThan16Bytes is a basic test for structs bigger than 16 bytes
37unsigned long GreaterThan16Bytes(struct GreaterThan16Bytes g) {
38 return *g.x + *g.y + *g.z;
39}
40
41// AfterRegisters tests to make sure that structs placed on the stack work properly
42unsigned long AfterRegisters(long a, long b, long c, long d, long e, long f, long g, long h, struct GreaterThan16Bytes bytes) {
43 long registers = a + b + c + d + e + f + g + h;
44 long stack = *bytes.x + *bytes.y + *bytes.z;
45 if (registers != stack) {
46 return 0xbadbad;
47 }
48 if (stack != 0xdeadbeef) {
49 return 0xcafebad;
50 }
51 return stack;
52}
53
54unsigned long BeforeRegisters(struct GreaterThan16Bytes bytes, long a, long b) {
55 return *bytes.x + *bytes.y + *bytes.z + a + b;
56}
57
58struct GreaterThan16BytesStruct {
59 struct {
60 long *x, *y, *z;
61 } a ;
62};
63
64unsigned long GreaterThan16BytesStruct(struct GreaterThan16BytesStruct g) {
65 return *(g.a.x) + *(g.a.y) + *(g.a.z);
66}
67
68struct IntLessThan16Bytes {
69 long x, y;
70};
71
72unsigned long IntLessThan16Bytes(struct IntLessThan16Bytes l) {
73 return l.x + l.y;
74}
75
76struct FloatLessThan16Bytes {
77 float x, y;
78};
79
80float FloatLessThan16Bytes(struct FloatLessThan16Bytes f) {
81 return f.x + f.y;
82}
83
84struct ThreeSmallFields {
85 float x, y, z;
86};
87
88float ThreeSmallFields(struct ThreeSmallFields f) {
89 return f.x + f.y + f.z;
90}
91
92struct FloatAndInt {
93 float x;
94 int y;
95};
96
97float FloatAndInt(struct FloatAndInt f) {
98 return f.x + f.y;
99}
100
101struct DoubleStruct {
102 double x;
103};
104
105double DoubleStruct(struct DoubleStruct d) {
106 return d.x;
107}
108
109struct TwoDoubleStruct {
110 double x, y;
111};
112
113double TwoDoubleStruct(struct TwoDoubleStruct d) {
114 return d.x + d.y;
115}
116
117struct TwoDoubleTwoStruct {
118 struct {
119 double x, y;
120 } s;
121};
122
123double TwoDoubleTwoStruct(struct TwoDoubleTwoStruct d) {
124 return d.s.x + d.s.y;
125}
126
127struct ThreeDoubleStruct {
128 double x, y, z;
129};
130
131double ThreeDoubleStruct(struct ThreeDoubleStruct d) {
132 return d.x + d.y + d.z;
133}
134
135struct LargeFloatStruct {
136 double a, b, c, d, e, f;
137};
138
139double LargeFloatStruct(struct LargeFloatStruct s) {
140 return s.a + s.b + s.c + s.d + s.e + s.f;
141}
142
143double LargeFloatStructWithRegs(double a, double b, double c, struct LargeFloatStruct s) {
144 return a + b + c + s.a + s.b + s.c + s.d + s.e + s.f;
145}
146
147struct Rect {
148 double x, y, w, h;
149};
150
151double Rectangle(struct Rect rect) {
152 return rect.x + rect.y + rect.w + rect.h;
153}
154
155double RectangleSubtract(struct Rect rect) {
156 return (rect.x + rect.y) - (rect.w + rect.h);
157}
158
159double RectangleWithRegs(double a, double b, double c, double d, double e, struct Rect rect) {
160 return a + b + c + d + e + rect.x + rect.y + rect.w + rect.h;
161}
162
163struct FloatArray {
164 double a[2];
165};
166
167double FloatArray(struct FloatArray f) {
168 return f.a[0] + f.a[1];
169}
170
171struct UnsignedChar4Bytes {
172 unsigned char a, b, c, d;
173};
174
175unsigned int UnsignedChar4Bytes(struct UnsignedChar4Bytes b) {
176 return (((int)b.a)<<24) | (((int)b.b)<<16) | (((int)b.c)<<8) | (((int)b.d)<<0);
177}
178
179struct UnsignedChar4BytesStruct {
180 struct {
181 unsigned char a;
182 } x;
183 struct {
184 unsigned char b;
185 } y;
186 struct {
187 unsigned char c;
188 } z;
189 struct {
190 unsigned char d;
191 } w;
192};
193
194unsigned int UnsignedChar4BytesStruct(struct UnsignedChar4BytesStruct b) {
195 return (((int)b.x.a)<<24) | (((int)b.y.b)<<16) | (((int)b.z.c)<<8) | (((int)b.w.d)<<0);
196}
197
198struct Short {
199 unsigned short a, b, c, d;
200};
201
202unsigned long Short(struct Short s) {
203 return (long)s.a << 48 | (long)s.b << 32 | (long)s.c << 16 | (long)s.d << 0;
204}
205
206struct Int {
207 unsigned int a, b;
208};
209
210unsigned long Int(struct Int i) {
211 return (long)i.a << 32 | (long)i.b << 0;
212}
213
214struct Long {
215 unsigned long a;
216};
217
218unsigned long Long(struct Long l) {
219 return l.a;
220}
221
222struct Char8Bytes {
223 signed char a, b, c, d, e, f, g, h;
224};
225
226int Char8Bytes(struct Char8Bytes b) {
227 return (int)b.a + (int)b.b + (int)b.c + (int)b.d + (int)b.e + (int)b.f + (int)b.g + (int)b.h;
228}
229
230struct Odd {
231 unsigned char a, b, c;
232};
233
234int Odd(struct Odd o) {
235 return (int)o.a + (int)o.b + (int)o.c;
236}
237
238struct Char2Short1 {
239 unsigned char a, b;
240 unsigned short c;
241};
242
243int Char2Short1s(struct Char2Short1 s) {
244 return (int)s.a + (int)s.b + (int)s.c;
245}
246
247struct SignedChar2Short1 {
248 signed char a, b;
249 signed short c;
250};
251
252int SignedChar2Short1(struct SignedChar2Short1 s) {
253 return s.a + s.b + s.c;
254}
255
256struct Array4UnsignedChars {
257 unsigned char a[4];
258};
259
260unsigned int Array4UnsignedChars(struct Array4UnsignedChars a) {
261 return (((int)a.a[0])<<24) | (((int)a.a[1])<<16) | (((int)a.a[2])<<8) | (((int)a.a[3])<<0);
262}
263
264struct Array3UnsignedChar {
265 unsigned char a[3];
266};
267
268unsigned int Array3UnsignedChars(struct Array3UnsignedChar a) {
269 return (((int)a.a[0])<<24) | (((int)a.a[1])<<16) | (((int)a.a[2])<<8) | 0xef;
270}
271
272struct Array2UnsignedShort {
273 unsigned short a[2];
274};
275
276unsigned int Array2UnsignedShorts(struct Array2UnsignedShort a) {
277 return (((int)a.a[0])<<16) | (((int)a.a[1])<<0);
278}
279
280struct Array4Chars {
281 char a[4];
282};
283
284int Array4Chars(struct Array4Chars a) {
285 return (int)a.a[0] + (int)a.a[1] + (int)a.a[2] + (int)a.a[3];
286}
287
288struct Array2Short {
289 short a[2];
290};
291
292int Array2Shorts(struct Array2Short a) {
293 return (int)a.a[0] + (int)a.a[1];
294}
295
296struct Array3Short {
297 short a[3];
298};
299
300int Array3Shorts(struct Array3Short a) {
301 return (int)a.a[0] + (int)a.a[1] + (int)a.a[2];
302}
303
304struct BoolStruct {
305 _Bool b;
306};
307
308_Bool BoolStruct(struct BoolStruct b) {
309 return b.b;
310}
311
312struct BoolFloat {
313 _Bool b;
314 float f;
315};
316
317float BoolFloat(struct BoolFloat s) {
318 if (s.b)
319 return s.f;
320 return -s.f;
321}
322
323struct Content {
324 struct { double x, y; } point;
325 struct { double width, height; } size;
326};
327
328unsigned long InitWithContentRect(int *win, struct Content c, int style, int backing, _Bool flag) {
329 if (win == 0)
330 return 0xBAD;
331 if (!flag)
332 return 0xF1A6; // FLAG
333 return (unsigned long)(c.point.x + c.point.y + c.size.width + c.size.height) / (style - backing);
334}
335
336struct GoInt4 {
337 GoInt a, b, c, d;
338};
339
340GoInt GoInt4(struct GoInt4 g) {
341 return g.a + g.b - g.c + g.d;
342}
343
344struct GoUint4 {
345 GoUint a, b, c, d;
346};
347
348GoUint GoUint4(struct GoUint4 g) {
349 return g.a + g.b + g.c + g.d;
350}
351
352GoUint TakeGoUintAndReturn(GoUint a) {
353 return a;
354}