comparison dyncall/dyncall_callvm_x86.c @ 0:3e629dc19168

initial from svn dyncall-1745
author Daniel Adler
date Thu, 19 Mar 2015 22:24:28 +0100
parents
children 67961454902b
comparison
equal deleted inserted replaced
-1:000000000000 0:3e629dc19168
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
9 Copyright (c) 2007-2015 Daniel Adler <dadler@uni-goettingen.de>,
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
32 void dc_callvm_mode_x86(DCCallVM* in_self, DCint mode);
33
34 /* call vm allocator */
35
36 static DCCallVM* dc_callvm_new_x86(DCCallVM_vt* vt, DCsize size)
37 {
38 DCCallVM_x86* self = (DCCallVM_x86*) dcAllocMem( sizeof(DCCallVM_x86)+size );
39
40 dc_callvm_base_init(&self->mInterface, vt);
41
42 self->mIntRegs = 0;
43 dcVecInit(&self->mVecHead, size);
44 return (DCCallVM*) self;
45 }
46
47 /* call vm destructor */
48
49 static void dc_callvm_free_x86(DCCallVM* in_self)
50 {
51 dcFreeMem(in_self);
52 }
53
54 /* reset */
55
56 static void dc_callvm_reset_x86(DCCallVM* in_self)
57 {
58 DCCallVM_x86* self = (DCCallVM_x86*) in_self;
59 dcVecReset(&self->mVecHead);
60 self->mIntRegs = 0;
61 }
62
63 /* arg (bool,char,short,long auto-promoted) to int */
64
65 static void dc_callvm_argInt_x86(DCCallVM* in_self, DCint x)
66 {
67 DCCallVM_x86* self = (DCCallVM_x86*) in_self;
68 dcVecAppend(&self->mVecHead, &x, sizeof(DCint) );
69 }
70
71 /* arg bool - promoted to int */
72
73 static void dc_callvm_argBool_x86(DCCallVM* in_self, DCbool x)
74 {
75
76 DCint v = (DCint) x;
77 dc_callvm_argInt_x86(in_self, v);
78 }
79
80 /* arg char - promoted to int */
81
82 static void dc_callvm_argChar_x86(DCCallVM* in_self, DCchar x)
83 {
84 DCint v = (DCint) x;
85 dc_callvm_argInt_x86(in_self, v);
86 }
87
88 /* arg short - promoted to int */
89
90 static void dc_callvm_argShort_x86(DCCallVM* in_self, DCshort x)
91 {
92 DCint v = (DCint) x;
93 dc_callvm_argInt_x86(in_self, v);
94 }
95
96 /* arg long - promoted to int */
97
98 static void dc_callvm_argLong_x86(DCCallVM* in_self, DClong x)
99 {
100 DCint v = (DCint) x;
101 dc_callvm_argInt_x86(in_self, v);
102 }
103
104 /* arg long long */
105
106 static void dc_callvm_argLongLong_x86(DCCallVM* in_self, DClonglong x)
107 {
108 DCCallVM_x86* self = (DCCallVM_x86*) in_self;
109 dcVecAppend(&self->mVecHead, &x, sizeof(DClonglong) );
110 }
111
112 /* arg float */
113
114 static void dc_callvm_argFloat_x86(DCCallVM* in_self, DCfloat x)
115 {
116 DCCallVM_x86* self = (DCCallVM_x86*) in_self;
117 dcVecAppend(&self->mVecHead, &x, sizeof(DCfloat) );
118 }
119
120 /* arg double */
121
122 static void dc_callvm_argDouble_x86(DCCallVM* in_self, DCdouble x)
123 {
124 DCCallVM_x86* self = (DCCallVM_x86*) in_self;
125 dcVecAppend(&self->mVecHead, &x, sizeof(DCdouble) );
126 }
127
128 /* arg pointer */
129
130 static void dc_callvm_argPointer_x86(DCCallVM* in_self, DCpointer x)
131 {
132 DCCallVM_x86* self = (DCCallVM_x86*) in_self;
133 dcVecAppend(&self->mVecHead, &x, sizeof(DCpointer) );
134 }
135
136
137 /* Plan9 specific calling convention. */
138 #if defined(DC__OS_Plan9)
139
140 /* call 'plan9' */
141
142 void dc_callvm_call_x86_plan9(DCCallVM* in_self, DCpointer target)
143 {
144 /* Calls with 32-bit return values have it returned via EAX, so we don't */
145 /* need to do anything special here. */
146 DCCallVM_x86* self = (DCCallVM_x86*) in_self;
147 dcCall_x86_plan9(target, dcVecData(&self->mVecHead), dcVecSize(&self->mVecHead));
148 }
149
150 DClonglong dc_callvm_call_x86_plan9_ll(DCCallVM* in_self, DCpointer target)
151 {
152 /* Call for 64 bit integer return values is a bit different, call a */
153 /* different assembler stub that stores the return value in a variable */
154 /* for us, and return the latter. */
155 DClonglong ret;
156 DCCallVM_x86* self = (DCCallVM_x86*) in_self;
157 dcCall_x86_plan9_ll(target, dcVecData(&self->mVecHead), dcVecSize(&self->mVecHead), &ret );
158 return ret;
159 }
160
161 DCCallVM_vt gVT_x86_plan9 =
162 {
163 &dc_callvm_free_x86
164 , &dc_callvm_reset_x86
165 , &dc_callvm_mode_x86
166 , &dc_callvm_argBool_x86
167 , &dc_callvm_argChar_x86
168 , &dc_callvm_argShort_x86
169 , &dc_callvm_argInt_x86
170 , &dc_callvm_argLong_x86
171 , &dc_callvm_argLongLong_x86
172 , &dc_callvm_argFloat_x86
173 , &dc_callvm_argDouble_x86
174 , &dc_callvm_argPointer_x86
175 , NULL /* argStruct */
176 , (DCvoidvmfunc*) &dc_callvm_call_x86_plan9
177 , (DCboolvmfunc*) &dc_callvm_call_x86_plan9
178 , (DCcharvmfunc*) &dc_callvm_call_x86_plan9
179 , (DCshortvmfunc*) &dc_callvm_call_x86_plan9
180 , (DCintvmfunc*) &dc_callvm_call_x86_plan9
181 , (DClongvmfunc*) &dc_callvm_call_x86_plan9
182 , (DClonglongvmfunc*) &dc_callvm_call_x86_plan9_ll
183 , (DCfloatvmfunc*) &dc_callvm_call_x86_plan9
184 , (DCdoublevmfunc*) &dc_callvm_call_x86_plan9
185 , (DCpointervmfunc*) &dc_callvm_call_x86_plan9
186 , NULL /* callStruct */
187 };
188
189 DCCallVM* dcNewCallVM_x86_plan9(DCsize size)
190 {
191 return dc_callvm_new_x86( &gVT_x86_plan9, size );
192 }
193
194
195 #else
196
197
198 /* call 'cdecl' */
199
200 void dc_callvm_call_x86_cdecl(DCCallVM* in_self, DCpointer target)
201 {
202 DCCallVM_x86* self = (DCCallVM_x86*) in_self;
203 dcCall_x86_cdecl( target, dcVecData(&self->mVecHead), dcVecSize(&self->mVecHead) );
204 }
205
206 DCCallVM_vt gVT_x86_cdecl =
207 {
208 &dc_callvm_free_x86
209 , &dc_callvm_reset_x86
210 , &dc_callvm_mode_x86
211 , &dc_callvm_argBool_x86
212 , &dc_callvm_argChar_x86
213 , &dc_callvm_argShort_x86
214 , &dc_callvm_argInt_x86
215 , &dc_callvm_argLong_x86
216 , &dc_callvm_argLongLong_x86
217 , &dc_callvm_argFloat_x86
218 , &dc_callvm_argDouble_x86
219 , &dc_callvm_argPointer_x86
220 , NULL /* argStruct */
221 , (DCvoidvmfunc*) &dc_callvm_call_x86_cdecl
222 , (DCboolvmfunc*) &dc_callvm_call_x86_cdecl
223 , (DCcharvmfunc*) &dc_callvm_call_x86_cdecl
224 , (DCshortvmfunc*) &dc_callvm_call_x86_cdecl
225 , (DCintvmfunc*) &dc_callvm_call_x86_cdecl
226 , (DClongvmfunc*) &dc_callvm_call_x86_cdecl
227 , (DClonglongvmfunc*) &dc_callvm_call_x86_cdecl
228 , (DCfloatvmfunc*) &dc_callvm_call_x86_cdecl
229 , (DCdoublevmfunc*) &dc_callvm_call_x86_cdecl
230 , (DCpointervmfunc*) &dc_callvm_call_x86_cdecl
231 , NULL /* callStruct */
232 };
233
234 DCCallVM* dcNewCallVM_x86_cdecl(DCsize size)
235 {
236 return dc_callvm_new_x86( &gVT_x86_cdecl, size );
237 }
238
239
240
241 /* --- stdcall -------------------------------------------------------------- */
242
243 /* call win32/std */
244
245 void dc_callvm_call_x86_win32_std(DCCallVM* in_self, DCpointer target)
246 {
247 DCCallVM_x86* self = (DCCallVM_x86*) in_self;
248 dcCall_x86_win32_std( target, dcVecData(&self->mVecHead), dcVecSize(&self->mVecHead) );
249 }
250
251 /* win32/std vtable */
252
253 DCCallVM_vt gVT_x86_win32_std =
254 {
255 &dc_callvm_free_x86
256 , &dc_callvm_reset_x86
257 , &dc_callvm_mode_x86
258 , &dc_callvm_argBool_x86
259 , &dc_callvm_argChar_x86
260 , &dc_callvm_argShort_x86
261 , &dc_callvm_argInt_x86
262 , &dc_callvm_argLong_x86
263 , &dc_callvm_argLongLong_x86
264 , &dc_callvm_argFloat_x86
265 , &dc_callvm_argDouble_x86
266 , &dc_callvm_argPointer_x86
267 , NULL /* argStruct */
268 , (DCvoidvmfunc*) &dc_callvm_call_x86_win32_std
269 , (DCboolvmfunc*) &dc_callvm_call_x86_win32_std
270 , (DCcharvmfunc*) &dc_callvm_call_x86_win32_std
271 , (DCshortvmfunc*) &dc_callvm_call_x86_win32_std
272 , (DCintvmfunc*) &dc_callvm_call_x86_win32_std
273 , (DClongvmfunc*) &dc_callvm_call_x86_win32_std
274 , (DClonglongvmfunc*) &dc_callvm_call_x86_win32_std
275 , (DCfloatvmfunc*) &dc_callvm_call_x86_win32_std
276 , (DCdoublevmfunc*) &dc_callvm_call_x86_win32_std
277 , (DCpointervmfunc*) &dc_callvm_call_x86_win32_std
278 , NULL /* callStruct */
279 };
280
281 /* win32/std callvm allocator */
282
283 DCCallVM* dcNewCallVM_x86_win32_std(DCsize size)
284 {
285 return dc_callvm_new_x86( &gVT_x86_win32_std, size );
286 }
287
288 /* --- fastcall common (ms/gnu) -------------------------------------------- */
289
290 /* call win32 ms fast */
291
292 static void dc_callvm_call_x86_win32_fast(DCCallVM* in_self, DCpointer target)
293 {
294 DCCallVM_x86* self = (DCCallVM_x86*) in_self;
295 dcCall_x86_win32_fast( target, dcVecData(&self->mVecHead), dcVecSize(&self->mVecHead) );
296 }
297
298 /* reset - always resize to 8 bytes (stores ECX and EDX) */
299
300 static void dc_callvm_reset_x86_win32_fast(DCCallVM* in_self)
301 {
302 DCCallVM_x86* self = (DCCallVM_x86*) in_self;
303 dcVecResize(&self->mVecHead, sizeof(DCint) * 2 );
304 self->mIntRegs = 0;
305 }
306
307
308 /* --- fastcall ms --------------------------------------------------------- */
309
310 /* arg int - probably hold in ECX and EDX */
311
312 static void dc_callvm_argInt_x86_win32_fast_ms(DCCallVM* in_self, DCint x)
313 {
314 DCCallVM_x86* self = (DCCallVM_x86*) in_self;
315 if (self->mIntRegs < 2) {
316 *( (int*) dcVecAt(&self->mVecHead, sizeof(DCint) * self->mIntRegs ) ) = x;
317 ++( self->mIntRegs );
318 } else
319 dcVecAppend(&self->mVecHead, &x, sizeof(DCint) );
320 }
321
322 /* arg bool - promote to int */
323
324 static void dc_callvm_argBool_x86_win32_fast_ms(DCCallVM* in_self, DCbool x)
325 {
326 DCint v = (DCint) x;
327 dc_callvm_argInt_x86_win32_fast_ms(in_self,v);
328 }
329
330 /* arg char - promote to int */
331
332 static void dc_callvm_argChar_x86_win32_fast_ms(DCCallVM* in_self, DCchar x)
333 {
334 DCint v = (DCint) x;
335 dc_callvm_argInt_x86_win32_fast_ms(in_self,v);
336 }
337
338 /* arg short - promote to int */
339
340 static void dc_callvm_argShort_x86_win32_fast_ms(DCCallVM* in_self, DCshort x)
341 {
342 DCint v = (DCint) x;
343 dc_callvm_argInt_x86_win32_fast_ms(in_self,v);
344 }
345
346 /* arg long - promote to int */
347
348 static void dc_callvm_argLong_x86_win32_fast_ms(DCCallVM* in_self, DClong x)
349 {
350 DCint v = (DCint) x;
351 dc_callvm_argInt_x86_win32_fast_ms(in_self,v);
352 }
353
354 /* arg pointer - promote to int */
355
356 static void dc_callvm_argPointer_x86_win32_fast_ms(DCCallVM* in_self, DCpointer x)
357 {
358 DCint v = (DCint) x;
359 dc_callvm_argInt_x86_win32_fast_ms(in_self,v);
360 }
361
362 /* win32/fast vt */
363
364 DCCallVM_vt gVT_x86_win32_fast_ms =
365 {
366 &dc_callvm_free_x86
367 , &dc_callvm_reset_x86_win32_fast
368 , &dc_callvm_mode_x86
369 , &dc_callvm_argBool_x86_win32_fast_ms
370 , &dc_callvm_argChar_x86_win32_fast_ms
371 , &dc_callvm_argShort_x86_win32_fast_ms
372 , &dc_callvm_argInt_x86_win32_fast_ms
373 , &dc_callvm_argLong_x86_win32_fast_ms
374 , &dc_callvm_argLongLong_x86
375 , &dc_callvm_argFloat_x86
376 , &dc_callvm_argDouble_x86
377 , &dc_callvm_argPointer_x86_win32_fast_ms
378 , NULL /* argStruct */
379 , (DCvoidvmfunc*) &dc_callvm_call_x86_win32_fast
380 , (DCboolvmfunc*) &dc_callvm_call_x86_win32_fast
381 , (DCcharvmfunc*) &dc_callvm_call_x86_win32_fast
382 , (DCshortvmfunc*) &dc_callvm_call_x86_win32_fast
383 , (DCintvmfunc*) &dc_callvm_call_x86_win32_fast
384 , (DClongvmfunc*) &dc_callvm_call_x86_win32_fast
385 , (DClonglongvmfunc*) &dc_callvm_call_x86_win32_fast
386 , (DCfloatvmfunc*) &dc_callvm_call_x86_win32_fast
387 , (DCdoublevmfunc*) &dc_callvm_call_x86_win32_fast
388 , (DCpointervmfunc*) &dc_callvm_call_x86_win32_fast
389 , NULL /* callStruct */
390 };
391
392 DCCallVM* dcNewCallVM_x86_win32_fast_ms(DCsize size)
393 {
394 return dc_callvm_new_x86( &gVT_x86_win32_fast_ms, size );
395 }
396
397 /* --- gnu fastcall -------------------------------------------------------- */
398
399 /* arg int - probably hold in ECX and EDX */
400
401 static void dc_callvm_argInt_x86_win32_fast_gnu(DCCallVM* in_self, DCint x)
402 {
403 DCCallVM_x86* self = (DCCallVM_x86*) in_self;
404 if (self->mIntRegs < 2) {
405 *( (int*) dcVecAt(&self->mVecHead, sizeof(DCint) * self->mIntRegs ) ) = x;
406 ++( self->mIntRegs );
407 } else
408 dcVecAppend(&self->mVecHead, &x, sizeof(DCint) );
409 }
410
411 /* arg bool - promote to int */
412
413 static void dc_callvm_argBool_x86_win32_fast_gnu(DCCallVM* in_self, DCbool x)
414 {
415 DCint v = (DCint) x;
416 dc_callvm_argInt_x86_win32_fast_gnu(in_self,v);
417 }
418
419 /* arg char - promote to int */
420
421 static void dc_callvm_argChar_x86_win32_fast_gnu(DCCallVM* in_self, DCchar x)
422 {
423 DCint v = (DCint) x;
424 dc_callvm_argInt_x86_win32_fast_gnu(in_self,v);
425 }
426
427 /* arg short - promote to int */
428
429 static void dc_callvm_argShort_x86_win32_fast_gnu(DCCallVM* in_self, DCshort x)
430 {
431 DCint v = (DCint) x;
432 dc_callvm_argInt_x86_win32_fast_gnu(in_self,v);
433 }
434
435 /* arg long - promote to int */
436
437 static void dc_callvm_argLong_x86_win32_fast_gnu(DCCallVM* in_self, DClong x)
438 {
439 DCint v = (DCint) x;
440 dc_callvm_argInt_x86_win32_fast_gnu(in_self,v);
441 }
442
443 /* arg pointer - promote to int */
444
445 static void dc_callvm_argPointer_x86_win32_fast_gnu(DCCallVM* in_self, DCpointer x)
446 {
447 DCint v = (DCint) x;
448 dc_callvm_argInt_x86_win32_fast_gnu(in_self,v);
449 }
450
451 /* arg long long - skip registers and push on stack */
452
453 static void dc_callvm_argLongLong_x86_win32_fast_gnu(DCCallVM* in_self, DClonglong x)
454 {
455 DCCallVM_x86* self = (DCCallVM_x86*) in_self;
456 self->mIntRegs = 2;
457 dc_callvm_argLongLong_x86(in_self,x);
458 }
459
460 /* win32/fast/gnu vt */
461
462 DCCallVM_vt gVT_x86_win32_fast_gnu =
463 {
464 &dc_callvm_free_x86
465 , &dc_callvm_reset_x86_win32_fast
466 , &dc_callvm_mode_x86
467 , &dc_callvm_argBool_x86_win32_fast_gnu
468 , &dc_callvm_argChar_x86_win32_fast_gnu
469 , &dc_callvm_argShort_x86_win32_fast_gnu
470 , &dc_callvm_argInt_x86_win32_fast_gnu
471 , &dc_callvm_argLong_x86_win32_fast_gnu
472 , &dc_callvm_argLongLong_x86_win32_fast_gnu
473 , &dc_callvm_argFloat_x86
474 , &dc_callvm_argDouble_x86
475 , &dc_callvm_argPointer_x86_win32_fast_gnu
476 , NULL /* argStruct */
477 , (DCvoidvmfunc*) &dc_callvm_call_x86_win32_fast
478 , (DCboolvmfunc*) &dc_callvm_call_x86_win32_fast
479 , (DCcharvmfunc*) &dc_callvm_call_x86_win32_fast
480 , (DCshortvmfunc*) &dc_callvm_call_x86_win32_fast
481 , (DCintvmfunc*) &dc_callvm_call_x86_win32_fast
482 , (DClongvmfunc*) &dc_callvm_call_x86_win32_fast
483 , (DClonglongvmfunc*) &dc_callvm_call_x86_win32_fast
484 , (DCfloatvmfunc*) &dc_callvm_call_x86_win32_fast
485 , (DCdoublevmfunc*) &dc_callvm_call_x86_win32_fast
486 , (DCpointervmfunc*) &dc_callvm_call_x86_win32_fast
487 , NULL /* callStruct */
488 };
489
490 DCCallVM* dcNewCallVM_x86_win32_fast_gnu(DCsize size)
491 {
492 return dc_callvm_new_x86( &gVT_x86_win32_fast_gnu, size );
493 }
494
495 /* --- this ms ------------------------------------------------------------- */
496
497 /* call win32/this/ms */
498
499 void dc_callvm_call_x86_win32_this_ms(DCCallVM* in_self, DCpointer target)
500 {
501 DCCallVM_x86* self = (DCCallVM_x86*) in_self;
502 dcCall_x86_win32_msthis( target, dcVecData(&self->mVecHead), dcVecSize(&self->mVecHead) );
503 }
504
505 /* win32/this/ms vt */
506
507 DCCallVM_vt gVT_x86_win32_this_ms =
508 {
509 &dc_callvm_free_x86
510 , &dc_callvm_reset_x86
511 , &dc_callvm_mode_x86
512 , &dc_callvm_argBool_x86
513 , &dc_callvm_argChar_x86
514 , &dc_callvm_argShort_x86
515 , &dc_callvm_argInt_x86
516 , &dc_callvm_argLong_x86
517 , &dc_callvm_argLongLong_x86
518 , &dc_callvm_argFloat_x86
519 , &dc_callvm_argDouble_x86
520 , &dc_callvm_argPointer_x86
521 , NULL /* argStruct */
522 , (DCvoidvmfunc*) &dc_callvm_call_x86_win32_this_ms
523 , (DCboolvmfunc*) &dc_callvm_call_x86_win32_this_ms
524 , (DCcharvmfunc*) &dc_callvm_call_x86_win32_this_ms
525 , (DCshortvmfunc*) &dc_callvm_call_x86_win32_this_ms
526 , (DCintvmfunc*) &dc_callvm_call_x86_win32_this_ms
527 , (DClongvmfunc*) &dc_callvm_call_x86_win32_this_ms
528 , (DClonglongvmfunc*) &dc_callvm_call_x86_win32_this_ms
529 , (DCfloatvmfunc*) &dc_callvm_call_x86_win32_this_ms
530 , (DCdoublevmfunc*) &dc_callvm_call_x86_win32_this_ms
531 , (DCpointervmfunc*) &dc_callvm_call_x86_win32_this_ms
532 , NULL /* callStruct */
533 };
534
535 /* --- syscall ------------------------------------------------------------- */
536
537 /* call syscall */
538
539 void dc_callvm_call_x86_sys_int80h_linux(DCCallVM* in_self, DCpointer target)
540 {
541 DCCallVM_x86* self = (DCCallVM_x86*) in_self;
542 dcCall_x86_sys_int80h_linux( target, dcVecData(&self->mVecHead), dcVecSize(&self->mVecHead) );
543 }
544
545 void dc_callvm_call_x86_sys_int80h_bsd(DCCallVM* in_self, DCpointer target)
546 {
547 DCCallVM_x86* self = (DCCallVM_x86*) in_self;
548 dcCall_x86_sys_int80h_bsd( target, dcVecData(&self->mVecHead), dcVecSize(&self->mVecHead) );
549 }
550
551 DCCallVM_vt gVT_x86_sys_int80h_linux =
552 {
553 &dc_callvm_free_x86
554 , &dc_callvm_reset_x86
555 , &dc_callvm_mode_x86
556 , &dc_callvm_argBool_x86
557 , &dc_callvm_argChar_x86
558 , &dc_callvm_argShort_x86
559 , &dc_callvm_argInt_x86
560 , &dc_callvm_argLong_x86
561 , &dc_callvm_argLongLong_x86
562 , &dc_callvm_argFloat_x86
563 , &dc_callvm_argDouble_x86
564 , &dc_callvm_argPointer_x86
565 , NULL /* argStruct */
566 , (DCvoidvmfunc*) &dc_callvm_call_x86_sys_int80h_linux
567 , (DCboolvmfunc*) &dc_callvm_call_x86_sys_int80h_linux
568 , (DCcharvmfunc*) &dc_callvm_call_x86_sys_int80h_linux
569 , (DCshortvmfunc*) &dc_callvm_call_x86_sys_int80h_linux
570 , (DCintvmfunc*) &dc_callvm_call_x86_sys_int80h_linux
571 , (DClongvmfunc*) &dc_callvm_call_x86_sys_int80h_linux
572 , (DClonglongvmfunc*) &dc_callvm_call_x86_sys_int80h_linux
573 , (DCfloatvmfunc*) &dc_callvm_call_x86_sys_int80h_linux
574 , (DCdoublevmfunc*) &dc_callvm_call_x86_sys_int80h_linux
575 , (DCpointervmfunc*) &dc_callvm_call_x86_sys_int80h_linux
576 , NULL /* callStruct */
577 };
578
579 DCCallVM_vt gVT_x86_sys_int80h_bsd =
580 {
581 &dc_callvm_free_x86
582 , &dc_callvm_reset_x86
583 , &dc_callvm_mode_x86
584 , &dc_callvm_argBool_x86
585 , &dc_callvm_argChar_x86
586 , &dc_callvm_argShort_x86
587 , &dc_callvm_argInt_x86
588 , &dc_callvm_argLong_x86
589 , &dc_callvm_argLongLong_x86
590 , &dc_callvm_argFloat_x86
591 , &dc_callvm_argDouble_x86
592 , &dc_callvm_argPointer_x86
593 , NULL /* argStruct */
594 , (DCvoidvmfunc*) &dc_callvm_call_x86_sys_int80h_bsd
595 , (DCboolvmfunc*) &dc_callvm_call_x86_sys_int80h_bsd
596 , (DCcharvmfunc*) &dc_callvm_call_x86_sys_int80h_bsd
597 , (DCshortvmfunc*) &dc_callvm_call_x86_sys_int80h_bsd
598 , (DCintvmfunc*) &dc_callvm_call_x86_sys_int80h_bsd
599 , (DClongvmfunc*) &dc_callvm_call_x86_sys_int80h_bsd
600 , (DClonglongvmfunc*) &dc_callvm_call_x86_sys_int80h_bsd
601 , (DCfloatvmfunc*) &dc_callvm_call_x86_sys_int80h_bsd
602 , (DCdoublevmfunc*) &dc_callvm_call_x86_sys_int80h_bsd
603 , (DCpointervmfunc*) &dc_callvm_call_x86_sys_int80h_bsd
604 , NULL /* callStruct */
605 };
606
607
608 /* win32/this/ms callvm allocator */
609
610 DCCallVM* dcNewCallVM_x86_win32_this_ms(DCsize size)
611 {
612 return dc_callvm_new_x86( &gVT_x86_win32_this_ms, size );
613 }
614
615 #endif
616
617
618 /* mode */
619
620 void dc_callvm_mode_x86(DCCallVM* in_self, DCint mode)
621 {
622 DCCallVM_x86* self = (DCCallVM_x86*) in_self;
623 DCCallVM_vt* vt;
624 switch(mode) {
625 case DC_CALL_C_ELLIPSIS:
626 case DC_CALL_C_ELLIPSIS_VARARGS:
627 case DC_CALL_C_DEFAULT:
628 #if defined(DC_PLAN9) /* Plan9 (and forks) have their own calling convention (and no support for foreign ones). */
629 case DC_CALL_C_X86_PLAN9: vt = &gVT_x86_plan9; break;
630 #else
631 case DC_CALL_C_X86_CDECL: vt = &gVT_x86_cdecl; break;
632 case DC_CALL_C_X86_WIN32_STD: vt = &gVT_x86_win32_std; break;
633 case DC_CALL_C_X86_WIN32_FAST_MS: vt = &gVT_x86_win32_fast_ms; break;
634 case DC_CALL_C_X86_WIN32_THIS_MS: vt = &gVT_x86_win32_this_ms; break;
635 case DC_CALL_C_X86_WIN32_FAST_GNU: vt = &gVT_x86_win32_fast_gnu; break;
636 case DC_CALL_C_X86_WIN32_THIS_GNU: vt = &gVT_x86_cdecl; break;
637 case DC_CALL_SYS_DEFAULT:
638 # if defined DC_UNIX
639 # if defined DC__OS_Linux
640 vt = &gVT_x86_sys_int80h_linux; break;
641 # else
642 vt = &gVT_x86_sys_int80h_bsd; break;
643 # endif
644 # else
645 self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; return;
646 # endif
647 case DC_CALL_SYS_X86_INT80H_LINUX:
648 vt = &gVT_x86_sys_int80h_linux; break;
649 case DC_CALL_SYS_X86_INT80H_BSD:
650 vt = &gVT_x86_sys_int80h_bsd; break;
651 #endif
652 default:
653 self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; return;
654 }
655 self->mInterface.mVTpointer = vt;
656 }
657
658 /* new */
659
660 DCCallVM* dcNewCallVM(DCsize size)
661 {
662 #if defined(DC__OS_Plan9)
663 return dcNewCallVM_x86_plan9(size);
664 #else
665 return dcNewCallVM_x86_cdecl(size);
666 #endif
667 }
668