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