File: sys_386.s

package info (click to toggle)
golang-github-ebitengine-purego 0.10.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,452 kB
  • sloc: asm: 31,862; ansic: 1,001; cpp: 8; makefile: 3
file content (147 lines) | stat: -rw-r--r-- 3,821 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2026 The Ebitengine Authors

//go:build linux

#include "textflag.h"
#include "go_asm.h"
#include "funcdata.h"

#define STACK_SIZE 160
#define PTR_ADDRESS (STACK_SIZE - 4)

// syscall15X calls a function in libc on behalf of the syscall package.
// syscall15X takes a pointer to a struct like:
// struct {
//	fn    uintptr
//	a1    uintptr
//  ...
//	a32   uintptr
//	f1    uintptr
//	...
//	f16   uintptr
//	arm64_r8 uintptr
// }
// syscall15X must be called on the g0 stack with the
// C calling convention (use libcCall).
//
// On i386 System V ABI, all arguments are passed on the stack.
// Return value is in EAX (and EDX for 64-bit values).
GLOBL ·syscall15XABI0(SB), NOPTR|RODATA, $4
DATA ·syscall15XABI0(SB)/4, $syscall15X(SB)
TEXT syscall15X(SB), NOSPLIT|NOFRAME, $0-0
	// Called via C calling convention: argument pointer at 4(SP)
	// NOT via Go calling convention
	// On i386, the first argument is at 4(SP) after CALL pushes return address
	MOVL 4(SP), AX // get pointer to syscall15Args

	// Save callee-saved registers
	PUSHL BP
	PUSHL BX
	PUSHL SI
	PUSHL DI

	MOVL AX, BX // save args pointer in BX

	// Allocate stack space for C function arguments
	// i386 SysV: all 32 args on stack = 32 * 4 = 128 bytes
	// Plus 16 bytes for alignment and local storage
	SUBL $STACK_SIZE, SP
	MOVL BX, PTR_ADDRESS(SP) // save args pointer

	// Load function pointer
	MOVL syscall15Args_fn(BX), AX
	MOVL AX, (PTR_ADDRESS-4)(SP)  // save fn pointer

	// Push all integer arguments onto the stack (a1-a32)
	// i386 SysV ABI: arguments pushed right-to-left, but we're
	// setting up the stack from low to high addresses
	MOVL syscall15Args_a1(BX), AX
	MOVL AX, 0(SP)
	MOVL syscall15Args_a2(BX), AX
	MOVL AX, 4(SP)
	MOVL syscall15Args_a3(BX), AX
	MOVL AX, 8(SP)
	MOVL syscall15Args_a4(BX), AX
	MOVL AX, 12(SP)
	MOVL syscall15Args_a5(BX), AX
	MOVL AX, 16(SP)
	MOVL syscall15Args_a6(BX), AX
	MOVL AX, 20(SP)
	MOVL syscall15Args_a7(BX), AX
	MOVL AX, 24(SP)
	MOVL syscall15Args_a8(BX), AX
	MOVL AX, 28(SP)
	MOVL syscall15Args_a9(BX), AX
	MOVL AX, 32(SP)
	MOVL syscall15Args_a10(BX), AX
	MOVL AX, 36(SP)
	MOVL syscall15Args_a11(BX), AX
	MOVL AX, 40(SP)
	MOVL syscall15Args_a12(BX), AX
	MOVL AX, 44(SP)
	MOVL syscall15Args_a13(BX), AX
	MOVL AX, 48(SP)
	MOVL syscall15Args_a14(BX), AX
	MOVL AX, 52(SP)
	MOVL syscall15Args_a15(BX), AX
	MOVL AX, 56(SP)
	MOVL syscall15Args_a16(BX), AX
	MOVL AX, 60(SP)
	MOVL syscall15Args_a17(BX), AX
	MOVL AX, 64(SP)
	MOVL syscall15Args_a18(BX), AX
	MOVL AX, 68(SP)
	MOVL syscall15Args_a19(BX), AX
	MOVL AX, 72(SP)
	MOVL syscall15Args_a20(BX), AX
	MOVL AX, 76(SP)
	MOVL syscall15Args_a21(BX), AX
	MOVL AX, 80(SP)
	MOVL syscall15Args_a22(BX), AX
	MOVL AX, 84(SP)
	MOVL syscall15Args_a23(BX), AX
	MOVL AX, 88(SP)
	MOVL syscall15Args_a24(BX), AX
	MOVL AX, 92(SP)
	MOVL syscall15Args_a25(BX), AX
	MOVL AX, 96(SP)
	MOVL syscall15Args_a26(BX), AX
	MOVL AX, 100(SP)
	MOVL syscall15Args_a27(BX), AX
	MOVL AX, 104(SP)
	MOVL syscall15Args_a28(BX), AX
	MOVL AX, 108(SP)
	MOVL syscall15Args_a29(BX), AX
	MOVL AX, 112(SP)
	MOVL syscall15Args_a30(BX), AX
	MOVL AX, 116(SP)
	MOVL syscall15Args_a31(BX), AX
	MOVL AX, 120(SP)
	MOVL syscall15Args_a32(BX), AX
	MOVL AX, 124(SP)

	// Call the C function
	MOVL (PTR_ADDRESS-4)(SP), AX
	CALL AX

	// Get args pointer back and save results
	MOVL PTR_ADDRESS(SP), BX
	MOVL AX, syscall15Args_a1(BX) // return value r1
	MOVL DX, syscall15Args_a2(BX) // return value r2 (for 64-bit returns)

	// Save x87 FPU return value (ST0) to f1 field
	// On i386 System V ABI, float/double returns are in ST(0)
	// We save as float64 (8 bytes) to preserve precision
	FMOVDP F0, syscall15Args_f1(BX)

	// Clean up stack
	ADDL $STACK_SIZE, SP

	// Restore callee-saved registers
	POPL DI
	POPL SI
	POPL BX
	POPL BP

	RET