Mercurial > pub > dyncall > dyncall
annotate dyncall/dyncall_callvm_x86.c @ 465:e2899b4ff713
- // -> /* */, mainly for consistency (but also for a few obscure compilers)
author | Tassilo Philipp |
---|---|
date | Wed, 02 Feb 2022 12:55:23 +0100 |
parents | ad5f9803f52f |
children | ddfb9577a00e |
rev | line source |
---|---|
0 | 1 /* |
2 | |
3 Package: dyncall | |
4 Library: dyncall | |
5 File: dyncall/dyncall_callvm_x86.c | |
6 Description: Call VM for x86 architecture implementation | |
7 License: | |
8 | |
339 | 9 Copyright (c) 2007-2020 Daniel Adler <dadler@uni-goettingen.de>, |
0 | 10 Tassilo Philipp <tphilipp@potion-studios.com> |
11 | |
12 Permission to use, copy, modify, and distribute this software for any | |
13 purpose with or without fee is hereby granted, provided that the above | |
14 copyright notice and this permission notice appear in all copies. | |
15 | |
16 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
17 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
18 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
19 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
22 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
23 | |
24 */ | |
25 | |
26 | |
27 | |
28 #include "dyncall_callvm_x86.h" | |
29 #include "dyncall_alloc.h" | |
30 | |
31 | |
366
ad5f9803f52f
- removal of some unnecessary headers that only contained internally used forward declarations, so no need to have them
Tassilo Philipp
parents:
365
diff
changeset
|
32 /* |
ad5f9803f52f
- removal of some unnecessary headers that only contained internally used forward declarations, so no need to have them
Tassilo Philipp
parents:
365
diff
changeset
|
33 ** x86 calling convention calls |
ad5f9803f52f
- removal of some unnecessary headers that only contained internally used forward declarations, so no need to have them
Tassilo Philipp
parents:
365
diff
changeset
|
34 ** |
ad5f9803f52f
- removal of some unnecessary headers that only contained internally used forward declarations, so no need to have them
Tassilo Philipp
parents:
365
diff
changeset
|
35 ** - hybrid return-type call (bool ... pointer) |
ad5f9803f52f
- removal of some unnecessary headers that only contained internally used forward declarations, so no need to have them
Tassilo Philipp
parents:
365
diff
changeset
|
36 ** |
ad5f9803f52f
- removal of some unnecessary headers that only contained internally used forward declarations, so no need to have them
Tassilo Philipp
parents:
365
diff
changeset
|
37 */ |
ad5f9803f52f
- removal of some unnecessary headers that only contained internally used forward declarations, so no need to have them
Tassilo Philipp
parents:
365
diff
changeset
|
38 |
ad5f9803f52f
- removal of some unnecessary headers that only contained internally used forward declarations, so no need to have them
Tassilo Philipp
parents:
365
diff
changeset
|
39 #if defined(DC__OS_Plan9) /* No support for other cconvs on Plan9 and vice-versa. */ |
ad5f9803f52f
- removal of some unnecessary headers that only contained internally used forward declarations, so no need to have them
Tassilo Philipp
parents:
365
diff
changeset
|
40 void dcCall_x86_plan9 (DCpointer target, DCpointer stackdata, DCsize size); |
ad5f9803f52f
- removal of some unnecessary headers that only contained internally used forward declarations, so no need to have them
Tassilo Philipp
parents:
365
diff
changeset
|
41 #else |
ad5f9803f52f
- removal of some unnecessary headers that only contained internally used forward declarations, so no need to have them
Tassilo Philipp
parents:
365
diff
changeset
|
42 void dcCall_x86_cdecl (DCpointer target, DCpointer stackdata, DCsize size); |
ad5f9803f52f
- removal of some unnecessary headers that only contained internally used forward declarations, so no need to have them
Tassilo Philipp
parents:
365
diff
changeset
|
43 void dcCall_x86_win32_std (DCpointer target, DCpointer stackdata, DCsize size); |
ad5f9803f52f
- removal of some unnecessary headers that only contained internally used forward declarations, so no need to have them
Tassilo Philipp
parents:
365
diff
changeset
|
44 void dcCall_x86_win32_fast (DCpointer target, DCpointer stackdata, DCsize size); |
ad5f9803f52f
- removal of some unnecessary headers that only contained internally used forward declarations, so no need to have them
Tassilo Philipp
parents:
365
diff
changeset
|
45 void dcCall_x86_win32_msthis (DCpointer target, DCpointer stackdata, DCsize size); |
ad5f9803f52f
- removal of some unnecessary headers that only contained internally used forward declarations, so no need to have them
Tassilo Philipp
parents:
365
diff
changeset
|
46 void dcCall_x86_syscall_int80h_linux(DCpointer target, DCpointer stackdata, DCsize size); |
ad5f9803f52f
- removal of some unnecessary headers that only contained internally used forward declarations, so no need to have them
Tassilo Philipp
parents:
365
diff
changeset
|
47 void dcCall_x86_syscall_int80h_bsd (DCpointer target, DCpointer stackdata, DCsize size); |
ad5f9803f52f
- removal of some unnecessary headers that only contained internally used forward declarations, so no need to have them
Tassilo Philipp
parents:
365
diff
changeset
|
48 #endif |
ad5f9803f52f
- removal of some unnecessary headers that only contained internally used forward declarations, so no need to have them
Tassilo Philipp
parents:
365
diff
changeset
|
49 |
ad5f9803f52f
- removal of some unnecessary headers that only contained internally used forward declarations, so no need to have them
Tassilo Philipp
parents:
365
diff
changeset
|
50 |
0 | 51 void dc_callvm_mode_x86(DCCallVM* in_self, DCint mode); |
52 | |
53 /* call vm destructor */ | |
54 | |
55 static void dc_callvm_free_x86(DCCallVM* in_self) | |
56 { | |
57 dcFreeMem(in_self); | |
58 } | |
59 | |
60 /* reset */ | |
61 | |
62 static void dc_callvm_reset_x86(DCCallVM* in_self) | |
63 { | |
64 DCCallVM_x86* self = (DCCallVM_x86*) in_self; | |
65 dcVecReset(&self->mVecHead); | |
66 self->mIntRegs = 0; | |
67 } | |
68 | |
69 /* arg (bool,char,short,long auto-promoted) to int */ | |
70 | |
71 static void dc_callvm_argInt_x86(DCCallVM* in_self, DCint x) | |
72 { | |
73 DCCallVM_x86* self = (DCCallVM_x86*) in_self; | |
74 dcVecAppend(&self->mVecHead, &x, sizeof(DCint) ); | |
75 } | |
76 | |
77 /* arg bool - promoted to int */ | |
78 | |
79 static void dc_callvm_argBool_x86(DCCallVM* in_self, DCbool x) | |
80 { | |
81 | |
82 DCint v = (DCint) x; | |
83 dc_callvm_argInt_x86(in_self, v); | |
84 } | |
85 | |
86 /* arg char - promoted to int */ | |
87 | |
88 static void dc_callvm_argChar_x86(DCCallVM* in_self, DCchar x) | |
89 { | |
90 DCint v = (DCint) x; | |
91 dc_callvm_argInt_x86(in_self, v); | |
92 } | |
93 | |
94 /* arg short - promoted to int */ | |
95 | |
96 static void dc_callvm_argShort_x86(DCCallVM* in_self, DCshort x) | |
97 { | |
98 DCint v = (DCint) x; | |
99 dc_callvm_argInt_x86(in_self, v); | |
100 } | |
101 | |
102 /* arg long - promoted to int */ | |
103 | |
104 static void dc_callvm_argLong_x86(DCCallVM* in_self, DClong x) | |
105 { | |
106 DCint v = (DCint) x; | |
107 dc_callvm_argInt_x86(in_self, v); | |
108 } | |
109 | |
110 /* arg long long */ | |
111 | |
112 static void dc_callvm_argLongLong_x86(DCCallVM* in_self, DClonglong x) | |
113 { | |
114 DCCallVM_x86* self = (DCCallVM_x86*) in_self; | |
115 dcVecAppend(&self->mVecHead, &x, sizeof(DClonglong) ); | |
116 } | |
117 | |
118 /* arg float */ | |
119 | |
120 static void dc_callvm_argFloat_x86(DCCallVM* in_self, DCfloat x) | |
121 { | |
122 DCCallVM_x86* self = (DCCallVM_x86*) in_self; | |
123 dcVecAppend(&self->mVecHead, &x, sizeof(DCfloat) ); | |
124 } | |
125 | |
126 /* arg double */ | |
127 | |
128 static void dc_callvm_argDouble_x86(DCCallVM* in_self, DCdouble x) | |
129 { | |
130 DCCallVM_x86* self = (DCCallVM_x86*) in_self; | |
131 dcVecAppend(&self->mVecHead, &x, sizeof(DCdouble) ); | |
132 } | |
133 | |
134 /* arg pointer */ | |
135 | |
136 static void dc_callvm_argPointer_x86(DCCallVM* in_self, DCpointer x) | |
137 { | |
138 DCCallVM_x86* self = (DCCallVM_x86*) in_self; | |
139 dcVecAppend(&self->mVecHead, &x, sizeof(DCpointer) ); | |
140 } | |
141 | |
142 | |
143 /* Plan9 specific calling convention. */ | |
144 #if defined(DC__OS_Plan9) | |
145 | |
146 /* call 'plan9' */ | |
147 | |
148 void dc_callvm_call_x86_plan9(DCCallVM* in_self, DCpointer target) | |
149 { | |
150 /* Calls with 32-bit return values have it returned via EAX, so we don't */ | |
151 /* need to do anything special here. */ | |
152 DCCallVM_x86* self = (DCCallVM_x86*) in_self; | |
153 dcCall_x86_plan9(target, dcVecData(&self->mVecHead), dcVecSize(&self->mVecHead)); | |
154 } | |
155 | |
156 DClonglong dc_callvm_call_x86_plan9_ll(DCCallVM* in_self, DCpointer target) | |
157 { | |
158 /* Call for 64 bit integer return values is a bit different, call a */ | |
159 /* different assembler stub that stores the return value in a variable */ | |
160 /* for us, and return the latter. */ | |
161 DClonglong ret; | |
162 DCCallVM_x86* self = (DCCallVM_x86*) in_self; | |
163 dcCall_x86_plan9_ll(target, dcVecData(&self->mVecHead), dcVecSize(&self->mVecHead), &ret ); | |
164 return ret; | |
165 } | |
166 | |
167 DCCallVM_vt gVT_x86_plan9 = | |
168 { | |
169 &dc_callvm_free_x86 | |
170 , &dc_callvm_reset_x86 | |
171 , &dc_callvm_mode_x86 | |
172 , &dc_callvm_argBool_x86 | |
173 , &dc_callvm_argChar_x86 | |
174 , &dc_callvm_argShort_x86 | |
175 , &dc_callvm_argInt_x86 | |
176 , &dc_callvm_argLong_x86 | |
177 , &dc_callvm_argLongLong_x86 | |
178 , &dc_callvm_argFloat_x86 | |
179 , &dc_callvm_argDouble_x86 | |
180 , &dc_callvm_argPointer_x86 | |
181 , NULL /* argStruct */ | |
182 , (DCvoidvmfunc*) &dc_callvm_call_x86_plan9 | |
183 , (DCboolvmfunc*) &dc_callvm_call_x86_plan9 | |
184 , (DCcharvmfunc*) &dc_callvm_call_x86_plan9 | |
185 , (DCshortvmfunc*) &dc_callvm_call_x86_plan9 | |
186 , (DCintvmfunc*) &dc_callvm_call_x86_plan9 | |
187 , (DClongvmfunc*) &dc_callvm_call_x86_plan9 | |
188 , (DClonglongvmfunc*) &dc_callvm_call_x86_plan9_ll | |
189 , (DCfloatvmfunc*) &dc_callvm_call_x86_plan9 | |
190 , (DCdoublevmfunc*) &dc_callvm_call_x86_plan9 | |
191 , (DCpointervmfunc*) &dc_callvm_call_x86_plan9 | |
192 , NULL /* callStruct */ | |
193 }; | |
194 | |
195 | |
196 #else | |
197 | |
198 | |
199 /* call 'cdecl' */ | |
200 | |
201 void dc_callvm_call_x86_cdecl(DCCallVM* in_self, DCpointer target) | |
202 { | |
203 DCCallVM_x86* self = (DCCallVM_x86*) in_self; | |
204 dcCall_x86_cdecl( target, dcVecData(&self->mVecHead), dcVecSize(&self->mVecHead) ); | |
205 } | |
206 | |
207 DCCallVM_vt gVT_x86_cdecl = | |
208 { | |
209 &dc_callvm_free_x86 | |
210 , &dc_callvm_reset_x86 | |
211 , &dc_callvm_mode_x86 | |
212 , &dc_callvm_argBool_x86 | |
213 , &dc_callvm_argChar_x86 | |
214 , &dc_callvm_argShort_x86 | |
215 , &dc_callvm_argInt_x86 | |
216 , &dc_callvm_argLong_x86 | |
217 , &dc_callvm_argLongLong_x86 | |
218 , &dc_callvm_argFloat_x86 | |
219 , &dc_callvm_argDouble_x86 | |
220 , &dc_callvm_argPointer_x86 | |
221 , NULL /* argStruct */ | |
222 , (DCvoidvmfunc*) &dc_callvm_call_x86_cdecl | |
223 , (DCboolvmfunc*) &dc_callvm_call_x86_cdecl | |
224 , (DCcharvmfunc*) &dc_callvm_call_x86_cdecl | |
225 , (DCshortvmfunc*) &dc_callvm_call_x86_cdecl | |
226 , (DCintvmfunc*) &dc_callvm_call_x86_cdecl | |
227 , (DClongvmfunc*) &dc_callvm_call_x86_cdecl | |
228 , (DClonglongvmfunc*) &dc_callvm_call_x86_cdecl | |
229 , (DCfloatvmfunc*) &dc_callvm_call_x86_cdecl | |
230 , (DCdoublevmfunc*) &dc_callvm_call_x86_cdecl | |
231 , (DCpointervmfunc*) &dc_callvm_call_x86_cdecl | |
232 , NULL /* callStruct */ | |
233 }; | |
234 | |
235 | |
236 | |
237 /* --- stdcall -------------------------------------------------------------- */ | |
238 | |
239 /* call win32/std */ | |
240 | |
241 void dc_callvm_call_x86_win32_std(DCCallVM* in_self, DCpointer target) | |
242 { | |
243 DCCallVM_x86* self = (DCCallVM_x86*) in_self; | |
244 dcCall_x86_win32_std( target, dcVecData(&self->mVecHead), dcVecSize(&self->mVecHead) ); | |
245 } | |
246 | |
247 /* win32/std vtable */ | |
248 | |
249 DCCallVM_vt gVT_x86_win32_std = | |
250 { | |
251 &dc_callvm_free_x86 | |
252 , &dc_callvm_reset_x86 | |
253 , &dc_callvm_mode_x86 | |
254 , &dc_callvm_argBool_x86 | |
255 , &dc_callvm_argChar_x86 | |
256 , &dc_callvm_argShort_x86 | |
257 , &dc_callvm_argInt_x86 | |
258 , &dc_callvm_argLong_x86 | |
259 , &dc_callvm_argLongLong_x86 | |
260 , &dc_callvm_argFloat_x86 | |
261 , &dc_callvm_argDouble_x86 | |
262 , &dc_callvm_argPointer_x86 | |
263 , NULL /* argStruct */ | |
264 , (DCvoidvmfunc*) &dc_callvm_call_x86_win32_std | |
265 , (DCboolvmfunc*) &dc_callvm_call_x86_win32_std | |
266 , (DCcharvmfunc*) &dc_callvm_call_x86_win32_std | |
267 , (DCshortvmfunc*) &dc_callvm_call_x86_win32_std | |
268 , (DCintvmfunc*) &dc_callvm_call_x86_win32_std | |
269 , (DClongvmfunc*) &dc_callvm_call_x86_win32_std | |
270 , (DClonglongvmfunc*) &dc_callvm_call_x86_win32_std | |
271 , (DCfloatvmfunc*) &dc_callvm_call_x86_win32_std | |
272 , (DCdoublevmfunc*) &dc_callvm_call_x86_win32_std | |
273 , (DCpointervmfunc*) &dc_callvm_call_x86_win32_std | |
274 , NULL /* callStruct */ | |
275 }; | |
276 | |
277 | |
278 /* --- fastcall common (ms/gnu) -------------------------------------------- */ | |
279 | |
280 /* call win32 ms fast */ | |
281 | |
282 static void dc_callvm_call_x86_win32_fast(DCCallVM* in_self, DCpointer target) | |
283 { | |
284 DCCallVM_x86* self = (DCCallVM_x86*) in_self; | |
285 dcCall_x86_win32_fast( target, dcVecData(&self->mVecHead), dcVecSize(&self->mVecHead) ); | |
286 } | |
287 | |
288 /* reset - always resize to 8 bytes (stores ECX and EDX) */ | |
289 | |
290 static void dc_callvm_reset_x86_win32_fast(DCCallVM* in_self) | |
291 { | |
292 DCCallVM_x86* self = (DCCallVM_x86*) in_self; | |
293 dcVecResize(&self->mVecHead, sizeof(DCint) * 2 ); | |
294 self->mIntRegs = 0; | |
295 } | |
296 | |
297 | |
298 /* --- fastcall ms --------------------------------------------------------- */ | |
299 | |
300 /* arg int - probably hold in ECX and EDX */ | |
301 | |
302 static void dc_callvm_argInt_x86_win32_fast_ms(DCCallVM* in_self, DCint x) | |
303 { | |
304 DCCallVM_x86* self = (DCCallVM_x86*) in_self; | |
305 if (self->mIntRegs < 2) { | |
306 *( (int*) dcVecAt(&self->mVecHead, sizeof(DCint) * self->mIntRegs ) ) = x; | |
307 ++( self->mIntRegs ); | |
308 } else | |
309 dcVecAppend(&self->mVecHead, &x, sizeof(DCint) ); | |
310 } | |
311 | |
312 /* arg bool - promote to int */ | |
313 | |
314 static void dc_callvm_argBool_x86_win32_fast_ms(DCCallVM* in_self, DCbool x) | |
315 { | |
316 DCint v = (DCint) x; | |
317 dc_callvm_argInt_x86_win32_fast_ms(in_self,v); | |
318 } | |
319 | |
320 /* arg char - promote to int */ | |
321 | |
322 static void dc_callvm_argChar_x86_win32_fast_ms(DCCallVM* in_self, DCchar x) | |
323 { | |
324 DCint v = (DCint) x; | |
325 dc_callvm_argInt_x86_win32_fast_ms(in_self,v); | |
326 } | |
327 | |
328 /* arg short - promote to int */ | |
329 | |
330 static void dc_callvm_argShort_x86_win32_fast_ms(DCCallVM* in_self, DCshort x) | |
331 { | |
332 DCint v = (DCint) x; | |
333 dc_callvm_argInt_x86_win32_fast_ms(in_self,v); | |
334 } | |
335 | |
336 /* arg long - promote to int */ | |
337 | |
338 static void dc_callvm_argLong_x86_win32_fast_ms(DCCallVM* in_self, DClong x) | |
339 { | |
340 DCint v = (DCint) x; | |
341 dc_callvm_argInt_x86_win32_fast_ms(in_self,v); | |
342 } | |
343 | |
344 /* arg pointer - promote to int */ | |
345 | |
346 static void dc_callvm_argPointer_x86_win32_fast_ms(DCCallVM* in_self, DCpointer x) | |
347 { | |
348 DCint v = (DCint) x; | |
349 dc_callvm_argInt_x86_win32_fast_ms(in_self,v); | |
350 } | |
351 | |
352 /* win32/fast vt */ | |
353 | |
354 DCCallVM_vt gVT_x86_win32_fast_ms = | |
355 { | |
356 &dc_callvm_free_x86 | |
357 , &dc_callvm_reset_x86_win32_fast | |
358 , &dc_callvm_mode_x86 | |
359 , &dc_callvm_argBool_x86_win32_fast_ms | |
360 , &dc_callvm_argChar_x86_win32_fast_ms | |
361 , &dc_callvm_argShort_x86_win32_fast_ms | |
362 , &dc_callvm_argInt_x86_win32_fast_ms | |
363 , &dc_callvm_argLong_x86_win32_fast_ms | |
364 , &dc_callvm_argLongLong_x86 | |
365 , &dc_callvm_argFloat_x86 | |
366 , &dc_callvm_argDouble_x86 | |
367 , &dc_callvm_argPointer_x86_win32_fast_ms | |
368 , NULL /* argStruct */ | |
369 , (DCvoidvmfunc*) &dc_callvm_call_x86_win32_fast | |
370 , (DCboolvmfunc*) &dc_callvm_call_x86_win32_fast | |
371 , (DCcharvmfunc*) &dc_callvm_call_x86_win32_fast | |
372 , (DCshortvmfunc*) &dc_callvm_call_x86_win32_fast | |
373 , (DCintvmfunc*) &dc_callvm_call_x86_win32_fast | |
374 , (DClongvmfunc*) &dc_callvm_call_x86_win32_fast | |
375 , (DClonglongvmfunc*) &dc_callvm_call_x86_win32_fast | |
376 , (DCfloatvmfunc*) &dc_callvm_call_x86_win32_fast | |
377 , (DCdoublevmfunc*) &dc_callvm_call_x86_win32_fast | |
378 , (DCpointervmfunc*) &dc_callvm_call_x86_win32_fast | |
379 , NULL /* callStruct */ | |
380 }; | |
381 | |
382 | |
383 /* --- gnu fastcall -------------------------------------------------------- */ | |
384 | |
385 /* arg int - probably hold in ECX and EDX */ | |
386 | |
387 static void dc_callvm_argInt_x86_win32_fast_gnu(DCCallVM* in_self, DCint x) | |
388 { | |
389 DCCallVM_x86* self = (DCCallVM_x86*) in_self; | |
390 if (self->mIntRegs < 2) { | |
391 *( (int*) dcVecAt(&self->mVecHead, sizeof(DCint) * self->mIntRegs ) ) = x; | |
392 ++( self->mIntRegs ); | |
393 } else | |
394 dcVecAppend(&self->mVecHead, &x, sizeof(DCint) ); | |
395 } | |
396 | |
397 /* arg bool - promote to int */ | |
398 | |
399 static void dc_callvm_argBool_x86_win32_fast_gnu(DCCallVM* in_self, DCbool x) | |
400 { | |
401 DCint v = (DCint) x; | |
402 dc_callvm_argInt_x86_win32_fast_gnu(in_self,v); | |
403 } | |
404 | |
405 /* arg char - promote to int */ | |
406 | |
407 static void dc_callvm_argChar_x86_win32_fast_gnu(DCCallVM* in_self, DCchar x) | |
408 { | |
409 DCint v = (DCint) x; | |
410 dc_callvm_argInt_x86_win32_fast_gnu(in_self,v); | |
411 } | |
412 | |
413 /* arg short - promote to int */ | |
414 | |
415 static void dc_callvm_argShort_x86_win32_fast_gnu(DCCallVM* in_self, DCshort x) | |
416 { | |
417 DCint v = (DCint) x; | |
418 dc_callvm_argInt_x86_win32_fast_gnu(in_self,v); | |
419 } | |
420 | |
421 /* arg long - promote to int */ | |
422 | |
423 static void dc_callvm_argLong_x86_win32_fast_gnu(DCCallVM* in_self, DClong x) | |
424 { | |
425 DCint v = (DCint) x; | |
426 dc_callvm_argInt_x86_win32_fast_gnu(in_self,v); | |
427 } | |
428 | |
429 /* arg pointer - promote to int */ | |
430 | |
431 static void dc_callvm_argPointer_x86_win32_fast_gnu(DCCallVM* in_self, DCpointer x) | |
432 { | |
433 DCint v = (DCint) x; | |
434 dc_callvm_argInt_x86_win32_fast_gnu(in_self,v); | |
435 } | |
436 | |
437 /* arg long long - skip registers and push on stack */ | |
438 | |
439 static void dc_callvm_argLongLong_x86_win32_fast_gnu(DCCallVM* in_self, DClonglong x) | |
440 { | |
441 DCCallVM_x86* self = (DCCallVM_x86*) in_self; | |
442 self->mIntRegs = 2; | |
443 dc_callvm_argLongLong_x86(in_self,x); | |
444 } | |
445 | |
446 /* win32/fast/gnu vt */ | |
447 | |
448 DCCallVM_vt gVT_x86_win32_fast_gnu = | |
449 { | |
450 &dc_callvm_free_x86 | |
451 , &dc_callvm_reset_x86_win32_fast | |
452 , &dc_callvm_mode_x86 | |
453 , &dc_callvm_argBool_x86_win32_fast_gnu | |
454 , &dc_callvm_argChar_x86_win32_fast_gnu | |
455 , &dc_callvm_argShort_x86_win32_fast_gnu | |
456 , &dc_callvm_argInt_x86_win32_fast_gnu | |
457 , &dc_callvm_argLong_x86_win32_fast_gnu | |
458 , &dc_callvm_argLongLong_x86_win32_fast_gnu | |
459 , &dc_callvm_argFloat_x86 | |
460 , &dc_callvm_argDouble_x86 | |
461 , &dc_callvm_argPointer_x86_win32_fast_gnu | |
462 , NULL /* argStruct */ | |
463 , (DCvoidvmfunc*) &dc_callvm_call_x86_win32_fast | |
464 , (DCboolvmfunc*) &dc_callvm_call_x86_win32_fast | |
465 , (DCcharvmfunc*) &dc_callvm_call_x86_win32_fast | |
466 , (DCshortvmfunc*) &dc_callvm_call_x86_win32_fast | |
467 , (DCintvmfunc*) &dc_callvm_call_x86_win32_fast | |
468 , (DClongvmfunc*) &dc_callvm_call_x86_win32_fast | |
469 , (DClonglongvmfunc*) &dc_callvm_call_x86_win32_fast | |
470 , (DCfloatvmfunc*) &dc_callvm_call_x86_win32_fast | |
471 , (DCdoublevmfunc*) &dc_callvm_call_x86_win32_fast | |
472 , (DCpointervmfunc*) &dc_callvm_call_x86_win32_fast | |
473 , NULL /* callStruct */ | |
474 }; | |
475 | |
476 | |
477 /* --- this ms ------------------------------------------------------------- */ | |
478 | |
479 /* call win32/this/ms */ | |
480 | |
481 void dc_callvm_call_x86_win32_this_ms(DCCallVM* in_self, DCpointer target) | |
482 { | |
483 DCCallVM_x86* self = (DCCallVM_x86*) in_self; | |
484 dcCall_x86_win32_msthis( target, dcVecData(&self->mVecHead), dcVecSize(&self->mVecHead) ); | |
485 } | |
486 | |
487 /* win32/this/ms vt */ | |
488 | |
489 DCCallVM_vt gVT_x86_win32_this_ms = | |
490 { | |
491 &dc_callvm_free_x86 | |
492 , &dc_callvm_reset_x86 | |
493 , &dc_callvm_mode_x86 | |
494 , &dc_callvm_argBool_x86 | |
495 , &dc_callvm_argChar_x86 | |
496 , &dc_callvm_argShort_x86 | |
497 , &dc_callvm_argInt_x86 | |
498 , &dc_callvm_argLong_x86 | |
499 , &dc_callvm_argLongLong_x86 | |
500 , &dc_callvm_argFloat_x86 | |
501 , &dc_callvm_argDouble_x86 | |
502 , &dc_callvm_argPointer_x86 | |
503 , NULL /* argStruct */ | |
504 , (DCvoidvmfunc*) &dc_callvm_call_x86_win32_this_ms | |
505 , (DCboolvmfunc*) &dc_callvm_call_x86_win32_this_ms | |
506 , (DCcharvmfunc*) &dc_callvm_call_x86_win32_this_ms | |
507 , (DCshortvmfunc*) &dc_callvm_call_x86_win32_this_ms | |
508 , (DCintvmfunc*) &dc_callvm_call_x86_win32_this_ms | |
509 , (DClongvmfunc*) &dc_callvm_call_x86_win32_this_ms | |
510 , (DClonglongvmfunc*) &dc_callvm_call_x86_win32_this_ms | |
511 , (DCfloatvmfunc*) &dc_callvm_call_x86_win32_this_ms | |
512 , (DCdoublevmfunc*) &dc_callvm_call_x86_win32_this_ms | |
513 , (DCpointervmfunc*) &dc_callvm_call_x86_win32_this_ms | |
514 , NULL /* callStruct */ | |
515 }; | |
516 | |
517 /* --- syscall ------------------------------------------------------------- */ | |
518 | |
519 /* call syscall */ | |
520 | |
341 | 521 void dc_callvm_call_x86_syscall_int80h_linux(DCCallVM* in_self, DCpointer target) |
0 | 522 { |
523 DCCallVM_x86* self = (DCCallVM_x86*) in_self; | |
341 | 524 dcCall_x86_syscall_int80h_linux( target, dcVecData(&self->mVecHead), dcVecSize(&self->mVecHead) ); |
0 | 525 } |
526 | |
341 | 527 void dc_callvm_call_x86_syscall_int80h_bsd(DCCallVM* in_self, DCpointer target) |
0 | 528 { |
529 DCCallVM_x86* self = (DCCallVM_x86*) in_self; | |
341 | 530 dcCall_x86_syscall_int80h_bsd( target, dcVecData(&self->mVecHead), dcVecSize(&self->mVecHead) ); |
0 | 531 } |
532 | |
341 | 533 DCCallVM_vt gVT_x86_syscall_int80h_linux = |
0 | 534 { |
535 &dc_callvm_free_x86 | |
536 , &dc_callvm_reset_x86 | |
537 , &dc_callvm_mode_x86 | |
538 , &dc_callvm_argBool_x86 | |
539 , &dc_callvm_argChar_x86 | |
540 , &dc_callvm_argShort_x86 | |
541 , &dc_callvm_argInt_x86 | |
542 , &dc_callvm_argLong_x86 | |
543 , &dc_callvm_argLongLong_x86 | |
544 , &dc_callvm_argFloat_x86 | |
545 , &dc_callvm_argDouble_x86 | |
546 , &dc_callvm_argPointer_x86 | |
547 , NULL /* argStruct */ | |
341 | 548 , (DCvoidvmfunc*) &dc_callvm_call_x86_syscall_int80h_linux |
549 , (DCboolvmfunc*) &dc_callvm_call_x86_syscall_int80h_linux | |
550 , (DCcharvmfunc*) &dc_callvm_call_x86_syscall_int80h_linux | |
551 , (DCshortvmfunc*) &dc_callvm_call_x86_syscall_int80h_linux | |
552 , (DCintvmfunc*) &dc_callvm_call_x86_syscall_int80h_linux | |
553 , (DClongvmfunc*) &dc_callvm_call_x86_syscall_int80h_linux | |
554 , (DClonglongvmfunc*) &dc_callvm_call_x86_syscall_int80h_linux | |
555 , (DCfloatvmfunc*) &dc_callvm_call_x86_syscall_int80h_linux | |
556 , (DCdoublevmfunc*) &dc_callvm_call_x86_syscall_int80h_linux | |
557 , (DCpointervmfunc*) &dc_callvm_call_x86_syscall_int80h_linux | |
0 | 558 , NULL /* callStruct */ |
559 }; | |
560 | |
341 | 561 DCCallVM_vt gVT_x86_syscall_int80h_bsd = |
0 | 562 { |
563 &dc_callvm_free_x86 | |
564 , &dc_callvm_reset_x86 | |
565 , &dc_callvm_mode_x86 | |
566 , &dc_callvm_argBool_x86 | |
567 , &dc_callvm_argChar_x86 | |
568 , &dc_callvm_argShort_x86 | |
569 , &dc_callvm_argInt_x86 | |
570 , &dc_callvm_argLong_x86 | |
571 , &dc_callvm_argLongLong_x86 | |
572 , &dc_callvm_argFloat_x86 | |
573 , &dc_callvm_argDouble_x86 | |
574 , &dc_callvm_argPointer_x86 | |
575 , NULL /* argStruct */ | |
341 | 576 , (DCvoidvmfunc*) &dc_callvm_call_x86_syscall_int80h_bsd |
577 , (DCboolvmfunc*) &dc_callvm_call_x86_syscall_int80h_bsd | |
578 , (DCcharvmfunc*) &dc_callvm_call_x86_syscall_int80h_bsd | |
579 , (DCshortvmfunc*) &dc_callvm_call_x86_syscall_int80h_bsd | |
580 , (DCintvmfunc*) &dc_callvm_call_x86_syscall_int80h_bsd | |
581 , (DClongvmfunc*) &dc_callvm_call_x86_syscall_int80h_bsd | |
582 , (DClonglongvmfunc*) &dc_callvm_call_x86_syscall_int80h_bsd | |
583 , (DCfloatvmfunc*) &dc_callvm_call_x86_syscall_int80h_bsd | |
584 , (DCdoublevmfunc*) &dc_callvm_call_x86_syscall_int80h_bsd | |
585 , (DCpointervmfunc*) &dc_callvm_call_x86_syscall_int80h_bsd | |
0 | 586 , NULL /* callStruct */ |
587 }; | |
588 | |
589 | |
590 #endif | |
591 | |
592 | |
593 /* mode */ | |
594 | |
595 void dc_callvm_mode_x86(DCCallVM* in_self, DCint mode) | |
596 { | |
84 | 597 DCCallVM_x86* self = (DCCallVM_x86*)in_self; |
598 DCCallVM_vt* vt; | |
599 | |
0 | 600 switch(mode) { |
84 | 601 case DC_CALL_C_DEFAULT: |
0 | 602 case DC_CALL_C_ELLIPSIS: |
603 case DC_CALL_C_ELLIPSIS_VARARGS: | |
84 | 604 /* Plan9 (and forks) have their own calling convention (and no support for foreign ones). */ |
605 #if defined(DC_PLAN9) | |
0 | 606 case DC_CALL_C_X86_PLAN9: vt = &gVT_x86_plan9; break; |
607 #else | |
465
e2899b4ff713
- // -> /* */, mainly for consistency (but also for a few obscure compilers)
Tassilo Philipp
parents:
366
diff
changeset
|
608 case DC_CALL_C_X86_CDECL: vt = &gVT_x86_cdecl; break; /* also handles DC_CALL_C_X86_WIN32_THIS_GNU */ |
0 | 609 case DC_CALL_C_X86_WIN32_STD: vt = &gVT_x86_win32_std; break; |
610 case DC_CALL_C_X86_WIN32_FAST_MS: vt = &gVT_x86_win32_fast_ms; break; | |
611 case DC_CALL_C_X86_WIN32_THIS_MS: vt = &gVT_x86_win32_this_ms; break; | |
612 case DC_CALL_C_X86_WIN32_FAST_GNU: vt = &gVT_x86_win32_fast_gnu; break; | |
339 | 613 case DC_CALL_SYS_DEFAULT: |
0 | 614 # if defined DC_UNIX |
615 # if defined DC__OS_Linux | |
341 | 616 vt = &gVT_x86_syscall_int80h_linux; break; |
0 | 617 # else |
341 | 618 vt = &gVT_x86_syscall_int80h_bsd; break; |
0 | 619 # endif |
620 # else | |
621 self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; return; | |
622 # endif | |
341 | 623 case DC_CALL_SYS_X86_INT80H_LINUX: vt = &gVT_x86_syscall_int80h_linux; break; |
624 case DC_CALL_SYS_X86_INT80H_BSD: vt = &gVT_x86_syscall_int80h_bsd; break; | |
0 | 625 #endif |
626 default: | |
84 | 627 self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; |
628 return; | |
0 | 629 } |
84 | 630 dc_callvm_base_init(&self->mInterface, vt); |
0 | 631 } |
632 | |
84 | 633 /* Public API. */ |
0 | 634 DCCallVM* dcNewCallVM(DCsize size) |
635 { | |
84 | 636 DCCallVM_x86* p = (DCCallVM_x86*)dcAllocMem(sizeof(DCCallVM_x86)+size); |
637 | |
638 dc_callvm_mode_x86((DCCallVM*)p, DC_CALL_C_DEFAULT); | |
639 | |
640 dcVecInit(&p->mVecHead, size); | |
641 dc_callvm_reset_x86((DCCallVM*)p); | |
642 | |
643 return (DCCallVM*)p; | |
0 | 644 } |
645 |