abi_amd64.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. // Copyright 2021 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // Macros for transitioning from the host ABI to Go ABI0.
  5. //
  6. // These save the frame pointer, so in general, functions that use
  7. // these should have zero frame size to suppress the automatic frame
  8. // pointer, though it's harmless to not do this.
  9. #ifdef GOOS_windows
  10. // REGS_HOST_TO_ABI0_STACK is the stack bytes used by
  11. // PUSH_REGS_HOST_TO_ABI0.
  12. #define REGS_HOST_TO_ABI0_STACK (28*8 + 8)
  13. // PUSH_REGS_HOST_TO_ABI0 prepares for transitioning from
  14. // the host ABI to Go ABI0 code. It saves all registers that are
  15. // callee-save in the host ABI and caller-save in Go ABI0 and prepares
  16. // for entry to Go.
  17. //
  18. // Save DI SI BP BX R12 R13 R14 R15 X6-X15 registers and the DF flag.
  19. // Clear the DF flag for the Go ABI.
  20. // MXCSR matches the Go ABI, so we don't have to set that,
  21. // and Go doesn't modify it, so we don't have to save it.
  22. #define PUSH_REGS_HOST_TO_ABI0() \
  23. PUSHFQ \
  24. CLD \
  25. ADJSP $(REGS_HOST_TO_ABI0_STACK - 8) \
  26. MOVQ DI, (0*0)(SP) \
  27. MOVQ SI, (1*8)(SP) \
  28. MOVQ BP, (2*8)(SP) \
  29. MOVQ BX, (3*8)(SP) \
  30. MOVQ R12, (4*8)(SP) \
  31. MOVQ R13, (5*8)(SP) \
  32. MOVQ R14, (6*8)(SP) \
  33. MOVQ R15, (7*8)(SP) \
  34. MOVUPS X6, (8*8)(SP) \
  35. MOVUPS X7, (10*8)(SP) \
  36. MOVUPS X8, (12*8)(SP) \
  37. MOVUPS X9, (14*8)(SP) \
  38. MOVUPS X10, (16*8)(SP) \
  39. MOVUPS X11, (18*8)(SP) \
  40. MOVUPS X12, (20*8)(SP) \
  41. MOVUPS X13, (22*8)(SP) \
  42. MOVUPS X14, (24*8)(SP) \
  43. MOVUPS X15, (26*8)(SP)
  44. #define POP_REGS_HOST_TO_ABI0() \
  45. MOVQ (0*0)(SP), DI \
  46. MOVQ (1*8)(SP), SI \
  47. MOVQ (2*8)(SP), BP \
  48. MOVQ (3*8)(SP), BX \
  49. MOVQ (4*8)(SP), R12 \
  50. MOVQ (5*8)(SP), R13 \
  51. MOVQ (6*8)(SP), R14 \
  52. MOVQ (7*8)(SP), R15 \
  53. MOVUPS (8*8)(SP), X6 \
  54. MOVUPS (10*8)(SP), X7 \
  55. MOVUPS (12*8)(SP), X8 \
  56. MOVUPS (14*8)(SP), X9 \
  57. MOVUPS (16*8)(SP), X10 \
  58. MOVUPS (18*8)(SP), X11 \
  59. MOVUPS (20*8)(SP), X12 \
  60. MOVUPS (22*8)(SP), X13 \
  61. MOVUPS (24*8)(SP), X14 \
  62. MOVUPS (26*8)(SP), X15 \
  63. ADJSP $-(REGS_HOST_TO_ABI0_STACK - 8) \
  64. POPFQ
  65. #else
  66. // SysV ABI
  67. #define REGS_HOST_TO_ABI0_STACK (6*8)
  68. // SysV MXCSR matches the Go ABI, so we don't have to set that,
  69. // and Go doesn't modify it, so we don't have to save it.
  70. // Both SysV and Go require DF to be cleared, so that's already clear.
  71. // The SysV and Go frame pointer conventions are compatible.
  72. #define PUSH_REGS_HOST_TO_ABI0() \
  73. ADJSP $(REGS_HOST_TO_ABI0_STACK) \
  74. MOVQ BP, (5*8)(SP) \
  75. LEAQ (5*8)(SP), BP \
  76. MOVQ BX, (0*8)(SP) \
  77. MOVQ R12, (1*8)(SP) \
  78. MOVQ R13, (2*8)(SP) \
  79. MOVQ R14, (3*8)(SP) \
  80. MOVQ R15, (4*8)(SP)
  81. #define POP_REGS_HOST_TO_ABI0() \
  82. MOVQ (0*8)(SP), BX \
  83. MOVQ (1*8)(SP), R12 \
  84. MOVQ (2*8)(SP), R13 \
  85. MOVQ (3*8)(SP), R14 \
  86. MOVQ (4*8)(SP), R15 \
  87. MOVQ (5*8)(SP), BP \
  88. ADJSP $-(REGS_HOST_TO_ABI0_STACK)
  89. #endif