Merge remote-tracking branch 'upstream/master' into name2ee
[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_argument_register Reg
199         pop_register \Reg
200 .endm
201
202 .macro POP_ARGUMENT_REGISTERS
203
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
210
211 .endm
212
213 .macro SAVE_FLOAT_ARGUMENT_REGISTERS ofs
214
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
223
224 .endm
225
226 .macro RESTORE_FLOAT_ARGUMENT_REGISTERS ofs
227
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
236
237 .endm
238
239 // Stack layout:
240 //
241 // (stack parameters)
242 // ...
243 // return address
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
257 // xmm7
258 // xmm6
259 // xmm5
260 // xmm4
261 // xmm3
262 // xmm2
263 // xmm1
264 // xmm0                      <- __PWTB_FloatArgumentRegisters
265 // extra locals + padding to qword align
266 .macro PROLOG_WITH_TRANSITION_BLOCK extraLocals = 0, stackAllocOnEntry = 0, stackAllocSpill1, stackAllocSpill2, stackAllocSpill3
267
268         __PWTB_FloatArgumentRegisters = \extraLocals
269
270         .if ((__PWTB_FloatArgumentRegisters % 16) != 0)
271         __PWTB_FloatArgumentRegisters = __PWTB_FloatArgumentRegisters + 8
272         .endif
273
274         __PWTB_StackAlloc = __PWTB_FloatArgumentRegisters + 8 * 16 + 8 // 8 floating point registers
275         __PWTB_TransitionBlock = __PWTB_StackAlloc
276
277         .if \stackAllocOnEntry >= 4*8
278         .error "Max supported stackAllocOnEntry is 3*8"
279         .endif
280
281         .if \stackAllocOnEntry > 0
282         .cfi_adjust_cfa_offset \stackAllocOnEntry
283         .endif
284
285         // PUSH_CALLEE_SAVED_REGISTERS expanded here
286
287         .if \stackAllocOnEntry < 8
288         push_nonvol_reg rbp
289         mov rbp, rsp
290         .endif
291
292         .if \stackAllocOnEntry < 2*8
293         push_nonvol_reg rbx
294         .endif
295
296         .if \stackAllocOnEntry < 3*8
297         push_nonvol_reg r15
298         .endif
299
300         push_nonvol_reg r14
301         push_nonvol_reg r13
302         push_nonvol_reg r12
303
304         // ArgumentRegisters
305         PUSH_ARGUMENT_REGISTERS
306
307         .if \stackAllocOnEntry >= 3*8
308         mov \stackAllocSpill3, [rsp + 0x48]
309         save_reg_postrsp    r15, 0x48
310         .endif
311
312         .if \stackAllocOnEntry >= 2*8
313         mov \stackAllocSpill2, [rsp + 0x50]
314         save_reg_postrsp    rbx, 0x50
315         .endif
316
317         .if \stackAllocOnEntry >= 8
318         mov \stackAllocSpill1, [rsp + 0x58]
319         save_reg_postrsp    rbp, 0x58
320         lea rbp, [rsp + 0x58]
321         .endif
322
323         alloc_stack     __PWTB_StackAlloc
324         SAVE_FLOAT_ARGUMENT_REGISTERS __PWTB_FloatArgumentRegisters
325
326         END_PROLOGUE
327
328 .endm
329
330 .macro EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
331
332         RESTORE_FLOAT_ARGUMENT_REGISTERS __PWTB_FloatArgumentRegisters
333         free_stack      __PWTB_StackAlloc
334         POP_ARGUMENT_REGISTERS
335         POP_CALLEE_SAVED_REGISTERS
336
337 .endm