Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2288 clevermous 1
 
2
3
 
8965 Boppan 4
; @param proc Callee name
5
; @param arg Arguments to pass
6
macro stdcall proc,[arg]
7
 { common
2288 clevermous 8
    if ~ arg eq
9
   reverse
10
        pushd   arg
11
   common
12
    end if
13
        call    proc }
14
15
 
8969 Boppan 16
; @param proc Callee name
17
; @param arg Arguments to pass
18
macro invoke proc,[arg]
19
 { common
2288 clevermous 20
    if ~ arg eq
21
   reverse
22
        pushd   arg
23
   common
24
    end if
25
        call    [proc] }
26
27
 
8970 Boppan 28
; @param proc Callee name
29
; @param arg Arguments to pass
30
macro ccall proc,[arg]
31
 { common
2288 clevermous 32
    size@ccall = 0
33
    if ~ arg eq
34
   reverse
35
        pushd   arg
36
    size@ccall = size@ccall+4
37
   common
38
    end if
39
        call    proc
40
    if size@ccall
41
        add     esp, size@ccall
42
    end if }
43
44
 
8971 Boppan 45
; @param proc Callee name
46
; @param arg Arguments to pass
47
macro cinvoke proc,[arg]
48
 { common
2288 clevermous 49
    size@ccall = 0
50
    if ~ arg eq
51
   reverse
52
        pushd   arg
53
    size@ccall = size@ccall+4
54
   common
55
    end if
56
        call    [proc]
57
    if size@ccall
58
        add     esp, size@ccall
59
    end if }
60
61
 
8972 Boppan 62
;        Calling convention for the procedure may be defined before parameter
63
;        list using `stdcall` or `c` word like this:\n
64
;        `proc name stdcall, param0, param1`\n
65
;        List of registers used in the procedure may be specified before
66
;        parameter list using `uses` word like this:\n
67
;        `proc name uses eax ebx ecx, param0, param1`\n
68
;        If you need to specify both calling convention and used registers
69
;        put calling convention first and then `uses` statement like this:\n
70
;        `proc name stdcall uses ebx ecx edx, param0, param1`
71
; @param args Name of the procedure and a comma-separated argument list.
72
;             Type of any parameter may be specified by semicolon after its
73
;             name like this:\n
74
;             `proc name param0:dword, param1:qword`.
75
macro proc [args]
76
 { common
2288 clevermous 77
    match name params, args>
78
    \{ define@proc name,
79
80
 
81
82
 
83
 { local loc
7294 dunkaist 84
   loc = (localbytes+3) and (not 3)
85
   parmbase@proc equ ebp+8
86
   localbase@proc equ ebp-loc
87
   if parmbytes | localbytes
88
        push    ebp
2288 clevermous 89
        mov     ebp, esp
90
    if localbytes
91
        sub     esp, loc
7294 dunkaist 92
    end if
2288 clevermous 93
   end if
94
   irps reg, reglist \{ push reg \} }
95
96
 
97
98
 
99
 { irps reg, reglist \{ reverse pop reg \}
100
   if parmbytes | localbytes
101
        leave
102
   end if
103
   if flag and 10000b
7294 dunkaist 104
        retn
2288 clevermous 105
   else
106
        retn    parmbytes
107
   end if }
108
109
 
7294 dunkaist 110
111
 
2288 clevermous 112
 { local params,flag,regs,parmbytes,localbytes,current
113
   if used name
114
   name:
115
   match =stdcall args, statement \{ params equ args
116
                                     flag = 11b \}
117
   match =stdcall, statement \{ params equ
118
                                flag = 11b \}
119
   match =c args, statement \{ params equ args
120
                               flag = 10001b \}
121
   match =c, statement \{ params equ
122
                          flag = 10001b \}
123
   match =params, params \{ params equ statement
124
                            flag = 0 \}
125
   match =uses reglist=,args, params \{ regs equ reglist
126
                                        params equ args \}
127
   match =regs =uses reglist, regs params \{ regs equ reglist
128
                                             params equ \}
129
   match =regs, regs \{ regs equ \}
130
   match prologue:reglist, prologue@proc: \{ prologue name,flag,parmbytes,localbytes,reglist \}
7294 dunkaist 131
   virtual at parmbase@proc
132
   match =,args, params \{ defargs@proc args \}
2288 clevermous 133
   match =args@proc args, args@proc params \{ defargs@proc args \}
134
   parmbytes = $-(parmbase@proc)
7294 dunkaist 135
   end virtual
2288 clevermous 136
   name # % = parmbytes/4
137
   all@vars equ
138
   current = 0
139
   macro locals
140
   \{ virtual at localbase@proc+current
7294 dunkaist 141
      macro label def \\{ match . type,def> \\\{ deflocal@proc .,label,
142
      struc db [val] \\{ \common deflocal@proc .,db,val \\}
2288 clevermous 143
      struc du [val] \\{ \common deflocal@proc .,du,val \\}
7294 dunkaist 144
      struc dw [val] \\{ \common deflocal@proc .,dw,val \\}
2288 clevermous 145
      struc dp [val] \\{ \common deflocal@proc .,dp,val \\}
146
      struc dd [val] \\{ \common deflocal@proc .,dd,val \\}
147
      struc dt [val] \\{ \common deflocal@proc .,dt,val \\}
148
      struc dq [val] \\{ \common deflocal@proc .,dq,val \\}
149
      struc rb cnt \\{ deflocal@proc .,rb cnt, \\}
150
      struc rw cnt \\{ deflocal@proc .,rw cnt, \\}
151
      struc rp cnt \\{ deflocal@proc .,rp cnt, \\}
152
      struc rd cnt \\{ deflocal@proc .,rd cnt, \\}
153
      struc rt cnt \\{ deflocal@proc .,rt cnt, \\}
154
      struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \}
155
   macro endl
156
   \{ purge label
157
      restruc db,du,dw,dp,dd,dt,dq
7294 dunkaist 158
      restruc rb,rw,rp,rd,rt,rq
2288 clevermous 159
      current = $-(localbase@proc)
7294 dunkaist 160
      end virtual \}
2288 clevermous 161
   macro ret operand
162
   \{ match any, operand \\{ retn operand \\}
163
      match , operand \\{ match epilogue:reglist, epilogue@proc: \\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \}
7294 dunkaist 164
   macro finish@proc
165
   \{ localbytes = current
166
      match close:reglist, close@proc: \\{ close name,flag,parmbytes,localbytes,reglist \\}
167
      end if \} }
168
2288 clevermous 169
 
170
 { common
171
    if ~ arg eq
172
   forward
173
     local ..arg,current@arg
174
     match argname:type, arg
175
      \{ current@arg equ argname
176
         label ..arg type
177
         argname equ ..arg
178
         if dqword eq type
179
           dd ?,?,?,?
180
         else if tbyte eq type
181
           dd ?,?,?
182
         else if qword eq type | pword eq type
183
           dd ?,?
184
         else
185
           dd ?
186
         end if \}
187
     match =current@arg,current@arg
188
      \{ current@arg equ arg
189
         arg equ ..arg
190
         ..arg dd ? \}
191
   common
192
     args@proc equ current@arg
193
   forward
194
     restore current@arg
195
   common
196
    end if }
197
198
 
7294 dunkaist 199
200
 
2288 clevermous 201
 { common
202
    match vars, all@vars \{ all@vars equ all@vars, \}
203
    all@vars equ all@vars name
204
   forward
205
    local ..var,..tmp
206
    ..var def val
207
    match =?, val \{ ..tmp equ \}
208
    match any =?, val \{ ..tmp equ \}
7294 dunkaist 209
    match any (=?), val \{ ..tmp equ \}
210
    match =label, def \{ ..tmp equ \}
211
    match tmp : value, ..tmp : val
2288 clevermous 212
     \{ tmp: end virtual
213
        initlocal@proc ..var,def value
214
        virtual at tmp\}
215
   common
216
    match first rest, ..var, \{ name equ first \} }
217
218
 
7294 dunkaist 219
220
 
2288 clevermous 221
 { virtual at name
222
    def
223
    size@initlocal = $ - name
224
   end virtual
225
   position@initlocal = 0
226
   while size@initlocal > position@initlocal
227
    virtual at name
228
     def
229
     if size@initlocal - position@initlocal < 2
230
      current@initlocal = 1
231
      load byte@initlocal byte from name+position@initlocal
232
     else if size@initlocal - position@initlocal < 4
233
      current@initlocal = 2
234
      load word@initlocal word from name+position@initlocal
235
     else
236
      current@initlocal = 4
237
      load dword@initlocal dword from name+position@initlocal
238
     end if
239
    end virtual
240
    if current@initlocal = 1
241
        mov     byte [name+position@initlocal], byte@initlocal
242
    else if current@initlocal = 2
243
        mov     word [name+position@initlocal], word@initlocal
244
    else
245
        mov     dword [name+position@initlocal], dword@initlocal
246
    end if
247
    position@initlocal = position@initlocal + current@initlocal
248
   end while }
249
250
 
251
 { purge ret,locals,endl
252
   finish@proc
253
   purge finish@proc
254
   restore regs@proc
255
   match all,args@proc \{ restore all \}
256
   restore args@proc
257
   match all,all@vars \{ restore all \} }
258
259
 
260
 { common
261
    locals
262
   forward done@local equ
263
    match varname[count]:vartype, var
264
    \{ match =BYTE, vartype \\{ varname rb count
265
                                restore done@local \\}
266
       match =WORD, vartype \\{ varname rw count
267
                                restore done@local \\}
268
       match =DWORD, vartype \\{ varname rd count
269
                                 restore done@local \\}
270
       match =PWORD, vartype \\{ varname rp count
271
                                 restore done@local \\}
272
       match =QWORD, vartype \\{ varname rq count
273
                                 restore done@local \\}
274
       match =TBYTE, vartype \\{ varname rt count
275
                                 restore done@local \\}
276
       match =DQWORD, vartype \\{ label varname dqword
277
                                  rq count+count
278
                                  restore done@local \\}
279
       match , done@local \\{ virtual
280
                               varname vartype
281
                              end virtual
282
                              rb count*sizeof.\#vartype
283
                              restore done@local \\} \}
284
    match :varname:vartype, done@local:var
285
    \{ match =BYTE, vartype \\{ varname db ?
286
                                restore done@local \\}
287
       match =WORD, vartype \\{ varname dw ?
288
                                restore done@local \\}
289
       match =DWORD, vartype \\{ varname dd ?
290
                                 restore done@local \\}
291
       match =PWORD, vartype \\{ varname dp ?
292
                                 restore done@local \\}
293
       match =QWORD, vartype \\{ varname dq ?
294
                                 restore done@local \\}
295
       match =TBYTE, vartype \\{ varname dt ?
296
                                 restore done@local \\}
297
       match =DQWORD, vartype \\{ label varname dqword
298
                                  dq ?,?
299
                                  restore done@local \\}
300
       match , done@local \\{ varname vartype
301
                              restore done@local \\} \}
302
    match ,done@local
303
    \{ var
304
       restore done@local \}
305
   common
306
    endl }
307