1 /* -----------------------------------------------------------------------
2 ffi.c - Copyright (c) 2002 Bo Thorsen <bo@suse.de>
4 x86-64 Foreign Function Interface
6 Permission is hereby granted, free of charge, to any person obtaining
7 a copy of this software and associated documentation files (the
8 ``Software''), to deal in the Software without restriction, including
9 without limitation the rights to use, copy, modify, merge, publish,
10 distribute, sublicense, and/or sell copies of the Software, and to
11 permit persons to whom the Software is furnished to do so, subject to
12 the following conditions:
14 The above copyright notice and this permission notice shall be included
15 in all copies or substantial portions of the Software.
17 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 OTHER DEALINGS IN THE SOFTWARE.
24 ----------------------------------------------------------------------- */
27 #include <ffi_common.h>
31 /* ffi_prep_args is called by the assembly routine once stack space
32 has been allocated for the function's arguments */
36 #define MAX_GPR_REGS 6
37 #define MAX_SSE_REGS 8
40 /* Registers for argument passing. */
41 long gpr[MAX_GPR_REGS];
42 __int128_t sse[MAX_SSE_REGS];
44 /* Stack space for arguments. */
48 /* All reference to register classes here is identical to the code in
49 gcc/config/i386/i386.c. Do *not* change one without the other. */
51 /* Register class used for passing given 64bit part of the argument.
52 These represent classes as documented by the PS ABI, with the exception
53 of SSESF, SSEDF classes, that are basically SSE class, just gcc will
54 use SF or DFmode move instead of DImode to avoid reformating penalties.
56 Similary we play games with INTEGERSI_CLASS to use cheaper SImode moves
57 whenever possible (upper half does contain padding).
63 X86_64_INTEGERSI_CLASS,
75 /* x86-64 register passing implementation. See x86-64 ABI for details. Goal
76 of this code is to classify each 8bytes of incoming argument by the register
77 class and assign registers accordingly. */
79 /* Return the union class of CLASS1 and CLASS2.
80 See the x86-64 PS ABI for details. */
82 static enum x86_64_reg_class
83 merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)
85 /* Rule #1: If both classes are equal, this is the resulting class. */
89 /* Rule #2: If one of the classes is NO_CLASS, the resulting class is
91 if (class1 == X86_64_NO_CLASS)
93 if (class2 == X86_64_NO_CLASS)
96 /* Rule #3: If one of the classes is MEMORY, the result is MEMORY. */
97 if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
98 return X86_64_MEMORY_CLASS;
100 /* Rule #4: If one of the classes is INTEGER, the result is INTEGER. */
101 if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS)
102 || (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS))
103 return X86_64_INTEGERSI_CLASS;
104 if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS
105 || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)
106 return X86_64_INTEGER_CLASS;
108 /* Rule #5: If one of the classes is X87 or X87UP class, MEMORY is used. */
109 if (class1 == X86_64_X87_CLASS || class1 == X86_64_X87UP_CLASS
110 || class2 == X86_64_X87_CLASS || class2 == X86_64_X87UP_CLASS)
111 return X86_64_MEMORY_CLASS;
113 /* Rule #6: Otherwise class SSE is used. */
114 return X86_64_SSE_CLASS;
117 /* Classify the argument of type TYPE and mode MODE.
118 CLASSES will be filled by the register class used to pass each word
119 of the operand. The number of words is returned. In case the parameter
120 should be passed in memory, 0 is returned. As a special case for zero
121 sized containers, classes[0] will be NO_CLASS and 1 is returned.
123 See the x86-64 PS ABI for details.
126 classify_argument (ffi_type *type, enum x86_64_reg_class classes[],
129 /* First, align to the right place. */
130 *byte_offset = ALIGN(*byte_offset, type->alignment);
136 case FFI_TYPE_UINT16:
137 case FFI_TYPE_SINT16:
138 case FFI_TYPE_UINT32:
139 case FFI_TYPE_SINT32:
140 case FFI_TYPE_UINT64:
141 case FFI_TYPE_SINT64:
142 case FFI_TYPE_POINTER:
143 if (((*byte_offset) % 8 + type->size) <= 4)
144 classes[0] = X86_64_INTEGERSI_CLASS;
146 classes[0] = X86_64_INTEGER_CLASS;
149 if (((*byte_offset) % 8) == 0)
150 classes[0] = X86_64_SSESF_CLASS;
152 classes[0] = X86_64_SSE_CLASS;
154 case FFI_TYPE_DOUBLE:
155 classes[0] = X86_64_SSEDF_CLASS;
157 case FFI_TYPE_LONGDOUBLE:
158 classes[0] = X86_64_X87_CLASS;
159 classes[1] = X86_64_X87UP_CLASS;
161 case FFI_TYPE_STRUCT:
163 const int UNITS_PER_WORD = 8;
164 int words = (type->size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
167 enum x86_64_reg_class subclasses[MAX_CLASSES];
169 /* If the struct is larger than 16 bytes, pass it on the stack. */
173 for (i = 0; i < words; i++)
174 classes[i] = X86_64_NO_CLASS;
176 /* Merge the fields of structure. */
177 for (ptr=type->elements; (*ptr)!=NULL; ptr++)
181 num = classify_argument (*ptr, subclasses, byte_offset);
184 for (i = 0; i < num; i++)
186 int pos = *byte_offset / 8;
188 merge_classes (subclasses[i], classes[i + pos]);
191 if ((*ptr)->type != FFI_TYPE_STRUCT)
192 *byte_offset += (*ptr)->size;
195 /* Final merger cleanup. */
196 for (i = 0; i < words; i++)
198 /* If one class is MEMORY, everything should be passed in
200 if (classes[i] == X86_64_MEMORY_CLASS)
203 /* The X86_64_SSEUP_CLASS should be always preceded by
205 if (classes[i] == X86_64_SSEUP_CLASS
206 && (i == 0 || classes[i - 1] != X86_64_SSE_CLASS))
207 classes[i] = X86_64_SSE_CLASS;
209 /* X86_64_X87UP_CLASS should be preceded by X86_64_X87_CLASS. */
210 if (classes[i] == X86_64_X87UP_CLASS
211 && (i == 0 || classes[i - 1] != X86_64_X87_CLASS))
212 classes[i] = X86_64_SSE_CLASS;
220 return 0; /* Never reached. */
223 /* Examine the argument and return set number of register required in each
224 class. Return 0 iff parameter should be passed in memory. */
226 examine_argument (ffi_type *type, int in_return, int *int_nregs,int *sse_nregs)
228 enum x86_64_reg_class class[MAX_CLASSES];
232 n = classify_argument (type, class, &offset);
242 case X86_64_INTEGER_CLASS:
243 case X86_64_INTEGERSI_CLASS:
246 case X86_64_SSE_CLASS:
247 case X86_64_SSESF_CLASS:
248 case X86_64_SSEDF_CLASS:
251 case X86_64_NO_CLASS:
252 case X86_64_SSEUP_CLASS:
254 case X86_64_X87_CLASS:
255 case X86_64_X87UP_CLASS:
265 /* Functions to load floats and double to an SSE register placeholder. */
266 extern void float2sse (float, __int128_t *);
267 extern void double2sse (double, __int128_t *);
268 extern void floatfloat2sse (void *, __int128_t *);
270 /* Functions to put the floats and doubles back. */
271 extern float sse2float (__int128_t *);
272 extern double sse2double (__int128_t *);
273 extern void sse2floatfloat(__int128_t *, void *);
277 ffi_prep_args (stackLayout *stack, extended_cif *ecif)
280 int gprcount, ssecount, i, g, s;
282 void *argp = &stack->argspace;
285 /* First check if the return value should be passed in memory. If so,
286 pass the pointer as the first argument. */
287 gprcount = ssecount = 0;
288 if (examine_argument (ecif->cif->rtype, 1, &g, &s) == 0)
289 (void *)stack->gpr[gprcount++] = ecif->rvalue;
291 for (i=ecif->cif->nargs, p_arg=ecif->cif->arg_types, p_argv = ecif->avalue;
292 i!=0; i--, p_arg++, p_argv++)
296 switch ((*p_arg)->type)
299 case FFI_TYPE_SINT16:
300 case FFI_TYPE_SINT32:
301 case FFI_TYPE_SINT64:
303 case FFI_TYPE_UINT16:
304 case FFI_TYPE_UINT32:
305 case FFI_TYPE_UINT64:
306 case FFI_TYPE_POINTER:
307 if (gprcount < MAX_GPR_REGS)
309 stack->gpr[gprcount] = 0;
310 stack->gpr[gprcount++] = *(long long *)(*p_argv);
316 if (ssecount < MAX_SSE_REGS)
318 float2sse (*(float *)(*p_argv), &stack->sse[ssecount++]);
323 case FFI_TYPE_DOUBLE:
324 if (ssecount < MAX_SSE_REGS)
326 double2sse (*(double *)(*p_argv), &stack->sse[ssecount++]);
335 /* Either all places in registers where filled, or this is a
336 type that potentially goes into a memory slot. */
337 if (examine_argument (*p_arg, 0, &g, &s) == 0
338 || gprcount + g > MAX_GPR_REGS || ssecount + s > MAX_SSE_REGS)
340 /* Pass this argument in memory. */
341 argp = (void *)ALIGN(argp, (*p_arg)->alignment);
342 memcpy (argp, *p_argv, (*p_arg)->size);
343 argp += (*p_arg)->size;
347 /* All easy cases are eliminated. Now fire the big guns. */
349 enum x86_64_reg_class classes[MAX_CLASSES];
350 int offset = 0, j, num;
353 num = classify_argument (*p_arg, classes, &offset);
354 for (j=0, a=*p_argv; j<num; j++, a+=8)
358 case X86_64_INTEGER_CLASS:
359 case X86_64_INTEGERSI_CLASS:
360 stack->gpr[gprcount++] = *(long long *)a;
362 case X86_64_SSE_CLASS:
363 floatfloat2sse (a, &stack->sse[ssecount++]);
365 case X86_64_SSESF_CLASS:
366 float2sse (*(float *)a, &stack->sse[ssecount++]);
368 case X86_64_SSEDF_CLASS:
369 double2sse (*(double *)a, &stack->sse[ssecount++]);
379 /* Perform machine dependent cif processing. */
381 ffi_prep_cif_machdep (ffi_cif *cif)
383 int gprcount, ssecount, i, g, s;
385 gprcount = ssecount = 0;
387 /* Reset the byte count. We handle this size estimation here. */
390 /* If the return value should be passed in memory, pass the pointer
391 as the first argument. The actual memory isn't allocated here. */
393 if (examine_argument (cif->rtype, 1, &g, &s) == 0)
396 /* Go over all arguments and determine the way they should be passed.
397 If it's in a register and there is space for it, let that be so. If
398 not, add it's size to the stack byte count. */
399 for (i=0; i<cif->nargs; i++)
401 if (examine_argument (cif->arg_types[i], 0, &g, &s) == 0
402 || gprcount + g > MAX_GPR_REGS || ssecount + s > MAX_SSE_REGS)
404 /* This is passed in memory. First align to the basic type. */
405 cif->bytes = ALIGN(cif->bytes, cif->arg_types[i]->alignment);
407 /* Stack arguments are *always* at least 8 byte aligned. */
408 cif->bytes = ALIGN(cif->bytes, 8);
410 /* Now add the size of this argument. */
411 cif->bytes += cif->arg_types[i]->size;
420 /* Set the flag for the closures return. */
421 switch (cif->rtype->type)
424 case FFI_TYPE_STRUCT:
425 case FFI_TYPE_SINT64:
427 case FFI_TYPE_DOUBLE:
428 case FFI_TYPE_LONGDOUBLE:
429 cif->flags = (unsigned) cif->rtype->type;
432 case FFI_TYPE_UINT64:
433 cif->flags = FFI_TYPE_SINT64;
437 cif->flags = FFI_TYPE_INT;
441 puts ("prep_machdep\n");
454 ffi_fill_return_value (return_value *rv, extended_cif *ecif)
456 enum x86_64_reg_class classes[MAX_CLASSES];
459 __int128_t *sse = rv->sse;
463 /* This is needed because of the way x86-64 handles signed short
465 switch (ecif->cif->rtype->type)
468 sc = *(signed char *)gpr;
469 *(long long *)ecif->rvalue = (long long)sc;
471 case FFI_TYPE_SINT16:
472 ss = *(signed short *)gpr;
473 *(long long *)ecif->rvalue = (long long)ss;
480 num = classify_argument (ecif->cif->rtype, classes, &i);
483 /* Return in memory. */
484 ecif->rvalue = (void *) rv->gpr[0];
485 else if (num == 2 && classes[0] == X86_64_X87_CLASS &&
486 classes[1] == X86_64_X87UP_CLASS)
487 /* This is a long double (this is easiest to handle this way instead
488 of an eightbyte at a time as in the loop below. */
489 *((long double *)ecif->rvalue) = rv->st0;
494 for (i=0, a=ecif->rvalue; i<num; i++, a+=8)
498 case X86_64_INTEGER_CLASS:
499 case X86_64_INTEGERSI_CLASS:
500 *(long long *)a = *gpr;
503 case X86_64_SSE_CLASS:
504 sse2floatfloat (sse++, a);
506 case X86_64_SSESF_CLASS:
507 *(float *)a = sse2float (sse++);
509 case X86_64_SSEDF_CLASS:
510 *(double *)a = sse2double (sse++);
521 extern void ffi_call_UNIX64(void (*)(stackLayout *, extended_cif *),
522 void (*) (return_value *, extended_cif *),
523 /*@out@*/ extended_cif *,
524 unsigned, /*@out@*/ unsigned *, void (*fn)());
528 void ffi_call(/*@dependent@*/ ffi_cif *cif,
530 /*@out@*/ void *rvalue,
531 /*@dependent@*/ void **avalue)
537 ecif.avalue = avalue;
539 /* If the return value is a struct and we don't have a return */
540 /* value address then we need to make one */
542 if ((rvalue == NULL) &&
543 (examine_argument (cif->rtype, 1, &dummy, &dummy) == 0))
546 ecif.rvalue = alloca(cif->rtype->size);
550 ecif.rvalue = rvalue;
552 /* Stack must always be 16byte aligned. Make it so. */
553 cif->bytes = ALIGN(cif->bytes, 16);
558 /* Calling 32bit code from 64bit is not possible */
564 ffi_call_UNIX64 (ffi_prep_args, ffi_fill_return_value, &ecif,
565 cif->bytes, ecif.rvalue, fn);
575 #endif /* ifndef __x86_64__ */