Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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