trampolines_amd64.s 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // SPDX-License-Identifier: Apache-2.0
  2. // SPDX-FileCopyrightText: 2022 The Ebitengine Authors
  3. //go:build !cgo && (darwin || linux || freebsd)
  4. /*
  5. trampoline for emulating required C functions for cgo in go (see cgo.go)
  6. (we convert cdecl calling convention to go and vice-versa)
  7. Since we're called from go and call into C we can cheat a bit with the calling conventions:
  8. - in go all the registers are caller saved
  9. - in C we have a couple of callee saved registers
  10. => we can use BX, R12, R13, R14, R15 instead of the stack
  11. C Calling convention cdecl used here (we only need integer args):
  12. 1. arg: DI
  13. 2. arg: SI
  14. 3. arg: DX
  15. 4. arg: CX
  16. 5. arg: R8
  17. 6. arg: R9
  18. We don't need floats with these functions -> AX=0
  19. return value will be in AX
  20. */
  21. #include "textflag.h"
  22. #include "go_asm.h"
  23. // these trampolines map the gcc ABI to Go ABI and then calls into the Go equivalent functions.
  24. TEXT x_cgo_init_trampoline(SB), NOSPLIT, $16
  25. MOVQ DI, AX
  26. MOVQ SI, BX
  27. MOVQ ·x_cgo_init_call(SB), DX
  28. MOVQ (DX), CX
  29. CALL CX
  30. RET
  31. TEXT x_cgo_thread_start_trampoline(SB), NOSPLIT, $8
  32. MOVQ DI, AX
  33. MOVQ ·x_cgo_thread_start_call(SB), DX
  34. MOVQ (DX), CX
  35. CALL CX
  36. RET
  37. TEXT x_cgo_setenv_trampoline(SB), NOSPLIT, $8
  38. MOVQ DI, AX
  39. MOVQ ·x_cgo_setenv_call(SB), DX
  40. MOVQ (DX), CX
  41. CALL CX
  42. RET
  43. TEXT x_cgo_unsetenv_trampoline(SB), NOSPLIT, $8
  44. MOVQ DI, AX
  45. MOVQ ·x_cgo_unsetenv_call(SB), DX
  46. MOVQ (DX), CX
  47. CALL CX
  48. RET
  49. TEXT x_cgo_notify_runtime_init_done_trampoline(SB), NOSPLIT, $0
  50. CALL ·x_cgo_notify_runtime_init_done(SB)
  51. RET
  52. TEXT x_cgo_bindm_trampoline(SB), NOSPLIT, $0
  53. CALL ·x_cgo_bindm(SB)
  54. RET
  55. // func setg_trampoline(setg uintptr, g uintptr)
  56. TEXT ·setg_trampoline(SB), NOSPLIT, $0-16
  57. MOVQ G+8(FP), DI
  58. MOVQ setg+0(FP), BX
  59. XORL AX, AX
  60. CALL BX
  61. RET
  62. TEXT threadentry_trampoline(SB), NOSPLIT, $16
  63. MOVQ DI, AX
  64. MOVQ ·threadentry_call(SB), DX
  65. MOVQ (DX), CX
  66. CALL CX
  67. RET
  68. TEXT ·call5(SB), NOSPLIT, $0-56
  69. MOVQ fn+0(FP), BX
  70. MOVQ a1+8(FP), DI
  71. MOVQ a2+16(FP), SI
  72. MOVQ a3+24(FP), DX
  73. MOVQ a4+32(FP), CX
  74. MOVQ a5+40(FP), R8
  75. XORL AX, AX // no floats
  76. PUSHQ BP // save BP
  77. MOVQ SP, BP // save SP inside BP bc BP is callee-saved
  78. SUBQ $16, SP // allocate space for alignment
  79. ANDQ $-16, SP // align on 16 bytes for SSE
  80. CALL BX
  81. MOVQ BP, SP // get SP back
  82. POPQ BP // restore BP
  83. MOVQ AX, ret+48(FP)
  84. RET