Merge remote-tracking branch 'upstream/master' into clrstack
[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 .endm
98
99 .macro END_PROLOGUE
100 .endm
101
102 .macro alloc_stack Size
103 .att_syntax
104         lea -\Size(%rsp), %rsp
105 .intel_syntax noprefix
106         .cfi_adjust_cfa_offset \Size
107 .endm
108
109 .macro free_stack Size
110 .att_syntax
111         lea \Size(%rsp), %rsp
112 .intel_syntax noprefix
113         .cfi_adjust_cfa_offset -\Size
114 .endm
115
116 .macro set_cfa_register Reg, Offset
117         .cfi_def_cfa_register \Reg
118         .cfi_def_cfa_offset \Offset
119 .endm
120
121 .macro save_reg_postrsp Reg, Offset
122         __Offset = \Offset
123         mov     qword ptr [rsp + __Offset], \Reg
124         .cfi_rel_offset \Reg, __Offset
125 .endm
126
127 .macro restore_reg Reg, Offset
128         __Offset = \Offset
129         mov             \Reg, [rsp + __Offset]
130         .cfi_restore \Reg
131 .endm
132
133 .macro save_xmm128_postrsp Reg, Offset
134         __Offset = \Offset
135         movdqa  [rsp + __Offset], \Reg
136         // NOTE: We cannot use ".cfi_rel_offset \Reg, __Offset" here, 
137         // the xmm registers are not supported by the libunwind
138 .endm
139
140 .macro restore_xmm128 Reg, ofs
141         __Offset = \ofs
142         movdqa          \Reg, [rsp + __Offset]
143         // NOTE: We cannot use ".cfi_restore \Reg" here, 
144         // the xmm registers are not supported by the libunwind
145         
146 .endm
147
148 .macro POP_CALLEE_SAVED_REGISTERS
149
150         pop_nonvol_reg r12
151         pop_nonvol_reg r13
152         pop_nonvol_reg r14
153         pop_nonvol_reg r15
154         pop_nonvol_reg rbx
155         pop_nonvol_reg rbp
156
157 .endm
158
159 .macro push_register Reg
160         push            \Reg
161         .cfi_adjust_cfa_offset 8
162 .endm
163
164 .macro push_eflags
165         pushfq
166         .cfi_adjust_cfa_offset 8
167 .endm
168
169 .macro push_argument_register Reg
170         push_register \Reg
171 .endm
172
173 .macro PUSH_ARGUMENT_REGISTERS
174
175         push_argument_register r9
176         push_argument_register r8
177         push_argument_register rdx
178         push_argument_register rcx
179         push_argument_register rsi
180         push_argument_register rdi
181
182 .endm
183
184 .macro pop_register Reg
185         pop            \Reg
186         .cfi_adjust_cfa_offset -8
187 .endm
188
189 .macro pop_argument_register Reg
190         pop_register \Reg
191 .endm
192
193 .macro POP_ARGUMENT_REGISTERS
194
195         pop_argument_register rdi
196         pop_argument_register rsi
197         pop_argument_register rcx
198         pop_argument_register rdx
199         pop_argument_register r8
200         pop_argument_register r9
201
202 .endm
203
204 .macro SAVE_FLOAT_ARGUMENT_REGISTERS ofs
205
206         save_xmm128_postrsp xmm0, \ofs
207         save_xmm128_postrsp xmm1, \ofs + 0x10
208         save_xmm128_postrsp xmm2, \ofs + 0x20
209         save_xmm128_postrsp xmm3, \ofs + 0x30
210         save_xmm128_postrsp xmm4, \ofs + 0x40
211         save_xmm128_postrsp xmm5, \ofs + 0x50
212         save_xmm128_postrsp xmm6, \ofs + 0x60
213         save_xmm128_postrsp xmm7, \ofs + 0x70
214
215 .endm
216
217 .macro RESTORE_FLOAT_ARGUMENT_REGISTERS ofs
218
219         restore_xmm128  xmm0, \ofs
220         restore_xmm128  xmm1, \ofs + 0x10
221         restore_xmm128  xmm2, \ofs + 0x20
222         restore_xmm128  xmm3, \ofs + 0x30
223         restore_xmm128  xmm4, \ofs + 0x40
224         restore_xmm128  xmm5, \ofs + 0x50
225         restore_xmm128  xmm6, \ofs + 0x60
226         restore_xmm128  xmm7, \ofs + 0x70
227
228 .endm
229
230 // Stack layout:
231 //
232 // (stack parameters)
233 // ...
234 // return address
235 // CalleeSavedRegisters::rbp
236 // CalleeSavedRegisters::rbx
237 // CalleeSavedRegisters::r15
238 // CalleeSavedRegisters::r14
239 // CalleeSavedRegisters::r13
240 // CalleeSavedRegisters::r12
241 // ArgumentRegisters::r9
242 // ArgumentRegisters::r8
243 // ArgumentRegisters::rcx
244 // ArgumentRegisters::rdx
245 // ArgumentRegisters::rsi
246 // ArgumentRegisters::rdi    <- __PWTB_StackAlloc, __PWTB_TransitionBlock
247 // padding to align xmm save area
248 // xmm7
249 // xmm6
250 // xmm5
251 // xmm4
252 // xmm3
253 // xmm2
254 // xmm1
255 // xmm0                      <- __PWTB_FloatArgumentRegisters
256 // extra locals + padding to qword align
257 .macro PROLOG_WITH_TRANSITION_BLOCK extraLocals = 0, stackAllocOnEntry = 0, stackAllocSpill1, stackAllocSpill2, stackAllocSpill3
258
259         __PWTB_FloatArgumentRegisters = \extraLocals
260
261         .if ((__PWTB_FloatArgumentRegisters % 16) != 0)
262         __PWTB_FloatArgumentRegisters = __PWTB_FloatArgumentRegisters + 8
263         .endif
264
265         __PWTB_StackAlloc = __PWTB_FloatArgumentRegisters + 8 * 16 + 8 // 8 floating point registers
266         __PWTB_TransitionBlock = __PWTB_StackAlloc
267
268         .if \stackAllocOnEntry >= 4*8
269         .error "Max supported stackAllocOnEntry is 3*8"
270         .endif
271
272         .if \stackAllocOnEntry > 0
273         .cfi_adjust_cfa_offset \stackAllocOnEntry
274         .endif
275
276         // PUSH_CALLEE_SAVED_REGISTERS expanded here
277
278         .if \stackAllocOnEntry < 8
279         push_nonvol_reg rbp
280         mov rbp, rsp
281         .endif
282
283         .if \stackAllocOnEntry < 2*8
284         push_nonvol_reg rbx
285         .endif
286
287         .if \stackAllocOnEntry < 3*8
288         push_nonvol_reg r15
289         .endif
290
291         push_nonvol_reg r14
292         push_nonvol_reg r13
293         push_nonvol_reg r12
294
295         // ArgumentRegisters
296         PUSH_ARGUMENT_REGISTERS
297
298         .if \stackAllocOnEntry >= 3*8
299         mov \stackAllocSpill3, [rsp + 0x48]
300         save_reg_postrsp    r15, 0x48
301         .endif
302
303         .if \stackAllocOnEntry >= 2*8
304         mov \stackAllocSpill2, [rsp + 0x50]
305         save_reg_postrsp    rbx, 0x50
306         .endif
307
308         .if \stackAllocOnEntry >= 8
309         mov \stackAllocSpill1, [rsp + 0x58]
310         save_reg_postrsp    rbp, 0x58
311         lea rbp, [rsp + 0x58]
312         .endif
313
314         alloc_stack     __PWTB_StackAlloc
315         SAVE_FLOAT_ARGUMENT_REGISTERS __PWTB_FloatArgumentRegisters
316
317         END_PROLOGUE
318
319 .endm
320
321 .macro EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
322
323         RESTORE_FLOAT_ARGUMENT_REGISTERS __PWTB_FloatArgumentRegisters
324         free_stack      __PWTB_StackAlloc
325         POP_ARGUMENT_REGISTERS
326         POP_CALLEE_SAVED_REGISTERS
327
328 .endm