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