-
Notifications
You must be signed in to change notification settings - Fork 45
/
MacrosX86-64-AVX.asmh
297 lines (264 loc) · 8.57 KB
/
MacrosX86-64-AVX.asmh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
.nolist
extern __chkstk:proc
;-------------------------------------------------------------------------
; X86-64 Macro Notes
;
; The macros defined in this file assume that the stack frame is
; organized as described in the text.
;
; A VS project rebuild may be necessary if any changes are made
; in this file.
;
; A function must use the macros in the following order:
; _CreateFrame required
; _SaveXmmRegs optional
; _EndProlog required
; _RestoreXmmRegs optional
; _DeleteFrame required
;-------------------------------------------------------------------------
;-------------------------------------------------------------------------
; _CreateFrame
;
; Description: The following macro generates code that creates a stack
; frame for x86-64 functions.
;
; Macro Parameters: Prefix Macro symbolic name prefix
; StkSizeLocal1 Size in bytes for local1 vars
; StkSizeLocal2 Size in bytes for XMM reg save area
; Rnv1 - Rnv7 Non-volatile registers to save
;-------------------------------------------------------------------------
_CreateFrame macro Prefix,StkSizeLocal1,StkSizeLocal2,Rnv1,Rnv2,Rnv3,Rnv4,Rnv5,Rnv6,Rnv7
; Make sure stack sizes are valid
.errnz StkSizeLocal1 MOD 16, <Macro parameter 'StkSizeLocal1' must be evenly divisible by 16>
.errnz StkSizeLocal2 MOD 16, <Macro parameter 'StkSizeLocal2' must be evenly divisible by 16>
.errnz StkSizeLocal2 GT 240, <Macro parameter 'StkSizeLocal2' must be less than or equal to 240>
push rbp
.pushreg rbp
NumPushReg=1
IFNB <Rnv1>
push Rnv1
.pushreg Rnv1
NumPushReg=NumPushReg+1
ENDIF
IFNB <Rnv2>
push Rnv2
.pushreg Rnv2
NumPushReg=NumPushReg+1
ENDIF
IFNB <Rnv3>
push Rnv3
.pushreg Rnv3
NumPushReg=NumPushReg+1
ENDIF
IFNB <Rnv4>
push Rnv4
.pushreg Rnv4
NumPushReg=NumPushReg+1
ENDIF
IFNB <Rnv5>
push Rnv5
.pushreg Rnv5
NumPushReg=NumPushReg+1
ENDIF
IFNB <Rnv6>
push Rnv6
.pushreg Rnv6
NumPushReg=NumPushReg+1
ENDIF
IFNB <Rnv7>
push Rnv7
.pushreg Rnv7
NumPushReg=NumPushReg+1
ENDIF
StackPad=((NumPushReg AND 1) XOR 1) * 8
StackSizeTotal=StkSizeLocal1+StkSizeLocal2+StackPad
; Call helper function __chkstk if StackSizeTotal >= 4096 bytes (1 page)
; See Visual Studio documentation for more information
IF (StackSizeTotal GE 4096)
mov rax,StackSizeTotal
call __chkstk
sub rsp,rax
.allocstack StackSizeTotal
ELSEIF (StackSizeTotal GT 0)
sub rsp,StackSizeTotal
.allocstack StackSizeTotal
ENDIF
IF (StkSizeLocal2 GT 0)
lea rbp,[rsp+StkSizeLocal2]
ELSE
mov rbp,rsp
ENDIF
.setframe rbp,StkSizeLocal2
; Create the symbols for current function
ValStackSizeTotal CATSTR <Prefix>,<StackSizeTotal>
ValStackSizeTotal=StackSizeTotal
ValStackSizeLocal1 CATSTR <Prefix>,<StackSizeLocal1>
ValStackSizeLocal1=StkSizeLocal1
ValStackSizeLocal2 CATSTR <Prefix>,<StackSizeLocal2>
ValStackSizeLocal2=StkSizeLocal2
ValNameOffsetHomeRCX CATSTR <Prefix>,<OffsetHomeRCX>
ValNameOffsetHomeRCX=StkSizeLocal1+NumPushReg*8+StackPad+8
ValNameOffsetHomeRDX CATSTR <Prefix>,<OffsetHomeRDX>
ValNameOffsetHomeRDX=StkSizeLocal1+NumPushReg*8+StackPad+16
ValNameOffsetHomeR8 CATSTR <Prefix>,<OffsetHomeR8>
ValNameOffsetHomeR8=StkSizeLocal1+NumPushReg*8+StackPad+24
ValNameOffsetHomeR9 CATSTR <Prefix>,<OffsetHomeR9>
ValNameOffsetHomeR9=StkSizeLocal1+NumPushReg*8+StackPad+32
ValNameOffsetStackArgs CATSTR <Prefix>,<OffsetStackArgs>
ValNameOffsetStackArgs=StkSizeLocal1+NumPushReg*8+StackPad+40
ValNameOffsetSaveXmmRegs CATSTR <Prefix>,<OffsetSaveXmmRegs>
ValNameOffsetSaveXmmRegs=StkSizeLocal2
ValNameOffsetDeleteFrame CATSTR <Prefix>,<OffsetDeleteFrame>
ValNameOffsetDeleteFrame=StkSizeLocal1+StackPad
endm
;-------------------------------------------------------------------------
; _EndProlog
;
; Description: The following macro generates the .endprolog directive.
;-------------------------------------------------------------------------
_EndProlog macro
.endprolog
endm
;-------------------------------------------------------------------------
; _DeleteFrame
;
; Description: The following macro generates code that de-allocate a
; stack frame previously created using _CreateFrame.
;
; Macro Parameters: Rnv1 - Rnv7 Non-volatile registers to restore
;-------------------------------------------------------------------------
_DeleteFrame macro Rnv1,Rnv2,Rnv3,Rnv4,Rnv5,Rnv6,Rnv7
IF (ValNameOffsetDeleteFrame GT 0)
lea rsp,[rbp+ValNameOffsetDeleteFrame]
ELSE
mov rsp,rbp
ENDIF
IFNB <Rnv7>
pop Rnv7
ENDIF
IFNB <Rnv6>
pop Rnv6
ENDIF
IFNB <Rnv5>
pop Rnv5
ENDIF
IFNB <Rnv4>
pop Rnv4
ENDIF
IFNB <Rnv3>
pop Rnv3
ENDIF
IFNB <Rnv2>
pop Rnv2
ENDIF
IFNB <Rnv1>
pop Rnv1
ENDIF
pop rbp
endm
;-------------------------------------------------------------------------
; _SaveXmmRegs
;
; Description: The following macro generates code that saves the
; specified non-volatile registers to the local save area.
;
; Macro Parameters: Rnv1 - Rnv7 Non-volatile XMM registers to save.
;-------------------------------------------------------------------------
_SaveXmmRegs macro Rnv0,Rnv1,Rnv2,Rnv3,Rnv4,Rnv5,Rnv6,Rnv7,Rnv8,Rnv9
NUMSAVEXMM = 0
IFNB <Rnv0>
vmovdqa xmmword ptr [rbp-ValNameOffsetSaveXmmRegs],Rnv0
.savexmm128 Rnv0,0
NUMSAVEXMM = NUMSAVEXMM + 1
ENDIF
IFNB <Rnv1>
vmovdqa xmmword ptr [rbp-ValNameOffsetSaveXmmRegs+16],Rnv1
.savexmm128 Rnv1,16
NUMSAVEXMM = NUMSAVEXMM + 1
ENDIF
IFNB <Rnv2>
vmovdqa xmmword ptr [rbp-ValNameOffsetSaveXmmRegs+32],Rnv2
.savexmm128 Rnv2,32
NUMSAVEXMM = NUMSAVEXMM + 1
ENDIF
IFNB <Rnv3>
vmovdqa xmmword ptr [rbp-ValNameOffsetSaveXmmRegs+48],Rnv3
.savexmm128 Rnv3,48
NUMSAVEXMM = NUMSAVEXMM + 1
ENDIF
IFNB <Rnv4>
vmovdqa xmmword ptr [rbp-ValNameOffsetSaveXmmRegs+64],Rnv4
.savexmm128 Rnv4,64
NUMSAVEXMM = NUMSAVEXMM + 1
ENDIF
IFNB <Rnv5>
vmovdqa xmmword ptr [rbp-ValNameOffsetSaveXmmRegs+80],Rnv5
.savexmm128 Rnv5,80
NUMSAVEXMM = NUMSAVEXMM + 1
ENDIF
IFNB <Rnv6>
vmovdqa xmmword ptr [rbp-ValNameOffsetSaveXmmRegs+96],Rnv6
.savexmm128 Rnv6,96
NUMSAVEXMM = NUMSAVEXMM + 1
ENDIF
IFNB <Rnv7>
vmovdqa xmmword ptr [rbp-ValNameOffsetSaveXmmRegs+112],Rnv7
.savexmm128 Rnv7,112
NUMSAVEXMM = NUMSAVEXMM + 1
ENDIF
IFNB <Rnv8>
vmovdqa xmmword ptr [rbp-ValNameOffsetSaveXmmRegs+128],Rnv8
.savexmm128 Rnv8,128
NUMSAVEXMM = NUMSAVEXMM + 1
ENDIF
IFNB <Rnv9>
vmovdqa xmmword ptr [rbp-ValNameOffsetSaveXmmRegs+144],Rnv9
.savexmm128 Rnv9,144
NUMSAVEXMM = NUMSAVEXMM + 1
ENDIF
; Make sure the stack frame was created with enough space to save
; all of the specified XMM registers.
.errnz (NUMSAVEXMM * 16) GT ValStackSizeLocal2, <XMM register save area is too small>
endm
;-------------------------------------------------------------------------
; _RestoreXmmRegs
;
; Description: The following macro generates code that restores the
; specified non-volatile registers from the local save area.
;
; Macro Parameters: Rnv1 - Rnv7 Non-volatile XMM registers to restore.
;-------------------------------------------------------------------------
_RestoreXmmRegs macro Rnv0,Rnv1,Rnv2,Rnv3,Rnv4,Rnv5,Rnv6,Rnv7,Rnv8,Rnv9
IFNB <Rnv0>
vmovdqa rnv0,xmmword ptr [rbp-ValNameOffsetSaveXmmRegs]
ENDIF
IFNB <Rnv1>
vmovdqa rnv1,xmmword ptr [rbp-ValNameOffsetSaveXmmRegs+16]
ENDIF
IFNB <Rnv2>
vmovdqa rnv2,xmmword ptr [rbp-ValNameOffsetSaveXmmRegs+32]
ENDIF
IFNB <Rnv3>
vmovdqa rnv3,xmmword ptr [rbp-ValNameOffsetSaveXmmRegs+48]
ENDIF
IFNB <Rnv4>
vmovdqa rnv4,xmmword ptr [rbp-ValNameOffsetSaveXmmRegs+64]
ENDIF
IFNB <Rnv5>
vmovdqa rnv5,xmmword ptr [rbp-ValNameOffsetSaveXmmRegs+80]
ENDIF
IFNB <Rnv6>
vmovdqa rnv6,xmmword ptr [rbp-ValNameOffsetSaveXmmRegs+96]
ENDIF
IFNB <Rnv7>
vmovdqa rnv7,xmmword ptr [rbp-ValNameOffsetSaveXmmRegs+112]
ENDIF
IFNB <Rnv8>
vmovdqa rnv8,xmmword ptr [rbp-ValNameOffsetSaveXmmRegs+128]
ENDIF
IFNB <Rnv9>
vmovdqa rnv9,xmmword ptr [rbp-ValNameOffsetSaveXmmRegs+144]
ENDIF
endm
.list
.listmacro