sys_386.s raw
1 // SPDX-License-Identifier: Apache-2.0
2 // SPDX-FileCopyrightText: 2026 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 160
11 #define PTR_ADDRESS (STACK_SIZE - 4)
12
13 // syscall15X calls a function in libc on behalf of the syscall package.
14 // syscall15X takes a pointer to a struct like:
15 // struct {
16 // fn uintptr
17 // a1 uintptr
18 // ...
19 // a32 uintptr
20 // f1 uintptr
21 // ...
22 // f16 uintptr
23 // arm64_r8 uintptr
24 // }
25 // syscall15X must be called on the g0 stack with the
26 // C calling convention (use libcCall).
27 //
28 // On i386 System V ABI, all arguments are passed on the stack.
29 // Return value is in EAX (and EDX for 64-bit values).
30 GLOBL ·syscall15XABI0(SB), NOPTR|RODATA, $4
31 DATA ·syscall15XABI0(SB)/4, $syscall15X(SB)
32 TEXT syscall15X(SB), NOSPLIT|NOFRAME, $0-0
33 // Called via C calling convention: argument pointer at 4(SP)
34 // NOT via Go calling convention
35 // On i386, the first argument is at 4(SP) after CALL pushes return address
36 MOVL 4(SP), AX // get pointer to syscall15Args
37
38 // Save callee-saved registers
39 PUSHL BP
40 PUSHL BX
41 PUSHL SI
42 PUSHL DI
43
44 MOVL AX, BX // save args pointer in BX
45
46 // Allocate stack space for C function arguments
47 // i386 SysV: all 32 args on stack = 32 * 4 = 128 bytes
48 // Plus 16 bytes for alignment and local storage
49 SUBL $STACK_SIZE, SP
50 MOVL BX, PTR_ADDRESS(SP) // save args pointer
51
52 // Load function pointer
53 MOVL syscall15Args_fn(BX), AX
54 MOVL AX, (PTR_ADDRESS-4)(SP) // save fn pointer
55
56 // Push all integer arguments onto the stack (a1-a32)
57 // i386 SysV ABI: arguments pushed right-to-left, but we're
58 // setting up the stack from low to high addresses
59 MOVL syscall15Args_a1(BX), AX
60 MOVL AX, 0(SP)
61 MOVL syscall15Args_a2(BX), AX
62 MOVL AX, 4(SP)
63 MOVL syscall15Args_a3(BX), AX
64 MOVL AX, 8(SP)
65 MOVL syscall15Args_a4(BX), AX
66 MOVL AX, 12(SP)
67 MOVL syscall15Args_a5(BX), AX
68 MOVL AX, 16(SP)
69 MOVL syscall15Args_a6(BX), AX
70 MOVL AX, 20(SP)
71 MOVL syscall15Args_a7(BX), AX
72 MOVL AX, 24(SP)
73 MOVL syscall15Args_a8(BX), AX
74 MOVL AX, 28(SP)
75 MOVL syscall15Args_a9(BX), AX
76 MOVL AX, 32(SP)
77 MOVL syscall15Args_a10(BX), AX
78 MOVL AX, 36(SP)
79 MOVL syscall15Args_a11(BX), AX
80 MOVL AX, 40(SP)
81 MOVL syscall15Args_a12(BX), AX
82 MOVL AX, 44(SP)
83 MOVL syscall15Args_a13(BX), AX
84 MOVL AX, 48(SP)
85 MOVL syscall15Args_a14(BX), AX
86 MOVL AX, 52(SP)
87 MOVL syscall15Args_a15(BX), AX
88 MOVL AX, 56(SP)
89 MOVL syscall15Args_a16(BX), AX
90 MOVL AX, 60(SP)
91 MOVL syscall15Args_a17(BX), AX
92 MOVL AX, 64(SP)
93 MOVL syscall15Args_a18(BX), AX
94 MOVL AX, 68(SP)
95 MOVL syscall15Args_a19(BX), AX
96 MOVL AX, 72(SP)
97 MOVL syscall15Args_a20(BX), AX
98 MOVL AX, 76(SP)
99 MOVL syscall15Args_a21(BX), AX
100 MOVL AX, 80(SP)
101 MOVL syscall15Args_a22(BX), AX
102 MOVL AX, 84(SP)
103 MOVL syscall15Args_a23(BX), AX
104 MOVL AX, 88(SP)
105 MOVL syscall15Args_a24(BX), AX
106 MOVL AX, 92(SP)
107 MOVL syscall15Args_a25(BX), AX
108 MOVL AX, 96(SP)
109 MOVL syscall15Args_a26(BX), AX
110 MOVL AX, 100(SP)
111 MOVL syscall15Args_a27(BX), AX
112 MOVL AX, 104(SP)
113 MOVL syscall15Args_a28(BX), AX
114 MOVL AX, 108(SP)
115 MOVL syscall15Args_a29(BX), AX
116 MOVL AX, 112(SP)
117 MOVL syscall15Args_a30(BX), AX
118 MOVL AX, 116(SP)
119 MOVL syscall15Args_a31(BX), AX
120 MOVL AX, 120(SP)
121 MOVL syscall15Args_a32(BX), AX
122 MOVL AX, 124(SP)
123
124 // Call the C function
125 MOVL (PTR_ADDRESS-4)(SP), AX
126 CALL AX
127
128 // Get args pointer back and save results
129 MOVL PTR_ADDRESS(SP), BX
130 MOVL AX, syscall15Args_a1(BX) // return value r1
131 MOVL DX, syscall15Args_a2(BX) // return value r2 (for 64-bit returns)
132
133 // Save x87 FPU return value (ST0) to f1 field
134 // On i386 System V ABI, float/double returns are in ST(0)
135 // We save as float64 (8 bytes) to preserve precision
136 FMOVDP F0, syscall15Args_f1(BX)
137
138 // Clean up stack
139 ADDL $STACK_SIZE, SP
140
141 // Restore callee-saved registers
142 POPL DI
143 POPL SI
144 POPL BX
145 POPL BP
146
147 RET
148