2
0

unixasmmacrosarm.inc 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. // -------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. // -------------------------------------------------------------------------------------------------------
  5. // Licensed to the .NET Foundation under one or more agreements.
  6. // The .NET Foundation licenses this file to you under the MIT license.
  7. // See the LICENSE file in the project root for more information.
  8. .macro LEAF_ENTRY Name, Section
  9. .thumb_func
  10. .global C_FUNC(\Name)
  11. .type \Name, %function
  12. C_FUNC(\Name):
  13. .fnstart
  14. .endm
  15. .macro NESTED_ENTRY Name, Section, Handler
  16. LEAF_ENTRY \Name, \Section
  17. .ifnc \Handler, NoHandler
  18. .personality C_FUNC(\Handler)
  19. .endif
  20. .endm
  21. .macro NESTED_END Name, Section
  22. LEAF_END \Name, \Section
  23. .endm
  24. .macro NESTED_END_MARKED Name, Section
  25. LEAF_END_MARKED \Name, \Section
  26. .endm
  27. .macro PATCH_LABEL Name
  28. .thumb_func
  29. .global C_FUNC(\Name)
  30. C_FUNC(\Name):
  31. .endm
  32. .macro LEAF_END Name, Section
  33. .size \Name, .-\Name
  34. .fnend
  35. .endm
  36. .macro LEAF_END_MARKED Name, Section
  37. .thumb_func
  38. .global C_FUNC(\Name\()_End)
  39. C_FUNC(\Name\()_End):
  40. LEAF_END \Name, \Section
  41. .endm
  42. .macro PREPARE_EXTERNAL_VAR Name, HelperReg
  43. ldr \HelperReg, [pc, #C_FUNC(\Name)@GOTPCREL]
  44. .endm
  45. .macro push_nonvol_reg Register
  46. push \Register
  47. .save \Register
  48. .endm
  49. .macro pop_nonvol_reg Register
  50. pop \Register
  51. .endm
  52. .macro vpush_nonvol_reg Register
  53. vpush \Register
  54. .vsave \Register
  55. .endm
  56. .macro vpop_nonvol_reg Register
  57. vpop \Register
  58. .endm
  59. .macro alloc_stack Size
  60. sub sp, sp, (\Size)
  61. .pad #(\Size)
  62. .endm
  63. .macro free_stack Size
  64. add sp, sp, (\Size)
  65. .pad #-(\Size)
  66. .endm
  67. .macro POP_CALLEE_SAVED_REGISTERS
  68. pop_nonvol_reg "{r4-r11, lr}"
  69. .endm
  70. .macro PUSH_CALLEE_SAVED_REGISTERS
  71. push_nonvol_reg "{r4-r11, lr}"
  72. .endm
  73. .macro push_register Reg
  74. push \Reg
  75. .endm
  76. .macro push_argument_register Reg
  77. push_register \Reg
  78. .endm
  79. .macro PUSH_ARGUMENT_REGISTERS
  80. push {r0-r3}
  81. .save {r0-r3}
  82. .endm
  83. .macro pop_register Reg
  84. pop \Reg
  85. .endm
  86. .macro pop_argument_register Reg
  87. pop_register \Reg
  88. .endm
  89. .macro POP_ARGUMENT_REGISTERS
  90. pop {r0-r3}
  91. .endm
  92. // Stack layout:
  93. //
  94. // (stack parameters)
  95. // ...
  96. // ArgumentRegisters::r3
  97. // ArgumentRegisters::r2
  98. // ArgumentRegisters::r1
  99. // ArgumentRegisters::r0
  100. // CalleeSavedRegisters::lr
  101. // CalleeSavedRegisters::r11
  102. // CalleeSavedRegisters::r10
  103. // CalleeSavedRegisters::r9
  104. // CalleeSavedRegisters::r8
  105. // CalleeSavedRegisters::r7 <- r7
  106. // CalleeSavedRegisters::r6
  107. // CalleeSavedRegisters::r5
  108. // CalleeSavedRegisters::r4 <- __PWTB_StackAlloc, __PWTB_TransitionBlock
  109. // padding to align float save area
  110. // d7
  111. // d6
  112. // d5
  113. // d4
  114. // d3
  115. // d2
  116. // d1
  117. // d0 <- __PWTB_FloatArgumentRegisters
  118. .macro PROLOG_WITH_TRANSITION_BLOCK extraLocals = 0, saveFpArgs = 1, pushArgRegs = 0
  119. __PWTB_FloatArgumentRegisters = \extraLocals
  120. __PWTB_SaveFPArgs = \saveFpArgs
  121. .if (__PWTB_SaveFPArgs == 1)
  122. .if ((__PWTB_FloatArgumentRegisters % 8) != 0)
  123. __PWTB_FloatArgumentRegisters = __PWTB_FloatArgumentRegisters + 4
  124. .endif
  125. __PWTB_TransitionBlock = __PWTB_FloatArgumentRegisters + 8 * 8 + 4 // 8 floating point registers + padding
  126. .else
  127. .if ((__PWTB_FloatArgumentRegisters % 8) == 0)
  128. __PWTB_FloatArgumentRegisters = __PWTB_FloatArgumentRegisters + 4
  129. .endif
  130. __PWTB_TransitionBlock = __PWTB_FloatArgumentRegisters
  131. .endif
  132. __PWTB_StackAlloc = __PWTB_TransitionBlock
  133. .ifnc \pushArgRegs, DoNotPushArgRegs
  134. PUSH_ARGUMENT_REGISTERS
  135. .endif
  136. PUSH_CALLEE_SAVED_REGISTERS
  137. PROLOG_STACK_SAVE_OFFSET r7, #12
  138. // let r7 point the saved r7 in the stack (clang FP style)
  139. alloc_stack __PWTB_StackAlloc
  140. .if (__PWTB_SaveFPArgs == 1)
  141. add r6, sp, #(__PWTB_FloatArgumentRegisters)
  142. vstm r6, {d0-d7}
  143. .endif
  144. CHECK_STACK_ALIGNMENT
  145. END_PROLOGUE
  146. .endm
  147. .macro EPILOG_WITH_TRANSITION_BLOCK_RETURN
  148. free_stack __PWTB_StackAlloc
  149. POP_CALLEE_SAVED_REGISTERS
  150. free_stack 16
  151. bx lr
  152. .endm
  153. .macro EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
  154. .if (__PWTB_SaveFPArgs == 1)
  155. add r6, sp, #(__PWTB_FloatArgumentRegisters)
  156. vldm r6, {d0-d7}
  157. .endif
  158. free_stack __PWTB_StackAlloc
  159. POP_CALLEE_SAVED_REGISTERS
  160. POP_ARGUMENT_REGISTERS
  161. .endm
  162. .macro EMIT_BREAKPOINT
  163. .inst.w 0xde01
  164. .endm
  165. .macro PROLOG_PUSH RegList
  166. push_nonvol_reg "\RegList"
  167. .endm
  168. .macro PROLOG_VPUSH RegList
  169. vpush_nonvol_reg "\RegList"
  170. .endm
  171. .macro PROLOG_STACK_SAVE Register
  172. .setfp \Register, sp
  173. mov \Register, sp
  174. .endm
  175. .macro PROLOG_STACK_SAVE_OFFSET Register, Offset
  176. .setfp \Register, sp, \Offset
  177. add \Register, sp, \Offset
  178. .endm
  179. .macro EPILOG_STACK_FREE Size
  180. add sp, sp, \Size
  181. .endm
  182. .macro EPILOG_STACK_RESTORE Register
  183. mov sp, \Register
  184. .endm
  185. .macro EPILOG_STACK_RESTORE_OFFSET Register, Offset
  186. sub sp, \Register, \Offset
  187. .endm
  188. .macro EPILOG_BRANCH Target
  189. b \Target
  190. .endm
  191. .macro EPILOG_BRANCH_REG reg
  192. bx \reg
  193. .endm
  194. .macro EPILOG_POP RegList
  195. pop_nonvol_reg "\RegList"
  196. .endm
  197. .macro EPILOG_VPOP RegList
  198. vpop_nonvol_reg "\RegList"
  199. .endm
  200. //-----------------------------------------------------------------------------
  201. // Macro used to check (in debug builds only) whether the stack is 64-bit aligned (a requirement before calling
  202. // out into C++/OS code). Invoke this directly after your prolog (if the stack frame size is fixed) or directly
  203. // before a call (if you have a frame pointer and a dynamic stack). A breakpoint will be invoked if the stack
  204. // is misaligned.
  205. //
  206. .macro CHECK_STACK_ALIGNMENT
  207. #ifdef _DEBUG
  208. push {r0}
  209. add r0, sp, #4
  210. tst r0, #7
  211. pop {r0}
  212. beq 0f
  213. EMIT_BREAKPOINT
  214. 0:
  215. #endif
  216. .endm