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>
32 /* ffi_prep_args is called by the assembly routine once stack space
33 has been allocated for the function's arguments */
37 #define MAX_GPR_REGS 6
38 #define MAX_SSE_REGS 8
41 /* Registers for argument passing. */
42 long gpr[MAX_GPR_REGS];
43 __int128_t sse[MAX_SSE_REGS];
45 /* Stack space for arguments. */
49 /* All reference to register classes here is identical to the code in
50 gcc/config/i386/i386.c. Do *not* change one without the other. */
52 /* Register class used for passing given 64bit part of the argument.
53 These represent classes as documented by the PS ABI, with the exception
54 of SSESF, SSEDF classes, that are basically SSE class, just gcc will
55 use SF or DFmode move instead of DImode to avoid reformating penalties.
57 Similary we play games with INTEGERSI_CLASS to use cheaper SImode moves
58 whenever possible (upper half does contain padding).
64 X86_64_INTEGERSI_CLASS,
76 /* x86-64 register passing implementation. See x86-64 ABI for details. Goal
77 of this code is to classify each 8bytes of incoming argument by the register
78 class and assign registers accordingly. */
80 /* Return the union class of CLASS1 and CLASS2.
81 See the x86-64 PS ABI for details. */
83 static enum x86_64_reg_class
84 merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)
86 /* Rule #1: If both classes are equal, this is the resulting class. */
90 /* Rule #2: If one of the classes is NO_CLASS, the resulting class is
92 if (class1 == X86_64_NO_CLASS)
94 if (class2 == X86_64_NO_CLASS)
97 /* Rule #3: If one of the classes is MEMORY, the result is MEMORY. */
98 if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
99 return X86_64_MEMORY_CLASS;
101 /* Rule #4: If one of the classes is INTEGER, the result is INTEGER. */
102 if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS)
103 || (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS))
104 return X86_64_INTEGERSI_CLASS;
105 if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS
106 || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)
107 return X86_64_INTEGER_CLASS;
109 /* Rule #5: If one of the classes is X87 or X87UP class, MEMORY is used. */
110 if (class1 == X86_64_X87_CLASS || class1 == X86_64_X87UP_CLASS
111 || class2 == X86_64_X87_CLASS || class2 == X86_64_X87UP_CLASS)
112 return X86_64_MEMORY_CLASS;
114 /* Rule #6: Otherwise class SSE is used. */
115 return X86_64_SSE_CLASS;
118 /* Classify the argument of type TYPE and mode MODE.
119 CLASSES will be filled by the register class used to pass each word
120 of the operand. The number of words is returned. In case the parameter
121 should be passed in memory, 0 is returned. As a special case for zero
122 sized containers, classes[0] will be NO_CLASS and 1 is returned.
124 See the x86-64 PS ABI for details.
127 classify_argument (ffi_type *type, enum x86_64_reg_class classes[],
130 /* First, align to the right place. */
131 *byte_offset = ALIGN(*byte_offset, type->alignment);
137 case FFI_TYPE_UINT16:
138 case FFI_TYPE_SINT16:
139 case FFI_TYPE_UINT32:
140 case FFI_TYPE_SINT32:
141 case FFI_TYPE_UINT64:
142 case FFI_TYPE_SINT64:
143 case FFI_TYPE_POINTER:
144 if (((*byte_offset) % 8 + type->size) <= 4)
145 classes[0] = X86_64_INTEGERSI_CLASS;
147 classes[0] = X86_64_INTEGER_CLASS;
150 if (((*byte_offset) % 8) == 0)
151 classes[0] = X86_64_SSESF_CLASS;
153 classes[0] = X86_64_SSE_CLASS;
155 case FFI_TYPE_DOUBLE:
156 classes[0] = X86_64_SSEDF_CLASS;
158 case FFI_TYPE_LONGDOUBLE:
159 classes[0] = X86_64_X87_CLASS;
160 classes[1] = X86_64_X87UP_CLASS;
162 case FFI_TYPE_STRUCT:
164 const int UNITS_PER_WORD = 8;
165 int words = (type->size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
168 enum x86_64_reg_class subclasses[MAX_CLASSES];
170 /* If the struct is larger than 16 bytes, pass it on the stack. */
174 for (i = 0; i < words; i++)
175 classes[i] = X86_64_NO_CLASS;
177 /* Merge the fields of structure. */
178 for (ptr=type->elements; (*ptr)!=NULL; ptr++)
182 num = classify_argument (*ptr, subclasses, byte_offset);
185 for (i = 0; i < num; i++)
187 int pos = *byte_offset / 8;
189 merge_classes (subclasses[i], classes[i + pos]);
192 if ((*ptr)->type != FFI_TYPE_STRUCT)
193 *byte_offset += (*ptr)->size;
196 /* Final merger cleanup. */
197 for (i = 0; i < words; i++)
199 /* If one class is MEMORY, everything should be passed in
201 if (classes[i] == X86_64_MEMORY_CLASS)
204 /* The X86_64_SSEUP_CLASS should be always preceded by
206 if (classes[i] == X86_64_SSEUP_CLASS
207 && (i == 0 || classes[i - 1] != X86_64_SSE_CLASS))
208 classes[i] = X86_64_SSE_CLASS;
210 /* X86_64_X87UP_CLASS should be preceded by X86_64_X87_CLASS. */
211 if (classes[i] == X86_64_X87UP_CLASS
212 && (i == 0 || classes[i - 1] != X86_64_X87_CLASS))
213 classes[i] = X86_64_SSE_CLASS;
221 return 0; /* Never reached. */
224 /* Examine the argument and return set number of register required in each
225 class. Return 0 iff parameter should be passed in memory. */
227 examine_argument (ffi_type *type, int in_return, int *int_nregs,int *sse_nregs)
229 enum x86_64_reg_class class[MAX_CLASSES];
233 n = classify_argument (type, class, &offset);
243 case X86_64_INTEGER_CLASS:
244 case X86_64_INTEGERSI_CLASS:
247 case X86_64_SSE_CLASS:
248 case X86_64_SSESF_CLASS:
249 case X86_64_SSEDF_CLASS:
252 case X86_64_NO_CLASS:
253 case X86_64_SSEUP_CLASS:
255 case X86_64_X87_CLASS:
256 case X86_64_X87UP_CLASS:
266 /* Functions to load floats and double to an SSE register placeholder. */
267 extern void float2sse (float, __int128_t *);
268 extern void double2sse (double, __int128_t *);
269 extern void floatfloat2sse (void *, __int128_t *);
271 /* Functions to put the floats and doubles back. */
272 extern float sse2float (__int128_t *);
273 extern double sse2double (__int128_t *);
274 extern void sse2floatfloat(__int128_t *, void *);
278 ffi_prep_args (stackLayout *stack, extended_cif *ecif)
281 int gprcount, ssecount, i, g, s;
283 void *argp = &stack->argspace;
286 /* First check if the return value should be passed in memory. If so,
287 pass the pointer as the first argument. */
288 gprcount = ssecount = 0;
289 if (ecif->cif->rtype->type != FFI_TYPE_VOID
290 && examine_argument (ecif->cif->rtype, 1, &g, &s) == 0)
291 stack->gpr[gprcount++] = (long) ecif->rvalue;
293 for (i=ecif->cif->nargs, p_arg=ecif->cif->arg_types, p_argv = ecif->avalue;
294 i!=0; i--, p_arg++, p_argv++)
298 switch ((*p_arg)->type)
301 case FFI_TYPE_SINT16:
302 case FFI_TYPE_SINT32:
303 case FFI_TYPE_SINT64:
305 case FFI_TYPE_UINT16:
306 case FFI_TYPE_UINT32:
307 case FFI_TYPE_UINT64:
308 case FFI_TYPE_POINTER:
309 if (gprcount < MAX_GPR_REGS)
311 stack->gpr[gprcount] = 0;
312 stack->gpr[gprcount++] = *(long long *)(*p_argv);
318 if (ssecount < MAX_SSE_REGS)
320 float2sse (*(float *)(*p_argv), &stack->sse[ssecount++]);
325 case FFI_TYPE_DOUBLE:
326 if (ssecount < MAX_SSE_REGS)
328 double2sse (*(double *)(*p_argv), &stack->sse[ssecount++]);
337 /* Either all places in registers where filled, or this is a
338 type that potentially goes into a memory slot. */
339 if (examine_argument (*p_arg, 0, &g, &s) == 0
340 || gprcount + g > MAX_GPR_REGS || ssecount + s > MAX_SSE_REGS)
342 /* Pass this argument in memory. */
343 argp = (void *)ALIGN(argp, (*p_arg)->alignment);
344 /* Stack arguments are *always* at least 8 byte aligned. */
345 argp = (void *)ALIGN(argp, 8);
346 memcpy (argp, *p_argv, (*p_arg)->size);
347 argp += (*p_arg)->size;
351 /* All easy cases are eliminated. Now fire the big guns. */
353 enum x86_64_reg_class classes[MAX_CLASSES];
354 int offset = 0, j, num;
357 num = classify_argument (*p_arg, classes, &offset);
358 for (j=0, a=*p_argv; j<num; j++, a+=8)
362 case X86_64_INTEGER_CLASS:
363 case X86_64_INTEGERSI_CLASS:
364 stack->gpr[gprcount++] = *(long long *)a;
366 case X86_64_SSE_CLASS:
367 floatfloat2sse (a, &stack->sse[ssecount++]);
369 case X86_64_SSESF_CLASS:
370 float2sse (*(float *)a, &stack->sse[ssecount++]);
372 case X86_64_SSEDF_CLASS:
373 double2sse (*(double *)a, &stack->sse[ssecount++]);
383 /* Perform machine dependent cif processing. */
385 ffi_prep_cif_machdep (ffi_cif *cif)
387 int gprcount, ssecount, i, g, s;
389 gprcount = ssecount = 0;
391 /* Reset the byte count. We handle this size estimation here. */
394 /* If the return value should be passed in memory, pass the pointer
395 as the first argument. The actual memory isn't allocated here. */
396 if (cif->rtype->type != FFI_TYPE_VOID
397 && examine_argument (cif->rtype, 1, &g, &s) == 0)
400 /* Go over all arguments and determine the way they should be passed.
401 If it's in a register and there is space for it, let that be so. If
402 not, add it's size to the stack byte count. */
403 for (i=0; i<cif->nargs; i++)
405 if (examine_argument (cif->arg_types[i], 0, &g, &s) == 0
406 || gprcount + g > MAX_GPR_REGS || ssecount + s > MAX_SSE_REGS)
408 /* This is passed in memory. First align to the basic type. */
409 cif->bytes = ALIGN(cif->bytes, cif->arg_types[i]->alignment);
411 /* Stack arguments are *always* at least 8 byte aligned. */
412 cif->bytes = ALIGN(cif->bytes, 8);
414 /* Now add the size of this argument. */
415 cif->bytes += cif->arg_types[i]->size;
424 /* Set the flag for the closures return. */
425 switch (cif->rtype->type)
428 case FFI_TYPE_STRUCT:
429 case FFI_TYPE_SINT64:
431 case FFI_TYPE_DOUBLE:
432 case FFI_TYPE_LONGDOUBLE:
433 cif->flags = (unsigned) cif->rtype->type;
436 case FFI_TYPE_UINT64:
437 cif->flags = FFI_TYPE_SINT64;
441 cif->flags = FFI_TYPE_INT;
456 ffi_fill_return_value (return_value *rv, extended_cif *ecif)
458 enum x86_64_reg_class classes[MAX_CLASSES];
461 __int128_t *sse = rv->sse;
465 /* This is needed because of the way x86-64 handles signed short
467 switch (ecif->cif->rtype->type)
470 sc = *(signed char *)gpr;
471 *(long long *)ecif->rvalue = (long long)sc;
473 case FFI_TYPE_SINT16:
474 ss = *(signed short *)gpr;
475 *(long long *)ecif->rvalue = (long long)ss;
482 num = classify_argument (ecif->cif->rtype, classes, &i);
485 /* Return in memory. */
486 ecif->rvalue = (void *) rv->gpr[0];
487 else if (num == 2 && classes[0] == X86_64_X87_CLASS &&
488 classes[1] == X86_64_X87UP_CLASS)
489 /* This is a long double (this is easiest to handle this way instead
490 of an eightbyte at a time as in the loop below. */
491 *((long double *)ecif->rvalue) = rv->st0;
496 for (i=0, a=ecif->rvalue; i<num; i++, a+=8)
500 case X86_64_INTEGER_CLASS:
501 case X86_64_INTEGERSI_CLASS:
502 *(long long *)a = *gpr;
505 case X86_64_SSE_CLASS:
506 sse2floatfloat (sse++, a);
508 case X86_64_SSESF_CLASS:
509 *(float *)a = sse2float (sse++);
511 case X86_64_SSEDF_CLASS:
512 *(double *)a = sse2double (sse++);
523 extern void ffi_call_UNIX64(void (*)(stackLayout *, extended_cif *),
524 void (*) (return_value *, extended_cif *),
525 /*@out@*/ extended_cif *,
526 unsigned, /*@out@*/ unsigned *, void (*fn)());
530 void ffi_call(/*@dependent@*/ ffi_cif *cif,
532 /*@out@*/ void *rvalue,
533 /*@dependent@*/ void **avalue)
539 ecif.avalue = avalue;
541 /* If the return value is a struct and we don't have a return */
542 /* value address then we need to make one */
544 if ((rvalue == NULL) &&
545 (examine_argument (cif->rtype, 1, &dummy, &dummy) == 0))
548 ecif.rvalue = alloca(cif->rtype->size);
552 ecif.rvalue = rvalue;
554 /* Stack must always be 16byte aligned. Make it so. */
555 cif->bytes = ALIGN(cif->bytes, 16);
560 /* Calling 32bit code from 64bit is not possible */
566 ffi_call_UNIX64 (ffi_prep_args, ffi_fill_return_value, &ecif,
567 cif->bytes, ecif.rvalue, fn);
577 extern void ffi_closure_UNIX64(void);
580 ffi_prep_closure (ffi_closure* closure,
582 void (*fun)(ffi_cif*, void*, void**, void*),
585 volatile unsigned short *tramp;
587 /* FFI_ASSERT (cif->abi == FFI_OSF); */
589 tramp = (volatile unsigned short *) &closure->tramp[0];
590 tramp[0] = 0xbb49; /* mov <code>, %r11 */
591 tramp[5] = 0xba49; /* mov <data>, %r10 */
592 tramp[10] = 0xff49; /* jmp *%r11 */
594 *(void * volatile *) &tramp[1] = ffi_closure_UNIX64;
595 *(void * volatile *) &tramp[6] = closure;
599 closure->user_data = user_data;
605 ffi_closure_UNIX64_inner(ffi_closure *closure, va_list l, void *rp)
609 ffi_type **arg_types;
613 avalue = alloca(cif->nargs * sizeof(void *));
619 arg_types = cif->arg_types;
621 /* Grab the addresses of the arguments from the stack frame. */
624 switch (arg_types[i]->type)
628 case FFI_TYPE_SINT16:
629 case FFI_TYPE_UINT16:
630 case FFI_TYPE_SINT32:
631 case FFI_TYPE_UINT32:
632 case FFI_TYPE_SINT64:
633 case FFI_TYPE_UINT64:
634 case FFI_TYPE_POINTER:
636 if (l->gp_offset > 48-8)
638 avalue[i] = l->overflow_arg_area;
639 l->overflow_arg_area = (char *)l->overflow_arg_area + 8;
643 avalue[i] = (char *)l->reg_save_area + l->gp_offset;
649 case FFI_TYPE_STRUCT:
654 case FFI_TYPE_DOUBLE:
656 if (l->fp_offset > 176-16)
658 avalue[i] = l->overflow_arg_area;
659 l->overflow_arg_area = (char *)l->overflow_arg_area + 8;
663 avalue[i] = (char *)l->reg_save_area + l->fp_offset;
668 fprintf (stderr, "double arg %d = %g\n", i, *(double *)avalue[i]);
674 if (l->fp_offset > 176-16)
676 avalue[i] = l->overflow_arg_area;
677 l->overflow_arg_area = (char *)l->overflow_arg_area + 8;
681 avalue[i] = (char *)l->reg_save_area + l->fp_offset;
686 fprintf (stderr, "float arg %d = %g\n", i, *(float *)avalue[i]);
694 argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
698 /* Invoke the closure. */
699 (closure->fun) (cif, rp, avalue, closure->user_data);
701 /* FIXME: Structs not supported. */
702 FFI_ASSERT(cif->rtype->type != FFI_TYPE_STRUCT);
704 /* Tell ffi_closure_UNIX64 how to perform return type promotions. */
706 return cif->rtype->type;
708 #endif /* ifndef __x86_64__ */