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