unixasmmacrosamd64.inc 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. //
  2. // Copyright (c) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE file in the project root for full license information.
  4. //
  5. .macro LEAF_END Name, Section
  6. LEAF_END_MARKED \Name, \Section
  7. .endm
  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 0, C_FUNC(\Handler) // 0 == DW_EH_PE_absptr
  15. #endif
  16. .endif
  17. .endm
  18. .macro NESTED_END Name, Section
  19. LEAF_END \Name, \Section
  20. #if defined(__APPLE__)
  21. .section __LD,__compact_unwind,regular,debug
  22. .quad C_FUNC(\Name)
  23. .set C_FUNC(\Name\()_Size), C_FUNC(\Name\()_End) - C_FUNC(\Name)
  24. .long C_FUNC(\Name\()_Size)
  25. .long 0x04000000 # DWARF
  26. .quad 0
  27. .quad 0
  28. #endif
  29. .endm
  30. .macro PATCH_LABEL Name
  31. .global C_FUNC(\Name)
  32. C_FUNC(\Name):
  33. .endm
  34. .macro LEAF_ENTRY Name, Section
  35. .global C_FUNC(\Name)
  36. #if defined(__APPLE__)
  37. .text
  38. #else
  39. .type \Name, %function
  40. #endif
  41. C_FUNC(\Name):
  42. .cfi_startproc
  43. .endm
  44. .macro LEAF_END_MARKED Name, Section
  45. C_FUNC(\Name\()_End):
  46. .global C_FUNC(\Name\()_End)
  47. #if !defined(__APPLE__)
  48. .size \Name, .-\Name
  49. #endif
  50. .cfi_endproc
  51. .endm
  52. .macro NOP_3_BYTE
  53. nop dword ptr [rax]
  54. .endm
  55. .macro NOP_2_BYTE
  56. xchg ax, ax
  57. .endm
  58. .macro REPRET
  59. .byte 0xf3
  60. .byte 0xc3
  61. .endm
  62. .macro TAILJMP_RAX
  63. .byte 0x48
  64. .byte 0xFF
  65. .byte 0xE0
  66. .endm
  67. .macro PREPARE_EXTERNAL_VAR Name, HelperReg
  68. mov \HelperReg, [rip + C_FUNC(\Name)@GOTPCREL]
  69. .endm
  70. .macro push_nonvol_reg Register
  71. push \Register
  72. .cfi_adjust_cfa_offset 8
  73. .cfi_rel_offset \Register, 0
  74. .endm
  75. .macro pop_nonvol_reg Register
  76. pop \Register
  77. .cfi_adjust_cfa_offset -8
  78. .cfi_restore \Register
  79. .endm
  80. .macro alloc_stack Size
  81. .att_syntax
  82. lea -\Size(%rsp), %rsp
  83. .intel_syntax noprefix
  84. .cfi_adjust_cfa_offset \Size
  85. .endm
  86. .macro free_stack Size
  87. .att_syntax
  88. lea \Size(%rsp), %rsp
  89. .intel_syntax noprefix
  90. .cfi_adjust_cfa_offset -\Size
  91. .endm
  92. .macro set_cfa_register Reg, Offset
  93. .cfi_def_cfa_register \Reg
  94. .cfi_def_cfa_offset \Offset
  95. .endm
  96. .macro save_reg_postrsp Reg, Offset
  97. __Offset = \Offset
  98. mov qword ptr [rsp + __Offset], \Reg
  99. .cfi_rel_offset \Reg, __Offset
  100. .endm
  101. .macro restore_reg Reg, Offset
  102. __Offset = \Offset
  103. mov \Reg, [rsp + __Offset]
  104. .cfi_restore \Reg
  105. .endm
  106. .macro save_xmm128_postrsp Reg, Offset
  107. __Offset = \Offset
  108. movdqa xmmword ptr [rsp + __Offset], \Reg
  109. // NOTE: We cannot use ".cfi_rel_offset \Reg, __Offset" here,
  110. // the xmm registers are not supported by the libunwind
  111. .endm
  112. .macro restore_xmm128 Reg, ofs
  113. __Offset = \ofs
  114. movdqa \Reg, xmmword ptr [rsp + __Offset]
  115. // NOTE: We cannot use ".cfi_restore \Reg" here,
  116. // the xmm registers are not supported by the libunwind
  117. .endm
  118. .macro PUSH_CALLEE_SAVED_REGISTERS
  119. push_register rbp
  120. push_register rbx
  121. push_register r15
  122. push_register r14
  123. push_register r13
  124. push_register r12
  125. .endm
  126. .macro POP_CALLEE_SAVED_REGISTERS
  127. pop_nonvol_reg r12
  128. pop_nonvol_reg r13
  129. pop_nonvol_reg r14
  130. pop_nonvol_reg r15
  131. pop_nonvol_reg rbx
  132. pop_nonvol_reg rbp
  133. .endm
  134. .macro push_register Reg
  135. push \Reg
  136. .cfi_adjust_cfa_offset 8
  137. .endm
  138. .macro push_eflags
  139. pushfq
  140. .cfi_adjust_cfa_offset 8
  141. .endm
  142. .macro push_argument_register Reg
  143. push_register \Reg
  144. .endm
  145. .macro PUSH_ARGUMENT_REGISTERS
  146. push_argument_register r9
  147. push_argument_register r8
  148. push_argument_register rcx
  149. push_argument_register rdx
  150. push_argument_register rsi
  151. push_argument_register rdi
  152. .endm
  153. .macro pop_register Reg
  154. pop \Reg
  155. .cfi_adjust_cfa_offset -8
  156. .endm
  157. .macro pop_eflags
  158. popfq
  159. .cfi_adjust_cfa_offset -8
  160. .endm
  161. .macro pop_argument_register Reg
  162. pop_register \Reg
  163. .endm
  164. .macro POP_ARGUMENT_REGISTERS
  165. pop_argument_register rdi
  166. pop_argument_register rsi
  167. pop_argument_register rdx
  168. pop_argument_register rcx
  169. pop_argument_register r8
  170. pop_argument_register r9
  171. .endm
  172. .macro SAVE_FLOAT_ARGUMENT_REGISTERS ofs
  173. save_xmm128_postrsp xmm0, \ofs
  174. save_xmm128_postrsp xmm1, \ofs + 0x10
  175. save_xmm128_postrsp xmm2, \ofs + 0x20
  176. save_xmm128_postrsp xmm3, \ofs + 0x30
  177. save_xmm128_postrsp xmm4, \ofs + 0x40
  178. save_xmm128_postrsp xmm5, \ofs + 0x50
  179. save_xmm128_postrsp xmm6, \ofs + 0x60
  180. save_xmm128_postrsp xmm7, \ofs + 0x70
  181. .endm
  182. .macro RESTORE_FLOAT_ARGUMENT_REGISTERS ofs
  183. restore_xmm128 xmm0, \ofs
  184. restore_xmm128 xmm1, \ofs + 0x10
  185. restore_xmm128 xmm2, \ofs + 0x20
  186. restore_xmm128 xmm3, \ofs + 0x30
  187. restore_xmm128 xmm4, \ofs + 0x40
  188. restore_xmm128 xmm5, \ofs + 0x50
  189. restore_xmm128 xmm6, \ofs + 0x60
  190. restore_xmm128 xmm7, \ofs + 0x70
  191. .endm
  192. // Stack layout:
  193. //
  194. // (stack parameters)
  195. // ...
  196. // return address
  197. // CalleeSavedRegisters::rbp
  198. // CalleeSavedRegisters::rbx
  199. // CalleeSavedRegisters::r15
  200. // CalleeSavedRegisters::r14
  201. // CalleeSavedRegisters::r13
  202. // CalleeSavedRegisters::r12
  203. // ArgumentRegisters::r9
  204. // ArgumentRegisters::r8
  205. // ArgumentRegisters::rcx
  206. // ArgumentRegisters::rdx
  207. // ArgumentRegisters::rsi
  208. // ArgumentRegisters::rdi <- __PWTB_StackAlloc, __PWTB_TransitionBlock
  209. // padding to align xmm save area
  210. // xmm7
  211. // xmm6
  212. // xmm5
  213. // xmm4
  214. // xmm3
  215. // xmm2
  216. // xmm1
  217. // xmm0 <- __PWTB_FloatArgumentRegisters
  218. // extra locals + padding to qword align
  219. .macro PROLOG_WITH_TRANSITION_BLOCK extraLocals = 0, stackAllocOnEntry = 0, stackAllocSpill1, stackAllocSpill2, stackAllocSpill3
  220. __PWTB_FloatArgumentRegisters = \extraLocals
  221. .if ((__PWTB_FloatArgumentRegisters % 16) != 0)
  222. __PWTB_FloatArgumentRegisters = __PWTB_FloatArgumentRegisters + 8
  223. .endif
  224. __PWTB_StackAlloc = __PWTB_FloatArgumentRegisters + 8 * 16 + 8 // 8 floating point registers
  225. __PWTB_TransitionBlock = __PWTB_StackAlloc
  226. .if \stackAllocOnEntry >= 4*8
  227. .error "Max supported stackAllocOnEntry is 3*8"
  228. .endif
  229. .if \stackAllocOnEntry > 0
  230. .cfi_adjust_cfa_offset \stackAllocOnEntry
  231. .endif
  232. // PUSH_CALLEE_SAVED_REGISTERS expanded here
  233. .if \stackAllocOnEntry < 8
  234. push_nonvol_reg rbp
  235. mov rbp, rsp
  236. .endif
  237. .if \stackAllocOnEntry < 2*8
  238. push_nonvol_reg rbx
  239. .endif
  240. .if \stackAllocOnEntry < 3*8
  241. push_nonvol_reg r15
  242. .endif
  243. push_nonvol_reg r14
  244. push_nonvol_reg r13
  245. push_nonvol_reg r12
  246. // ArgumentRegisters
  247. PUSH_ARGUMENT_REGISTERS
  248. .if \stackAllocOnEntry >= 3*8
  249. mov \stackAllocSpill3, [rsp + 0x48]
  250. save_reg_postrsp r15, 0x48
  251. .endif
  252. .if \stackAllocOnEntry >= 2*8
  253. mov \stackAllocSpill2, [rsp + 0x50]
  254. save_reg_postrsp rbx, 0x50
  255. .endif
  256. .if \stackAllocOnEntry >= 8
  257. mov \stackAllocSpill1, [rsp + 0x58]
  258. save_reg_postrsp rbp, 0x58
  259. lea rbp, [rsp + 0x58]
  260. .endif
  261. alloc_stack __PWTB_StackAlloc
  262. SAVE_FLOAT_ARGUMENT_REGISTERS __PWTB_FloatArgumentRegisters
  263. END_PROLOGUE
  264. .endm
  265. .macro EPILOG_WITH_TRANSITION_BLOCK_RETURN
  266. add rsp, __PWTB_StackAlloc
  267. POP_CALLEE_SAVED_REGISTERS
  268. ret
  269. .endm
  270. .macro EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
  271. RESTORE_FLOAT_ARGUMENT_REGISTERS __PWTB_FloatArgumentRegisters
  272. free_stack __PWTB_StackAlloc
  273. POP_ARGUMENT_REGISTERS
  274. POP_CALLEE_SAVED_REGISTERS
  275. .endm