sys_unix_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  // callbackasm1 is the second part of the callback trampoline.
  11  // On entry:
  12  //   - CX contains the callback index (set by callbackasm)
  13  //   - 0(SP) contains the return address to C caller
  14  //   - 4(SP), 8(SP), ... contain C arguments (cdecl convention)
  15  //
  16  // i386 cdecl calling convention:
  17  // - All arguments passed on stack
  18  // - Return value in EAX (and EDX for 64-bit)
  19  // - Caller cleans the stack
  20  // - Callee must preserve: EBX, ESI, EDI, EBP
  21  TEXT callbackasm1(SB), NOSPLIT|NOFRAME, $0
  22  	NO_LOCAL_POINTERS
  23  
  24  	// Save the return address
  25  	MOVL 0(SP), AX
  26  
  27  	// Allocate stack frame (must be done carefully to preserve args access)
  28  	// Layout:
  29  	//   0-15: saved callee-saved registers (BX, SI, DI, BP)
  30  	//   16-19: saved callback index
  31  	//   20-23: saved return address
  32  	//   24-35: callbackArgs struct (12 bytes)
  33  	//   36-291: copy of C arguments (256 bytes for 64 args, matching callbackMaxFrame)
  34  	// Total: 292 bytes, round up to 304 for alignment
  35  	SUBL $304, SP
  36  
  37  	// Save callee-saved registers
  38  	MOVL BX, 0(SP)
  39  	MOVL SI, 4(SP)
  40  	MOVL DI, 8(SP)
  41  	MOVL BP, 12(SP)
  42  
  43  	// Save callback index and return address
  44  	MOVL CX, 16(SP)
  45  	MOVL AX, 20(SP)
  46  
  47  	// Copy C arguments from original stack location to our frame
  48  	// Original args start at 304+4(SP) = 308(SP) (past our frame + original return addr)
  49  	// Copy to our frame at 36(SP)
  50  	// Copy 64 arguments (256 bytes, matching callbackMaxFrame = 64 * ptrSize)
  51  	MOVL 308(SP), AX
  52  	MOVL AX, 36(SP)
  53  	MOVL 312(SP), AX
  54  	MOVL AX, 40(SP)
  55  	MOVL 316(SP), AX
  56  	MOVL AX, 44(SP)
  57  	MOVL 320(SP), AX
  58  	MOVL AX, 48(SP)
  59  	MOVL 324(SP), AX
  60  	MOVL AX, 52(SP)
  61  	MOVL 328(SP), AX
  62  	MOVL AX, 56(SP)
  63  	MOVL 332(SP), AX
  64  	MOVL AX, 60(SP)
  65  	MOVL 336(SP), AX
  66  	MOVL AX, 64(SP)
  67  	MOVL 340(SP), AX
  68  	MOVL AX, 68(SP)
  69  	MOVL 344(SP), AX
  70  	MOVL AX, 72(SP)
  71  	MOVL 348(SP), AX
  72  	MOVL AX, 76(SP)
  73  	MOVL 352(SP), AX
  74  	MOVL AX, 80(SP)
  75  	MOVL 356(SP), AX
  76  	MOVL AX, 84(SP)
  77  	MOVL 360(SP), AX
  78  	MOVL AX, 88(SP)
  79  	MOVL 364(SP), AX
  80  	MOVL AX, 92(SP)
  81  	MOVL 368(SP), AX
  82  	MOVL AX, 96(SP)
  83  	MOVL 372(SP), AX
  84  	MOVL AX, 100(SP)
  85  	MOVL 376(SP), AX
  86  	MOVL AX, 104(SP)
  87  	MOVL 380(SP), AX
  88  	MOVL AX, 108(SP)
  89  	MOVL 384(SP), AX
  90  	MOVL AX, 112(SP)
  91  	MOVL 388(SP), AX
  92  	MOVL AX, 116(SP)
  93  	MOVL 392(SP), AX
  94  	MOVL AX, 120(SP)
  95  	MOVL 396(SP), AX
  96  	MOVL AX, 124(SP)
  97  	MOVL 400(SP), AX
  98  	MOVL AX, 128(SP)
  99  	MOVL 404(SP), AX
 100  	MOVL AX, 132(SP)
 101  	MOVL 408(SP), AX
 102  	MOVL AX, 136(SP)
 103  	MOVL 412(SP), AX
 104  	MOVL AX, 140(SP)
 105  	MOVL 416(SP), AX
 106  	MOVL AX, 144(SP)
 107  	MOVL 420(SP), AX
 108  	MOVL AX, 148(SP)
 109  	MOVL 424(SP), AX
 110  	MOVL AX, 152(SP)
 111  	MOVL 428(SP), AX
 112  	MOVL AX, 156(SP)
 113  	MOVL 432(SP), AX
 114  	MOVL AX, 160(SP)
 115  	MOVL 436(SP), AX
 116  	MOVL AX, 164(SP)
 117  	MOVL 440(SP), AX
 118  	MOVL AX, 168(SP)
 119  	MOVL 444(SP), AX
 120  	MOVL AX, 172(SP)
 121  	MOVL 448(SP), AX
 122  	MOVL AX, 176(SP)
 123  	MOVL 452(SP), AX
 124  	MOVL AX, 180(SP)
 125  	MOVL 456(SP), AX
 126  	MOVL AX, 184(SP)
 127  	MOVL 460(SP), AX
 128  	MOVL AX, 188(SP)
 129  	MOVL 464(SP), AX
 130  	MOVL AX, 192(SP)
 131  	MOVL 468(SP), AX
 132  	MOVL AX, 196(SP)
 133  	MOVL 472(SP), AX
 134  	MOVL AX, 200(SP)
 135  	MOVL 476(SP), AX
 136  	MOVL AX, 204(SP)
 137  	MOVL 480(SP), AX
 138  	MOVL AX, 208(SP)
 139  	MOVL 484(SP), AX
 140  	MOVL AX, 212(SP)
 141  	MOVL 488(SP), AX
 142  	MOVL AX, 216(SP)
 143  	MOVL 492(SP), AX
 144  	MOVL AX, 220(SP)
 145  	MOVL 496(SP), AX
 146  	MOVL AX, 224(SP)
 147  	MOVL 500(SP), AX
 148  	MOVL AX, 228(SP)
 149  	MOVL 504(SP), AX
 150  	MOVL AX, 232(SP)
 151  	MOVL 508(SP), AX
 152  	MOVL AX, 236(SP)
 153  	MOVL 512(SP), AX
 154  	MOVL AX, 240(SP)
 155  	MOVL 516(SP), AX
 156  	MOVL AX, 244(SP)
 157  	MOVL 520(SP), AX
 158  	MOVL AX, 248(SP)
 159  	MOVL 524(SP), AX
 160  	MOVL AX, 252(SP)
 161  	MOVL 528(SP), AX
 162  	MOVL AX, 256(SP)
 163  	MOVL 532(SP), AX
 164  	MOVL AX, 260(SP)
 165  	MOVL 536(SP), AX
 166  	MOVL AX, 264(SP)
 167  	MOVL 540(SP), AX
 168  	MOVL AX, 268(SP)
 169  	MOVL 544(SP), AX
 170  	MOVL AX, 272(SP)
 171  	MOVL 548(SP), AX
 172  	MOVL AX, 276(SP)
 173  	MOVL 552(SP), AX
 174  	MOVL AX, 280(SP)
 175  	MOVL 556(SP), AX
 176  	MOVL AX, 284(SP)
 177  	MOVL 560(SP), AX
 178  	MOVL AX, 288(SP)
 179  
 180  	// Set up callbackArgs struct at 24(SP)
 181  	// struct callbackArgs {
 182  	//     index  uintptr  // offset 0
 183  	//     args   *byte    // offset 4
 184  	//     result uintptr  // offset 8
 185  	// }
 186  	MOVL 16(SP), AX // callback index
 187  	MOVL AX, 24(SP) // callbackArgs.index
 188  	LEAL 36(SP), AX // pointer to copied arguments
 189  	MOVL AX, 28(SP) // callbackArgs.args
 190  	MOVL $0, 32(SP) // callbackArgs.result = 0
 191  
 192  	// Call crosscall2(fn, frame, 0, ctxt)
 193  	// crosscall2 expects arguments on stack:
 194  	//   0(SP) = fn
 195  	//   4(SP) = frame (pointer to callbackArgs)
 196  	//   8(SP) = ignored (was n)
 197  	//   12(SP) = ctxt
 198  	SUBL $16, SP
 199  
 200  	MOVL ·callbackWrap_call(SB), AX
 201  	MOVL (AX), AX                   // fn = *callbackWrap_call
 202  	MOVL AX, 0(SP)                  // fn
 203  	LEAL (24+16)(SP), AX            // &callbackArgs (adjusted for SUB $16)
 204  	MOVL AX, 4(SP)                  // frame
 205  	MOVL $0, 8(SP)                  // 0
 206  	MOVL $0, 12(SP)                 // ctxt
 207  
 208  	CALL crosscall2(SB)
 209  
 210  	ADDL $16, SP
 211  
 212  	// Get result from callbackArgs.result
 213  	MOVL 32(SP), AX
 214  
 215  	// Restore callee-saved registers
 216  	MOVL 0(SP), BX
 217  	MOVL 4(SP), SI
 218  	MOVL 8(SP), DI
 219  	MOVL 12(SP), BP
 220  
 221  	// Restore return address and clean up
 222  	MOVL 20(SP), CX // get return address
 223  	ADDL $304, SP   // remove our frame
 224  	MOVL CX, 0(SP)  // put return address back
 225  
 226  	RET
 227