sys_ppc64le.s 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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. // PPC64LE ELFv2 ABI:
  8. // - Integer args: R3-R10 (8 registers)
  9. // - Float args: F1-F8 (8 registers)
  10. // - Return: R3 (integer), F1 (float)
  11. // - Stack pointer: R1
  12. // - Link register: LR (special)
  13. // - TOC pointer: R2 (must preserve)
  14. // Stack layout for ELFv2 ABI (aligned to 16 bytes):
  15. // From callee's perspective when we call BL (CTR):
  16. // 0(R1) - back chain (our old R1)
  17. // 8(R1) - CR save word (optional)
  18. // 16(R1) - LR save (optional, we save it)
  19. // 24(R1) - Reserved (compilers)
  20. // 32(R1) - Parameter save area start (8 * 8 = 64 bytes for R3-R10)
  21. // 96(R1) - First stack arg (a9) - this is where callee looks
  22. // 104(R1) - Second stack arg (a10)
  23. // 112-152 - Stack args a11-a15 (5 * 8 = 40 bytes)
  24. // 160(R1) - TOC save (we put it here, outside param save area)
  25. // 168(R1) - saved args pointer
  26. // 176(R1) - padding for 16-byte alignment
  27. // Total: 176 bytes
  28. #define STACK_SIZE 176
  29. #define LR_SAVE 16
  30. #define TOC_SAVE 160
  31. #define ARGP_SAVE 168
  32. GLOBL ·syscall15XABI0(SB), NOPTR|RODATA, $8
  33. DATA ·syscall15XABI0(SB)/8, $syscall15X(SB)
  34. TEXT syscall15X(SB), NOSPLIT, $0
  35. // Prologue: create stack frame
  36. // R3 contains the args pointer on entry
  37. MOVD R1, R12 // save old SP
  38. SUB $STACK_SIZE, R1 // allocate stack frame
  39. MOVD R12, 0(R1) // save back chain
  40. MOVD LR, R12
  41. MOVD R12, LR_SAVE(R1) // save LR
  42. MOVD R2, TOC_SAVE(R1) // save TOC
  43. // Save args pointer (in R3)
  44. MOVD R3, ARGP_SAVE(R1)
  45. // R11 := args pointer (syscall15Args*)
  46. MOVD R3, R11
  47. // Load float args into F1-F8
  48. FMOVD syscall15Args_f1(R11), F1
  49. FMOVD syscall15Args_f2(R11), F2
  50. FMOVD syscall15Args_f3(R11), F3
  51. FMOVD syscall15Args_f4(R11), F4
  52. FMOVD syscall15Args_f5(R11), F5
  53. FMOVD syscall15Args_f6(R11), F6
  54. FMOVD syscall15Args_f7(R11), F7
  55. FMOVD syscall15Args_f8(R11), F8
  56. // Load integer args into R3-R10
  57. MOVD syscall15Args_a1(R11), R3
  58. MOVD syscall15Args_a2(R11), R4
  59. MOVD syscall15Args_a3(R11), R5
  60. MOVD syscall15Args_a4(R11), R6
  61. MOVD syscall15Args_a5(R11), R7
  62. MOVD syscall15Args_a6(R11), R8
  63. MOVD syscall15Args_a7(R11), R9
  64. MOVD syscall15Args_a8(R11), R10
  65. // Spill a9-a15 onto the stack (stack parameters start at 96(R1))
  66. // Per ELFv2: parameter save area is 32-95, stack args start at 96
  67. MOVD ARGP_SAVE(R1), R11 // reload args pointer
  68. MOVD syscall15Args_a9(R11), R12
  69. MOVD R12, 96(R1) // a9 at 96(R1)
  70. MOVD syscall15Args_a10(R11), R12
  71. MOVD R12, 104(R1) // a10 at 104(R1)
  72. MOVD syscall15Args_a11(R11), R12
  73. MOVD R12, 112(R1) // a11 at 112(R1)
  74. MOVD syscall15Args_a12(R11), R12
  75. MOVD R12, 120(R1) // a12 at 120(R1)
  76. MOVD syscall15Args_a13(R11), R12
  77. MOVD R12, 128(R1) // a13 at 128(R1)
  78. MOVD syscall15Args_a14(R11), R12
  79. MOVD R12, 136(R1) // a14 at 136(R1)
  80. MOVD syscall15Args_a15(R11), R12
  81. MOVD R12, 144(R1) // a15 at 144(R1)
  82. // Call function: load fn and call
  83. MOVD syscall15Args_fn(R11), R12
  84. MOVD R12, CTR
  85. BL (CTR)
  86. // Restore TOC after call
  87. MOVD TOC_SAVE(R1), R2
  88. // Restore args pointer for storing results
  89. MOVD ARGP_SAVE(R1), R11
  90. // Store integer results back (R3, R4)
  91. MOVD R3, syscall15Args_a1(R11)
  92. MOVD R4, syscall15Args_a2(R11)
  93. // Store float return values (F1-F4)
  94. FMOVD F1, syscall15Args_f1(R11)
  95. FMOVD F2, syscall15Args_f2(R11)
  96. FMOVD F3, syscall15Args_f3(R11)
  97. FMOVD F4, syscall15Args_f4(R11)
  98. // Epilogue: restore and return
  99. MOVD LR_SAVE(R1), R12
  100. MOVD R12, LR
  101. ADD $STACK_SIZE, R1
  102. RET