as_callfunc_arm64_msvc.asm 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. ;
  2. ; AngelCode Scripting Library
  3. ; Copyright (c) 2020-2020 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 Windows 10 on ARM
  31. ; Written by Max Waine in July 2020, based on as_callfunc_arm_msvc.asm
  32. ; MSVC currently doesn't support inline assembly for the ARM64 platform,
  33. ; and if they're treating it like x64 /won't/ ever support inline assembly,
  34. ; so this separate file is needed.
  35. ; Compile with Microsoft ARM64 assembler (armasm64)
  36. ; http://msdn.microsoft.com/en-us/library/hh873190.aspx
  37. AREA |.rdata|, DATA, READONLY
  38. EXPORT GetHFAReturnDouble
  39. EXPORT GetHFAReturnFloat
  40. EXPORT CallARM64Ret128
  41. EXPORT CallARM64RetInMemory
  42. EXPORT CallARM64Double
  43. EXPORT CallARM64Float
  44. EXPORT CallARM64
  45. AREA |.text|, CODE, ALIGN=2
  46. ALIGN 4
  47. GetHFAReturnDouble PROC
  48. adr x9, |populateDoubles|
  49. sub x9, x9, x1, lsr 1 ; x9 -= returnSize >> 1; (/2 because double is 2x instruction size)
  50. br x9
  51. str d3, [x0, #0x18]
  52. str d2, [x0, #0x10]
  53. str d1, [x1]
  54. str d0, [x0]
  55. |populateDoubles|
  56. ret
  57. ENDP ; GetHFAReturnDouble
  58. ALIGN 4
  59. GetHFAReturnFloat PROC
  60. adr x9, |populateFloats|
  61. sub x9, x9, x2 // x9 -= returnSize; (already 4 bytes per return)
  62. br x9
  63. str s3, [x1, #0x4]
  64. str s2, [x1]
  65. str s1, [x0, #0x4]
  66. str s0, [x0]
  67. |populateFloats|
  68. ret
  69. ENDP ; GetHFAReturnFloat
  70. ;[returnType] CallARM64[type](
  71. ; const asQWORD *gpRegArgs, asQWORD numGPRegArgs,
  72. ; const asQWORD *floatRegArgs, asQWORD numFloatRegArgs,
  73. ; const asQWORD *stackArgs, asQWORD numStackArgs,
  74. ; asFUNCTION_t func
  75. ;)
  76. ALIGN 4
  77. CallARM64Double PROC
  78. stp fp, lr, [sp,#-0x10]!
  79. bl CallARM64
  80. ldp fp, lr, [sp,#-0x10]!
  81. ret
  82. ENDP ; CallARM64Double
  83. ALIGN 4
  84. CallARM64Float PROC
  85. stp fp, lr, [sp,#-0x10]!
  86. bl CallARM64
  87. ldp fp, lr, [sp,#-0x10]!
  88. ret
  89. ENDP ; CallARM64Float
  90. ALIGN 4
  91. CallARM64 PROC
  92. stp fp, lr, [sp,#-0x20]!
  93. str x20, [sp,#0x10]
  94. mov x20, #0;
  95. cbz x5, |stackArgsLoopEnd|
  96. ; Align count to 2, then multiply by 8, resulting in a size aligned to 16
  97. add x20, x5, #1
  98. lsl x20, x20, #3
  99. and x20, x20, #-0x10
  100. ; Multiply count by 8
  101. lsl x10, x5, #3
  102. sub sp, sp, x20
  103. |stackArgsLoopStart|
  104. ldp x9,x11, [x4],#16
  105. stp x9,x11, [sp],#16
  106. subs x10, x10, #16
  107. bgt |stackArgsLoopStart|
  108. |stackArgsLoopEnd|
  109. ; Calculate amount to jump forward, avoiding pointless instructions
  110. adr x9, |populateFloatRegisterArgsEnd|
  111. sub x9, x9, x3, lsl 2 ; x9 -= numFloatRegArgs * 4
  112. br x9
  113. ldr d7, [x2, #0x38]
  114. ldr d6, [x2, #0x30]
  115. ldr d5, [x2, #0x28]
  116. ldr d4, [x2, #0x20]
  117. ldr d3, [x2, #0x18]
  118. ldr d2, [x2, #0x10]
  119. ldr d1, [x2, #0x08]
  120. ldr d0, [x2]
  121. |populateFloatRegisterArgsEnd|
  122. mov x15, x6
  123. ; Calculate amount to jump forward, avoiding pointless instructions
  124. adr x9, |populateGPRegisterArgsEnd|
  125. sub x9, x9, x1, lsl 2 ; x9 -= numGPRegArgs * 4
  126. br x9
  127. ldr x7, [x0, #0x38]
  128. ldr x6, [x0, #0x30]
  129. ldr x5, [x0, #0x28]
  130. ldr x4, [x0, #0x20]
  131. ldr x3, [x0, #0x18]
  132. ldr x2, [x0, #0x10]
  133. ldr x1, [x0, #0x08]
  134. ldr x0, [x0]
  135. |populateGPRegisterArgsEnd|
  136. ; Actually call function
  137. sub sp, sp, x20
  138. blr x15
  139. add sp, sp, x20
  140. ldr x20, [sp,#0x10]
  141. ldp fp, lr, [sp],#0x20
  142. ret
  143. ENDP ; CallARM64
  144. ALIGN 4
  145. CallARM64Ret128 PROC
  146. stp fp, lr, [sp,#-0x20]!
  147. str x20, [sp,#0x10]
  148. mov fp, sp
  149. mov x20, x6
  150. mov x6, x7
  151. mov x7, #0
  152. bl CallARM64
  153. str x1, [x20]
  154. ldr x20, [sp,#0x10]
  155. ldp fp, lr, [sp],#0x20
  156. ret ; CallARM64Ret128
  157. ALIGN 4
  158. CallARM64RetInMemory PROC
  159. stp fp, lr, [sp,#-0x10]!
  160. mov fp, sp
  161. mov x8, x6
  162. mov x6, x7
  163. mov x7, #0
  164. bl CallARM64
  165. mov x0, x8
  166. ldp fp, lr, [sp],#0x10
  167. ret ; CallARM64RetInMemory
  168. END