Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2465 Serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
465 serge 7
 
593 mikedld 8
$Revision: 2465 $
9
 
10
 
168 serge 11
; Macroinstructions for defining and calling procedures
12
 
2434 Serge 13
macro stdcall proc,[arg]                ; directly call STDCALL procedure
168 serge 14
 { common
15
    if ~ arg eq
16
   reverse
2434 Serge 17
        pushd   arg
168 serge 18
   common
19
    end if
2434 Serge 20
        call    proc }
168 serge 21
 
2434 Serge 22
macro invoke proc,[arg]                 ; indirectly call STDCALL procedure
168 serge 23
 { common
24
    if ~ arg eq
25
   reverse
2434 Serge 26
        pushd   arg
168 serge 27
   common
28
    end if
2434 Serge 29
        call    [proc] }
168 serge 30
 
2434 Serge 31
macro ccall proc,[arg]                  ; directly call CDECL procedure
168 serge 32
 { common
33
    size@ccall = 0
34
    if ~ arg eq
35
   reverse
2434 Serge 36
        pushd   arg
168 serge 37
    size@ccall = size@ccall+4
38
   common
39
    end if
2434 Serge 40
        call    proc
168 serge 41
    if size@ccall
2434 Serge 42
        add     esp, size@ccall
168 serge 43
    end if }
44
 
2434 Serge 45
macro cinvoke proc,[arg]                ; indirectly call CDECL procedure
168 serge 46
 { common
47
    size@ccall = 0
48
    if ~ arg eq
49
   reverse
2434 Serge 50
        pushd   arg
168 serge 51
    size@ccall = size@ccall+4
52
   common
53
    end if
2434 Serge 54
        call    [proc]
168 serge 55
    if size@ccall
2434 Serge 56
        add     esp, size@ccall
168 serge 57
    end if }
58
 
2434 Serge 59
macro proc [args]                       ; define procedure
168 serge 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
2434 Serge 68
        push    ebp
69
        mov     ebp, esp
168 serge 70
    if localbytes
2434 Serge 71
        sub     esp, localbytes
168 serge 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
2434 Serge 81
        leave
168 serge 82
   end if
213 diamond 83
   if (flag and 10000b) | (parmbytes=0)
2434 Serge 84
        retn
168 serge 85
   else
2434 Serge 86
        retn    parmbytes
168 serge 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
2434 Serge 94
                                     flag = 11b \}
168 serge 95
   match =stdcall, statement \{ params equ
2434 Serge 96
                                flag = 11b \}
168 serge 97
   match =c args, statement \{ params equ args
2434 Serge 98
                               flag = 10001b \}
168 serge 99
   match =c, statement \{ params equ
2434 Serge 100
                          flag = 10001b \}
168 serge 101
   match =params, params \{ params equ statement
2434 Serge 102
                            flag = 0 \}
168 serge 103
   virtual at ebp+8
104
   match =uses reglist=,args, params \{ regs equ reglist
2434 Serge 105
                                        params equ args \}
168 serge 106
   match =regs =uses reglist, regs params \{ regs equ reglist
2434 Serge 107
                                             params equ \}
168 serge 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:
2434 Serge 142
                          \\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \}
168 serge 143
   macro finish@proc \{ localbytes = (((current-1) shr 2)+1) shl 2
2434 Serge 144
                        end if \} }
168 serge 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
2434 Serge 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 \}
168 serge 164
     match =current@arg,current@arg
165
      \{ current@arg equ arg
2434 Serge 166
         arg equ ..arg
167
         ..arg dd ? \}
168 serge 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
2434 Serge 186
        initlocal@proc ..var,def value
187
        virtual at tmp\}
168 serge 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
2434 Serge 212
        mov     byte [name+position@initlocal], byte@initlocal
168 serge 213
    else if current@initlocal = 2
2434 Serge 214
        mov     word [name+position@initlocal], word@initlocal
168 serge 215
    else
2434 Serge 216
        mov     dword [name+position@initlocal], dword@initlocal
168 serge 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
2434 Serge 236
                                restore done@local \\}
168 serge 237
       match =WORD, vartype \\{ varname rw count
2434 Serge 238
                                restore done@local \\}
168 serge 239
       match =DWORD, vartype \\{ varname rd count
2434 Serge 240
                                 restore done@local \\}
168 serge 241
       match =PWORD, vartype \\{ varname rp count
2434 Serge 242
                                 restore done@local \\}
168 serge 243
       match =QWORD, vartype \\{ varname rq count
2434 Serge 244
                                 restore done@local \\}
168 serge 245
       match =TBYTE, vartype \\{ varname rt count
2434 Serge 246
                                 restore done@local \\}
168 serge 247
       match =DQWORD, vartype \\{ label varname dqword
2434 Serge 248
                                  rq count+count
249
                                  restore done@local \\}
168 serge 250
       match , done@local \\{ virtual
2434 Serge 251
                               varname vartype
252
                              end virtual
253
                              rb count*sizeof.\#vartype
254
                              restore done@local \\} \}
168 serge 255
    match :varname:vartype, done@local:var
256
    \{ match =BYTE, vartype \\{ varname db ?
2434 Serge 257
                                restore done@local \\}
168 serge 258
       match =WORD, vartype \\{ varname dw ?
2434 Serge 259
                                restore done@local \\}
168 serge 260
       match =DWORD, vartype \\{ varname dd ?
2434 Serge 261
                                 restore done@local \\}
168 serge 262
       match =PWORD, vartype \\{ varname dp ?
2434 Serge 263
                                 restore done@local \\}
168 serge 264
       match =QWORD, vartype \\{ varname dq ?
2434 Serge 265
                                 restore done@local \\}
168 serge 266
       match =TBYTE, vartype \\{ varname dt ?
2434 Serge 267
                                 restore done@local \\}
168 serge 268
       match =DQWORD, vartype \\{ label varname dqword
2434 Serge 269
                                  dq ?,?
270
                                  restore done@local \\}
168 serge 271
       match , done@local \\{ varname vartype
2434 Serge 272
                              restore done@local \\} \}
168 serge 273
    match ,done@local
274
    \{ var
275
       restore done@local \}
276
   common
277
    endl }