2 * CLANGDLL.C - Direct interface for C Language DLL functions
4 * (c)Copyright 1993-2014, Matthew Dillon, All Rights Reserved. See the
5 * COPYRIGHT file at the base of the distribution.
10 typedef void *void_ptr;
11 typedef void_ptr (*isys_generic_c_call_t)(runctx_p ct, Exp *exp, RefStor **prs);
14 * isys_generic_c_call()
16 * Execute a generic C call. Note that the right hand side should
17 * already be properly aligned for the call, we simply switch on the
18 * number of arguments and the size of the return value.
20 static __inline void *
21 isys_call(runctx_p ct, Exp *exp, RefStor **prs __unused, const int asize, const int rsize)
32 void (*func0)(struct my_rhs rhs);
33 int8_t (*func1)(struct my_rhs rhs);
34 int16_t (*func2)(struct my_rhs rhs);
35 int32_t (*func4)(struct my_rhs rhs);
36 int64_t (*func8)(struct my_rhs rhs);
37 struct my_lhs (*funcX)(struct my_rhs rhs);
40 ts = getExpTmpData(ct, exp);
41 rhs = exp->ex_Rhs->ex_Func(ct, exp->ex_Rhs, &rs);
42 func.func0 = exp->ex_Lhs->ex_Decl->d_ProcDecl.ed_DLLFunc;
44 switch(exp->ex_Type->ty_Bytes) {
49 *(int8_t *)ts = func.func1(*rhs);
52 *(int16_t *)ts = func.func2(*rhs);
55 *(int32_t *)ts = func.func4(*rhs);
58 *(int64_t *)ts = func.func8(*rhs);
62 /* *(struct my_lhs *)ts = func.funcX(*rhs); */
69 #define ISYS_CALL(asize,rsize) \
71 isys_call_ ## asize ## _ ## rsize(runctx_p ct, Exp *exp, RefStor **prs) \
73 return(isys_call(ct, exp, prs, 0x ## asize, 0x ## rsize));\
76 #define ISYS_CALLGROUP(asize) \
113 isys_generic_c_call_t isys_array[64 / sizeof(int)][64] = {
114 { isys_call_00_00, isys_call_00_01, isys_call_00_02, NULL,
115 isys_call_00_04, NULL, NULL, NULL,
116 isys_call_00_08, NULL, NULL, NULL,
117 isys_call_00_0C, NULL, NULL, NULL,
118 isys_call_00_10, NULL, NULL, NULL,
119 isys_call_00_14, NULL, NULL, NULL,
120 isys_call_00_18, NULL, NULL, NULL,
121 isys_call_00_1C, NULL, NULL, NULL,
122 isys_call_00_20, NULL, NULL, NULL,
123 isys_call_00_24, NULL, NULL, NULL,
124 isys_call_00_28, NULL, NULL, NULL,
125 isys_call_00_2C, NULL, NULL, NULL,
126 isys_call_00_30, NULL, NULL, NULL,
127 isys_call_00_34, NULL, NULL, NULL,
128 isys_call_00_38, NULL, NULL, NULL,
129 isys_call_00_3C, NULL, NULL, NULL },
130 { isys_call_04_00, isys_call_04_01, isys_call_04_02, NULL,
131 isys_call_04_04, NULL, NULL, NULL,
132 isys_call_04_08, NULL, NULL, NULL,
133 isys_call_04_0C, NULL, NULL, NULL,
134 isys_call_04_10, NULL, NULL, NULL,
135 isys_call_04_14, NULL, NULL, NULL,
136 isys_call_04_18, NULL, NULL, NULL,
137 isys_call_04_1C, NULL, NULL, NULL,
138 isys_call_04_20, NULL, NULL, NULL,
139 isys_call_04_24, NULL, NULL, NULL,
140 isys_call_04_28, NULL, NULL, NULL,
141 isys_call_04_2C, NULL, NULL, NULL,
142 isys_call_04_30, NULL, NULL, NULL,
143 isys_call_04_34, NULL, NULL, NULL,
144 isys_call_04_38, NULL, NULL, NULL,
145 isys_call_04_3C, NULL, NULL, NULL },
146 { isys_call_08_00, isys_call_08_01, isys_call_08_02, NULL,
147 isys_call_08_04, NULL, NULL, NULL,
148 isys_call_08_08, NULL, NULL, NULL,
149 isys_call_08_0C, NULL, NULL, NULL,
150 isys_call_08_10, NULL, NULL, NULL,
151 isys_call_08_14, NULL, NULL, NULL,
152 isys_call_08_18, NULL, NULL, NULL,
153 isys_call_08_1C, NULL, NULL, NULL,
154 isys_call_08_20, NULL, NULL, NULL,
155 isys_call_08_24, NULL, NULL, NULL,
156 isys_call_08_28, NULL, NULL, NULL,
157 isys_call_08_2C, NULL, NULL, NULL,
158 isys_call_08_30, NULL, NULL, NULL,
159 isys_call_08_34, NULL, NULL, NULL,
160 isys_call_08_38, NULL, NULL, NULL,
161 isys_call_08_3C, NULL, NULL, NULL },
162 { isys_call_0C_00, isys_call_0C_01, isys_call_0C_02, NULL,
163 isys_call_0C_04, NULL, NULL, NULL,
164 isys_call_0C_08, NULL, NULL, NULL,
165 isys_call_0C_0C, NULL, NULL, NULL,
166 isys_call_0C_10, NULL, NULL, NULL,
167 isys_call_0C_14, NULL, NULL, NULL,
168 isys_call_0C_18, NULL, NULL, NULL,
169 isys_call_0C_1C, NULL, NULL, NULL,
170 isys_call_0C_20, NULL, NULL, NULL,
171 isys_call_0C_24, NULL, NULL, NULL,
172 isys_call_0C_28, NULL, NULL, NULL,
173 isys_call_0C_2C, NULL, NULL, NULL,
174 isys_call_0C_30, NULL, NULL, NULL,
175 isys_call_0C_34, NULL, NULL, NULL,
176 isys_call_0C_38, NULL, NULL, NULL,
177 isys_call_0C_3C, NULL, NULL, NULL },
178 { isys_call_10_00, isys_call_10_01, isys_call_10_02, NULL,
179 isys_call_10_04, NULL, NULL, NULL,
180 isys_call_10_08, NULL, NULL, NULL,
181 isys_call_10_0C, NULL, NULL, NULL,
182 isys_call_10_10, NULL, NULL, NULL,
183 isys_call_10_14, NULL, NULL, NULL,
184 isys_call_10_18, NULL, NULL, NULL,
185 isys_call_10_1C, NULL, NULL, NULL,
186 isys_call_10_20, NULL, NULL, NULL,
187 isys_call_10_24, NULL, NULL, NULL,
188 isys_call_10_28, NULL, NULL, NULL,
189 isys_call_10_2C, NULL, NULL, NULL,
190 isys_call_10_30, NULL, NULL, NULL,
191 isys_call_10_34, NULL, NULL, NULL,
192 isys_call_10_38, NULL, NULL, NULL,
193 isys_call_10_3C, NULL, NULL, NULL },
194 { isys_call_14_00, isys_call_14_01, isys_call_14_02, NULL,
195 isys_call_14_04, NULL, NULL, NULL,
196 isys_call_14_08, NULL, NULL, NULL,
197 isys_call_14_0C, NULL, NULL, NULL,
198 isys_call_14_10, NULL, NULL, NULL,
199 isys_call_14_14, NULL, NULL, NULL,
200 isys_call_14_18, NULL, NULL, NULL,
201 isys_call_14_1C, NULL, NULL, NULL,
202 isys_call_14_20, NULL, NULL, NULL,
203 isys_call_14_24, NULL, NULL, NULL,
204 isys_call_14_28, NULL, NULL, NULL,
205 isys_call_14_2C, NULL, NULL, NULL,
206 isys_call_14_30, NULL, NULL, NULL,
207 isys_call_14_34, NULL, NULL, NULL,
208 isys_call_14_38, NULL, NULL, NULL,
209 isys_call_14_3C, NULL, NULL, NULL },
210 { isys_call_18_00, isys_call_18_01, isys_call_18_02, NULL,
211 isys_call_18_04, NULL, NULL, NULL,
212 isys_call_18_08, NULL, NULL, NULL,
213 isys_call_18_0C, NULL, NULL, NULL,
214 isys_call_18_10, NULL, NULL, NULL,
215 isys_call_18_14, NULL, NULL, NULL,
216 isys_call_18_18, NULL, NULL, NULL,
217 isys_call_18_1C, NULL, NULL, NULL,
218 isys_call_18_20, NULL, NULL, NULL,
219 isys_call_18_24, NULL, NULL, NULL,
220 isys_call_18_28, NULL, NULL, NULL,
221 isys_call_18_2C, NULL, NULL, NULL,
222 isys_call_18_30, NULL, NULL, NULL,
223 isys_call_18_34, NULL, NULL, NULL,
224 isys_call_18_38, NULL, NULL, NULL,
225 isys_call_18_3C, NULL, NULL, NULL },
226 { isys_call_1C_00, isys_call_1C_01, isys_call_1C_02, NULL,
227 isys_call_1C_04, NULL, NULL, NULL,
228 isys_call_1C_08, NULL, NULL, NULL,
229 isys_call_1C_0C, NULL, NULL, NULL,
230 isys_call_1C_10, NULL, NULL, NULL,
231 isys_call_1C_14, NULL, NULL, NULL,
232 isys_call_1C_18, NULL, NULL, NULL,
233 isys_call_1C_1C, NULL, NULL, NULL,
234 isys_call_1C_20, NULL, NULL, NULL,
235 isys_call_1C_24, NULL, NULL, NULL,
236 isys_call_1C_28, NULL, NULL, NULL,
237 isys_call_1C_2C, NULL, NULL, NULL,
238 isys_call_1C_30, NULL, NULL, NULL,
239 isys_call_1C_34, NULL, NULL, NULL,
240 isys_call_1C_38, NULL, NULL, NULL,
241 isys_call_1C_3C, NULL, NULL, NULL },
242 { isys_call_20_00, isys_call_20_01, isys_call_20_02, NULL,
243 isys_call_20_04, NULL, NULL, NULL,
244 isys_call_20_08, NULL, NULL, NULL,
245 isys_call_20_0C, NULL, NULL, NULL,
246 isys_call_20_10, NULL, NULL, NULL,
247 isys_call_20_14, NULL, NULL, NULL,
248 isys_call_20_18, NULL, NULL, NULL,
249 isys_call_20_1C, NULL, NULL, NULL,
250 isys_call_20_20, NULL, NULL, NULL,
251 isys_call_20_24, NULL, NULL, NULL,
252 isys_call_20_28, NULL, NULL, NULL,
253 isys_call_20_2C, NULL, NULL, NULL,
254 isys_call_20_30, NULL, NULL, NULL,
255 isys_call_20_34, NULL, NULL, NULL,
256 isys_call_20_38, NULL, NULL, NULL,
257 isys_call_20_3C, NULL, NULL, NULL },
258 { isys_call_24_00, isys_call_24_01, isys_call_24_02, NULL,
259 isys_call_24_04, NULL, NULL, NULL,
260 isys_call_24_08, NULL, NULL, NULL,
261 isys_call_24_0C, NULL, NULL, NULL,
262 isys_call_24_10, NULL, NULL, NULL,
263 isys_call_24_14, NULL, NULL, NULL,
264 isys_call_24_18, NULL, NULL, NULL,
265 isys_call_24_1C, NULL, NULL, NULL,
266 isys_call_24_20, NULL, NULL, NULL,
267 isys_call_24_24, NULL, NULL, NULL,
268 isys_call_24_28, NULL, NULL, NULL,
269 isys_call_24_2C, NULL, NULL, NULL,
270 isys_call_24_30, NULL, NULL, NULL,
271 isys_call_24_34, NULL, NULL, NULL,
272 isys_call_24_38, NULL, NULL, NULL,
273 isys_call_24_3C, NULL, NULL, NULL },
274 { isys_call_28_00, isys_call_28_01, isys_call_28_02, NULL,
275 isys_call_28_04, NULL, NULL, NULL,
276 isys_call_28_08, NULL, NULL, NULL,
277 isys_call_28_0C, NULL, NULL, NULL,
278 isys_call_28_10, NULL, NULL, NULL,
279 isys_call_28_14, NULL, NULL, NULL,
280 isys_call_28_18, NULL, NULL, NULL,
281 isys_call_28_1C, NULL, NULL, NULL,
282 isys_call_28_20, NULL, NULL, NULL,
283 isys_call_28_24, NULL, NULL, NULL,
284 isys_call_28_28, NULL, NULL, NULL,
285 isys_call_28_2C, NULL, NULL, NULL,
286 isys_call_28_30, NULL, NULL, NULL,
287 isys_call_28_34, NULL, NULL, NULL,
288 isys_call_28_38, NULL, NULL, NULL,
289 isys_call_28_3C, NULL, NULL, NULL },
290 { isys_call_2C_00, isys_call_2C_01, isys_call_2C_02, NULL,
291 isys_call_2C_04, NULL, NULL, NULL,
292 isys_call_2C_08, NULL, NULL, NULL,
293 isys_call_2C_0C, NULL, NULL, NULL,
294 isys_call_2C_10, NULL, NULL, NULL,
295 isys_call_2C_14, NULL, NULL, NULL,
296 isys_call_2C_18, NULL, NULL, NULL,
297 isys_call_2C_1C, NULL, NULL, NULL,
298 isys_call_2C_20, NULL, NULL, NULL,
299 isys_call_2C_24, NULL, NULL, NULL,
300 isys_call_2C_28, NULL, NULL, NULL,
301 isys_call_2C_2C, NULL, NULL, NULL,
302 isys_call_2C_30, NULL, NULL, NULL,
303 isys_call_2C_34, NULL, NULL, NULL,
304 isys_call_2C_38, NULL, NULL, NULL,
305 isys_call_2C_3C, NULL, NULL, NULL },
306 { isys_call_30_00, isys_call_30_01, isys_call_30_02, NULL,
307 isys_call_30_04, NULL, NULL, NULL,
308 isys_call_30_08, NULL, NULL, NULL,
309 isys_call_30_0C, NULL, NULL, NULL,
310 isys_call_30_10, NULL, NULL, NULL,
311 isys_call_30_14, NULL, NULL, NULL,
312 isys_call_30_18, NULL, NULL, NULL,
313 isys_call_30_1C, NULL, NULL, NULL,
314 isys_call_30_20, NULL, NULL, NULL,
315 isys_call_30_24, NULL, NULL, NULL,
316 isys_call_30_28, NULL, NULL, NULL,
317 isys_call_30_2C, NULL, NULL, NULL,
318 isys_call_30_30, NULL, NULL, NULL,
319 isys_call_30_34, NULL, NULL, NULL,
320 isys_call_30_38, NULL, NULL, NULL,
321 isys_call_30_3C, NULL, NULL, NULL },
322 { isys_call_34_00, isys_call_34_01, isys_call_34_02, NULL,
323 isys_call_34_04, NULL, NULL, NULL,
324 isys_call_34_08, NULL, NULL, NULL,
325 isys_call_34_0C, NULL, NULL, NULL,
326 isys_call_34_10, NULL, NULL, NULL,
327 isys_call_34_14, NULL, NULL, NULL,
328 isys_call_34_18, NULL, NULL, NULL,
329 isys_call_34_1C, NULL, NULL, NULL,
330 isys_call_34_20, NULL, NULL, NULL,
331 isys_call_34_24, NULL, NULL, NULL,
332 isys_call_34_28, NULL, NULL, NULL,
333 isys_call_34_2C, NULL, NULL, NULL,
334 isys_call_34_30, NULL, NULL, NULL,
335 isys_call_34_34, NULL, NULL, NULL,
336 isys_call_34_38, NULL, NULL, NULL,
337 isys_call_34_3C, NULL, NULL, NULL },
338 { isys_call_38_00, isys_call_38_01, isys_call_38_02, NULL,
339 isys_call_38_04, NULL, NULL, NULL,
340 isys_call_38_08, NULL, NULL, NULL,
341 isys_call_38_0C, NULL, NULL, NULL,
342 isys_call_38_10, NULL, NULL, NULL,
343 isys_call_38_14, NULL, NULL, NULL,
344 isys_call_38_18, NULL, NULL, NULL,
345 isys_call_38_1C, NULL, NULL, NULL,
346 isys_call_38_20, NULL, NULL, NULL,
347 isys_call_38_24, NULL, NULL, NULL,
348 isys_call_38_28, NULL, NULL, NULL,
349 isys_call_38_2C, NULL, NULL, NULL,
350 isys_call_38_30, NULL, NULL, NULL,
351 isys_call_38_34, NULL, NULL, NULL,
352 isys_call_38_38, NULL, NULL, NULL,
353 isys_call_38_3C, NULL, NULL, NULL },
354 { isys_call_3C_00, isys_call_3C_01, isys_call_3C_02, NULL,
355 isys_call_3C_04, NULL, NULL, NULL,
356 isys_call_3C_08, NULL, NULL, NULL,
357 isys_call_3C_0C, NULL, NULL, NULL,
358 isys_call_3C_10, NULL, NULL, NULL,
359 isys_call_3C_14, NULL, NULL, NULL,
360 isys_call_3C_18, NULL, NULL, NULL,
361 isys_call_3C_1C, NULL, NULL, NULL,
362 isys_call_3C_20, NULL, NULL, NULL,
363 isys_call_3C_24, NULL, NULL, NULL,
364 isys_call_3C_28, NULL, NULL, NULL,
365 isys_call_3C_2C, NULL, NULL, NULL,
366 isys_call_3C_30, NULL, NULL, NULL,
367 isys_call_3C_34, NULL, NULL, NULL,
368 isys_call_3C_38, NULL, NULL, NULL,
369 isys_call_3C_3C, NULL, NULL, NULL }
373 * Construct an interpreter Exp execution function for this C Language
377 DLLCLangConstruct(Declaration *d)
384 * If the resolver could not find the DLL symbol there is nothing
387 dassert(d->d_Op == DOP_PROC);
388 if (d->d_ProcDecl.ed_DLLFunc == NULL)
392 * Validate argument and return type sizes
394 type = d->d_ProcDecl.ed_Type;
395 atsize = type->ty_ProcType.et_ArgsType->ty_Bytes;
396 if (atsize & (sizeof(int) - 1)) {
397 fatal("DLLLFunction %s args not C-aligned (%d bytes)",
401 fatal("DLLLFunction %s args %d "
402 "bytes >= 64 bytes, not supported!",
405 rtsize = type->ty_ProcType.et_RetType->ty_Bytes;
406 if (rtsize > sizeof(int) && (rtsize & (sizeof(int) - 1))) {
407 fatal("DLLLFunction %s return type > sizeof(int) must be "
408 "C-aligned (%d bytes)",
412 fatal("DLLLFunction %s return type %d bytes >= 64 bytes, "
416 return(isys_array[atsize / sizeof(int)][rtsize]);