sys_unix_arm64.s 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // SPDX-License-Identifier: Apache-2.0
  2. // SPDX-FileCopyrightText: 2023 The Ebitengine Authors
  3. //go:build darwin || freebsd || linux
  4. #include "textflag.h"
  5. #include "go_asm.h"
  6. #include "funcdata.h"
  7. #include "abi_arm64.h"
  8. TEXT callbackasm1(SB), NOSPLIT|NOFRAME, $0
  9. NO_LOCAL_POINTERS
  10. // On entry, the trampoline in zcallback_darwin_arm64.s left
  11. // the callback index in R12 (which is volatile in the C ABI).
  12. // Save callback register arguments R0-R7 and F0-F7.
  13. // We do this at the top of the frame so they're contiguous with stack arguments.
  14. SUB $(16*8), RSP, R14
  15. FSTPD (F0, F1), (0*8)(R14)
  16. FSTPD (F2, F3), (2*8)(R14)
  17. FSTPD (F4, F5), (4*8)(R14)
  18. FSTPD (F6, F7), (6*8)(R14)
  19. STP (R0, R1), (8*8)(R14)
  20. STP (R2, R3), (10*8)(R14)
  21. STP (R4, R5), (12*8)(R14)
  22. STP (R6, R7), (14*8)(R14)
  23. // Adjust SP by frame size.
  24. SUB $(26*8), RSP
  25. // It is important to save R27 because the go assembler
  26. // uses it for move instructions for a variable.
  27. // This line:
  28. // MOVD ·callbackWrap_call(SB), R0
  29. // Creates the instructions:
  30. // ADRP 14335(PC), R27
  31. // MOVD 388(27), R0
  32. // R27 is a callee saved register so we are responsible
  33. // for ensuring its value doesn't change. So save it and
  34. // restore it at the end of this function.
  35. // R30 is the link register. crosscall2 doesn't save it
  36. // so it's saved here.
  37. STP (R27, R30), 0(RSP)
  38. // Create a struct callbackArgs on our stack.
  39. MOVD $(callbackArgs__size)(RSP), R13
  40. MOVD R12, callbackArgs_index(R13) // callback index
  41. MOVD R14, callbackArgs_args(R13) // address of args vector
  42. MOVD ZR, callbackArgs_result(R13) // result
  43. // Move parameters into registers
  44. // Get the ABIInternal function pointer
  45. // without <ABIInternal> by using a closure.
  46. MOVD ·callbackWrap_call(SB), R0
  47. MOVD (R0), R0 // fn unsafe.Pointer
  48. MOVD R13, R1 // frame (&callbackArgs{...})
  49. MOVD $0, R3 // ctxt uintptr
  50. BL crosscall2(SB)
  51. // Get callback result.
  52. MOVD $(callbackArgs__size)(RSP), R13
  53. MOVD callbackArgs_result(R13), R0
  54. // Restore LR and R27
  55. LDP 0(RSP), (R27, R30)
  56. ADD $(26*8), RSP
  57. RET