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
200 .cfi_adjust_cfa_offset -8
203 .macro pop_argument_register Reg
207 .macro POP_ARGUMENT_REGISTERS
209 pop_argument_register rdi
210 pop_argument_register rsi
211 pop_argument_register rdx
212 pop_argument_register rcx
213 pop_argument_register r8
214 pop_argument_register r9
218 .macro SAVE_FLOAT_ARGUMENT_REGISTERS ofs
220 save_xmm128_postrsp xmm0, \ofs
221 save_xmm128_postrsp xmm1, \ofs + 0x10
222 save_xmm128_postrsp xmm2, \ofs + 0x20
223 save_xmm128_postrsp xmm3, \ofs + 0x30
224 save_xmm128_postrsp xmm4, \ofs + 0x40
225 save_xmm128_postrsp xmm5, \ofs + 0x50
226 save_xmm128_postrsp xmm6, \ofs + 0x60
227 save_xmm128_postrsp xmm7, \ofs + 0x70
231 .macro RESTORE_FLOAT_ARGUMENT_REGISTERS ofs
233 restore_xmm128 xmm0, \ofs
234 restore_xmm128 xmm1, \ofs + 0x10
235 restore_xmm128 xmm2, \ofs + 0x20
236 restore_xmm128 xmm3, \ofs + 0x30
237 restore_xmm128 xmm4, \ofs + 0x40
238 restore_xmm128 xmm5, \ofs + 0x50
239 restore_xmm128 xmm6, \ofs + 0x60
240 restore_xmm128 xmm7, \ofs + 0x70
246 // (stack parameters)
249 // CalleeSavedRegisters::rbp
250 // CalleeSavedRegisters::rbx
251 // CalleeSavedRegisters::r15
252 // CalleeSavedRegisters::r14
253 // CalleeSavedRegisters::r13
254 // CalleeSavedRegisters::r12
255 // ArgumentRegisters::r9
256 // ArgumentRegisters::r8
257 // ArgumentRegisters::rcx
258 // ArgumentRegisters::rdx
259 // ArgumentRegisters::rsi
260 // ArgumentRegisters::rdi <- __PWTB_StackAlloc, __PWTB_TransitionBlock
261 // padding to align xmm save area
269 // xmm0 <- __PWTB_FloatArgumentRegisters
270 // extra locals + padding to qword align
271 .macro PROLOG_WITH_TRANSITION_BLOCK extraLocals = 0, stackAllocOnEntry = 0, stackAllocSpill1, stackAllocSpill2, stackAllocSpill3
273 __PWTB_FloatArgumentRegisters = \extraLocals
275 .if ((__PWTB_FloatArgumentRegisters % 16) != 0)
276 __PWTB_FloatArgumentRegisters = __PWTB_FloatArgumentRegisters + 8
279 __PWTB_StackAlloc = __PWTB_FloatArgumentRegisters + 8 * 16 + 8 // 8 floating point registers
280 __PWTB_TransitionBlock = __PWTB_StackAlloc
282 .if \stackAllocOnEntry >= 4*8
283 .error "Max supported stackAllocOnEntry is 3*8"
286 .if \stackAllocOnEntry > 0
287 .cfi_adjust_cfa_offset \stackAllocOnEntry
290 // PUSH_CALLEE_SAVED_REGISTERS expanded here
292 .if \stackAllocOnEntry < 8
297 .if \stackAllocOnEntry < 2*8
301 .if \stackAllocOnEntry < 3*8
310 PUSH_ARGUMENT_REGISTERS
312 .if \stackAllocOnEntry >= 3*8
313 mov \stackAllocSpill3, [rsp + 0x48]
314 save_reg_postrsp r15, 0x48
317 .if \stackAllocOnEntry >= 2*8
318 mov \stackAllocSpill2, [rsp + 0x50]
319 save_reg_postrsp rbx, 0x50
322 .if \stackAllocOnEntry >= 8
323 mov \stackAllocSpill1, [rsp + 0x58]
324 save_reg_postrsp rbp, 0x58
325 lea rbp, [rsp + 0x58]
328 alloc_stack __PWTB_StackAlloc
329 SAVE_FLOAT_ARGUMENT_REGISTERS __PWTB_FloatArgumentRegisters
335 .macro EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
337 RESTORE_FLOAT_ARGUMENT_REGISTERS __PWTB_FloatArgumentRegisters
338 free_stack __PWTB_StackAlloc
339 POP_ARGUMENT_REGISTERS
340 POP_CALLEE_SAVED_REGISTERS