annotate dyncall/dyncall_callvm_x64.c @ 357:d982a00c2177

- PPC64 asm syntax fix, specifying explicitly comparison mode for cmpi (newer toolchains complain, older ones took optional field of instruction which happened to be same value)
author Tassilo Philipp
date Tue, 25 Feb 2020 18:16:13 +0100
parents a2a42f477662
children ad5f9803f52f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
1 /*
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
2
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
3 Package: dyncall
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
4 Library: dyncall
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
5 File: dyncall/dyncall_callvm_x64.c
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
6 Description:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
7 License:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
8
339
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
9 Copyright (c) 2007-2020 Daniel Adler <dadler@uni-goettingen.de>,
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
10 Tassilo Philipp <tphilipp@potion-studios.com>
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
11
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
12 Permission to use, copy, modify, and distribute this software for any
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
13 purpose with or without fee is hereby granted, provided that the above
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
14 copyright notice and this permission notice appear in all copies.
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
15
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
16 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
17 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
18 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
19 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
22 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
23
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
24 */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
25
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
26
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
27
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
28
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
29 /* MS Windows x64 calling convention, AMD64 SystemV ABI. */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
30
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
31
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
32 #include "dyncall_callvm_x64.h"
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
33 #include "dyncall_alloc.h"
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
34 #include "dyncall_struct.h"
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
35
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
36
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
37 static void dc_callvm_free_x64(DCCallVM* in_self)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
38 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
39 dcFreeMem(in_self);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
40 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
41
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
42
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
43 static void dc_callvm_reset_x64(DCCallVM* in_self)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
44 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
45 DCCallVM_x64* self = (DCCallVM_x64*)in_self;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
46 dcVecReset(&self->mVecHead);
84
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
47 self->mRegCount.i = self->mRegCount.f = 0;
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
48 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
49
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
50
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
51 static void dc_callvm_argLongLong_x64(DCCallVM* in_self, DClonglong x)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
52 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
53 /* A long long always has 64 bits on the supported x64 platforms (lp64 on unix and llp64 on windows). */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
54 DCCallVM_x64* self = (DCCallVM_x64*)in_self;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
55 if(self->mRegCount.i < numIntRegs)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
56 self->mRegData.i[self->mRegCount.i++] = x;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
57 else
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
58 dcVecAppend(&self->mVecHead, &x, sizeof(DClonglong));
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
59 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
60
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
61
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
62 static void dc_callvm_argBool_x64(DCCallVM* in_self, DCbool x)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
63 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
64 dc_callvm_argLongLong_x64(in_self, (DClonglong)x);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
65 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
66
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
67
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
68 static void dc_callvm_argChar_x64(DCCallVM* in_self, DCchar x)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
69 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
70 dc_callvm_argLongLong_x64(in_self, x);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
71 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
72
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
73
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
74 static void dc_callvm_argShort_x64(DCCallVM* in_self, DCshort x)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
75 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
76 dc_callvm_argLongLong_x64(in_self, x);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
77 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
78
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
79
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
80 static void dc_callvm_argInt_x64(DCCallVM* in_self, DCint x)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
81 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
82 dc_callvm_argLongLong_x64(in_self, x);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
83 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
84
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
85
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
86 static void dc_callvm_argLong_x64(DCCallVM* in_self, DClong x)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
87 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
88 dc_callvm_argLongLong_x64(in_self, x);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
89 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
90
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
91
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
92 static void dc_callvm_argFloat_x64(DCCallVM* in_self, DCfloat x)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
93 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
94 DCCallVM_x64* self = (DCCallVM_x64*)in_self;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
95
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
96 /* Although not promoted to doubles, floats are stored with 64bits in this API.*/
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
97 union {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
98 DCdouble d;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
99 DCfloat f;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
100 } f;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
101 f.f = x;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
102
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
103 if(self->mRegCount.f < numFloatRegs)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
104 *(DCfloat*)&self->mRegData.f[self->mRegCount.f++] = x;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
105 else
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
106 dcVecAppend(&self->mVecHead, &f.f, sizeof(DCdouble));
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
107 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
108
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
109
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
110 static void dc_callvm_argDouble_x64(DCCallVM* in_self, DCdouble x)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
111 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
112 DCCallVM_x64* self = (DCCallVM_x64*)in_self;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
113 if(self->mRegCount.f < numFloatRegs)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
114 self->mRegData.f[self->mRegCount.f++] = x;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
115 else
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
116 dcVecAppend(&self->mVecHead, &x, sizeof(DCdouble));
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
117 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
118
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
119
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
120 static void dc_callvm_argPointer_x64(DCCallVM* in_self, DCpointer x)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
121 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
122 DCCallVM_x64* self = (DCCallVM_x64*)in_self;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
123 if(self->mRegCount.i < numIntRegs)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
124 *(DCpointer*)&self->mRegData.i[self->mRegCount.i++] = x;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
125 else
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
126 dcVecAppend(&self->mVecHead, &x, sizeof(DCpointer));
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
127 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
128
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
129 static void dc_callvm_argStruct_x64(DCCallVM* in_self, DCstruct* s, DCpointer x)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
130 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
131 DCCallVM_x64* self = (DCCallVM_x64*)in_self;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
132 dcVecAppend(&self->mVecHead, x, s->size);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
133 /*printf("dc_callvm_argStruct_x64 size = %d\n", (int)s->size);@@@*/
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
134 if (s->size <= 64)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
135 dcArgStructUnroll(in_self, s, x);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
136 /*else@@@*/
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
137 /* dcVecAppend(&self->mVecHead, &x, sizeof(DCpointer));@@@*/
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
138 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
139
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
140
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
141 /* Call. */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
142 void dc_callvm_call_x64(DCCallVM* in_self, DCpointer target)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
143 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
144 DCCallVM_x64* self = (DCCallVM_x64*)in_self;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
145 #if defined(DC_UNIX)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
146 dcCall_x64_sysv(
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
147 #else
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
148 dcCall_x64_win64(
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
149 #endif
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
150 dcVecSize(&self->mVecHead), /* Size of stack data. */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
151 dcVecData(&self->mVecHead), /* Pointer to stack arguments. */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
152 self->mRegData.i, /* Pointer to register arguments (ints on SysV). */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
153 #if defined(DC_UNIX)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
154 self->mRegData.f, /* Pointer to floating point register arguments. */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
155 #endif
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
156 target
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
157 );
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
158 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
159
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
160
84
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
161 static void dc_callvm_mode_x64(DCCallVM* in_self, DCint mode);
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
162
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
163 DCCallVM_vt gVT_x64 =
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
164 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
165 &dc_callvm_free_x64
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
166 , &dc_callvm_reset_x64
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
167 , &dc_callvm_mode_x64
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
168 , &dc_callvm_argBool_x64
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
169 , &dc_callvm_argChar_x64
339
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
170 , &dc_callvm_argShort_x64
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
171 , &dc_callvm_argInt_x64
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
172 , &dc_callvm_argLong_x64
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
173 , &dc_callvm_argLongLong_x64
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
174 , &dc_callvm_argFloat_x64
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
175 , &dc_callvm_argDouble_x64
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
176 , &dc_callvm_argPointer_x64
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
177 , &dc_callvm_argStruct_x64
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
178 , (DCvoidvmfunc*) &dc_callvm_call_x64
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
179 , (DCboolvmfunc*) &dc_callvm_call_x64
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
180 , (DCcharvmfunc*) &dc_callvm_call_x64
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
181 , (DCshortvmfunc*) &dc_callvm_call_x64
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
182 , (DCintvmfunc*) &dc_callvm_call_x64
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
183 , (DClongvmfunc*) &dc_callvm_call_x64
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
184 , (DClonglongvmfunc*) &dc_callvm_call_x64
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
185 , (DCfloatvmfunc*) &dc_callvm_call_x64
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
186 , (DCdoublevmfunc*) &dc_callvm_call_x64
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
187 , (DCpointervmfunc*) &dc_callvm_call_x64
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
188 , NULL /* callStruct */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
189 };
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
190
339
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
191
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
192 /* --- syscall ------------------------------------------------------------- */
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
193
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
194 #include <assert.h>
341
ab2d78e48ca2 - gen-masm
Tassilo Philipp
parents: 339
diff changeset
195 void dc_callvm_call_x64_syscall_sysv(DCCallVM* in_self, DCpointer target)
339
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
196 {
347
a2a42f477662 - C declaration order fix
Tassilo Philipp
parents: 341
diff changeset
197 DCCallVM_x64* self;
a2a42f477662 - C declaration order fix
Tassilo Philipp
parents: 341
diff changeset
198
339
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
199 /* syscalls can have up to 6 args, required to be "Only values of class INTEGER or class MEMORY" (from */
347
a2a42f477662 - C declaration order fix
Tassilo Philipp
parents: 341
diff changeset
200 /* SysV manual), so we can use self->mRegData.i directly; verify this has space for at least 6 values, though. */
339
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
201 assert(numIntRegs >= 6);
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
202
347
a2a42f477662 - C declaration order fix
Tassilo Philipp
parents: 341
diff changeset
203 self = (DCCallVM_x64*)in_self;
341
ab2d78e48ca2 - gen-masm
Tassilo Philipp
parents: 339
diff changeset
204 dcCall_x64_syscall_sysv(self->mRegData.i, target);
339
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
205 }
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
206
341
ab2d78e48ca2 - gen-masm
Tassilo Philipp
parents: 339
diff changeset
207 DCCallVM_vt gVT_x64_syscall_sysv =
339
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
208 {
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
209 &dc_callvm_free_x64
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
210 , &dc_callvm_reset_x64
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
211 , &dc_callvm_mode_x64
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
212 , &dc_callvm_argBool_x64
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
213 , &dc_callvm_argChar_x64
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
214 , &dc_callvm_argShort_x64
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
215 , &dc_callvm_argInt_x64
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
216 , &dc_callvm_argLong_x64
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
217 , &dc_callvm_argLongLong_x64
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
218 , &dc_callvm_argFloat_x64
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
219 , &dc_callvm_argDouble_x64
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
220 , &dc_callvm_argPointer_x64
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
221 , NULL /* argStruct */
341
ab2d78e48ca2 - gen-masm
Tassilo Philipp
parents: 339
diff changeset
222 , (DCvoidvmfunc*) &dc_callvm_call_x64_syscall_sysv
ab2d78e48ca2 - gen-masm
Tassilo Philipp
parents: 339
diff changeset
223 , (DCboolvmfunc*) &dc_callvm_call_x64_syscall_sysv
ab2d78e48ca2 - gen-masm
Tassilo Philipp
parents: 339
diff changeset
224 , (DCcharvmfunc*) &dc_callvm_call_x64_syscall_sysv
ab2d78e48ca2 - gen-masm
Tassilo Philipp
parents: 339
diff changeset
225 , (DCshortvmfunc*) &dc_callvm_call_x64_syscall_sysv
ab2d78e48ca2 - gen-masm
Tassilo Philipp
parents: 339
diff changeset
226 , (DCintvmfunc*) &dc_callvm_call_x64_syscall_sysv
ab2d78e48ca2 - gen-masm
Tassilo Philipp
parents: 339
diff changeset
227 , (DClongvmfunc*) &dc_callvm_call_x64_syscall_sysv
ab2d78e48ca2 - gen-masm
Tassilo Philipp
parents: 339
diff changeset
228 , (DClonglongvmfunc*) &dc_callvm_call_x64_syscall_sysv
ab2d78e48ca2 - gen-masm
Tassilo Philipp
parents: 339
diff changeset
229 , (DCfloatvmfunc*) &dc_callvm_call_x64_syscall_sysv
ab2d78e48ca2 - gen-masm
Tassilo Philipp
parents: 339
diff changeset
230 , (DCdoublevmfunc*) &dc_callvm_call_x64_syscall_sysv
ab2d78e48ca2 - gen-masm
Tassilo Philipp
parents: 339
diff changeset
231 , (DCpointervmfunc*) &dc_callvm_call_x64_syscall_sysv
339
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
232 , NULL /* callStruct */
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
233 };
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
234
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
235
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
236
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
237 /* mode */
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
238
84
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
239 static void dc_callvm_mode_x64(DCCallVM* in_self, DCint mode)
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
240 {
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
241 DCCallVM_x64* self = (DCCallVM_x64*)in_self;
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
242 DCCallVM_vt* vt;
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
243
84
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
244 switch(mode) {
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
245 case DC_CALL_C_DEFAULT:
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
246 #if defined(DC_UNIX)
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
247 case DC_CALL_C_X64_SYSV:
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
248 #else
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
249 case DC_CALL_C_X64_WIN64:
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
250 #endif
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
251 case DC_CALL_C_ELLIPSIS:
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
252 case DC_CALL_C_ELLIPSIS_VARARGS:
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
253 vt = &gVT_x64;
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
254 break;
339
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
255 case DC_CALL_SYS_DEFAULT:
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
256 # if defined DC_UNIX
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
257 case DC_CALL_SYS_X64_SYSCALL_SYSV:
341
ab2d78e48ca2 - gen-masm
Tassilo Philipp
parents: 339
diff changeset
258 vt = &gVT_x64_syscall_sysv; break;
339
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
259 # else
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
260 self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; return;
4f9f49fb82ce - x64 SysV syscall support
Tassilo Philipp
parents: 281
diff changeset
261 # endif
84
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
262 default:
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
263 self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE;
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
264 return;
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
265 }
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
266 dc_callvm_base_init(&self->mInterface, vt);
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
267 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
268
84
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
269 /* Public API. */
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
270 DCCallVM* dcNewCallVM(DCsize size)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
271 {
84
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
272 DCCallVM_x64* p = (DCCallVM_x64*)dcAllocMem(sizeof(DCCallVM_x64)+size);
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
273
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
274 dc_callvm_mode_x64((DCCallVM*)p, DC_CALL_C_DEFAULT);
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
275
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
276 /* Since we store register parameters in DCCallVM_x64 directly, adjust the stack size. */
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
277 size -= sizeof(DCRegData_x64);
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
278 size = (((signed long)size) < 0) ? 0 : size;
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
279 dcVecInit(&p->mVecHead, size);
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
280 dc_callvm_reset_x64((DCCallVM*)p);
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
281
67961454902b - bigger cleanup in callvm code
cslag
parents: 0
diff changeset
282 return (DCCallVM*)p;
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
283 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
284