2018-08-29 Richard Biener <rguenther@suse.de>
[official-gcc.git] / libffi / src / x86 / darwin64_c.c
blob1daa1c0b6fd84ea47acd27a1d16047265ee980eb
1 /* -----------------------------------------------------------------------
2 ffi64.c - Copyright (c) 20011 Anthony Green
3 Copyright (c) 2008, 2010 Red Hat, Inc.
4 Copyright (c) 2002, 2007 Bo Thorsen <bo@suse.de>
6 x86-64 Foreign Function Interface
8 Permission is hereby granted, free of charge, to any person obtaining
9 a copy of this software and associated documentation files (the
10 ``Software''), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sublicense, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
16 The above copyright notice and this permission notice shall be included
17 in all copies or substantial portions of the Software.
19 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
20 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 DEALINGS IN THE SOFTWARE.
27 ----------------------------------------------------------------------- */
29 #include <ffi.h>
30 #include <ffi_common.h>
32 #include <stdlib.h>
33 #include <stdarg.h>
35 #ifdef __x86_64__
37 #define MAX_GPR_REGS 6
38 #define MAX_SSE_REGS 8
40 #ifdef __INTEL_COMPILER
41 #define UINT128 __m128
42 #else
43 #define UINT128 __int128_t
44 #endif
46 struct register_args
48 /* Registers for argument passing. */
49 UINT64 gpr[MAX_GPR_REGS];
50 UINT128 sse[MAX_SSE_REGS];
53 extern void ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags,
54 void *raddr, void (*fnaddr)(void), unsigned ssecount);
56 /* All reference to register classes here is identical to the code in
57 gcc/config/i386/i386.c. Do *not* change one without the other. */
59 /* Register class used for passing given 64bit part of the argument.
60 These represent classes as documented by the PS ABI, with the
61 exception of SSESF, SSEDF classes, that are basically SSE class,
62 just gcc will use SF or DFmode move instead of DImode to avoid
63 reformatting penalties.
65 Similary we play games with INTEGERSI_CLASS to use cheaper SImode moves
66 whenever possible (upper half does contain padding). */
67 enum x86_64_reg_class
69 X86_64_NO_CLASS,
70 X86_64_INTEGER_CLASS,
71 X86_64_INTEGERSI_CLASS,
72 X86_64_SSE_CLASS,
73 X86_64_SSESF_CLASS,
74 X86_64_SSEDF_CLASS,
75 X86_64_SSEUP_CLASS,
76 X86_64_X87_CLASS,
77 X86_64_X87UP_CLASS,
78 X86_64_COMPLEX_X87_CLASS,
79 X86_64_MEMORY_CLASS
82 #define MAX_CLASSES 4
84 #define SSE_CLASS_P(X) ((X) >= X86_64_SSE_CLASS && X <= X86_64_SSEUP_CLASS)
86 /* x86-64 register passing implementation. See x86-64 ABI for details. Goal
87 of this code is to classify each 8bytes of incoming argument by the register
88 class and assign registers accordingly. */
90 /* Return the union class of CLASS1 and CLASS2.
91 See the x86-64 PS ABI for details. */
93 static enum x86_64_reg_class
94 merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)
96 /* Rule #1: If both classes are equal, this is the resulting class. */
97 if (class1 == class2)
98 return class1;
100 /* Rule #2: If one of the classes is NO_CLASS, the resulting class is
101 the other class. */
102 if (class1 == X86_64_NO_CLASS)
103 return class2;
104 if (class2 == X86_64_NO_CLASS)
105 return class1;
107 /* Rule #3: If one of the classes is MEMORY, the result is MEMORY. */
108 if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
109 return X86_64_MEMORY_CLASS;
111 /* Rule #4: If one of the classes is INTEGER, the result is INTEGER. */
112 if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS)
113 || (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS))
114 return X86_64_INTEGERSI_CLASS;
115 if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS
116 || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)
117 return X86_64_INTEGER_CLASS;
119 /* Rule #5: If one of the classes is X87, X87UP, or COMPLEX_X87 class,
120 MEMORY is used. */
121 if (class1 == X86_64_X87_CLASS
122 || class1 == X86_64_X87UP_CLASS
123 || class1 == X86_64_COMPLEX_X87_CLASS
124 || class2 == X86_64_X87_CLASS
125 || class2 == X86_64_X87UP_CLASS
126 || class2 == X86_64_COMPLEX_X87_CLASS)
127 return X86_64_MEMORY_CLASS;
129 /* Rule #6: Otherwise class SSE is used. */
130 return X86_64_SSE_CLASS;
133 /* Classify the argument of type TYPE and mode MODE.
134 CLASSES will be filled by the register class used to pass each word
135 of the operand. The number of words is returned. In case the parameter
136 should be passed in memory, 0 is returned. As a special case for zero
137 sized containers, classes[0] will be NO_CLASS and 1 is returned.
139 See the x86-64 PS ABI for details.
141 static int
142 classify_argument (ffi_type *type, enum x86_64_reg_class classes[],
143 size_t byte_offset)
145 switch (type->type)
147 case FFI_TYPE_UINT8:
148 case FFI_TYPE_SINT8:
149 case FFI_TYPE_UINT16:
150 case FFI_TYPE_SINT16:
151 case FFI_TYPE_UINT32:
152 case FFI_TYPE_SINT32:
153 case FFI_TYPE_UINT64:
154 case FFI_TYPE_SINT64:
155 case FFI_TYPE_POINTER:
157 int size = byte_offset + type->size;
159 if (size <= 4)
161 classes[0] = X86_64_INTEGERSI_CLASS;
162 return 1;
164 else if (size <= 8)
166 classes[0] = X86_64_INTEGER_CLASS;
167 return 1;
169 else if (size <= 12)
171 classes[0] = X86_64_INTEGER_CLASS;
172 classes[1] = X86_64_INTEGERSI_CLASS;
173 return 2;
175 else if (size <= 16)
177 classes[0] = classes[1] = X86_64_INTEGERSI_CLASS;
178 return 2;
180 else
181 FFI_ASSERT (0);
183 case FFI_TYPE_FLOAT:
184 if (!(byte_offset % 8))
185 classes[0] = X86_64_SSESF_CLASS;
186 else
187 classes[0] = X86_64_SSE_CLASS;
188 return 1;
189 case FFI_TYPE_DOUBLE:
190 classes[0] = X86_64_SSEDF_CLASS;
191 return 1;
192 case FFI_TYPE_LONGDOUBLE:
193 classes[0] = X86_64_X87_CLASS;
194 classes[1] = X86_64_X87UP_CLASS;
195 return 2;
196 case FFI_TYPE_STRUCT:
198 const int UNITS_PER_WORD = 8;
199 int words = (type->size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
200 ffi_type **ptr;
201 int i;
202 enum x86_64_reg_class subclasses[MAX_CLASSES];
204 /* If the struct is larger than 32 bytes, pass it on the stack. */
205 if (type->size > 32)
206 return 0;
208 for (i = 0; i < words; i++)
209 classes[i] = X86_64_NO_CLASS;
211 /* Zero sized arrays or structures are NO_CLASS. We return 0 to
212 signalize memory class, so handle it as special case. */
213 if (!words)
215 classes[0] = X86_64_NO_CLASS;
216 return 1;
219 /* Merge the fields of structure. */
220 for (ptr = type->elements; *ptr != NULL; ptr++)
222 int num;
224 byte_offset = ALIGN (byte_offset, (*ptr)->alignment);
226 num = classify_argument (*ptr, subclasses, byte_offset % 8);
227 if (num == 0)
228 return 0;
229 for (i = 0; i < num; i++)
231 int pos = byte_offset / 8;
232 classes[i + pos] =
233 merge_classes (subclasses[i], classes[i + pos]);
236 byte_offset += (*ptr)->size;
239 if (words > 2)
241 /* When size > 16 bytes, if the first one isn't
242 X86_64_SSE_CLASS or any other ones aren't
243 X86_64_SSEUP_CLASS, everything should be passed in
244 memory. */
245 if (classes[0] != X86_64_SSE_CLASS)
246 return 0;
248 for (i = 1; i < words; i++)
249 if (classes[i] != X86_64_SSEUP_CLASS)
250 return 0;
253 /* Final merger cleanup. */
254 for (i = 0; i < words; i++)
256 /* If one class is MEMORY, everything should be passed in
257 memory. */
258 if (classes[i] == X86_64_MEMORY_CLASS)
259 return 0;
261 /* The X86_64_SSEUP_CLASS should be always preceded by
262 X86_64_SSE_CLASS or X86_64_SSEUP_CLASS. */
263 if (classes[i] == X86_64_SSEUP_CLASS
264 && classes[i - 1] != X86_64_SSE_CLASS
265 && classes[i - 1] != X86_64_SSEUP_CLASS)
267 /* The first one should never be X86_64_SSEUP_CLASS. */
268 FFI_ASSERT (i != 0);
269 classes[i] = X86_64_SSE_CLASS;
272 /* If X86_64_X87UP_CLASS isn't preceded by X86_64_X87_CLASS,
273 everything should be passed in memory. */
274 if (classes[i] == X86_64_X87UP_CLASS
275 && (classes[i - 1] != X86_64_X87_CLASS))
277 /* The first one should never be X86_64_X87UP_CLASS. */
278 FFI_ASSERT (i != 0);
279 return 0;
282 return words;
285 default:
286 FFI_ASSERT(0);
288 return 0; /* Never reached. */
291 /* Examine the argument and return set number of register required in each
292 class. Return zero iff parameter should be passed in memory, otherwise
293 the number of registers. */
295 static int
296 examine_argument (ffi_type *type, enum x86_64_reg_class classes[MAX_CLASSES],
297 _Bool in_return, int *pngpr, int *pnsse)
299 int i, n, ngpr, nsse;
301 n = classify_argument (type, classes, 0);
302 if (n == 0)
303 return 0;
305 ngpr = nsse = 0;
306 for (i = 0; i < n; ++i)
307 switch (classes[i])
309 case X86_64_INTEGER_CLASS:
310 case X86_64_INTEGERSI_CLASS:
311 ngpr++;
312 break;
313 case X86_64_SSE_CLASS:
314 case X86_64_SSESF_CLASS:
315 case X86_64_SSEDF_CLASS:
316 nsse++;
317 break;
318 case X86_64_NO_CLASS:
319 case X86_64_SSEUP_CLASS:
320 break;
321 case X86_64_X87_CLASS:
322 case X86_64_X87UP_CLASS:
323 case X86_64_COMPLEX_X87_CLASS:
324 return in_return != 0;
325 default:
326 abort ();
329 *pngpr = ngpr;
330 *pnsse = nsse;
332 return n;
335 /* Perform machine dependent cif processing. */
337 ffi_status
338 ffi_prep_cif_machdep (ffi_cif *cif)
340 int gprcount, ssecount, i, avn, n, ngpr, nsse, flags;
341 enum x86_64_reg_class classes[MAX_CLASSES];
342 size_t bytes;
344 gprcount = ssecount = 0;
346 flags = cif->rtype->type;
347 if (flags != FFI_TYPE_VOID)
349 n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse);
350 if (n == 0)
352 /* The return value is passed in memory. A pointer to that
353 memory is the first argument. Allocate a register for it. */
354 gprcount++;
355 /* We don't have to do anything in asm for the return. */
356 flags = FFI_TYPE_VOID;
358 else if (flags == FFI_TYPE_STRUCT)
360 /* Mark which registers the result appears in. */
361 _Bool sse0 = SSE_CLASS_P (classes[0]);
362 _Bool sse1 = n == 2 && SSE_CLASS_P (classes[1]);
363 if (sse0 && !sse1)
364 flags |= 1 << 8;
365 else if (!sse0 && sse1)
366 flags |= 1 << 9;
367 else if (sse0 && sse1)
368 flags |= 1 << 10;
369 /* Mark the true size of the structure. */
370 flags |= cif->rtype->size << 12;
374 /* Go over all arguments and determine the way they should be passed.
375 If it's in a register and there is space for it, let that be so. If
376 not, add it's size to the stack byte count. */
377 for (bytes = 0, i = 0, avn = cif->nargs; i < avn; i++)
379 if (examine_argument (cif->arg_types[i], classes, 0, &ngpr, &nsse) == 0
380 || gprcount + ngpr > MAX_GPR_REGS
381 || ssecount + nsse > MAX_SSE_REGS)
383 long align = cif->arg_types[i]->alignment;
385 if (align < 8)
386 align = 8;
388 bytes = ALIGN (bytes, align);
389 bytes += cif->arg_types[i]->size;
391 else
393 gprcount += ngpr;
394 ssecount += nsse;
397 if (ssecount)
398 flags |= 1 << 11;
399 cif->flags = flags;
400 cif->bytes = ALIGN (bytes, 8);
402 return FFI_OK;
405 void
406 ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
408 enum x86_64_reg_class classes[MAX_CLASSES];
409 char *stack, *argp;
410 ffi_type **arg_types;
411 int gprcount, ssecount, ngpr, nsse, i, avn;
412 _Bool ret_in_memory;
413 struct register_args *reg_args;
415 /* Can't call 32-bit mode from 64-bit mode. */
416 FFI_ASSERT (cif->abi == FFI_UNIX64);
418 /* If the return value is a struct and we don't have a return value
419 address then we need to make one. Note the setting of flags to
420 VOID above in ffi_prep_cif_machdep. */
421 ret_in_memory = (cif->rtype->type == FFI_TYPE_STRUCT
422 && (cif->flags & 0xff) == FFI_TYPE_VOID);
423 if (rvalue == NULL && ret_in_memory)
424 rvalue = alloca (cif->rtype->size);
426 /* Allocate the space for the arguments, plus 4 words of temp space. */
427 stack = alloca (sizeof (struct register_args) + cif->bytes + 4*8);
428 reg_args = (struct register_args *) stack;
429 argp = stack + sizeof (struct register_args);
431 gprcount = ssecount = 0;
433 /* If the return value is passed in memory, add the pointer as the
434 first integer argument. */
435 if (ret_in_memory)
436 reg_args->gpr[gprcount++] = (unsigned long) rvalue;
438 avn = cif->nargs;
439 arg_types = cif->arg_types;
441 for (i = 0; i < avn; ++i)
443 size_t size = arg_types[i]->size;
444 int n;
446 n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse);
447 if (n == 0
448 || gprcount + ngpr > MAX_GPR_REGS
449 || ssecount + nsse > MAX_SSE_REGS)
451 long align = arg_types[i]->alignment;
453 /* Stack arguments are *always* at least 8 byte aligned. */
454 if (align < 8)
455 align = 8;
457 /* Pass this argument in memory. */
458 argp = (void *) ALIGN (argp, align);
459 memcpy (argp, avalue[i], size);
460 argp += size;
462 else
464 /* The argument is passed entirely in registers. */
465 char *a = (char *) avalue[i];
466 int j;
468 for (j = 0; j < n; j++, a += 8, size -= 8)
470 switch (classes[j])
472 case X86_64_INTEGER_CLASS:
473 case X86_64_INTEGERSI_CLASS:
474 reg_args->gpr[gprcount] = 0;
475 memcpy (&reg_args->gpr[gprcount], a, size < 8 ? size : 8);
476 gprcount++;
477 break;
478 case X86_64_SSE_CLASS:
479 case X86_64_SSEDF_CLASS:
480 reg_args->sse[ssecount++] = *(UINT64 *) a;
481 break;
482 case X86_64_SSESF_CLASS:
483 reg_args->sse[ssecount++] = *(UINT32 *) a;
484 break;
485 default:
486 abort();
492 ffi_call_unix64 (stack, cif->bytes + sizeof (struct register_args),
493 cif->flags, rvalue, fn, ssecount);
497 extern void ffi_closure_unix64(void);
499 ffi_status
500 ffi_prep_closure_loc (ffi_closure* closure,
501 ffi_cif* cif,
502 void (*fun)(ffi_cif*, void*, void**, void*),
503 void *user_data,
504 void *codeloc)
506 volatile unsigned short *tramp;
508 /* Sanity check on the cif ABI. */
510 int abi = cif->abi;
511 if (UNLIKELY (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI)))
512 return FFI_BAD_ABI;
515 tramp = (volatile unsigned short *) &closure->tramp[0];
517 tramp[0] = 0xbb49; /* mov <code>, %r11 */
518 *((unsigned long long * volatile) &tramp[1])
519 = (unsigned long) ffi_closure_unix64;
520 tramp[5] = 0xba49; /* mov <data>, %r10 */
521 *((unsigned long long * volatile) &tramp[6])
522 = (unsigned long) codeloc;
524 /* Set the carry bit iff the function uses any sse registers.
525 This is clc or stc, together with the first byte of the jmp. */
526 tramp[10] = cif->flags & (1 << 11) ? 0x49f9 : 0x49f8;
528 tramp[11] = 0xe3ff; /* jmp *%r11 */
530 closure->cif = cif;
531 closure->fun = fun;
532 closure->user_data = user_data;
534 return FFI_OK;
538 ffi_closure_unix64_inner(ffi_closure *closure, void *rvalue,
539 struct register_args *reg_args, char *argp)
541 ffi_cif *cif;
542 void **avalue;
543 ffi_type **arg_types;
544 long i, avn;
545 int gprcount, ssecount, ngpr, nsse;
546 int ret;
548 cif = closure->cif;
549 avalue = alloca(cif->nargs * sizeof(void *));
550 gprcount = ssecount = 0;
552 ret = cif->rtype->type;
553 if (ret != FFI_TYPE_VOID)
555 enum x86_64_reg_class classes[MAX_CLASSES];
556 int n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse);
557 if (n == 0)
559 /* The return value goes in memory. Arrange for the closure
560 return value to go directly back to the original caller. */
561 rvalue = (void *) (unsigned long) reg_args->gpr[gprcount++];
562 /* We don't have to do anything in asm for the return. */
563 ret = FFI_TYPE_VOID;
565 else if (ret == FFI_TYPE_STRUCT && n == 2)
567 /* Mark which register the second word of the structure goes in. */
568 _Bool sse0 = SSE_CLASS_P (classes[0]);
569 _Bool sse1 = SSE_CLASS_P (classes[1]);
570 if (!sse0 && sse1)
571 ret |= 1 << 8;
572 else if (sse0 && !sse1)
573 ret |= 1 << 9;
577 avn = cif->nargs;
578 arg_types = cif->arg_types;
580 for (i = 0; i < avn; ++i)
582 enum x86_64_reg_class classes[MAX_CLASSES];
583 int n;
585 n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse);
586 if (n == 0
587 || gprcount + ngpr > MAX_GPR_REGS
588 || ssecount + nsse > MAX_SSE_REGS)
590 long align = arg_types[i]->alignment;
592 /* Stack arguments are *always* at least 8 byte aligned. */
593 if (align < 8)
594 align = 8;
596 /* Pass this argument in memory. */
597 argp = (void *) ALIGN (argp, align);
598 avalue[i] = argp;
599 argp += arg_types[i]->size;
601 /* If the argument is in a single register, or two consecutive
602 integer registers, then we can use that address directly. */
603 else if (n == 1
604 || (n == 2 && !(SSE_CLASS_P (classes[0])
605 || SSE_CLASS_P (classes[1]))))
607 /* The argument is in a single register. */
608 if (SSE_CLASS_P (classes[0]))
610 avalue[i] = &reg_args->sse[ssecount];
611 ssecount += n;
613 else
615 avalue[i] = &reg_args->gpr[gprcount];
616 gprcount += n;
619 /* Otherwise, allocate space to make them consecutive. */
620 else
622 char *a = alloca (16);
623 int j;
625 avalue[i] = a;
626 for (j = 0; j < n; j++, a += 8)
628 if (SSE_CLASS_P (classes[j]))
629 memcpy (a, &reg_args->sse[ssecount++], 8);
630 else
631 memcpy (a, &reg_args->gpr[gprcount++], 8);
636 /* Invoke the closure. */
637 closure->fun (cif, rvalue, avalue, closure->user_data);
639 /* Tell assembly how to perform return type promotions. */
640 return ret;
643 #endif /* __x86_64__ */