Subversion Repositories Kolibri OS

Rev

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: \{ prologue name,flag,parmbytes,localbytes,reglist \}
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: \\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \}
388
   macro finish@proc
389
   \{ localbytes = current
390
      match close:reglist, close@proc: \\{ close name,flag,parmbytes,localbytes,reglist \\}
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
>