2
0

as_callfunc_arm_gcc.S 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*
  2. AngelCode Scripting Library
  3. Copyright (c) 2003-2009 Andreas Jonsson
  4. This software is provided 'as-is', without any express or implied
  5. warranty. In no event will the authors be held liable for any
  6. damages arising from the use of this software.
  7. Permission is granted to anyone to use this software for any
  8. purpose, including commercial applications, and to alter it and
  9. redistribute it freely, subject to the following restrictions:
  10. 1. The origin of this software must not be misrepresented; you
  11. must not claim that you wrote the original software. If you use
  12. this software in a product, an acknowledgment in the product
  13. documentation would be appreciated but is not required.
  14. 2. Altered source versions must be plainly marked as such, and
  15. must not be misrepresented as being the original software.
  16. 3. This notice may not be removed or altered from any source
  17. distribution.
  18. The original version of this library can be located at:
  19. http://www.angelcode.com/angelscript/
  20. Andreas Jonsson
  21. [email protected]
  22. */
  23. // Assembly routines for the ARM call convention
  24. // Written by Fredrik Ehnbom in June 2009
  25. // Adapted to GNUC by darktemplar216 in September 2009
  26. #if defined(__arm__) || defined(__ARM__)
  27. .global armFunc
  28. .global armFuncR0
  29. .global armFuncR0R1
  30. .global armFuncObjLast
  31. .global armFuncR0ObjLast
  32. armFunc:
  33. stmdb sp!, {r4-r8, lr}
  34. mov r6, r0 // arg table
  35. movs r7, r1 // arg size (also set the condition code flags so that we detect if there are no arguments)
  36. mov r4, r2 // function address
  37. mov r8, #0
  38. beq nomoreargs
  39. // Load the first 4 arguments into r0-r3
  40. cmp r7, #4
  41. ldrge r0, [r6],#4
  42. cmp r7, #2*4
  43. ldrge r1, [r6],#4
  44. cmp r7, #3*4
  45. ldrge r2, [r6],#4
  46. cmp r7, #4*4
  47. ldrge r3, [r6],#4
  48. ble nomoreargs
  49. // Load the rest of the arguments onto the stack
  50. sub r7, r7, #4*4 // skip the 4 registers already loaded into r0-r3
  51. sub sp, sp, r7
  52. mov r8, r7
  53. stackargsloop:
  54. ldr r5, [r6], #4
  55. str r5, [sp], #4
  56. subs r7, r7, #4
  57. bne stackargsloop
  58. nomoreargs:
  59. sub sp, sp, r8
  60. blx r4
  61. add sp, sp, r8
  62. ldmia sp!, {r4-r8, pc}
  63. armFuncObjLast:
  64. stmdb sp!, {r4-r8, lr}
  65. mov r6, r0 // arg table
  66. movs r7, r1 // arg size (also set the condition code flags so that we detect if there are no arguments)
  67. mov r4, r2 // function address
  68. mov r8, #0
  69. mov r0, r3 // objlast. might get overwritten
  70. str r3, [sp, #-4]! // objlast again.
  71. beq nomoreargsarmFuncObjLast
  72. // Load the first 4 arguments into r0-r3
  73. cmp r7, #4
  74. ldrge r0, [r6],#4
  75. cmp r7, #2*4
  76. ldrge r1, [r6],#4
  77. ldrlt r1, [sp]
  78. cmp r7, #3*4
  79. ldrge r2, [r6],#4
  80. ldrlt r2, [sp]
  81. cmp r7, #4*4
  82. ldrge r3, [r6],#4
  83. ldrlt r3, [sp]
  84. ble nomoreargsarmFuncObjLast
  85. // Load the rest of the arguments onto the stack
  86. sub r7, r7, #4*4 // skip the 4 registers already loaded into r0-r3
  87. sub sp, sp, r7
  88. mov r8, r7
  89. stackargslooparmFuncObjLast:
  90. ldr r5, [r6], #4
  91. str r5, [sp], #4
  92. subs r7, r7, #4
  93. bne stackargslooparmFuncObjLast
  94. nomoreargsarmFuncObjLast:
  95. sub sp, sp, r8
  96. blx r4
  97. add sp, sp, r8
  98. add sp, sp, #4
  99. ldmia sp!, {r4-r8, pc}
  100. armFuncR0ObjLast:
  101. stmdb sp!, {r4-r8, lr}
  102. ldr r7, [sp,#6*4]
  103. str r7, [sp,#-4]!
  104. mov r6, r0 // arg table
  105. movs r7, r1 // arg size (also set the condition code flags so that we detect if there are no arguments)
  106. mov r4, r2 // function address
  107. mov r8, #0
  108. mov r0, r3 // r0 explicitly set
  109. ldr r1, [sp] // objlast. might get overwritten
  110. beq nomoreargsarmFuncR0ObjLast
  111. // Load the first 3 arguments into r1-r3
  112. cmp r7, #1*4
  113. ldrge r1, [r6],#4
  114. cmp r7, #2*4
  115. ldrge r2, [r6],#4
  116. ldrlt r2, [sp]
  117. cmp r7, #3*4
  118. ldrge r3, [r6],#4
  119. ldrlt r3, [sp]
  120. ble nomoreargsarmFuncR0ObjLast
  121. // Load the rest of the arguments onto the stack
  122. sub r7, r7, #3*4 // skip the 3 registers already loaded into r1-r3
  123. sub sp, sp, r7
  124. mov r8, r7
  125. stackargslooparmFuncR0ObjLast:
  126. ldr r5, [r6], #4
  127. str r5, [sp], #4
  128. subs r7, r7, #4
  129. bne stackargslooparmFuncR0ObjLast
  130. nomoreargsarmFuncR0ObjLast:
  131. sub sp, sp, r8
  132. blx r4
  133. add sp, sp, r8
  134. add sp, sp, #4
  135. ldmia sp!, {r4-r8, pc}
  136. armFuncR0:
  137. stmdb sp!, {r4-r8, lr}
  138. mov r6, r0 // arg table
  139. movs r7, r1 // arg size (also set the condition code flags so that we detect if there are no arguments)
  140. mov r4, r2 // function address
  141. mov r8, #0
  142. mov r0, r3 // r0 explicitly set
  143. beq nomoreargsarmFuncR0
  144. // Load the first 3 arguments into r1-r3
  145. cmp r7, #1*4
  146. ldrge r1, [r6],#4
  147. cmp r7, #2*4
  148. ldrge r2, [r6],#4
  149. cmp r7, #3*4
  150. ldrge r3, [r6],#4
  151. ble nomoreargsarmFuncR0
  152. // Load the rest of the arguments onto the stack
  153. sub r7, r7, #3*4 // skip the 3 registers already loaded into r1-r3
  154. sub sp, sp, r7
  155. mov r8, r7
  156. stackargslooparmFuncR0:
  157. ldr r5, [r6], #4
  158. str r5, [sp], #4
  159. subs r7, r7, #4
  160. bne stackargslooparmFuncR0
  161. nomoreargsarmFuncR0:
  162. sub sp, sp, r8
  163. blx r4
  164. add sp, sp, r8
  165. ldmia sp!, {r4-r8, pc}
  166. armFuncR0R1:
  167. stmdb sp!, {r4-r8, lr}
  168. mov r6, r0 // arg table
  169. movs r7, r1 // arg size (also set the condition code flags so that we detect if there are no arguments)
  170. mov r4, r2 // function address
  171. mov r8, #0
  172. mov r0, r3 // r0 explicitly set
  173. ldr r1, [sp, #6*4] // r1 explicitly set too
  174. beq nomoreargsarmFuncR0R1
  175. // Load the first 2 arguments into r2-r3
  176. cmp r7, #1*4
  177. ldrge r2, [r6],#4
  178. cmp r7, #2*4
  179. ldrge r3, [r6],#4
  180. ble nomoreargsarmFuncR0R1
  181. // Load the rest of the arguments onto the stack
  182. sub r7, r7, #2*4 // skip the 2 registers already loaded into r2-r3
  183. sub sp, sp, r7
  184. mov r8, r7
  185. stackargslooparmFuncR0R1:
  186. ldr r5, [r6], #4
  187. str r5, [sp], #4
  188. subs r7, r7, #4
  189. bne stackargslooparmFuncR0R1
  190. nomoreargsarmFuncR0R1:
  191. sub sp, sp, r8
  192. blx r4
  193. add sp, sp, r8
  194. ldmia sp!, {r4-r8, pc}
  195. #endif