Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
9227 | dunkaist | 1 | |
2 | |||
3 | |||
4 | { common fastcall [proc],arg } |
||
5 | |||
6 | |||
7 | { common local stackspace,argscount,counter |
||
8 | if argscount < 4 |
||
9 | stackspace = 4*8 |
||
10 | else if argscount and 1 |
||
11 | stackspace = (argscount+1)*8 |
||
12 | else |
||
13 | stackspace = argscount*8 |
||
14 | end if |
||
15 | counter = 0 |
||
16 | if stackspace |
||
17 | if defined current@frame |
||
18 | if current@frame |
||
19 | current@frame = stackspace |
||
20 | end if |
||
21 | else |
||
22 | if stackspace |
||
23 | sub rsp, stackspace |
||
24 | end if |
||
25 | end if |
||
26 | end if |
||
27 | forward |
||
28 | counter = counter + 1 |
||
29 | define type@param |
||
30 | define definition@param arg |
||
31 | match =float value,definition@param |
||
32 | \{ define definition@param value |
||
33 | define type@param float \} |
||
34 | match =addr value,definition@param |
||
35 | \{ define definition@param value |
||
36 | define type@param addr \} |
||
37 | match any=,any,definition@param |
||
38 | \{ \local ..string,..continue |
||
39 | jmp ..continue |
||
40 | align sizeof.TCHAR |
||
41 | ..string TCHAR definition@param,0 |
||
42 | ..continue: |
||
43 | define definition@param ..string |
||
44 | define type@param addr \} |
||
45 | match any,definition@param |
||
46 | \{ match \`any,any |
||
47 | \\{ \\local ..string,..continue |
||
48 | jmp ..continue |
||
49 | align sizeof.TCHAR |
||
50 | ..string TCHAR definition@param,0 |
||
51 | ..continue: |
||
52 | define definition@param ..string |
||
53 | define type@param addr \\} \} |
||
54 | match param,definition@param |
||
55 | \{ local opcode,origin |
||
56 | size@param = 0 |
||
57 | if param eqtype 0 | param eqtype 0f | type@param eq addr |
||
58 | size@param = 8 |
||
59 | else if param eqtype byte 0 | param eqtype byte 0f |
||
60 | match prefix value,definition@param |
||
61 | \\{ if prefix eq qword |
||
62 | size@param = 8 |
||
63 | else if prefix eq dword |
||
64 | size@param = 4 |
||
65 | else if prefix eq word |
||
66 | size@param = 2 |
||
67 | else if prefix eq byte |
||
68 | size@param = 1 |
||
69 | end if \\} |
||
70 | else if ~ param in |
||
71 | virtual |
||
72 | origin = $ |
||
73 | inc param |
||
74 | load opcode byte from origin |
||
75 | if opcode = 67h | opcode = 41h |
||
76 | load opcode byte from origin+1 |
||
77 | end if |
||
78 | if opcode and 0F8h = 48h |
||
79 | size@param = 8 |
||
80 | else if opcode = 66h |
||
81 | size@param = 2 |
||
82 | else if opcode = 0FFh |
||
83 | size@param = 4 |
||
84 | else |
||
85 | size@param = 1 |
||
86 | end if |
||
87 | end virtual |
||
88 | end if |
||
89 | if counter = 1 |
||
90 | if type@param eq float |
||
91 | if ~ param eq xmm0 |
||
92 | if size@param = 4 |
||
93 | if param eqtype byte 0 | param eqtype byte 0f |
||
94 | mov eax, param |
||
95 | movd xmm0, eax |
||
96 | else |
||
97 | movd xmm0, param |
||
98 | end if |
||
99 | else |
||
100 | if param eqtype 0 | param eqtype 0f | param eqtype byte 0 | param eqtype byte 0f |
||
101 | mov rax, param |
||
102 | movq xmm0, rax |
||
103 | else |
||
104 | movq xmm0, param |
||
105 | end if |
||
106 | end if |
||
107 | end if |
||
108 | if vararg@fastcall & ~ param eq rcx |
||
109 | movq rcx, xmm0 |
||
110 | end if |
||
111 | else if type@param eq addr |
||
112 | if ~ param eq rcx |
||
113 | lea rcx, [param] |
||
114 | end if |
||
115 | else if size@param = 8 |
||
116 | if ~ param eq rcx |
||
117 | mov rcx, param |
||
118 | end if |
||
119 | else if size@param = 4 |
||
120 | if ~ param eq ecx |
||
121 | mov ecx, param |
||
122 | end if |
||
123 | else if size@param = 2 |
||
124 | if ~ param eq cx |
||
125 | mov cx, param |
||
126 | end if |
||
127 | else if size@param = 1 |
||
128 | if ~ param eq cl |
||
129 | mov cl, param |
||
130 | end if |
||
131 | end if |
||
132 | else if counter = 2 |
||
133 | if type@param eq float |
||
134 | if ~ param eq xmm1 |
||
135 | if size@param = 4 |
||
136 | if param eqtype byte 0 | param eqtype byte 0f |
||
137 | mov eax, param |
||
138 | movd xmm1, eax |
||
139 | else |
||
140 | movd xmm1, param |
||
141 | end if |
||
142 | else |
||
143 | if param eqtype 0 | param eqtype 0f | param eqtype byte 0 | param eqtype byte 0f |
||
144 | mov rax, param |
||
145 | movq xmm1, rax |
||
146 | else |
||
147 | movq xmm1, param |
||
148 | end if |
||
149 | end if |
||
150 | end if |
||
151 | if vararg@fastcall & ~ param eq rdx |
||
152 | movq rdx, xmm1 |
||
153 | end if |
||
154 | else if type@param eq addr |
||
155 | if ~ param eq rdx |
||
156 | lea rdx, [param] |
||
157 | end if |
||
158 | else if size@param = 8 |
||
159 | if ~ param eq rdx |
||
160 | mov rdx, param |
||
161 | end if |
||
162 | else if size@param = 4 |
||
163 | if ~ param eq edx |
||
164 | mov edx, param |
||
165 | end if |
||
166 | else if size@param = 2 |
||
167 | if ~ param eq dx |
||
168 | mov dx, param |
||
169 | end if |
||
170 | else if size@param = 1 |
||
171 | if ~ param eq dl |
||
172 | mov dl, param |
||
173 | end if |
||
174 | end if |
||
175 | else if counter = 3 |
||
176 | if type@param eq float |
||
177 | if ~ param eq xmm2 |
||
178 | if size@param = 4 |
||
179 | if param eqtype byte 0 | param eqtype byte 0f |
||
180 | mov eax, param |
||
181 | movd xmm2, eax |
||
182 | else |
||
183 | movd xmm2, param |
||
184 | end if |
||
185 | else |
||
186 | if param eqtype 0 | param eqtype 0f | param eqtype byte 0 | param eqtype byte 0f |
||
187 | mov rax, param |
||
188 | movq xmm2, rax |
||
189 | else |
||
190 | movq xmm2, param |
||
191 | end if |
||
192 | end if |
||
193 | end if |
||
194 | if vararg@fastcall & ~ param eq r8 |
||
195 | movq r8, xmm2 |
||
196 | end if |
||
197 | else if type@param eq addr |
||
198 | if ~ param eq r8 |
||
199 | lea r8, [param] |
||
200 | end if |
||
201 | else if size@param = 8 |
||
202 | if ~ param eq r8 |
||
203 | mov r8, param |
||
204 | end if |
||
205 | else if size@param = 4 |
||
206 | if ~ param eq r8d |
||
207 | mov r8d, param |
||
208 | end if |
||
209 | else if size@param = 2 |
||
210 | if ~ param eq r8w |
||
211 | mov r8w, param |
||
212 | end if |
||
213 | else if size@param = 1 |
||
214 | if ~ param eq r8b |
||
215 | mov r8b, param |
||
216 | end if |
||
217 | end if |
||
218 | else if counter = 4 |
||
219 | if type@param eq float |
||
220 | if ~ param eq xmm3 |
||
221 | if size@param = 4 |
||
222 | if param eqtype byte 0 | param eqtype byte 0f |
||
223 | mov eax, param |
||
224 | movd xmm3, eax |
||
225 | else |
||
226 | movd xmm3, param |
||
227 | end if |
||
228 | else |
||
229 | if param eqtype 0 | param eqtype 0f | param eqtype byte 0 | param eqtype byte 0f |
||
230 | mov rax, param |
||
231 | movq xmm3, rax |
||
232 | else |
||
233 | movq xmm3, param |
||
234 | end if |
||
235 | end if |
||
236 | end if |
||
237 | if vararg@fastcall & ~ param eq r9 |
||
238 | movq r9, xmm3 |
||
239 | end if |
||
240 | else if type@param eq addr |
||
241 | if ~ param eq r9 |
||
242 | lea r9, [param] |
||
243 | end if |
||
244 | else if size@param = 8 |
||
245 | if ~ param eq r9 |
||
246 | mov r9, param |
||
247 | end if |
||
248 | else if size@param = 4 |
||
249 | if ~ param eq r9d |
||
250 | mov r9d, param |
||
251 | end if |
||
252 | else if size@param = 2 |
||
253 | if ~ param eq r9w |
||
254 | mov r9w, param |
||
255 | end if |
||
256 | else if size@param = 1 |
||
257 | if ~ param eq r9b |
||
258 | mov r9b, param |
||
259 | end if |
||
260 | end if |
||
261 | else |
||
262 | if type@param eq addr |
||
263 | lea rax, [param] |
||
264 | mov [rsp+(counter-1)*8], rax |
||
265 | else if param eqtype [0] | param eqtype byte [0] |
||
266 | if size@param = 8 |
||
267 | mov rax, param |
||
268 | mov [rsp+(counter-1)*8], rax |
||
269 | else if size@param = 4 |
||
270 | mov eax, param |
||
271 | mov [rsp+(counter-1)*8], eax |
||
272 | else if size@param = 2 |
||
273 | mov ax, param |
||
274 | mov [rsp+(counter-1)*8], ax |
||
275 | else |
||
276 | mov al, param |
||
277 | mov [rsp+(counter-1)*8], al |
||
278 | end if |
||
279 | else if size@param = 8 |
||
280 | virtual |
||
281 | origin = $ |
||
282 | mov rax, param |
||
283 | load opcode byte from origin+1 |
||
284 | end virtual |
||
285 | if opcode = 0B8h |
||
286 | mov rax, param |
||
287 | mov [rsp+(counter-1)*8], rax |
||
288 | else |
||
289 | mov qword [rsp+(counter-1)*8], param |
||
290 | end if |
||
291 | else if param in |
||
292 | movq [rsp+(counter-1)*8], param |
||
293 | else |
||
294 | mov [rsp+(counter-1)*8], param |
||
295 | end if |
||
296 | end if \} |
||
297 | common |
||
298 | argscount = counter |
||
299 | call proc |
||
300 | if stackspace & ~defined current@frame |
||
301 | add rsp, stackspace |
||
302 | end if } |
||
303 | |||
304 | |||
305 | { common |
||
306 | match name params, args> |
||
307 | \{ define@proc name, |
||
308 | |||
309 | |||
310 | |||
311 | |||
312 | { local loc,fill,counter |
||
313 | loc = (localbytes+15) and (not 15) |
||
314 | parmbase@proc equ rbp+16 |
||
315 | localbase@proc equ rbp-loc |
||
316 | push rbp |
||
317 | mov rbp, rsp |
||
318 | if loc+fill |
||
319 | sub rsp, loc+fill |
||
320 | end if |
||
321 | counter = 0 |
||
322 | irps reg, reglist \{ push reg |
||
323 | counter = counter+1 \} |
||
324 | fill = 8*(counter and 1) } |
||
325 | |||
326 | |||
327 | |||
328 | |||
329 | { irps reg, reglist \{ reverse pop reg \} |
||
330 | leave |
||
331 | retn } |
||
332 | |||
333 | |||
334 | |||
335 | |||
336 | { local params,flag,regs,parmbytes,localbytes,current |
||
337 | if used name |
||
338 | name: |
||
339 | match =stdcall args, statement \{ params equ args |
||
340 | flag = 11b \} |
||
341 | match =stdcall, statement \{ params equ |
||
342 | flag = 11b \} |
||
343 | match =c args, statement \{ params equ args |
||
344 | flag = 10001b \} |
||
345 | match =c, statement \{ params equ |
||
346 | flag = 10001b \} |
||
347 | match =params, params \{ params equ statement |
||
348 | flag = 10000b \} |
||
349 | match =uses reglist=,args, params \{ regs equ reglist |
||
350 | params equ args \} |
||
351 | match =regs =uses reglist, regs params \{ regs equ reglist |
||
352 | params equ \} |
||
353 | match =regs, regs \{ regs equ \} |
||
354 | match prologue:reglist, prologue@proc: |
||
355 | virtual at parmbase@proc |
||
356 | match =,args, params \{ defargs@proc args \} |
||
357 | match =args@proc args, args@proc params \{ defargs@proc args \} |
||
358 | parmbytes = $-(parmbase@proc) |
||
359 | end virtual |
||
360 | name # % = parmbytes/8 |
||
361 | all@vars equ |
||
362 | current = 0 |
||
363 | macro locals |
||
364 | \{ virtual at localbase@proc+current |
||
365 | macro label def \\{ match . type,def> \\\{ deflocal@proc .,label, |
||
366 | struc db [val] \\{ \common deflocal@proc .,db,val \\} |
||
367 | struc du [val] \\{ \common deflocal@proc .,du,val \\} |
||
368 | struc dw [val] \\{ \common deflocal@proc .,dw,val \\} |
||
369 | struc dp [val] \\{ \common deflocal@proc .,dp,val \\} |
||
370 | struc dd [val] \\{ \common deflocal@proc .,dd,val \\} |
||
371 | struc dt [val] \\{ \common deflocal@proc .,dt,val \\} |
||
372 | struc dq [val] \\{ \common deflocal@proc .,dq,val \\} |
||
373 | struc rb cnt \\{ deflocal@proc .,rb cnt, \\} |
||
374 | struc rw cnt \\{ deflocal@proc .,rw cnt, \\} |
||
375 | struc rp cnt \\{ deflocal@proc .,rp cnt, \\} |
||
376 | struc rd cnt \\{ deflocal@proc .,rd cnt, \\} |
||
377 | struc rt cnt \\{ deflocal@proc .,rt cnt, \\} |
||
378 | struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \} |
||
379 | macro endl |
||
380 | \{ purge label |
||
381 | restruc db,du,dw,dp,dd,dt,dq |
||
382 | restruc rb,rw,rp,rd,rt,rq |
||
383 | current = $-(localbase@proc) |
||
384 | end virtual \} |
||
385 | macro ret operand |
||
386 | \{ match any, operand \\{ retn operand \\} |
||
387 | match , operand \\{ match epilogue:reglist, epilogue@proc: |
||
388 | macro finish@proc |
||
389 | \{ localbytes = current |
||
390 | match close:reglist, close@proc: |
||
391 | end if \} } |
||
392 | |||
393 | |||
394 | { common |
||
395 | if ~ arg eq |
||
396 | forward |
||
397 | local ..arg,current@arg |
||
398 | match argname:type, arg |
||
399 | \{ current@arg equ argname |
||
400 | label ..arg type |
||
401 | argname equ ..arg |
||
402 | if qqword eq type |
||
403 | dq ?,?,?,? |
||
404 | else if dqword eq type |
||
405 | dq ?,? |
||
406 | else if tbyte eq type |
||
407 | dq ?,? |
||
408 | else |
||
409 | dq ? |
||
410 | end if \} |
||
411 | match =current@arg,current@arg |
||
412 | \{ current@arg equ arg |
||
413 | arg equ ..arg |
||
414 | ..arg dq ? \} |
||
415 | common |
||
416 | args@proc equ current@arg |
||
417 | forward |
||
418 | restore current@arg |
||
419 | common |
||
420 | end if } |
||
421 | |||
422 | |||
423 | |||
424 | |||
425 | { common |
||
426 | match vars, all@vars \{ all@vars equ all@vars, \} |
||
427 | all@vars equ all@vars name |
||
428 | forward |
||
429 | local ..var,..tmp |
||
430 | ..var def val |
||
431 | match =?, val \{ ..tmp equ \} |
||
432 | match any =?, val \{ ..tmp equ \} |
||
433 | match any (=?), val \{ ..tmp equ \} |
||
434 | match =label, def \{ ..tmp equ \} |
||
435 | match tmp : value, ..tmp : val |
||
436 | \{ tmp: end virtual |
||
437 | initlocal@proc ..var,def value |
||
438 | virtual at tmp\} |
||
439 | common |
||
440 | match first rest, ..var, \{ name equ first \} } |
||
441 | |||
442 | |||
443 | |||
444 | |||
445 | { virtual at name |
||
446 | def |
||
447 | size@initlocal = $ - name |
||
448 | end virtual |
||
449 | position@initlocal = 0 |
||
450 | while size@initlocal > position@initlocal |
||
451 | virtual at name |
||
452 | def |
||
453 | if size@initlocal - position@initlocal < 2 |
||
454 | current@initlocal = 1 |
||
455 | load byte@initlocal byte from name+position@initlocal |
||
456 | else if size@initlocal - position@initlocal < 4 |
||
457 | current@initlocal = 2 |
||
458 | load word@initlocal word from name+position@initlocal |
||
459 | else if size@initlocal - position@initlocal < 8 |
||
460 | current@initlocal = 4 |
||
461 | load dword@initlocal dword from name+position@initlocal |
||
462 | else |
||
463 | load qword@initlocal qword from name+position@initlocal |
||
464 | if ( qword@initlocal > 0 & qword@initlocal < 80000000h ) | ( qword@initlocal < 0 & qword@initlocal >= -80000000h ) |
||
465 | current@initlocal = 8 |
||
466 | else |
||
467 | current@initlocal = 4 |
||
468 | dword@initlocal = qword@initlocal and 0FFFFFFFFh |
||
469 | end if |
||
470 | end if |
||
471 | end virtual |
||
472 | if current@initlocal = 1 |
||
473 | mov byte [name+position@initlocal], byte@initlocal |
||
474 | else if current@initlocal = 2 |
||
475 | mov word [name+position@initlocal], word@initlocal |
||
476 | else if current@initlocal = 4 |
||
477 | mov dword [name+position@initlocal], dword@initlocal |
||
478 | else |
||
479 | mov qword [name+position@initlocal], qword@initlocal |
||
480 | end if |
||
481 | position@initlocal = position@initlocal + current@initlocal |
||
482 | end while } |
||
483 | |||
484 | |||
485 | { purge ret,locals,endl |
||
486 | finish@proc |
||
487 | purge finish@proc |
||
488 | restore regs@proc |
||
489 | match all,args@proc \{ restore all \} |
||
490 | restore args@proc |
||
491 | match all,all@vars \{ restore all \} } |
||
492 | |||
493 | |||
494 | { common |
||
495 | locals |
||
496 | forward done@local equ |
||
497 | match varname[count]:vartype, var |
||
498 | \{ match =BYTE, vartype \\{ varname rb count |
||
499 | restore done@local \\} |
||
500 | match =WORD, vartype \\{ varname rw count |
||
501 | restore done@local \\} |
||
502 | match =DWORD, vartype \\{ varname rd count |
||
503 | restore done@local \\} |
||
504 | match =PWORD, vartype \\{ varname rp count |
||
505 | restore done@local \\} |
||
506 | match =QWORD, vartype \\{ varname rq count |
||
507 | restore done@local \\} |
||
508 | match =TBYTE, vartype \\{ varname rt count |
||
509 | restore done@local \\} |
||
510 | match =DQWORD, vartype \\{ label varname dqword |
||
511 | rq count*2 |
||
512 | restore done@local \\} |
||
513 | match =QQWORD, vartype \\{ label varname qqword |
||
514 | rq count*4 |
||
515 | restore done@local \\} |
||
516 | match =XWORD, vartype \\{ label varname xword |
||
517 | rq count*2 |
||
518 | restore done@local \\} |
||
519 | match =YWORD, vartype \\{ label varname yword |
||
520 | rq count*4 |
||
521 | restore done@local \\} |
||
522 | match , done@local \\{ virtual |
||
523 | varname vartype |
||
524 | end virtual |
||
525 | rb count*sizeof.\#vartype |
||
526 | restore done@local \\} \} |
||
527 | match :varname:vartype, done@local:var |
||
528 | \{ match =BYTE, vartype \\{ varname db ? |
||
529 | restore done@local \\} |
||
530 | match =WORD, vartype \\{ varname dw ? |
||
531 | restore done@local \\} |
||
532 | match =DWORD, vartype \\{ varname dd ? |
||
533 | restore done@local \\} |
||
534 | match =PWORD, vartype \\{ varname dp ? |
||
535 | restore done@local \\} |
||
536 | match =QWORD, vartype \\{ varname dq ? |
||
537 | restore done@local \\} |
||
538 | match =TBYTE, vartype \\{ varname dt ? |
||
539 | restore done@local \\} |
||
540 | match =DQWORD, vartype \\{ label varname dqword |
||
541 | dq ?,? |
||
542 | restore done@local \\} |
||
543 | match =QQWORD, vartype \\{ label varname qqword |
||
544 | dq ?,?,?,? |
||
545 | restore done@local \\} |
||
546 | match =XWORD, vartype \\{ label varname xword |
||
547 | dq ?,? |
||
548 | restore done@local \\} |
||
549 | match =YWORD, vartype \\{ label varname yword |
||
550 | dq ?,?,?,? |
||
551 | restore done@local \\} |
||
552 | match , done@local \\{ varname vartype |
||
553 | restore done@local \\} \} |
||
554 | match ,done@local |
||
555 | \{ var |
||
556 | restore done@local \} |
||
557 | common |
||
558 | endl } |
||
559 | |||
560 | |||
561 | { local size,current |
||
562 | if size |
||
563 | sub rsp, size |
||
564 | end if |
||
565 | current = 0 |
||
566 | current@frame equ current |
||
567 | size@frame equ size } |
||
568 | |||
569 | |||
570 | { size@frame = current@frame |
||
571 | if size@frame |
||
572 | add rsp, size@frame |
||
573 | end if |
||
574 | restore size@frame,current@frame } |
||
575 | |||
576 | |||
577 | { local counter,loc,frame,current |
||
578 | counter = 0 |
||
579 | irps reg, reglist \{ push reg |
||
580 | counter = counter+1 \} |
||
581 | loc = (localbytes+7) and (not 7) |
||
582 | if frame & (counter+loc shr 3+1) and 1 |
||
583 | loc = loc + 8 |
||
584 | end if |
||
585 | framebytes@proc equ frame+loc |
||
586 | if framebytes@proc |
||
587 | sub rsp, framebytes@proc |
||
588 | end if |
||
589 | localbase@proc equ rsp+frame |
||
590 | regsbase@proc equ rsp+frame+loc |
||
591 | parmbase@proc equ rsp+frame+loc+counter*8+8 |
||
592 | current = 0 |
||
593 | current@frame equ current |
||
594 | size@frame equ frame } |
||
595 | |||
596 | |||
597 | { if framebytes@proc |
||
598 | add rsp, framebytes@proc |
||
599 | end if |
||
600 | irps reg, reglist \{ reverse pop reg \} |
||
601 | retn } |
||
602 | |||
603 | |||
604 | { size@frame = current@frame |
||
605 | restore size@frame,current@frame } |
||
606 | |||
607 | |||
608 | |||
609 | |||
610 | { common ccall [proc],arg } |
||
611 | |||
612 | |||
613 | { common vararg@fastcall = 1 |
||
614 | fastcall proc,arg |
||
615 | vararg@fastcall = 0 } |
||
616 | |||
617 | |||
618 | >> |