as_callfunc_arm64_gcc.S 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. //
  2. // AngelCode Scripting Library
  3. // Copyright (c) 2020-2021 Andreas Jonsson
  4. //
  5. // This software is provided 'as-is', without any express or implied
  6. // warranty. In no event will the authors be held liable for any
  7. // damages arising from the use of this software.
  8. //
  9. // Permission is granted to anyone to use this software for any
  10. // purpose, including commercial applications, and to alter it and
  11. // redistribute it freely, subject to the following restrictions:
  12. //
  13. // 1. The origin of this software must not be misrepresented// you
  14. // must not claim that you wrote the original software. If you use
  15. // this software in a product, an acknowledgment in the product
  16. // documentation would be appreciated but is not required.
  17. //
  18. // 2. Altered source versions must be plainly marked as such, and
  19. // must not be misrepresented as being the original software.
  20. //
  21. // 3. This notice may not be removed or altered from any source
  22. // distribution.
  23. //
  24. // The original version of this library can be located at:
  25. // http://www.angelcode.com/angelscript/
  26. //
  27. // Andreas Jonsson
  28. // andreas@angelcode.com
  29. //
  30. // Assembly routines for the ARM64/AArch64 call convention used for Linux
  31. // Written by Max Waine in July 2020, based on as_callfunc_arm_msvc.asm,
  32. // with assistance & guidance provided by Sir Kane
  33. // Compile with GCC/GAS
  34. #if !defined(AS_MAX_PORTABILITY)
  35. #if defined(__aarch64__)
  36. .arch armv8-a
  37. .text
  38. .global GetHFAReturnDouble
  39. .global GetHFAReturnFloat
  40. .global CallARM64Ret128
  41. .global CallARM64RetInMemory
  42. .global CallARM64Double
  43. .global CallARM64Float
  44. .global CallARM64
  45. .type GetHFAReturnDouble, %function
  46. .type GetHFAReturnFloat, %function
  47. .type CallARM64Ret128, %function
  48. .type CallARM64RetInMemory, %function
  49. .type CallARM64Double, %function
  50. .type CallARM64Float, %function
  51. .type CallARM64, %function
  52. .align 2
  53. GetHFAReturnDouble:
  54. adr x9, populateDoubles
  55. sub x9, x9, x1, lsr 1 // x9 -= returnSize >> 1; (/2 because double is 2x instruction size)
  56. br x9
  57. str d3, [x0, #0x18]
  58. str d2, [x0, #0x10]
  59. str d1, [x1]
  60. str d0, [x0]
  61. populateDoubles:
  62. ret
  63. .align 2
  64. GetHFAReturnFloat:
  65. adr x9, populateFloats
  66. sub x9, x9, x2 // x9 -= returnSize; (already 4 bytes per return)
  67. br x9
  68. str s3, [x1, #0x4]
  69. str s2, [x1]
  70. str s1, [x0, #0x4]
  71. str s0, [x0]
  72. populateFloats:
  73. ret
  74. //[returnType] CallARM64[type](
  75. // const asQWORD *gpRegArgs, asQWORD numGPRegArgs,
  76. // const asQWORD *floatRegArgs, asQWORD numFloatRegArgs,
  77. // const asQWORD *stackArgs, asQWORD numStackArgs,
  78. // asFUNCTION_t func
  79. //)
  80. .align 2
  81. CallARM64Double:
  82. CallARM64Float:
  83. CallARM64:
  84. .cfi_startproc
  85. stp fp, lr, [sp,#-0x20]!
  86. str x20, [sp,#0x10]
  87. .cfi_def_cfa_offset 0x20
  88. .cfi_offset 20, 0x10
  89. .cfi_offset fp, -0x20
  90. .cfi_offset lr, -0x18
  91. mov fp, sp
  92. mov x20, #0
  93. cbz x5, stackArgsLoopEnd
  94. // Align count to 2, then multiply by 8, resulting in a size aligned to 16
  95. add x20, x5, #1
  96. lsl x20, x20, #3
  97. and x20, x20, #-0x10
  98. // Multiply count by 8
  99. lsl x10, x5, #3
  100. sub sp, sp, x20
  101. stackArgsLoopStart:
  102. ldp x9,x11, [x4],#16
  103. stp x9,x11, [sp],#16
  104. subs x10, x10, #16
  105. bgt stackArgsLoopStart
  106. stackArgsLoopEnd:
  107. // Calculate amount to jump forward, avoiding pointless instructions
  108. adr x9, populateFloatRegisterArgsEnd
  109. sub x9, x9, x3, lsl 2 // x9 -= numFloatRegArgs * 4
  110. br x9
  111. ldr d7, [x2, #0x38]
  112. ldr d6, [x2, #0x30]
  113. ldr d5, [x2, #0x28]
  114. ldr d4, [x2, #0x20]
  115. ldr d3, [x2, #0x18]
  116. ldr d2, [x2, #0x10]
  117. ldr d1, [x2, #0x08]
  118. ldr d0, [x2]
  119. populateFloatRegisterArgsEnd:
  120. mov x15, x6
  121. // Calculate amount to jump forward, avoiding pointless instructions
  122. adr x9, populateGPRegisterArgsEnd
  123. sub x9, x9, x1, lsl 2 // x9 -= numGPRegArgs * 4
  124. br x9
  125. ldr x7, [x0, #0x38]
  126. ldr x6, [x0, #0x30]
  127. ldr x5, [x0, #0x28]
  128. ldr x4, [x0, #0x20]
  129. ldr x3, [x0, #0x18]
  130. ldr x2, [x0, #0x10]
  131. ldr x1, [x0, #0x08]
  132. ldr x0, [x0]
  133. populateGPRegisterArgsEnd:
  134. // Actually call function
  135. sub sp, sp, x20
  136. blr x15
  137. add sp, sp, x20
  138. ldr x20, [sp,#0x10]
  139. ldp fp, lr, [sp],#0x20
  140. .cfi_restore lr
  141. .cfi_restore fp
  142. .cfi_restore 20
  143. .cfi_def_cfa_offset 0
  144. ret
  145. .cfi_endproc
  146. .align 2
  147. CallARM64Ret128:
  148. .cfi_startproc
  149. stp fp, lr, [sp,#-0x20]!
  150. str x20, [sp,#0x10]
  151. .cfi_def_cfa_offset 0x20
  152. .cfi_offset 20, 0x10
  153. .cfi_offset fp, -0x20
  154. .cfi_offset lr, -0x18
  155. mov fp, sp
  156. mov x20, x6
  157. mov x6, x7
  158. mov x7, #0
  159. bl CallARM64
  160. str x1, [x20]
  161. ldr x20, [sp,#0x10]
  162. ldp fp, lr, [sp],#0x20
  163. .cfi_restore lr
  164. .cfi_restore fp
  165. .cfi_restore 20
  166. .cfi_def_cfa_offset 0
  167. ret
  168. .cfi_endproc
  169. .align 2
  170. CallARM64RetInMemory:
  171. .cfi_startproc
  172. stp fp, lr, [sp,#-0x10]!
  173. mov fp, sp
  174. .cfi_def_cfa_offset 0x10
  175. .cfi_offset fp, -0x10
  176. .cfi_offset lr, -0x08
  177. mov x8, x6
  178. mov x6, x7
  179. mov x7, #0
  180. bl CallARM64
  181. mov x0, x8
  182. ldp fp, lr, [sp],#0x10
  183. .cfi_restore lr
  184. .cfi_restore fp
  185. .cfi_def_cfa_offset 0
  186. ret
  187. .cfi_endproc
  188. #endif /* __aarch64__ */
  189. #endif /* !AS_MAX_PORTABILITY */