Merge pull request #676 from dotnet-bot/from-tfs
[platform/upstream/coreclr.git] / src / pal / inc / unixasmmacros.inc
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
6 #define INVALIDGCVALUE -0x33333333 // 0CCCCCCCDh - the assembler considers it to be a signed integer constant
7
8 .macro NOP_3_BYTE
9         nop dword ptr [rax]
10 .endm
11
12 .macro NOP_2_BYTE
13         xchg ax, ax
14 .endm
15
16 .macro REPRET
17         .byte 0xf3
18         .byte 0xc3
19 .endm
20
21 .macro TAILJMP_RAX
22         .byte 0x48
23         .byte 0xFF
24         .byte 0xE0
25 .endm
26
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
31 #else
32 #define C_FUNC(name) name
33 #define EXTERNAL_C_FUNC(name) C_FUNC(name)@plt
34 #define LOCAL_LABEL(name) .L##name
35 #endif
36
37 #if defined(__APPLE__)
38 #define C_PLTFUNC(name) _##name
39 #else
40 #define C_PLTFUNC(name) name@PLT
41 #endif
42
43 .macro PATCH_LABEL Name
44         .global C_FUNC(\Name)
45 C_FUNC(\Name):
46 .endm
47
48 .macro LEAF_ENTRY Name, Section
49         .global C_FUNC(\Name)
50 #if defined(__APPLE__)
51         .text
52 #else
53         .type \Name, %function
54 #endif
55 C_FUNC(\Name):
56         .cfi_startproc
57 .endm
58
59 .macro LEAF_END_MARKED Name, Section
60 C_FUNC(\Name\()_End):
61         .global C_FUNC(\Name\()_End)
62 #if !defined(__APPLE__)
63         .size \Name, .-\Name
64 #endif
65         .cfi_endproc
66 .endm
67
68 .macro LEAF_END Name, Section
69         LEAF_END_MARKED \Name, \Section
70 .endm
71
72 .macro PREPARE_EXTERNAL_VAR Name, HelperReg
73         mov \HelperReg, [rip + C_FUNC(\Name)@GOTPCREL]
74 .endm
75
76 .macro push_nonvol_reg Register
77         push \Register
78         .cfi_adjust_cfa_offset 8
79         .cfi_rel_offset \Register, 0
80 .endm
81
82 .macro pop_nonvol_reg Register
83         pop \Register
84         .cfi_adjust_cfa_offset -8
85         .cfi_restore \Register
86 .endm
87
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
92         .endif
93 .endm
94
95 .macro NESTED_END Name, Section
96         LEAF_END \Name, \Section
97 #if defined(__APPLE__)
98         .section __LD,__compact_unwind,regular,debug
99         .quad C_FUNC(\Name)
100         .set C_FUNC(\Name\()_Size), C_FUNC(\Name\()_End) - C_FUNC(\Name)
101         .long C_FUNC(\Name\()_Size)
102         .long 0x04000000 # DWARF
103         .quad 0
104         .quad 0
105 #endif
106 .endm
107
108 .macro END_PROLOGUE
109 .endm
110
111 .macro alloc_stack Size
112 .att_syntax
113         lea -\Size(%rsp), %rsp
114 .intel_syntax noprefix
115         .cfi_adjust_cfa_offset \Size
116 .endm
117
118 .macro free_stack Size
119 .att_syntax
120         lea \Size(%rsp), %rsp
121 .intel_syntax noprefix
122         .cfi_adjust_cfa_offset -\Size
123 .endm
124
125 .macro set_cfa_register Reg, Offset
126         .cfi_def_cfa_register \Reg
127         .cfi_def_cfa_offset \Offset
128 .endm
129
130 .macro save_reg_postrsp Reg, Offset
131         __Offset = \Offset
132         mov     qword ptr [rsp + __Offset], \Reg
133         .cfi_rel_offset \Reg, __Offset
134 .endm
135
136 .macro restore_reg Reg, Offset
137         __Offset = \Offset
138         mov             \Reg, [rsp + __Offset]
139         .cfi_restore \Reg
140 .endm
141
142 .macro save_xmm128_postrsp Reg, Offset
143         __Offset = \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
147 .endm
148
149 .macro restore_xmm128 Reg, ofs
150         __Offset = \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
154         
155 .endm
156
157 .macro POP_CALLEE_SAVED_REGISTERS
158
159         pop_nonvol_reg r12
160         pop_nonvol_reg r13
161         pop_nonvol_reg r14
162         pop_nonvol_reg r15
163         pop_nonvol_reg rbx
164         pop_nonvol_reg rbp
165
166 .endm
167
168 .macro push_register Reg
169         push            \Reg
170         .cfi_adjust_cfa_offset 8
171 .endm
172
173 .macro push_eflags
174         pushfq
175         .cfi_adjust_cfa_offset 8
176 .endm
177
178 .macro push_argument_register Reg
179         push_register \Reg
180 .endm
181
182 .macro PUSH_ARGUMENT_REGISTERS
183
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
190
191 .endm
192
193 .macro pop_register Reg
194         pop            \Reg
195         .cfi_adjust_cfa_offset -8
196 .endm
197
198 .macro pop_eflags
199         popfq
200         .cfi_adjust_cfa_offset -8
201 .endm
202
203 .macro pop_argument_register Reg
204         pop_register \Reg
205 .endm
206
207 .macro POP_ARGUMENT_REGISTERS
208
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
215
216 .endm
217
218 .macro SAVE_FLOAT_ARGUMENT_REGISTERS ofs
219
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
228
229 .endm
230
231 .macro RESTORE_FLOAT_ARGUMENT_REGISTERS ofs
232
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
241
242 .endm
243
244 // Stack layout:
245 //
246 // (stack parameters)
247 // ...
248 // return address
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
262 // xmm7
263 // xmm6
264 // xmm5
265 // xmm4
266 // xmm3
267 // xmm2
268 // xmm1
269 // xmm0                      <- __PWTB_FloatArgumentRegisters
270 // extra locals + padding to qword align
271 .macro PROLOG_WITH_TRANSITION_BLOCK extraLocals = 0, stackAllocOnEntry = 0, stackAllocSpill1, stackAllocSpill2, stackAllocSpill3
272
273         __PWTB_FloatArgumentRegisters = \extraLocals
274
275         .if ((__PWTB_FloatArgumentRegisters % 16) != 0)
276         __PWTB_FloatArgumentRegisters = __PWTB_FloatArgumentRegisters + 8
277         .endif
278
279         __PWTB_StackAlloc = __PWTB_FloatArgumentRegisters + 8 * 16 + 8 // 8 floating point registers
280         __PWTB_TransitionBlock = __PWTB_StackAlloc
281
282         .if \stackAllocOnEntry >= 4*8
283         .error "Max supported stackAllocOnEntry is 3*8"
284         .endif
285
286         .if \stackAllocOnEntry > 0
287         .cfi_adjust_cfa_offset \stackAllocOnEntry
288         .endif
289
290         // PUSH_CALLEE_SAVED_REGISTERS expanded here
291
292         .if \stackAllocOnEntry < 8
293         push_nonvol_reg rbp
294         mov rbp, rsp
295         .endif
296
297         .if \stackAllocOnEntry < 2*8
298         push_nonvol_reg rbx
299         .endif
300
301         .if \stackAllocOnEntry < 3*8
302         push_nonvol_reg r15
303         .endif
304
305         push_nonvol_reg r14
306         push_nonvol_reg r13
307         push_nonvol_reg r12
308
309         // ArgumentRegisters
310         PUSH_ARGUMENT_REGISTERS
311
312         .if \stackAllocOnEntry >= 3*8
313         mov \stackAllocSpill3, [rsp + 0x48]
314         save_reg_postrsp    r15, 0x48
315         .endif
316
317         .if \stackAllocOnEntry >= 2*8
318         mov \stackAllocSpill2, [rsp + 0x50]
319         save_reg_postrsp    rbx, 0x50
320         .endif
321
322         .if \stackAllocOnEntry >= 8
323         mov \stackAllocSpill1, [rsp + 0x58]
324         save_reg_postrsp    rbp, 0x58
325         lea rbp, [rsp + 0x58]
326         .endif
327
328         alloc_stack     __PWTB_StackAlloc
329         SAVE_FLOAT_ARGUMENT_REGISTERS __PWTB_FloatArgumentRegisters
330
331         END_PROLOGUE
332
333 .endm
334
335 .macro EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
336
337         RESTORE_FLOAT_ARGUMENT_REGISTERS __PWTB_FloatArgumentRegisters
338         free_stack      __PWTB_StackAlloc
339         POP_ARGUMENT_REGISTERS
340         POP_CALLEE_SAVED_REGISTERS
341
342 .endm