sys_386.s 3.7 KB

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