Subversion Repositories Kolibri OS

Rev

Rev 168 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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