unixasmmacrosarm64.inc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. //-------------------------------------------------------------------------------------------------------
  2. // ChakraCore/Pal
  3. // Contains portions (c) copyright Microsoft, portions copyright (c) the .NET Foundation and Contributors
  4. // and edits (c) copyright the ChakraCore Contributors.
  5. // See THIRD-PARTY-NOTICES.txt in the project root for .NET Foundation license
  6. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  7. //-------------------------------------------------------------------------------------------------------
  8. .macro NESTED_ENTRY Name, Section, Handler
  9. LEAF_ENTRY \Name, \Section
  10. .ifnc \Handler, NoHandler
  11. #if defined(__APPLE__)
  12. .cfi_personality 0x9b, C_FUNC(\Handler) // 0x9b == DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4
  13. #else
  14. .cfi_personality 0x1b, C_FUNC(\Handler) // 0x1b == DW_EH_PE_pcrel | DW_EH_PE_sdata4
  15. #endif
  16. .endif
  17. .endm
  18. .macro NESTED_END Name, Section
  19. LEAF_END \Name, \Section
  20. .endm
  21. .macro PATCH_LABEL Name
  22. .global C_FUNC(\Name)
  23. C_FUNC(\Name):
  24. .endm
  25. .macro LEAF_ENTRY Name, Section
  26. .global C_FUNC(\Name)
  27. #if defined(__APPLE__)
  28. .text
  29. .p2align 2
  30. #else
  31. .type \Name, %function
  32. #endif
  33. C_FUNC(\Name):
  34. .cfi_startproc
  35. .endm
  36. .macro LEAF_END Name, Section
  37. #if !defined(__APPLE__)
  38. .size \Name, .-\Name
  39. #endif
  40. .cfi_endproc
  41. .endm
  42. .macro LEAF_END_MARKED Name, Section
  43. C_FUNC(\Name\()_End):
  44. .global C_FUNC(\Name\()_End)
  45. LEAF_END \Name, \Section
  46. // make sure this symbol gets its own address
  47. nop
  48. .endm
  49. .macro PREPARE_EXTERNAL_VAR Name, HelperReg
  50. #if defined(__APPLE__)
  51. adrp \HelperReg, C_FUNC(\Name)@GOTPAGE
  52. ldr \HelperReg, [\HelperReg, C_FUNC(\Name)@GOTPAGEOFF]
  53. #else
  54. adrp \HelperReg, C_FUNC(\Name)
  55. add \HelperReg, \HelperReg, :lo12:C_FUNC(\Name)
  56. #endif
  57. .endm
  58. .macro PROLOG_STACK_ALLOC Size
  59. sub sp, sp, \Size
  60. .endm
  61. .macro EPILOG_STACK_FREE Size
  62. add sp, sp, \Size
  63. .cfi_adjust_cfa_offset -\Size
  64. .endm
  65. .macro EPILOG_STACK_RESTORE
  66. mov sp, fp
  67. .cfi_restore sp
  68. .endm
  69. .macro PROLOG_SAVE_REG reg, ofs
  70. str \reg, [sp, \ofs]
  71. .cfi_rel_offset \reg, \ofs
  72. .endm
  73. .macro PROLOG_SAVE_REG_PAIR reg1, reg2, ofs
  74. stp \reg1, \reg2, [sp, \ofs]
  75. .cfi_rel_offset \reg1, \ofs
  76. .cfi_rel_offset \reg2, \ofs + 8
  77. .ifc \reg1, fp
  78. mov fp, sp
  79. .cfi_def_cfa_register fp
  80. .endif
  81. .endm
  82. .macro PROLOG_SAVE_REG_PAIR_INDEXED reg1, reg2, ofs
  83. stp \reg1, \reg2, [sp, \ofs]!
  84. .cfi_adjust_cfa_offset -\ofs
  85. .cfi_rel_offset \reg1, 0
  86. .cfi_rel_offset \reg2, 8
  87. .ifc \reg1, fp
  88. mov fp, sp
  89. .cfi_def_cfa_register fp
  90. .endif
  91. .endm
  92. .macro EPILOG_RESTORE_REG reg, ofs
  93. ldr \reg, [sp, \ofs]
  94. .cfi_restore \reg
  95. .endm
  96. .macro EPILOG_RESTORE_REG_PAIR reg1, reg2, ofs
  97. ldp \reg1, \reg2, [sp, \ofs]
  98. .cfi_restore \reg1
  99. .cfi_restore \reg2
  100. .endm
  101. .macro EPILOG_RESTORE_REG_PAIR_INDEXED reg1, reg2, ofs
  102. ldp \reg1, \reg2, [sp], \ofs
  103. .cfi_restore \reg1
  104. .cfi_restore \reg2
  105. .cfi_adjust_cfa_offset -\ofs
  106. .endm
  107. .macro EPILOG_RETURN
  108. ret
  109. .endm
  110. .macro EMIT_BREAKPOINT
  111. brk #0
  112. .endm
  113. //-----------------------------------------------------------------------------
  114. // Define the prolog for a TransitionFrame-based method. This macro should be called first in the method and
  115. // comprises the entire prolog (i.e. don't modify SP after calling this).The locals must be 8 byte aligned
  116. //
  117. // Stack layout:
  118. //
  119. // (stack parameters)
  120. // ...
  121. // fp
  122. // lr
  123. // CalleeSavedRegisters::x28
  124. // CalleeSavedRegisters::x27
  125. // CalleeSavedRegisters::x26
  126. // CalleeSavedRegisters::x25
  127. // CalleeSavedRegisters::x24
  128. // CalleeSavedRegisters::x23
  129. // CalleeSavedRegisters::x22
  130. // CalleeSavedRegisters::x21
  131. // CalleeSavedRegisters::x20
  132. // CalleeSavedRegisters::x19
  133. // CalleeSavedRegisters::x30 (Lr)
  134. // CalleeSavedRegisters::x29 (Fp)
  135. // ArgumentRegisters::x7
  136. // ArgumentRegisters::x6
  137. // ArgumentRegisters::x5
  138. // ArgumentRegisters::x4
  139. // ArgumentRegisters::x3
  140. // ArgumentRegisters::x2
  141. // ArgumentRegisters::x1
  142. // ArgumentRegisters::x0
  143. // FloatRegisters::q7
  144. // FloatRegisters::q6
  145. // FloatRegisters::q5
  146. // FloatRegisters::q4
  147. // FloatRegisters::q3
  148. // FloatRegisters::q2
  149. // FloatRegisters::q1
  150. // FloatRegisters::q0
  151. .macro PROLOG_WITH_TRANSITION_BLOCK extraLocals = 0, SaveFPArgs = 1
  152. __PWTB_FloatArgumentRegisters = \extraLocals
  153. __PWTB_SaveFPArgs = \SaveFPArgs
  154. .if ((__PWTB_FloatArgumentRegisters % 16) != 0)
  155. __PWTB_FloatArgumentRegisters = __PWTB_FloatArgumentRegisters + 8
  156. .endif
  157. __PWTB_TransitionBlock = __PWTB_FloatArgumentRegisters
  158. .if (__PWTB_SaveFPArgs == 1)
  159. __PWTB_TransitionBlock = __PWTB_TransitionBlock + SIZEOF__FloatArgumentRegisters
  160. .endif
  161. __PWTB_StackAlloc = __PWTB_TransitionBlock
  162. __PWTB_ArgumentRegisters = __PWTB_StackAlloc + 104
  163. __PWTB_ArgumentRegister_FirstArg = __PWTB_ArgumentRegisters + 8
  164. PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, -176
  165. // Spill callee saved registers
  166. PROLOG_SAVE_REG_PAIR x19, x20, 16
  167. PROLOG_SAVE_REG_PAIR x21, x22, 32
  168. PROLOG_SAVE_REG_PAIR x23, x24, 48
  169. PROLOG_SAVE_REG_PAIR x25, x26, 64
  170. PROLOG_SAVE_REG_PAIR x27, x28, 80
  171. // Allocate space for the rest of the frame
  172. PROLOG_STACK_ALLOC __PWTB_StackAlloc
  173. // Spill argument registers.
  174. SAVE_ARGUMENT_REGISTERS sp, __PWTB_ArgumentRegisters
  175. .if (__PWTB_SaveFPArgs == 1)
  176. SAVE_FLOAT_ARGUMENT_REGISTERS sp, \extraLocals
  177. .endif
  178. .endm
  179. //-----------------------------------------------------------------------------
  180. // The Following sets of SAVE_*_REGISTERS expect the memory to be reserved and
  181. // base address to be passed in $reg
  182. //
  183. // Reserve 64 bytes of memory before calling SAVE_ARGUMENT_REGISTERS
  184. .macro SAVE_ARGUMENT_REGISTERS reg, ofs
  185. str x8, [\reg, #(\ofs)]
  186. stp x0, x1, [\reg, #(\ofs + 8)]
  187. stp x2, x3, [\reg, #(\ofs + 24)]
  188. stp x4, x5, [\reg, #(\ofs + 40)]
  189. stp x6, x7, [\reg, #(\ofs + 56)]
  190. .endm
  191. // Reserve 128 bytes of memory before calling SAVE_FLOAT_ARGUMENT_REGISTERS
  192. .macro SAVE_FLOAT_ARGUMENT_REGISTERS reg, ofs
  193. stp q0, q1, [\reg, #(\ofs)]
  194. stp q2, q3, [\reg, #(\ofs + 32)]
  195. stp q4, q5, [\reg, #(\ofs + 64)]
  196. stp q6, q7, [\reg, #(\ofs + 96)]
  197. .endm
  198. .macro RESTORE_ARGUMENT_REGISTERS reg, ofs
  199. ldr x8, [\reg, #(\ofs)]
  200. ldp x0, x1, [\reg, #(\ofs + 8)]
  201. ldp x2, x3, [\reg, #(\ofs + 24)]
  202. ldp x4, x5, [\reg, #(\ofs + 40)]
  203. ldp x6, x7, [\reg, #(\ofs + 56)]
  204. .endm
  205. .macro RESTORE_FLOAT_ARGUMENT_REGISTERS reg, ofs
  206. ldp q0, q1, [\reg, #(\ofs)]
  207. ldp q2, q3, [\reg, #(\ofs + 32)]
  208. ldp q4, q5, [\reg, #(\ofs + 64)]
  209. ldp q6, q7, [\reg, #(\ofs + 96)]
  210. .endm
  211. .macro EPILOG_BRANCH Target
  212. b \Target
  213. .endm
  214. .macro EPILOG_BRANCH_REG reg
  215. br \reg
  216. .endm
  217. .macro EPILOG_WITH_TRANSITION_BLOCK_RETURN
  218. EPILOG_STACK_FREE __PWTB_StackAlloc
  219. EPILOG_RESTORE_REG_PAIR x19, x20, 16
  220. EPILOG_RESTORE_REG_PAIR x21, x22, 32
  221. EPILOG_RESTORE_REG_PAIR x23, x24, 48
  222. EPILOG_RESTORE_REG_PAIR x25, x26, 64
  223. EPILOG_RESTORE_REG_PAIR x27, x28, 80
  224. EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 176
  225. ret
  226. .endm
  227. //-----------------------------------------------------------------------------
  228. // Provides a matching epilog to PROLOG_WITH_TRANSITION_BLOCK and ends by preparing for tail-calling.
  229. // Since this is a tail call argument registers are restored.
  230. //
  231. .macro EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
  232. .if (__PWTB_SaveFPArgs == 1)
  233. RESTORE_FLOAT_ARGUMENT_REGISTERS sp, __PWTB_FloatArgumentRegisters
  234. .endif
  235. RESTORE_ARGUMENT_REGISTERS sp, __PWTB_ArgumentRegisters
  236. EPILOG_STACK_FREE __PWTB_StackAlloc
  237. EPILOG_RESTORE_REG_PAIR x19, x20, 16
  238. EPILOG_RESTORE_REG_PAIR x21, x22, 32
  239. EPILOG_RESTORE_REG_PAIR x23, x24, 48
  240. EPILOG_RESTORE_REG_PAIR x25, x26, 64
  241. EPILOG_RESTORE_REG_PAIR x27, x28, 80
  242. EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 176
  243. .endm
  244. // ------------------------------------------------------------------
  245. // Macro to generate Redirection Stubs
  246. //
  247. // $reason : reason for redirection
  248. // Eg. GCThreadControl
  249. // NOTE: If you edit this macro, make sure you update GetCONTEXTFromRedirectedStubStackFrame.
  250. // This function is used by both the personality routine and the debugger to retrieve the original CONTEXT.
  251. .macro GenerateRedirectedHandledJITCaseStub reason
  252. #if NOTYET
  253. GBLS __RedirectionStubFuncName
  254. GBLS __RedirectionStubEndFuncName
  255. GBLS __RedirectionFuncName
  256. __RedirectionStubFuncName SETS "RedirectedHandledJITCaseFor":CC:"$reason":CC:"_Stub"
  257. __RedirectionStubEndFuncName SETS "RedirectedHandledJITCaseFor":CC:"$reason":CC:"_StubEnd"
  258. __RedirectionFuncName SETS "|?RedirectedHandledJITCaseFor":CC:"$reason":CC:"@Thread@@CAXXZ|"
  259. IMPORT $__RedirectionFuncName
  260. NESTED_ENTRY $__RedirectionStubFuncName
  261. PROLOG_SAVE_REG_PAIR fp, lr, -16
  262. sub sp, sp, #16 // stack slot for CONTEXT * and padding
  263. //REDIRECTSTUB_SP_OFFSET_CONTEXT is defined in asmconstants.h and is used in GetCONTEXTFromRedirectedStubStackFrame
  264. //If CONTEXT is not saved at 0 offset from SP it must be changed as well.
  265. ASSERT REDIRECTSTUB_SP_OFFSET_CONTEXT == 0
  266. // Stack alignment. This check is necessary as this function can be
  267. // entered before complete execution of the prolog of another function.
  268. and x8, fp, #15
  269. sub sp, sp, x8
  270. //
  271. // Save a copy of the redirect CONTEXT*.
  272. // This is needed for the debugger to unwind the stack.
  273. //
  274. bl GetCurrentSavedRedirectContext
  275. str x0, [sp]
  276. //
  277. // Fetch the interrupted pc and save it as our return address.
  278. //
  279. ldr x1, [x0, #CONTEXT_Pc]
  280. str x1, [fp, #8]
  281. //
  282. // Call target, which will do whatever we needed to do in the context
  283. // of the target thread, and will RtlRestoreContext when it is done.
  284. //
  285. bl $__RedirectionFuncName
  286. EMIT_BREAKPOINT // Unreachable
  287. // Put a label here to tell the debugger where the end of this function is.
  288. $__RedirectionStubEndFuncName
  289. EXPORT $__RedirectionStubEndFuncName
  290. NESTED_END
  291. #else
  292. EMIT_BREAKPOINT
  293. #endif
  294. .endm