* lra-constraints.c (process_address_1): Swap base_term and index_term
[official-gcc.git] / libffi / src / sparc / ffi.c
blob77e3822065734de20f9fcd62ec9cf372ead614c8
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 #ifdef SPARC64
39 int
40 ffi_prep_args_v9(char *stack, extended_cif *ecif)
42 int i, ret = 0;
43 int tmp;
44 void **p_argv;
45 char *argp;
46 ffi_type **p_arg;
48 tmp = 0;
50 /* Skip 16 words for the window save area */
51 argp = stack + 16*sizeof(long long);
53 #ifdef USING_PURIFY
54 /* Purify will probably complain in our assembly routine, unless we
55 zero out this memory. */
57 ((long long*)argp)[0] = 0;
58 ((long long*)argp)[1] = 0;
59 ((long long*)argp)[2] = 0;
60 ((long long*)argp)[3] = 0;
61 ((long long*)argp)[4] = 0;
62 ((long long*)argp)[5] = 0;
63 #endif
65 p_argv = ecif->avalue;
67 if (ecif->cif->rtype->type == FFI_TYPE_STRUCT &&
68 ecif->cif->rtype->size > 32)
70 *(unsigned long long *) argp = (unsigned long)ecif->rvalue;
71 argp += sizeof(long long);
72 tmp = 1;
75 for (i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs;
76 i++, p_arg++)
78 size_t z;
80 z = (*p_arg)->size;
81 switch ((*p_arg)->type)
83 case FFI_TYPE_STRUCT:
84 if (z > 16)
86 /* For structures larger than 16 bytes we pass reference. */
87 *(unsigned long long *) argp = (unsigned long)* p_argv;
88 argp += sizeof(long long);
89 tmp++;
90 p_argv++;
91 continue;
93 /* FALLTHROUGH */
94 case FFI_TYPE_FLOAT:
95 case FFI_TYPE_DOUBLE:
96 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
97 case FFI_TYPE_LONGDOUBLE:
98 #endif
99 ret = 1; /* We should promote into FP regs as well as integer. */
100 break;
102 if (z < sizeof(long long))
104 switch ((*p_arg)->type)
106 case FFI_TYPE_SINT8:
107 *(signed long long *) argp = *(SINT8 *)(* p_argv);
108 break;
110 case FFI_TYPE_UINT8:
111 *(unsigned long long *) argp = *(UINT8 *)(* p_argv);
112 break;
114 case FFI_TYPE_SINT16:
115 *(signed long long *) argp = *(SINT16 *)(* p_argv);
116 break;
118 case FFI_TYPE_UINT16:
119 *(unsigned long long *) argp = *(UINT16 *)(* p_argv);
120 break;
122 case FFI_TYPE_SINT32:
123 *(signed long long *) argp = *(SINT32 *)(* p_argv);
124 break;
126 case FFI_TYPE_UINT32:
127 *(unsigned long long *) argp = *(UINT32 *)(* p_argv);
128 break;
130 case FFI_TYPE_FLOAT:
131 *(float *) (argp + 4) = *(FLOAT32 *)(* p_argv); /* Right justify */
132 break;
134 case FFI_TYPE_STRUCT:
135 memcpy(argp, *p_argv, z);
136 break;
138 default:
139 FFI_ASSERT(0);
141 z = sizeof(long long);
142 tmp++;
144 else if (z == sizeof(long long))
146 memcpy(argp, *p_argv, z);
147 z = sizeof(long long);
148 tmp++;
150 else
152 if ((tmp & 1) && (*p_arg)->alignment > 8)
154 tmp++;
155 argp += sizeof(long long);
157 memcpy(argp, *p_argv, z);
158 z = 2 * sizeof(long long);
159 tmp += 2;
161 p_argv++;
162 argp += z;
165 return ret;
168 #else
170 void
171 ffi_prep_args_v8(char *stack, extended_cif *ecif)
173 int i;
174 void **p_argv;
175 char *argp;
176 ffi_type **p_arg;
178 /* Skip 16 words for the window save area */
179 argp = stack + 16*sizeof(int);
181 /* This should only really be done when we are returning a structure,
182 however, it's faster just to do it all the time...
184 if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) */
185 *(int *) argp = (long)ecif->rvalue;
187 /* And 1 word for the structure return value. */
188 argp += sizeof(int);
190 #ifdef USING_PURIFY
191 /* Purify will probably complain in our assembly routine, unless we
192 zero out this memory. */
194 ((int*)argp)[0] = 0;
195 ((int*)argp)[1] = 0;
196 ((int*)argp)[2] = 0;
197 ((int*)argp)[3] = 0;
198 ((int*)argp)[4] = 0;
199 ((int*)argp)[5] = 0;
200 #endif
202 p_argv = ecif->avalue;
204 for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++)
206 size_t z;
208 if ((*p_arg)->type == FFI_TYPE_STRUCT
209 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
210 || (*p_arg)->type == FFI_TYPE_LONGDOUBLE
211 #endif
214 *(unsigned int *) argp = (unsigned long)(* p_argv);
215 z = sizeof(int);
217 else
219 z = (*p_arg)->size;
220 if (z < sizeof(int))
222 z = sizeof(int);
223 switch ((*p_arg)->type)
225 case FFI_TYPE_SINT8:
226 *(signed int *) argp = *(SINT8 *)(* p_argv);
227 break;
229 case FFI_TYPE_UINT8:
230 *(unsigned int *) argp = *(UINT8 *)(* p_argv);
231 break;
233 case FFI_TYPE_SINT16:
234 *(signed int *) argp = *(SINT16 *)(* p_argv);
235 break;
237 case FFI_TYPE_UINT16:
238 *(unsigned int *) argp = *(UINT16 *)(* p_argv);
239 break;
241 default:
242 FFI_ASSERT(0);
245 else
247 memcpy(argp, *p_argv, z);
250 p_argv++;
251 argp += z;
254 return;
257 #endif
259 /* Perform machine dependent cif processing */
261 static
262 ffi_status ffi_prep_cif_machdep_core(ffi_cif *cif)
264 int wordsize;
266 if (!V9_ABI_P (cif->abi))
268 wordsize = 4;
270 /* If we are returning a struct, this will already have been added.
271 Otherwise we need to add it because it's always got to be there! */
273 if (cif->rtype->type != FFI_TYPE_STRUCT)
274 cif->bytes += wordsize;
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 < 4*6+4)
280 cif->bytes = 4*6+4;
282 else
284 wordsize = 8;
286 /* sparc call frames require that space is allocated for 6 args,
287 even if they aren't used. Make that space if necessary. */
289 if (cif->bytes < 8*6)
290 cif->bytes = 8*6;
293 /* Adjust cif->bytes. to include 16 words for the window save area,
294 and maybe the struct/union return pointer area, */
296 cif->bytes += 16 * wordsize;
298 /* The stack must be 2 word aligned, so round bytes up
299 appropriately. */
301 cif->bytes = ALIGN(cif->bytes, 2 * wordsize);
303 /* Set the return type flag */
304 switch (cif->rtype->type)
306 case FFI_TYPE_VOID:
307 case FFI_TYPE_FLOAT:
308 case FFI_TYPE_DOUBLE:
309 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
310 case FFI_TYPE_LONGDOUBLE:
311 #endif
312 cif->flags = cif->rtype->type;
313 break;
315 case FFI_TYPE_STRUCT:
316 if (V9_ABI_P (cif->abi) && cif->rtype->size > 32)
317 cif->flags = FFI_TYPE_VOID;
318 else
319 cif->flags = FFI_TYPE_STRUCT;
320 break;
322 case FFI_TYPE_SINT8:
323 case FFI_TYPE_UINT8:
324 case FFI_TYPE_SINT16:
325 case FFI_TYPE_UINT16:
326 if (V9_ABI_P (cif->abi))
327 cif->flags = FFI_TYPE_INT;
328 else
329 cif->flags = cif->rtype->type;
330 break;
332 case FFI_TYPE_SINT64:
333 case FFI_TYPE_UINT64:
334 if (V9_ABI_P (cif->abi))
335 cif->flags = FFI_TYPE_INT;
336 else
337 cif->flags = FFI_TYPE_SINT64;
338 break;
340 default:
341 cif->flags = FFI_TYPE_INT;
342 break;
344 return FFI_OK;
347 ffi_status
348 ffi_prep_cif_machdep(ffi_cif *cif)
350 #ifdef SPARC64
351 if (cif->abi != FFI_COMPAT_V9)
352 cif->nfixedargs = cif->nargs;
353 #endif
354 return ffi_prep_cif_machdep_core (cif);
357 ffi_status
358 ffi_prep_cif_machdep_var(ffi_cif *cif, unsigned int nfixedargs,
359 unsigned int ntotalargs)
361 #ifdef SPARC64
362 if (cif->abi != FFI_COMPAT_V9)
363 cif->nfixedargs = nfixedargs;
364 #endif
365 return ffi_prep_cif_machdep_core (cif);
368 #ifdef SPARC64
371 ffi_v9_layout_struct(ffi_type *arg, int off, char *ret, char *intg, char *flt)
373 ffi_type **ptr = &arg->elements[0];
375 while (*ptr != NULL)
377 if (off & ((*ptr)->alignment - 1))
378 off = ALIGN(off, (*ptr)->alignment);
380 switch ((*ptr)->type)
382 case FFI_TYPE_STRUCT:
383 off = ffi_v9_layout_struct(*ptr, off, ret, intg, flt);
384 off = ALIGN(off, FFI_SIZEOF_ARG);
385 break;
386 case FFI_TYPE_FLOAT:
387 case FFI_TYPE_DOUBLE:
388 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
389 case FFI_TYPE_LONGDOUBLE:
390 #endif
391 memmove(ret + off, flt + off, (*ptr)->size);
392 off += (*ptr)->size;
393 break;
394 default:
395 memmove(ret + off, intg + off, (*ptr)->size);
396 off += (*ptr)->size;
397 break;
399 ptr++;
401 return off;
404 #endif
406 #ifdef SPARC64
407 extern int ffi_call_v9(void *, extended_cif *, unsigned,
408 unsigned, unsigned *, void (*fn)(void));
409 #else
410 extern int ffi_call_v8(void *, extended_cif *, unsigned,
411 unsigned, unsigned *, void (*fn)(void));
412 #endif
414 void
415 ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
417 extended_cif ecif;
418 #ifdef SPARC64
419 void *rval = rvalue;
420 #endif
422 ecif.cif = cif;
423 ecif.avalue = avalue;
424 ecif.rvalue = rvalue;
426 /* If the return value is a struct and we don't have a return value address,
427 then we need to make one. */
428 if (cif->rtype->type == FFI_TYPE_STRUCT)
430 if (ecif.rvalue == NULL)
431 ecif.rvalue = alloca(cif->rtype->size);
433 #ifdef SPARC64
434 if (cif->rtype->size <= 32)
435 rval = alloca(64);
436 else
437 rval = NULL;
438 #endif
441 switch (cif->abi)
443 case FFI_V8:
444 case FFI_V8PLUS:
445 #ifdef SPARC64
446 /* We don't yet support calling 32bit code from 64bit */
447 FFI_ASSERT(0);
448 #else
449 if (rvalue && (cif->rtype->type == FFI_TYPE_STRUCT
450 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
451 || cif->flags == FFI_TYPE_LONGDOUBLE
452 #endif
455 /* For v8, we need an "unimp" with size of returning struct */
456 /* behind "call", so we alloc some executable space for it. */
457 /* l7 is used, we need to make sure v8.S doesn't use %l7. */
458 unsigned int *call_struct = NULL;
459 ffi_closure_alloc(32, (void **)&call_struct);
460 if (call_struct)
462 unsigned long f = (unsigned long)fn;
463 call_struct[0] = 0xae10001f; /* mov %i7, %l7 */
464 call_struct[1] = 0xbe10000f; /* mov %o7, %i7 */
465 call_struct[2] = 0x03000000 | f >> 10; /* sethi %hi(fn), %g1 */
466 call_struct[3] = 0x9fc06000 | (f & 0x3ff); /* jmp %g1+%lo(fn), %o7 */
467 call_struct[4] = 0x01000000; /* nop */
468 if (cif->rtype->size < 0x7f)
469 call_struct[5] = cif->rtype->size; /* unimp */
470 else
471 call_struct[5] = 0x01000000; /* nop */
472 call_struct[6] = 0x81c7e008; /* ret */
473 call_struct[7] = 0xbe100017; /* mov %l7, %i7 */
474 asm volatile ("iflush %0; iflush %0+8; iflush %0+16; iflush %0+24" : :
475 "r" (call_struct) : "memory");
476 /* SPARC v8 requires 5 instructions for flush to be visible */
477 asm volatile ("nop; nop; nop; nop; nop");
478 ffi_call_v8(ffi_prep_args_v8, &ecif, cif->bytes,
479 cif->flags, rvalue, (void (*)(void)) call_struct);
480 ffi_closure_free(call_struct);
482 else
484 ffi_call_v8(ffi_prep_args_v8, &ecif, cif->bytes,
485 cif->flags, rvalue, fn);
488 else
490 ffi_call_v8(ffi_prep_args_v8, &ecif, cif->bytes,
491 cif->flags, rvalue, fn);
493 #endif
494 break;
495 case FFI_COMPAT_V9:
496 case FFI_V9:
497 #ifdef SPARC64
498 ffi_call_v9(ffi_prep_args_v9, &ecif, cif->bytes, cif->flags, rval, fn);
499 if (rvalue && rval && cif->rtype->type == FFI_TYPE_STRUCT)
500 ffi_v9_layout_struct(cif->rtype, 0, (char *)rvalue, (char *)rval,
501 ((char *)rval)+32);
502 #else
503 /* And vice versa */
504 FFI_ASSERT(0);
505 #endif
506 break;
507 default:
508 FFI_ASSERT(0);
509 break;
514 #ifdef SPARC64
515 extern void ffi_closure_v9(void);
516 #else
517 extern void ffi_closure_v8(void);
518 #endif
520 ffi_status
521 ffi_prep_closure_loc (ffi_closure* closure,
522 ffi_cif* cif,
523 void (*fun)(ffi_cif*, void*, void**, void*),
524 void *user_data,
525 void *codeloc)
527 unsigned int *tramp = (unsigned int *) &closure->tramp[0];
528 unsigned long fn;
529 #ifdef SPARC64
530 /* Trampoline address is equal to the closure address. We take advantage
531 of that to reduce the trampoline size by 8 bytes. */
532 if (!V9_ABI_P (cif->abi))
533 return FFI_BAD_ABI;
534 fn = (unsigned long) ffi_closure_v9;
535 tramp[0] = 0x83414000; /* rd %pc, %g1 */
536 tramp[1] = 0xca586010; /* ldx [%g1+16], %g5 */
537 tramp[2] = 0x81c14000; /* jmp %g5 */
538 tramp[3] = 0x01000000; /* nop */
539 *((unsigned long *) &tramp[4]) = fn;
540 #else
541 unsigned long ctx = (unsigned long) codeloc;
542 if (!V8_ABI_P (cif->abi))
543 return FFI_BAD_ABI;
544 fn = (unsigned long) ffi_closure_v8;
545 tramp[0] = 0x03000000 | fn >> 10; /* sethi %hi(fn), %g1 */
546 tramp[1] = 0x05000000 | ctx >> 10; /* sethi %hi(ctx), %g2 */
547 tramp[2] = 0x81c06000 | (fn & 0x3ff); /* jmp %g1+%lo(fn) */
548 tramp[3] = 0x8410a000 | (ctx & 0x3ff);/* or %g2, %lo(ctx) */
549 #endif
551 closure->cif = cif;
552 closure->fun = fun;
553 closure->user_data = user_data;
555 /* Flush the Icache. closure is 8 bytes aligned. */
556 #ifdef SPARC64
557 asm volatile ("flush %0; flush %0+8" : : "r" (closure) : "memory");
558 #else
559 asm volatile ("iflush %0; iflush %0+8" : : "r" (closure) : "memory");
560 /* SPARC v8 requires 5 instructions for flush to be visible */
561 asm volatile ("nop; nop; nop; nop; nop");
562 #endif
564 return FFI_OK;
567 #ifdef SPARC64
570 ffi_closure_sparc_inner_v9(ffi_closure *closure, void *rvalue,
571 unsigned long *gpr, double *fpr)
573 ffi_cif *cif;
574 ffi_type **arg_types;
575 void **avalue;
576 int i, argn, fp_slot_max;
578 cif = closure->cif;
579 arg_types = cif->arg_types;
580 avalue = alloca(cif->nargs * sizeof(void *));
582 /* Copy the caller's structure return address so that the closure
583 returns the data directly to the caller. */
584 if (cif->flags == FFI_TYPE_VOID && cif->rtype->type == FFI_TYPE_STRUCT)
586 rvalue = (void *) gpr[0];
587 /* Skip the structure return address. */
588 argn = 1;
590 else
591 argn = 0;
593 fp_slot_max = 16 - argn;
595 /* Grab the addresses of the arguments from the stack frame. */
596 for (i = 0; i < cif->nargs; i++)
598 /* If the function is variadic, FP arguments are passed in FP
599 registers only if the corresponding parameter is named. */
600 const int named
601 = (cif->abi == FFI_COMPAT_V9 ? 1 : i < cif->nfixedargs);
603 if (arg_types[i]->type == FFI_TYPE_STRUCT)
605 if (arg_types[i]->size > 16)
607 /* Straight copy of invisible reference. */
608 avalue[i] = (void *)gpr[argn++];
610 else
612 /* Left-justify. */
613 ffi_v9_layout_struct(arg_types[i],
615 (char *) &gpr[argn],
616 (char *) &gpr[argn],
617 named
618 ? (char *) &fpr[argn]
619 : (char *) &gpr[argn]);
620 avalue[i] = &gpr[argn];
621 argn
622 += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
625 else
627 /* Right-justify. */
628 argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
630 /* Align on a 16-byte boundary. */
631 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
632 if (arg_types[i]->type == FFI_TYPE_LONGDOUBLE && (argn % 2) != 0)
633 argn++;
634 #endif
635 if (i < fp_slot_max
636 && named
637 && (arg_types[i]->type == FFI_TYPE_FLOAT
638 || arg_types[i]->type == FFI_TYPE_DOUBLE
639 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
640 || arg_types[i]->type == FFI_TYPE_LONGDOUBLE
641 #endif
643 avalue[i] = ((char *) &fpr[argn]) - arg_types[i]->size;
644 else
645 avalue[i] = ((char *) &gpr[argn]) - arg_types[i]->size;
649 /* Invoke the closure. */
650 closure->fun (cif, rvalue, avalue, closure->user_data);
652 /* Tell ffi_closure_sparc how to perform return type promotions. */
653 return cif->rtype->type;
656 #else
659 ffi_closure_sparc_inner_v8(ffi_closure *closure, void *rvalue,
660 unsigned long *gpr, unsigned long *scratch)
662 ffi_cif *cif;
663 ffi_type **arg_types;
664 void **avalue;
665 int i, argn;
667 cif = closure->cif;
668 arg_types = cif->arg_types;
669 avalue = alloca(cif->nargs * sizeof(void *));
671 /* Copy the caller's structure return address so that the closure
672 returns the data directly to the caller. */
673 if (cif->flags == FFI_TYPE_STRUCT
674 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
675 || cif->flags == FFI_TYPE_LONGDOUBLE
676 #endif
678 rvalue = (void *) gpr[0];
680 /* Always skip the structure return address. */
681 argn = 1;
683 /* Grab the addresses of the arguments from the stack frame. */
684 for (i = 0; i < cif->nargs; i++)
686 if (arg_types[i]->type == FFI_TYPE_STRUCT
687 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
688 || arg_types[i]->type == FFI_TYPE_LONGDOUBLE
689 #endif
692 /* Straight copy of invisible reference. */
693 avalue[i] = (void *)gpr[argn++];
695 else if ((arg_types[i]->type == FFI_TYPE_DOUBLE
696 || arg_types[i]->type == FFI_TYPE_SINT64
697 || arg_types[i]->type == FFI_TYPE_UINT64)
698 /* gpr is 8-byte aligned. */
699 && (argn % 2) != 0)
701 /* Align on a 8-byte boundary. */
702 scratch[0] = gpr[argn];
703 scratch[1] = gpr[argn+1];
704 avalue[i] = scratch;
705 scratch -= 2;
706 argn += 2;
708 else
710 /* Always right-justify. */
711 argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
712 avalue[i] = ((char *) &gpr[argn]) - arg_types[i]->size;
716 /* Invoke the closure. */
717 closure->fun (cif, rvalue, avalue, closure->user_data);
719 /* Tell ffi_closure_sparc how to perform return type promotions. */
720 return cif->rtype->type;
723 #endif