PR tree-ssa/57385
[official-gcc.git] / libffi / src / sparc / ffi.c
blob1ac5d464e8b992770dfe1f90b685f0eb5ba7cdf6
1 /* -----------------------------------------------------------------------
2 ffi.c - Copyright (c) 2011 Anthony Green
3 Copyright (c) 1996, 2003-2004, 2007-2008 Red Hat, Inc.
5 SPARC Foreign Function Interface
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 ``Software''), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
15 The above copyright notice and this permission notice shall be included
16 in all copies or substantial portions of the Software.
18 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 DEALINGS IN THE SOFTWARE.
26 ----------------------------------------------------------------------- */
28 #include <ffi.h>
29 #include <ffi_common.h>
31 #include <stdlib.h>
34 /* ffi_prep_args is called by the assembly routine once stack space
35 has been allocated for the function's arguments */
37 void ffi_prep_args_v8(char *stack, extended_cif *ecif)
39 int i;
40 void **p_argv;
41 char *argp;
42 ffi_type **p_arg;
44 /* Skip 16 words for the window save area */
45 argp = stack + 16*sizeof(int);
47 /* This should only really be done when we are returning a structure,
48 however, it's faster just to do it all the time...
50 if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) */
51 *(int *) argp = (long)ecif->rvalue;
53 /* And 1 word for the structure return value. */
54 argp += sizeof(int);
56 #ifdef USING_PURIFY
57 /* Purify will probably complain in our assembly routine, unless we
58 zero out this memory. */
60 ((int*)argp)[0] = 0;
61 ((int*)argp)[1] = 0;
62 ((int*)argp)[2] = 0;
63 ((int*)argp)[3] = 0;
64 ((int*)argp)[4] = 0;
65 ((int*)argp)[5] = 0;
66 #endif
68 p_argv = ecif->avalue;
70 for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++)
72 size_t z;
74 if ((*p_arg)->type == FFI_TYPE_STRUCT
75 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
76 || (*p_arg)->type == FFI_TYPE_LONGDOUBLE
77 #endif
80 *(unsigned int *) argp = (unsigned long)(* p_argv);
81 z = sizeof(int);
83 else
85 z = (*p_arg)->size;
86 if (z < sizeof(int))
88 z = sizeof(int);
89 switch ((*p_arg)->type)
91 case FFI_TYPE_SINT8:
92 *(signed int *) argp = *(SINT8 *)(* p_argv);
93 break;
95 case FFI_TYPE_UINT8:
96 *(unsigned int *) argp = *(UINT8 *)(* p_argv);
97 break;
99 case FFI_TYPE_SINT16:
100 *(signed int *) argp = *(SINT16 *)(* p_argv);
101 break;
103 case FFI_TYPE_UINT16:
104 *(unsigned int *) argp = *(UINT16 *)(* p_argv);
105 break;
107 default:
108 FFI_ASSERT(0);
111 else
113 memcpy(argp, *p_argv, z);
116 p_argv++;
117 argp += z;
120 return;
123 int ffi_prep_args_v9(char *stack, extended_cif *ecif)
125 int i, ret = 0;
126 int tmp;
127 void **p_argv;
128 char *argp;
129 ffi_type **p_arg;
131 tmp = 0;
133 /* Skip 16 words for the window save area */
134 argp = stack + 16*sizeof(long long);
136 #ifdef USING_PURIFY
137 /* Purify will probably complain in our assembly routine, unless we
138 zero out this memory. */
140 ((long long*)argp)[0] = 0;
141 ((long long*)argp)[1] = 0;
142 ((long long*)argp)[2] = 0;
143 ((long long*)argp)[3] = 0;
144 ((long long*)argp)[4] = 0;
145 ((long long*)argp)[5] = 0;
146 #endif
148 p_argv = ecif->avalue;
150 if (ecif->cif->rtype->type == FFI_TYPE_STRUCT &&
151 ecif->cif->rtype->size > 32)
153 *(unsigned long long *) argp = (unsigned long)ecif->rvalue;
154 argp += sizeof(long long);
155 tmp = 1;
158 for (i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs;
159 i++, p_arg++)
161 size_t z;
163 z = (*p_arg)->size;
164 switch ((*p_arg)->type)
166 case FFI_TYPE_STRUCT:
167 if (z > 16)
169 /* For structures larger than 16 bytes we pass reference. */
170 *(unsigned long long *) argp = (unsigned long)* p_argv;
171 argp += sizeof(long long);
172 tmp++;
173 p_argv++;
174 continue;
176 /* FALLTHROUGH */
177 case FFI_TYPE_FLOAT:
178 case FFI_TYPE_DOUBLE:
179 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
180 case FFI_TYPE_LONGDOUBLE:
181 #endif
182 ret = 1; /* We should promote into FP regs as well as integer. */
183 break;
185 if (z < sizeof(long long))
187 switch ((*p_arg)->type)
189 case FFI_TYPE_SINT8:
190 *(signed long long *) argp = *(SINT8 *)(* p_argv);
191 break;
193 case FFI_TYPE_UINT8:
194 *(unsigned long long *) argp = *(UINT8 *)(* p_argv);
195 break;
197 case FFI_TYPE_SINT16:
198 *(signed long long *) argp = *(SINT16 *)(* p_argv);
199 break;
201 case FFI_TYPE_UINT16:
202 *(unsigned long long *) argp = *(UINT16 *)(* p_argv);
203 break;
205 case FFI_TYPE_SINT32:
206 *(signed long long *) argp = *(SINT32 *)(* p_argv);
207 break;
209 case FFI_TYPE_UINT32:
210 *(unsigned long long *) argp = *(UINT32 *)(* p_argv);
211 break;
213 case FFI_TYPE_FLOAT:
214 *(float *) (argp + 4) = *(FLOAT32 *)(* p_argv); /* Right justify */
215 break;
217 case FFI_TYPE_STRUCT:
218 memcpy(argp, *p_argv, z);
219 break;
221 default:
222 FFI_ASSERT(0);
224 z = sizeof(long long);
225 tmp++;
227 else if (z == sizeof(long long))
229 memcpy(argp, *p_argv, z);
230 z = sizeof(long long);
231 tmp++;
233 else
235 if ((tmp & 1) && (*p_arg)->alignment > 8)
237 tmp++;
238 argp += sizeof(long long);
240 memcpy(argp, *p_argv, z);
241 z = 2 * sizeof(long long);
242 tmp += 2;
244 p_argv++;
245 argp += z;
248 return ret;
251 /* Perform machine dependent cif processing */
252 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
254 int wordsize;
256 if (cif->abi != FFI_V9)
258 wordsize = 4;
260 /* If we are returning a struct, this will already have been added.
261 Otherwise we need to add it because it's always got to be there! */
263 if (cif->rtype->type != FFI_TYPE_STRUCT)
264 cif->bytes += wordsize;
266 /* sparc call frames require that space is allocated for 6 args,
267 even if they aren't used. Make that space if necessary. */
269 if (cif->bytes < 4*6+4)
270 cif->bytes = 4*6+4;
272 else
274 wordsize = 8;
276 /* sparc call frames require that space is allocated for 6 args,
277 even if they aren't used. Make that space if necessary. */
279 if (cif->bytes < 8*6)
280 cif->bytes = 8*6;
283 /* Adjust cif->bytes. to include 16 words for the window save area,
284 and maybe the struct/union return pointer area, */
286 cif->bytes += 16 * wordsize;
288 /* The stack must be 2 word aligned, so round bytes up
289 appropriately. */
291 cif->bytes = ALIGN(cif->bytes, 2 * wordsize);
293 /* Set the return type flag */
294 switch (cif->rtype->type)
296 case FFI_TYPE_VOID:
297 case FFI_TYPE_FLOAT:
298 case FFI_TYPE_DOUBLE:
299 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
300 case FFI_TYPE_LONGDOUBLE:
301 #endif
302 cif->flags = cif->rtype->type;
303 break;
305 case FFI_TYPE_STRUCT:
306 if (cif->abi == FFI_V9 && cif->rtype->size > 32)
307 cif->flags = FFI_TYPE_VOID;
308 else
309 cif->flags = FFI_TYPE_STRUCT;
310 break;
312 case FFI_TYPE_SINT8:
313 case FFI_TYPE_UINT8:
314 case FFI_TYPE_SINT16:
315 case FFI_TYPE_UINT16:
316 if (cif->abi == FFI_V9)
317 cif->flags = FFI_TYPE_INT;
318 else
319 cif->flags = cif->rtype->type;
320 break;
322 case FFI_TYPE_SINT64:
323 case FFI_TYPE_UINT64:
324 if (cif->abi == FFI_V9)
325 cif->flags = FFI_TYPE_INT;
326 else
327 cif->flags = FFI_TYPE_SINT64;
328 break;
330 default:
331 cif->flags = FFI_TYPE_INT;
332 break;
334 return FFI_OK;
337 int ffi_v9_layout_struct(ffi_type *arg, int off, char *ret, char *intg, char *flt)
339 ffi_type **ptr = &arg->elements[0];
341 while (*ptr != NULL)
343 if (off & ((*ptr)->alignment - 1))
344 off = ALIGN(off, (*ptr)->alignment);
346 switch ((*ptr)->type)
348 case FFI_TYPE_STRUCT:
349 off = ffi_v9_layout_struct(*ptr, off, ret, intg, flt);
350 off = ALIGN(off, FFI_SIZEOF_ARG);
351 break;
352 case FFI_TYPE_FLOAT:
353 case FFI_TYPE_DOUBLE:
354 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
355 case FFI_TYPE_LONGDOUBLE:
356 #endif
357 memmove(ret + off, flt + off, (*ptr)->size);
358 off += (*ptr)->size;
359 break;
360 default:
361 memmove(ret + off, intg + off, (*ptr)->size);
362 off += (*ptr)->size;
363 break;
365 ptr++;
367 return off;
371 #ifdef SPARC64
372 extern int ffi_call_v9(void *, extended_cif *, unsigned,
373 unsigned, unsigned *, void (*fn)(void));
374 #else
375 extern int ffi_call_v8(void *, extended_cif *, unsigned,
376 unsigned, unsigned *, void (*fn)(void));
377 #endif
379 void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
381 extended_cif ecif;
382 void *rval = rvalue;
384 ecif.cif = cif;
385 ecif.avalue = avalue;
387 /* If the return value is a struct and we don't have a return */
388 /* value address then we need to make one */
390 ecif.rvalue = rvalue;
391 if (cif->rtype->type == FFI_TYPE_STRUCT)
393 if (cif->rtype->size <= 32)
394 rval = alloca(64);
395 else
397 rval = NULL;
398 if (rvalue == NULL)
399 ecif.rvalue = alloca(cif->rtype->size);
403 switch (cif->abi)
405 case FFI_V8:
406 #ifdef SPARC64
407 /* We don't yet support calling 32bit code from 64bit */
408 FFI_ASSERT(0);
409 #else
410 if (rvalue && (cif->rtype->type == FFI_TYPE_STRUCT
411 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
412 || cif->flags == FFI_TYPE_LONGDOUBLE
413 #endif
416 /* For v8, we need an "unimp" with size of returning struct */
417 /* behind "call", so we alloc some executable space for it. */
418 /* l7 is used, we need to make sure v8.S doesn't use %l7. */
419 unsigned int *call_struct = NULL;
420 ffi_closure_alloc(32, &call_struct);
421 if (call_struct)
423 unsigned long f = (unsigned long)fn;
424 call_struct[0] = 0xae10001f; /* mov %i7, %l7 */
425 call_struct[1] = 0xbe10000f; /* mov %o7, %i7 */
426 call_struct[2] = 0x03000000 | f >> 10; /* sethi %hi(fn), %g1 */
427 call_struct[3] = 0x9fc06000 | (f & 0x3ff); /* jmp %g1+%lo(fn), %o7 */
428 call_struct[4] = 0x01000000; /* nop */
429 if (cif->rtype->size < 0x7f)
430 call_struct[5] = cif->rtype->size; /* unimp */
431 else
432 call_struct[5] = 0x01000000; /* nop */
433 call_struct[6] = 0x81c7e008; /* ret */
434 call_struct[7] = 0xbe100017; /* mov %l7, %i7 */
435 asm volatile ("iflush %0; iflush %0+8; iflush %0+16; iflush %0+24" : :
436 "r" (call_struct) : "memory");
437 /* SPARC v8 requires 5 instructions for flush to be visible */
438 asm volatile ("nop; nop; nop; nop; nop");
439 ffi_call_v8(ffi_prep_args_v8, &ecif, cif->bytes,
440 cif->flags, rvalue, call_struct);
441 ffi_closure_free(call_struct);
443 else
445 ffi_call_v8(ffi_prep_args_v8, &ecif, cif->bytes,
446 cif->flags, rvalue, fn);
449 else
451 ffi_call_v8(ffi_prep_args_v8, &ecif, cif->bytes,
452 cif->flags, rvalue, fn);
454 #endif
455 break;
456 case FFI_V9:
457 #ifdef SPARC64
458 ffi_call_v9(ffi_prep_args_v9, &ecif, cif->bytes,
459 cif->flags, rval, fn);
460 if (rvalue && rval && cif->rtype->type == FFI_TYPE_STRUCT)
461 ffi_v9_layout_struct(cif->rtype, 0, (char *)rvalue, (char *)rval, ((char *)rval)+32);
462 #else
463 /* And vice versa */
464 FFI_ASSERT(0);
465 #endif
466 break;
467 default:
468 FFI_ASSERT(0);
469 break;
474 #ifdef SPARC64
475 extern void ffi_closure_v9(void);
476 #else
477 extern void ffi_closure_v8(void);
478 #endif
480 ffi_status
481 ffi_prep_closure_loc (ffi_closure* closure,
482 ffi_cif* cif,
483 void (*fun)(ffi_cif*, void*, void**, void*),
484 void *user_data,
485 void *codeloc)
487 unsigned int *tramp = (unsigned int *) &closure->tramp[0];
488 unsigned long fn;
489 #ifdef SPARC64
490 /* Trampoline address is equal to the closure address. We take advantage
491 of that to reduce the trampoline size by 8 bytes. */
492 if (cif->abi != FFI_V9)
493 return FFI_BAD_ABI;
494 fn = (unsigned long) ffi_closure_v9;
495 tramp[0] = 0x83414000; /* rd %pc, %g1 */
496 tramp[1] = 0xca586010; /* ldx [%g1+16], %g5 */
497 tramp[2] = 0x81c14000; /* jmp %g5 */
498 tramp[3] = 0x01000000; /* nop */
499 *((unsigned long *) &tramp[4]) = fn;
500 #else
501 unsigned long ctx = (unsigned long) codeloc;
502 if (cif->abi != FFI_V8)
503 return FFI_BAD_ABI;
504 fn = (unsigned long) ffi_closure_v8;
505 tramp[0] = 0x03000000 | fn >> 10; /* sethi %hi(fn), %g1 */
506 tramp[1] = 0x05000000 | ctx >> 10; /* sethi %hi(ctx), %g2 */
507 tramp[2] = 0x81c06000 | (fn & 0x3ff); /* jmp %g1+%lo(fn) */
508 tramp[3] = 0x8410a000 | (ctx & 0x3ff);/* or %g2, %lo(ctx) */
509 #endif
511 closure->cif = cif;
512 closure->fun = fun;
513 closure->user_data = user_data;
515 /* Flush the Icache. closure is 8 bytes aligned. */
516 #ifdef SPARC64
517 asm volatile ("flush %0; flush %0+8" : : "r" (closure) : "memory");
518 #else
519 asm volatile ("iflush %0; iflush %0+8" : : "r" (closure) : "memory");
520 /* SPARC v8 requires 5 instructions for flush to be visible */
521 asm volatile ("nop; nop; nop; nop; nop");
522 #endif
524 return FFI_OK;
528 ffi_closure_sparc_inner_v8(ffi_closure *closure,
529 void *rvalue, unsigned long *gpr, unsigned long *scratch)
531 ffi_cif *cif;
532 ffi_type **arg_types;
533 void **avalue;
534 int i, argn;
536 cif = closure->cif;
537 arg_types = cif->arg_types;
538 avalue = alloca(cif->nargs * sizeof(void *));
540 /* Copy the caller's structure return address so that the closure
541 returns the data directly to the caller. */
542 if (cif->flags == FFI_TYPE_STRUCT
543 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
544 || cif->flags == FFI_TYPE_LONGDOUBLE
545 #endif
547 rvalue = (void *) gpr[0];
549 /* Always skip the structure return address. */
550 argn = 1;
552 /* Grab the addresses of the arguments from the stack frame. */
553 for (i = 0; i < cif->nargs; i++)
555 if (arg_types[i]->type == FFI_TYPE_STRUCT
556 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
557 || arg_types[i]->type == FFI_TYPE_LONGDOUBLE
558 #endif
561 /* Straight copy of invisible reference. */
562 avalue[i] = (void *)gpr[argn++];
564 else if ((arg_types[i]->type == FFI_TYPE_DOUBLE
565 || arg_types[i]->type == FFI_TYPE_SINT64
566 || arg_types[i]->type == FFI_TYPE_UINT64)
567 /* gpr is 8-byte aligned. */
568 && (argn % 2) != 0)
570 /* Align on a 8-byte boundary. */
571 scratch[0] = gpr[argn];
572 scratch[1] = gpr[argn+1];
573 avalue[i] = scratch;
574 scratch -= 2;
575 argn += 2;
577 else
579 /* Always right-justify. */
580 argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
581 avalue[i] = ((char *) &gpr[argn]) - arg_types[i]->size;
585 /* Invoke the closure. */
586 (closure->fun) (cif, rvalue, avalue, closure->user_data);
588 /* Tell ffi_closure_sparc how to perform return type promotions. */
589 return cif->rtype->type;
593 ffi_closure_sparc_inner_v9(ffi_closure *closure,
594 void *rvalue, unsigned long *gpr, double *fpr)
596 ffi_cif *cif;
597 ffi_type **arg_types;
598 void **avalue;
599 int i, argn, fp_slot_max;
601 cif = closure->cif;
602 arg_types = cif->arg_types;
603 avalue = alloca(cif->nargs * sizeof(void *));
605 /* Copy the caller's structure return address so that the closure
606 returns the data directly to the caller. */
607 if (cif->flags == FFI_TYPE_VOID
608 && cif->rtype->type == FFI_TYPE_STRUCT)
610 rvalue = (void *) gpr[0];
611 /* Skip the structure return address. */
612 argn = 1;
614 else
615 argn = 0;
617 fp_slot_max = 16 - argn;
619 /* Grab the addresses of the arguments from the stack frame. */
620 for (i = 0; i < cif->nargs; i++)
622 if (arg_types[i]->type == FFI_TYPE_STRUCT)
624 if (arg_types[i]->size > 16)
626 /* Straight copy of invisible reference. */
627 avalue[i] = (void *)gpr[argn++];
629 else
631 /* Left-justify. */
632 ffi_v9_layout_struct(arg_types[i],
634 (char *) &gpr[argn],
635 (char *) &gpr[argn],
636 (char *) &fpr[argn]);
637 avalue[i] = &gpr[argn];
638 argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
641 else
643 /* Right-justify. */
644 argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
646 /* Align on a 16-byte boundary. */
647 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
648 if (arg_types[i]->type == FFI_TYPE_LONGDOUBLE && (argn % 2) != 0)
649 argn++;
650 #endif
651 if (i < fp_slot_max
652 && (arg_types[i]->type == FFI_TYPE_FLOAT
653 || arg_types[i]->type == FFI_TYPE_DOUBLE
654 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
655 || arg_types[i]->type == FFI_TYPE_LONGDOUBLE
656 #endif
658 avalue[i] = ((char *) &fpr[argn]) - arg_types[i]->size;
659 else
660 avalue[i] = ((char *) &gpr[argn]) - arg_types[i]->size;
664 /* Invoke the closure. */
665 (closure->fun) (cif, rvalue, avalue, closure->user_data);
667 /* Tell ffi_closure_sparc how to perform return type promotions. */
668 return cif->rtype->type;