2 // Copyright (c) Microsoft. All rights reserved.
3 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
6 #define INVALIDGCVALUE -0x33333333 // 0CCCCCCCDh - the assembler considers it to be a signed integer constant
27 #if defined(__APPLE__)
28 #define C_FUNC(name) _##name
29 #define EXTERNAL_C_FUNC(name) C_FUNC(name)
30 #define LOCAL_LABEL(name) L##name
32 #define C_FUNC(name) name
33 #define EXTERNAL_C_FUNC(name) C_FUNC(name)@plt
34 #define LOCAL_LABEL(name) .L##name
37 #if defined(__APPLE__)
38 #define C_PLTFUNC(name) _##name
40 #define C_PLTFUNC(name) name@PLT
43 .macro PATCH_LABEL Name
48 .macro LEAF_ENTRY Name, Section
50 #if defined(__APPLE__)
53 .type \Name, %function
59 .macro LEAF_END_MARKED Name, Section
61 .global C_FUNC(\Name\()_End)
62 #if !defined(__APPLE__)
68 .macro LEAF_END Name, Section
69 LEAF_END_MARKED \Name, \Section
72 .macro PREPARE_EXTERNAL_VAR Name, HelperReg
73 mov \HelperReg, [rip + C_FUNC(\Name)@GOTPCREL]
76 .macro push_nonvol_reg Register
78 .cfi_adjust_cfa_offset 8
79 .cfi_rel_offset \Register, 0
82 .macro pop_nonvol_reg Register
84 .cfi_adjust_cfa_offset -8
85 .cfi_restore \Register
88 .macro NESTED_ENTRY Name, Section, Handler
89 LEAF_ENTRY \Name, \Section
90 .ifnc \Handler, NoHandler
91 .cfi_personality 0, \Handler // 4 == DW_EH_PE_udata8 0 == DW_EH_PE_absptr
95 .macro NESTED_END Name, Section
96 LEAF_END \Name, \Section
97 #if defined(__APPLE__)
98 .section __LD,__compact_unwind,regular,debug
100 .set C_FUNC(\Name\()_Size), C_FUNC(\Name\()_End) - C_FUNC(\Name)
101 .long C_FUNC(\Name\()_Size)
102 .long 0x04000000 # DWARF
111 .macro alloc_stack Size
113 lea -\Size(%rsp), %rsp
114 .intel_syntax noprefix
115 .cfi_adjust_cfa_offset \Size
118 .macro free_stack Size
120 lea \Size(%rsp), %rsp
121 .intel_syntax noprefix
122 .cfi_adjust_cfa_offset -\Size
125 .macro set_cfa_register Reg, Offset
126 .cfi_def_cfa_register \Reg
127 .cfi_def_cfa_offset \Offset
130 .macro save_reg_postrsp Reg, Offset
132 mov qword ptr [rsp + __Offset], \Reg
133 .cfi_rel_offset \Reg, __Offset
136 .macro restore_reg Reg, Offset
138 mov \Reg, [rsp + __Offset]
142 .macro save_xmm128_postrsp Reg, Offset
144 movdqa [rsp + __Offset], \Reg
145 // NOTE: We cannot use ".cfi_rel_offset \Reg, __Offset" here,
146 // the xmm registers are not supported by the libunwind
149 .macro restore_xmm128 Reg, ofs
151 movdqa \Reg, [rsp + __Offset]
152 // NOTE: We cannot use ".cfi_restore \Reg" here,
153 // the xmm registers are not supported by the libunwind
157 .macro POP_CALLEE_SAVED_REGISTERS
168 .macro push_register Reg
170 .cfi_adjust_cfa_offset 8
175 .cfi_adjust_cfa_offset 8
178 .macro push_argument_register Reg
182 .macro PUSH_ARGUMENT_REGISTERS
184 push_argument_register r9
185 push_argument_register r8
186 push_argument_register rcx
187 push_argument_register rdx
188 push_argument_register rsi
189 push_argument_register rdi
193 .macro pop_register Reg
195 .cfi_adjust_cfa_offset -8
198 .macro pop_argument_register Reg
202 .macro POP_ARGUMENT_REGISTERS
204 pop_argument_register rdi
205 pop_argument_register rsi
206 pop_argument_register rdx
207 pop_argument_register rcx
208 pop_argument_register r8
209 pop_argument_register r9
213 .macro SAVE_FLOAT_ARGUMENT_REGISTERS ofs
215 save_xmm128_postrsp xmm0, \ofs
216 save_xmm128_postrsp xmm1, \ofs + 0x10
217 save_xmm128_postrsp xmm2, \ofs + 0x20
218 save_xmm128_postrsp xmm3, \ofs + 0x30
219 save_xmm128_postrsp xmm4, \ofs + 0x40
220 save_xmm128_postrsp xmm5, \ofs + 0x50
221 save_xmm128_postrsp xmm6, \ofs + 0x60
222 save_xmm128_postrsp xmm7, \ofs + 0x70
226 .macro RESTORE_FLOAT_ARGUMENT_REGISTERS ofs
228 restore_xmm128 xmm0, \ofs
229 restore_xmm128 xmm1, \ofs + 0x10
230 restore_xmm128 xmm2, \ofs + 0x20
231 restore_xmm128 xmm3, \ofs + 0x30
232 restore_xmm128 xmm4, \ofs + 0x40
233 restore_xmm128 xmm5, \ofs + 0x50
234 restore_xmm128 xmm6, \ofs + 0x60
235 restore_xmm128 xmm7, \ofs + 0x70
241 // (stack parameters)
244 // CalleeSavedRegisters::rbp
245 // CalleeSavedRegisters::rbx
246 // CalleeSavedRegisters::r15
247 // CalleeSavedRegisters::r14
248 // CalleeSavedRegisters::r13
249 // CalleeSavedRegisters::r12
250 // ArgumentRegisters::r9
251 // ArgumentRegisters::r8
252 // ArgumentRegisters::rcx
253 // ArgumentRegisters::rdx
254 // ArgumentRegisters::rsi
255 // ArgumentRegisters::rdi <- __PWTB_StackAlloc, __PWTB_TransitionBlock
256 // padding to align xmm save area
264 // xmm0 <- __PWTB_FloatArgumentRegisters
265 // extra locals + padding to qword align
266 .macro PROLOG_WITH_TRANSITION_BLOCK extraLocals = 0, stackAllocOnEntry = 0, stackAllocSpill1, stackAllocSpill2, stackAllocSpill3
268 __PWTB_FloatArgumentRegisters = \extraLocals
270 .if ((__PWTB_FloatArgumentRegisters % 16) != 0)
271 __PWTB_FloatArgumentRegisters = __PWTB_FloatArgumentRegisters + 8
274 __PWTB_StackAlloc = __PWTB_FloatArgumentRegisters + 8 * 16 + 8 // 8 floating point registers
275 __PWTB_TransitionBlock = __PWTB_StackAlloc
277 .if \stackAllocOnEntry >= 4*8
278 .error "Max supported stackAllocOnEntry is 3*8"
281 .if \stackAllocOnEntry > 0
282 .cfi_adjust_cfa_offset \stackAllocOnEntry
285 // PUSH_CALLEE_SAVED_REGISTERS expanded here
287 .if \stackAllocOnEntry < 8
292 .if \stackAllocOnEntry < 2*8
296 .if \stackAllocOnEntry < 3*8
305 PUSH_ARGUMENT_REGISTERS
307 .if \stackAllocOnEntry >= 3*8
308 mov \stackAllocSpill3, [rsp + 0x48]
309 save_reg_postrsp r15, 0x48
312 .if \stackAllocOnEntry >= 2*8
313 mov \stackAllocSpill2, [rsp + 0x50]
314 save_reg_postrsp rbx, 0x50
317 .if \stackAllocOnEntry >= 8
318 mov \stackAllocSpill1, [rsp + 0x58]
319 save_reg_postrsp rbp, 0x58
320 lea rbp, [rsp + 0x58]
323 alloc_stack __PWTB_StackAlloc
324 SAVE_FLOAT_ARGUMENT_REGISTERS __PWTB_FloatArgumentRegisters
330 .macro EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
332 RESTORE_FLOAT_ARGUMENT_REGISTERS __PWTB_FloatArgumentRegisters
333 free_stack __PWTB_StackAlloc
334 POP_ARGUMENT_REGISTERS
335 POP_CALLEE_SAVED_REGISTERS