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