Subversion Repositories Kolibri OS

Rev

Rev 2288 | Rev 5363 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2455 mario79 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2288 clevermous 7
 
8
$Revision: 2455 $
9
 
10
 
11
; Macroinstructions for defining and calling procedures
12
 
13
macro stdcall proc,[arg]                ; directly call STDCALL procedure
14
 { common
15
    if ~ arg eq
16
   reverse
17
        pushd   arg
18
   common
19
    end if
20
        call    proc }
21
 
22
macro invoke proc,[arg]                 ; indirectly call STDCALL procedure
23
 { common
24
    if ~ arg eq
25
   reverse
26
        pushd   arg
27
   common
28
    end if
29
        call    [proc] }
30
 
31
macro ccall proc,[arg]                  ; directly call CDECL procedure
32
 { common
33
    size@ccall = 0
34
    if ~ arg eq
35
   reverse
36
        pushd   arg
37
    size@ccall = size@ccall+4
38
   common
39
    end if
40
        call    proc
41
    if size@ccall
42
        add     esp, size@ccall
43
    end if }
44
 
45
macro cinvoke proc,[arg]                ; indirectly call CDECL procedure
46
 { common
47
    size@ccall = 0
48
    if ~ arg eq
49
   reverse
50
        pushd   arg
51
    size@ccall = size@ccall+4
52
   common
53
    end if
54
        call    [proc]
55
    if size@ccall
56
        add     esp, size@ccall
57
    end if }
58
 
59
macro proc [args]                       ; define procedure
60
 { common
61
    match name params, args>
62
    \{ define@proc name,
63
 
64
prologue@proc equ prologuedef
65
 
66
macro prologuedef procname,flag,parmbytes,localbytes,reglist
67
 { if parmbytes | localbytes
68
        push    ebp
69
        mov     ebp, esp
70
    if localbytes
71
        sub     esp, localbytes
72
    end if
73
   end if
74
   irps reg, reglist \{ push reg \} }
75
 
76
epilogue@proc equ epiloguedef
77
 
78
macro epiloguedef procname,flag,parmbytes,localbytes,reglist
79
 { irps reg, reglist \{ reverse pop reg \}
80
   if parmbytes | localbytes
81
        leave
82
   end if
83
   if (flag and 10000b) | (parmbytes=0)
84
        retn
85
   else
86
        retn    parmbytes
87
   end if }
88
 
89
macro define@proc name,statement
90
 { local params,flag,regs,parmbytes,localbytes,current
91
   if used name
92
   name:
93
   match =stdcall args, statement \{ params equ args
94
                                     flag = 11b \}
95
   match =stdcall, statement \{ params equ
96
                                flag = 11b \}
97
   match =c args, statement \{ params equ args
98
                               flag = 10001b \}
99
   match =c, statement \{ params equ
100
                          flag = 10001b \}
101
   match =params, params \{ params equ statement
102
                            flag = 0 \}
103
   virtual at ebp+8
104
   match =uses reglist=,args, params \{ regs equ reglist
105
                                        params equ args \}
106
   match =regs =uses reglist, regs params \{ regs equ reglist
107
                                             params equ \}
108
   match =regs, regs \{ regs equ \}
109
   match =,args, params \{ defargs@proc args \}
110
   match =args@proc args, args@proc params \{ defargs@proc args \}
111
   parmbytes = $ - (ebp+8)
112
   end virtual
113
   name # % = parmbytes/4
114
   all@vars equ
115
   current = 0
116
   match prologue:reglist, prologue@proc: \{ prologue name,flag,parmbytes,localbytes,reglist \}
117
   macro locals
118
   \{ virtual at ebp-localbytes+current
119
      macro label . \\{ deflocal@proc .,:, \\}
120
      struc db [val] \\{ \common deflocal@proc .,db,val \\}
121
      struc dw [val] \\{ \common deflocal@proc .,dw,val \\}
122
      struc dp [val] \\{ \common deflocal@proc .,dp,val \\}
123
      struc dd [val] \\{ \common deflocal@proc .,dd,val \\}
124
      struc dt [val] \\{ \common deflocal@proc .,dt,val \\}
125
      struc dq [val] \\{ \common deflocal@proc .,dq,val \\}
126
      struc rb cnt \\{ deflocal@proc .,rb cnt, \\}
127
      struc rw cnt \\{ deflocal@proc .,rw cnt, \\}
128
      struc rp cnt \\{ deflocal@proc .,rp cnt, \\}
129
      struc rd cnt \\{ deflocal@proc .,rd cnt, \\}
130
      struc rt cnt \\{ deflocal@proc .,rt cnt, \\}
131
      struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \}
132
   macro endl
133
   \{ purge label
134
      restruc db,dw,dp,dd,dt,dq
135
      restruc rb,rw,rp,rd,rt,rq
136
      restruc byte,word,dword,pword,tword,qword
137
      current = $-(ebp-localbytes)
138
      end virtual \}
139
   macro ret operand
140
   \{ match any, operand \\{ retn operand \\}
141
      match , operand \\{ match epilogue:reglist, epilogue@proc:
142
                          \\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \}
143
   macro finish@proc \{ localbytes = (((current-1) shr 2)+1) shl 2
144
                        end if \} }
145
 
146
macro defargs@proc [arg]
147
 { common
148
    if ~ arg eq
149
   forward
150
     local ..arg,current@arg
151
     match argname:type, arg
152
      \{ current@arg equ argname
153
         label ..arg type
154
         argname equ ..arg
155
         if dqword eq type
156
           dd ?,?,?,?
157
         else if tbyte eq type
158
           dd ?,?,?
159
         else if qword eq type | pword eq type
160
           dd ?,?
161
         else
162
           dd ?
163
         end if \}
164
     match =current@arg,current@arg
165
      \{ current@arg equ arg
166
         arg equ ..arg
167
         ..arg dd ? \}
168
   common
169
     args@proc equ current@arg
170
   forward
171
     restore current@arg
172
   common
173
    end if }
174
 
175
macro deflocal@proc name,def,[val]
176
 { common
177
    match vars, all@vars \{ all@vars equ all@vars, \}
178
    all@vars equ all@vars name
179
   forward
180
    local ..var,..tmp
181
    ..var def val
182
    match =?, val \{ ..tmp equ \}
183
    match any =dup (=?), val \{ ..tmp equ \}
184
    match tmp : value, ..tmp : val
185
     \{ tmp: end virtual
186
        initlocal@proc ..var,def value
187
        virtual at tmp\}
188
   common
189
    match first rest, ..var, \{ name equ first \} }
190
 
191
macro initlocal@proc name,def
192
 { virtual at name
193
    def
194
    size@initlocal = $ - name
195
   end virtual
196
   position@initlocal = 0
197
   while size@initlocal > position@initlocal
198
    virtual at name
199
     def
200
     if size@initlocal - position@initlocal < 2
201
      current@initlocal = 1
202
      load byte@initlocal byte from name+position@initlocal
203
     else if size@initlocal - position@initlocal < 4
204
      current@initlocal = 2
205
      load word@initlocal word from name+position@initlocal
206
     else
207
      current@initlocal = 4
208
      load dword@initlocal dword from name+position@initlocal
209
     end if
210
    end virtual
211
    if current@initlocal = 1
212
        mov     byte [name+position@initlocal], byte@initlocal
213
    else if current@initlocal = 2
214
        mov     word [name+position@initlocal], word@initlocal
215
    else
216
        mov     dword [name+position@initlocal], dword@initlocal
217
    end if
218
    position@initlocal = position@initlocal + current@initlocal
219
   end while }
220
 
221
macro endp
222
 { purge ret,locals,endl
223
   finish@proc
224
   purge finish@proc
225
   restore regs@proc
226
   match all,args@proc \{ restore all \}
227
   restore args@proc
228
   match all,all@vars \{ restore all \} }
229
 
230
macro local [var]
231
 { common
232
    locals
233
   forward done@local equ
234
    match varname[count]:vartype, var
235
    \{ match =BYTE, vartype \\{ varname rb count
236
                                restore done@local \\}
237
       match =WORD, vartype \\{ varname rw count
238
                                restore done@local \\}
239
       match =DWORD, vartype \\{ varname rd count
240
                                 restore done@local \\}
241
       match =PWORD, vartype \\{ varname rp count
242
                                 restore done@local \\}
243
       match =QWORD, vartype \\{ varname rq count
244
                                 restore done@local \\}
245
       match =TBYTE, vartype \\{ varname rt count
246
                                 restore done@local \\}
247
       match =DQWORD, vartype \\{ label varname dqword
248
                                  rq count+count
249
                                  restore done@local \\}
250
       match , done@local \\{ virtual
251
                               varname vartype
252
                              end virtual
253
                              rb count*sizeof.\#vartype
254
                              restore done@local \\} \}
255
    match :varname:vartype, done@local:var
256
    \{ match =BYTE, vartype \\{ varname db ?
257
                                restore done@local \\}
258
       match =WORD, vartype \\{ varname dw ?
259
                                restore done@local \\}
260
       match =DWORD, vartype \\{ varname dd ?
261
                                 restore done@local \\}
262
       match =PWORD, vartype \\{ varname dp ?
263
                                 restore done@local \\}
264
       match =QWORD, vartype \\{ varname dq ?
265
                                 restore done@local \\}
266
       match =TBYTE, vartype \\{ varname dt ?
267
                                 restore done@local \\}
268
       match =DQWORD, vartype \\{ label varname dqword
269
                                  dq ?,?
270
                                  restore done@local \\}
271
       match , done@local \\{ varname vartype
272
                              restore done@local \\} \}
273
    match ,done@local
274
    \{ var
275
       restore done@local \}
276
   common
277
    endl }