Many new patches
[libffi.git] / src / sparc / ffi.c
1 /* -----------------------------------------------------------------------
2 ffi.c - Copyright (c) 2011 Anthony Green
3 Copyright (c) 1996, 2003-2004, 2007-2008 Red Hat, Inc.
4
5 SPARC Foreign Function Interface
6
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:
14
15 The above copyright notice and this permission notice shall be included
16 in all copies or substantial portions of the Software.
17
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 ----------------------------------------------------------------------- */
27
28 #include <ffi.h>
29 #include <ffi_common.h>
30
31 #include <stdlib.h>
32
33
34 /* ffi_prep_args is called by the assembly routine once stack space
35 has been allocated for the function's arguments */
36
37 void ffi_prep_args_v8(char *stack, extended_cif *ecif)
38 {
39 int i;
40 void **p_argv;
41 char *argp;
42 ffi_type **p_arg;
43
44 /* Skip 16 words for the window save area */
45 argp = stack + 16*sizeof(int);
46
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...
49
50 if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) */
51 *(int *) argp = (long)ecif->rvalue;
52
53 /* And 1 word for the structure return value. */
54 argp += sizeof(int);
55
56 #ifdef USING_PURIFY
57 /* Purify will probably complain in our assembly routine, unless we
58 zero out this memory. */
59
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
67
68 p_argv = ecif->avalue;
69
70 for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++)
71 {
72 size_t z;
73
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
78 )
79 {
80 *(unsigned int *) argp = (unsigned long)(* p_argv);
81 z = sizeof(int);
82 }
83 else
84 {
85 z = (*p_arg)->size;
86 if (z < sizeof(int))
87 {
88 z = sizeof(int);
89 switch ((*p_arg)->type)
90 {
91 case FFI_TYPE_SINT8:
92 *(signed int *) argp = *(SINT8 *)(* p_argv);
93 break;
94
95 case FFI_TYPE_UINT8:
96 *(unsigned int *) argp = *(UINT8 *)(* p_argv);
97 break;
98
99 case FFI_TYPE_SINT16:
100 *(signed int *) argp = *(SINT16 *)(* p_argv);
101 break;
102
103 case FFI_TYPE_UINT16:
104 *(unsigned int *) argp = *(UINT16 *)(* p_argv);
105 break;
106
107 default:
108 FFI_ASSERT(0);
109 }
110 }
111 else
112 {
113 memcpy(argp, *p_argv, z);
114 }
115 }
116 p_argv++;
117 argp += z;
118 }
119
120 return;
121 }
122
123 int ffi_prep_args_v9(char *stack, extended_cif *ecif)
124 {
125 int i, ret = 0;
126 int tmp;
127 void **p_argv;
128 char *argp;
129 ffi_type **p_arg;
130
131 tmp = 0;
132
133 /* Skip 16 words for the window save area */
134 argp = stack + 16*sizeof(long long);
135
136 #ifdef USING_PURIFY
137 /* Purify will probably complain in our assembly routine, unless we
138 zero out this memory. */
139
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
147
148 p_argv = ecif->avalue;
149
150 if (ecif->cif->rtype->type == FFI_TYPE_STRUCT &&
151 ecif->cif->rtype->size > 32)
152 {
153 *(unsigned long long *) argp = (unsigned long)ecif->rvalue;
154 argp += sizeof(long long);
155 tmp = 1;
156 }
157
158 for (i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs;
159 i++, p_arg++)
160 {
161 size_t z;
162
163 z = (*p_arg)->size;
164 switch ((*p_arg)->type)
165 {
166 case FFI_TYPE_STRUCT:
167 if (z > 16)
168 {
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;
175 }
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;
184 }
185 if (z < sizeof(long long))
186 {
187 switch ((*p_arg)->type)
188 {
189 case FFI_TYPE_SINT8:
190 *(signed long long *) argp = *(SINT8 *)(* p_argv);
191 break;
192
193 case FFI_TYPE_UINT8:
194 *(unsigned long long *) argp = *(UINT8 *)(* p_argv);
195 break;
196
197 case FFI_TYPE_SINT16:
198 *(signed long long *) argp = *(SINT16 *)(* p_argv);
199 break;
200
201 case FFI_TYPE_UINT16:
202 *(unsigned long long *) argp = *(UINT16 *)(* p_argv);
203 break;
204
205 case FFI_TYPE_SINT32:
206 *(signed long long *) argp = *(SINT32 *)(* p_argv);
207 break;
208
209 case FFI_TYPE_UINT32:
210 *(unsigned long long *) argp = *(UINT32 *)(* p_argv);
211 break;
212
213 case FFI_TYPE_FLOAT:
214 *(float *) (argp + 4) = *(FLOAT32 *)(* p_argv); /* Right justify */
215 break;
216
217 case FFI_TYPE_STRUCT:
218 memcpy(argp, *p_argv, z);
219 break;
220
221 default:
222 FFI_ASSERT(0);
223 }
224 z = sizeof(long long);
225 tmp++;
226 }
227 else if (z == sizeof(long long))
228 {
229 memcpy(argp, *p_argv, z);
230 z = sizeof(long long);
231 tmp++;
232 }
233 else
234 {
235 if ((tmp & 1) && (*p_arg)->alignment > 8)
236 {
237 tmp++;
238 argp += sizeof(long long);
239 }
240 memcpy(argp, *p_argv, z);
241 z = 2 * sizeof(long long);
242 tmp += 2;
243 }
244 p_argv++;
245 argp += z;
246 }
247
248 return ret;
249 }
250
251 /* Perform machine dependent cif processing */
252 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
253 {
254 int wordsize;
255
256 if (cif->abi != FFI_V9)
257 {
258 wordsize = 4;
259
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! */
262
263 if (cif->rtype->type != FFI_TYPE_STRUCT)
264 cif->bytes += wordsize;
265
266 /* sparc call frames require that space is allocated for 6 args,
267 even if they aren't used. Make that space if necessary. */
268
269 if (cif->bytes < 4*6+4)
270 cif->bytes = 4*6+4;
271 }
272 else
273 {
274 wordsize = 8;
275
276 /* sparc call frames require that space is allocated for 6 args,
277 even if they aren't used. Make that space if necessary. */
278
279 if (cif->bytes < 8*6)
280 cif->bytes = 8*6;
281 }
282
283 /* Adjust cif->bytes. to include 16 words for the window save area,
284 and maybe the struct/union return pointer area, */
285
286 cif->bytes += 16 * wordsize;
287
288 /* The stack must be 2 word aligned, so round bytes up
289 appropriately. */
290
291 cif->bytes = ALIGN(cif->bytes, 2 * wordsize);
292
293 /* Set the return type flag */
294 switch (cif->rtype->type)
295 {
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;
304
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;
311
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;
321
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;
329
330 default:
331 cif->flags = FFI_TYPE_INT;
332 break;
333 }
334 return FFI_OK;
335 }
336
337 int ffi_v9_layout_struct(ffi_type *arg, int off, char *ret, char *intg, char *flt)
338 {
339 ffi_type **ptr = &arg->elements[0];
340
341 while (*ptr != NULL)
342 {
343 if (off & ((*ptr)->alignment - 1))
344 off = ALIGN(off, (*ptr)->alignment);
345
346 switch ((*ptr)->type)
347 {
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;
364 }
365 ptr++;
366 }
367 return off;
368 }
369
370
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
378
379 void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
380 {
381 extended_cif ecif;
382 void *rval = rvalue;
383
384 ecif.cif = cif;
385 ecif.avalue = avalue;
386
387 /* If the return value is a struct and we don't have a return */
388 /* value address then we need to make one */
389
390 ecif.rvalue = rvalue;
391 if (cif->rtype->type == FFI_TYPE_STRUCT)
392 {
393 if (cif->rtype->size <= 32)
394 rval = alloca(64);
395 else
396 {
397 rval = NULL;
398 if (rvalue == NULL)
399 ecif.rvalue = alloca(cif->rtype->size);
400 }
401 }
402
403 switch (cif->abi)
404 {
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
414 ))
415 {
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)
422 {
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);
442 }
443 else
444 {
445 ffi_call_v8(ffi_prep_args_v8, &ecif, cif->bytes,
446 cif->flags, rvalue, fn);
447 }
448 }
449 else
450 {
451 ffi_call_v8(ffi_prep_args_v8, &ecif, cif->bytes,
452 cif->flags, rvalue, fn);
453 }
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;
470 }
471 }
472
473
474 #ifdef SPARC64
475 extern void ffi_closure_v9(void);
476 #else
477 extern void ffi_closure_v8(void);
478 #endif
479
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)
486 {
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
510
511 closure->cif = cif;
512 closure->fun = fun;
513 closure->user_data = user_data;
514
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
523
524 return FFI_OK;
525 }
526
527 int
528 ffi_closure_sparc_inner_v8(ffi_closure *closure,
529 void *rvalue, unsigned long *gpr, unsigned long *scratch)
530 {
531 ffi_cif *cif;
532 ffi_type **arg_types;
533 void **avalue;
534 int i, argn;
535
536 cif = closure->cif;
537 arg_types = cif->arg_types;
538 avalue = alloca(cif->nargs * sizeof(void *));
539
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
546 )
547 rvalue = (void *) gpr[0];
548
549 /* Always skip the structure return address. */
550 argn = 1;
551
552 /* Grab the addresses of the arguments from the stack frame. */
553 for (i = 0; i < cif->nargs; i++)
554 {
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
559 )
560 {
561 /* Straight copy of invisible reference. */
562 avalue[i] = (void *)gpr[argn++];
563 }
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)
569 {
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;
576 }
577 else
578 {
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;
582 }
583 }
584
585 /* Invoke the closure. */
586 (closure->fun) (cif, rvalue, avalue, closure->user_data);
587
588 /* Tell ffi_closure_sparc how to perform return type promotions. */
589 return cif->rtype->type;
590 }
591
592 int
593 ffi_closure_sparc_inner_v9(ffi_closure *closure,
594 void *rvalue, unsigned long *gpr, double *fpr)
595 {
596 ffi_cif *cif;
597 ffi_type **arg_types;
598 void **avalue;
599 int i, argn, fp_slot_max;
600
601 cif = closure->cif;
602 arg_types = cif->arg_types;
603 avalue = alloca(cif->nargs * sizeof(void *));
604
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)
609 {
610 rvalue = (void *) gpr[0];
611 /* Skip the structure return address. */
612 argn = 1;
613 }
614 else
615 argn = 0;
616
617 fp_slot_max = 16 - argn;
618
619 /* Grab the addresses of the arguments from the stack frame. */
620 for (i = 0; i < cif->nargs; i++)
621 {
622 if (arg_types[i]->type == FFI_TYPE_STRUCT)
623 {
624 if (arg_types[i]->size > 16)
625 {
626 /* Straight copy of invisible reference. */
627 avalue[i] = (void *)gpr[argn++];
628 }
629 else
630 {
631 /* Left-justify. */
632 ffi_v9_layout_struct(arg_types[i],
633 0,
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;
639 }
640 }
641 else
642 {
643 /* Right-justify. */
644 argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
645
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
657 ))
658 avalue[i] = ((char *) &fpr[argn]) - arg_types[i]->size;
659 else
660 avalue[i] = ((char *) &gpr[argn]) - arg_types[i]->size;
661 }
662 }
663
664 /* Invoke the closure. */
665 (closure->fun) (cif, rvalue, avalue, closure->user_data);
666
667 /* Tell ffi_closure_sparc how to perform return type promotions. */
668 return cif->rtype->type;
669 }