Merge from mainline (gomp-merge-2005-02-26).
[official-gcc.git] / libffi / src / mips / ffi.c
blob352226c7f547af59888fb8f40bc5d8a8a89d120b
1 /* -----------------------------------------------------------------------
2 ffi.c - Copyright (c) 1996 Red Hat, Inc.
4 MIPS 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 ----------------------------------------------------------------------- */
26 #include <ffi.h>
27 #include <ffi_common.h>
29 #include <stdlib.h>
30 #include <sys/cachectl.h>
32 #if _MIPS_SIM == _ABIN32
33 #define FIX_ARGP \
34 FFI_ASSERT(argp <= &stack[bytes]); \
35 if (argp == &stack[bytes]) \
36 { \
37 argp = stack; \
38 ffi_stop_here(); \
40 #else
41 #define FIX_ARGP
42 #endif
45 /* ffi_prep_args is called by the assembly routine once stack space
46 has been allocated for the function's arguments */
48 static void ffi_prep_args(char *stack,
49 extended_cif *ecif,
50 int bytes,
51 int flags)
53 register int i;
54 register void **p_argv;
55 register char *argp;
56 register ffi_type **p_arg;
58 #if _MIPS_SIM == _ABIN32
59 /* If more than 8 double words are used, the remainder go
60 on the stack. We reorder stuff on the stack here to
61 support this easily. */
62 if (bytes > 8 * FFI_SIZEOF_ARG)
63 argp = &stack[bytes - (8 * FFI_SIZEOF_ARG)];
64 else
65 argp = stack;
66 #else
67 argp = stack;
68 #endif
70 memset(stack, 0, bytes);
72 #if _MIPS_SIM == _ABIN32
73 if ( ecif->cif->rstruct_flag != 0 )
74 #else
75 if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT )
76 #endif
78 *(ffi_arg *) argp = (ffi_arg) ecif->rvalue;
79 argp += sizeof(ffi_arg);
80 FIX_ARGP;
83 p_argv = ecif->avalue;
85 for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++)
87 size_t z;
88 unsigned short a;
90 /* Align if necessary */
91 a = (*p_arg)->alignment;
92 if (a < FFI_SIZEOF_ARG)
93 a = FFI_SIZEOF_ARG;
95 if ((a - 1) & (unsigned) argp) {
96 argp = (char *) ALIGN(argp, a);
97 FIX_ARGP;
100 #if _MIPS_SIM == _ABIO32
101 #define OFFSET 0
102 #else
103 #define OFFSET sizeof(int)
104 #endif
106 z = (*p_arg)->size;
107 if (z < sizeof(ffi_arg))
109 z = sizeof(ffi_arg);
111 switch ((*p_arg)->type)
113 case FFI_TYPE_SINT8:
114 *(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT8 *)(* p_argv);
115 break;
117 case FFI_TYPE_UINT8:
118 *(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT8 *)(* p_argv);
119 break;
121 case FFI_TYPE_SINT16:
122 *(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT16 *)(* p_argv);
123 break;
125 case FFI_TYPE_UINT16:
126 *(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT16 *)(* p_argv);
127 break;
129 case FFI_TYPE_SINT32:
130 *(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT32 *)(* p_argv);
131 break;
133 case FFI_TYPE_UINT32:
134 case FFI_TYPE_POINTER:
135 *(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT32 *)(* p_argv);
136 break;
138 /* This can only happen with 64bit slots */
139 case FFI_TYPE_FLOAT:
140 *(float *) argp = *(float *)(* p_argv);
141 break;
143 /* Handle small structures */
144 case FFI_TYPE_STRUCT:
145 memcpy(argp, *p_argv, (*p_arg)->size);
146 break;
148 default:
149 FFI_ASSERT(0);
152 else
154 #if _MIPS_SIM == _ABIO32
155 memcpy(argp, *p_argv, z);
156 #else
158 unsigned end = (unsigned) argp+z;
159 unsigned cap = (unsigned) stack+bytes;
161 /* Check if the data will fit within the register
162 space. Handle it if it doesn't. */
164 if (end <= cap)
165 memcpy(argp, *p_argv, z);
166 else
168 unsigned portion = end - cap;
170 memcpy(argp, *p_argv, portion);
171 argp = stack;
172 memcpy(argp,
173 (void*)((unsigned)(*p_argv)+portion), z - portion);
176 #endif
178 p_argv++;
179 argp += z;
180 FIX_ARGP;
183 return;
186 #if _MIPS_SIM == _ABIN32
188 /* The n32 spec says that if "a chunk consists solely of a double
189 float field (but not a double, which is part of a union), it
190 is passed in a floating point register. Any other chunk is
191 passed in an integer register". This code traverses structure
192 definitions and generates the appropriate flags. */
194 unsigned calc_n32_struct_flags(ffi_type *arg, unsigned *shift)
196 unsigned flags = 0;
197 unsigned index = 0;
199 ffi_type *e;
201 while (e = arg->elements[index])
203 if (e->type == FFI_TYPE_DOUBLE)
205 flags += (FFI_TYPE_DOUBLE << *shift);
206 *shift += FFI_FLAG_BITS;
208 else if (e->type == FFI_TYPE_STRUCT)
209 flags += calc_n32_struct_flags(e, shift);
210 else
211 *shift += FFI_FLAG_BITS;
213 index++;
216 return flags;
219 unsigned calc_n32_return_struct_flags(ffi_type *arg)
221 unsigned flags = 0;
222 unsigned index = 0;
223 unsigned small = FFI_TYPE_SMALLSTRUCT;
224 ffi_type *e;
226 /* Returning structures under n32 is a tricky thing.
227 A struct with only one or two floating point fields
228 is returned in $f0 (and $f2 if necessary). Any other
229 struct results at most 128 bits are returned in $2
230 (the first 64 bits) and $3 (remainder, if necessary).
231 Larger structs are handled normally. */
233 if (arg->size > 16)
234 return 0;
236 if (arg->size > 8)
237 small = FFI_TYPE_SMALLSTRUCT2;
239 e = arg->elements[0];
240 if (e->type == FFI_TYPE_DOUBLE)
241 flags = FFI_TYPE_DOUBLE << FFI_FLAG_BITS;
242 else if (e->type == FFI_TYPE_FLOAT)
243 flags = FFI_TYPE_FLOAT << FFI_FLAG_BITS;
245 if (flags && (e = arg->elements[1]))
247 if (e->type == FFI_TYPE_DOUBLE)
248 flags += FFI_TYPE_DOUBLE;
249 else if (e->type == FFI_TYPE_FLOAT)
250 flags += FFI_TYPE_FLOAT;
251 else
252 return small;
254 if (flags && (arg->elements[2]))
256 /* There are three arguments and the first two are
257 floats! This must be passed the old way. */
258 return small;
261 else
262 if (!flags)
263 return small;
265 return flags;
268 #endif
270 /* Perform machine dependent cif processing */
271 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
273 cif->flags = 0;
275 #if _MIPS_SIM == _ABIO32
276 /* Set the flags necessary for O32 processing. FFI_O32_SOFT_FLOAT
277 * does not have special handling for floating point args.
280 if (cif->rtype->type != FFI_TYPE_STRUCT && cif->abi == FFI_O32)
282 if (cif->nargs > 0)
284 switch ((cif->arg_types)[0]->type)
286 case FFI_TYPE_FLOAT:
287 case FFI_TYPE_DOUBLE:
288 cif->flags += (cif->arg_types)[0]->type;
289 break;
291 default:
292 break;
295 if (cif->nargs > 1)
297 /* Only handle the second argument if the first
298 is a float or double. */
299 if (cif->flags)
301 switch ((cif->arg_types)[1]->type)
303 case FFI_TYPE_FLOAT:
304 case FFI_TYPE_DOUBLE:
305 cif->flags += (cif->arg_types)[1]->type << FFI_FLAG_BITS;
306 break;
308 default:
309 break;
316 /* Set the return type flag */
318 if (cif->abi == FFI_O32_SOFT_FLOAT)
320 switch (cif->rtype->type)
322 case FFI_TYPE_VOID:
323 case FFI_TYPE_STRUCT:
324 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
325 break;
327 case FFI_TYPE_SINT64:
328 case FFI_TYPE_UINT64:
329 case FFI_TYPE_DOUBLE:
330 cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);
331 break;
333 case FFI_TYPE_FLOAT:
334 default:
335 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
336 break;
339 else
341 /* FFI_O32 */
342 switch (cif->rtype->type)
344 case FFI_TYPE_VOID:
345 case FFI_TYPE_STRUCT:
346 case FFI_TYPE_FLOAT:
347 case FFI_TYPE_DOUBLE:
348 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
349 break;
351 case FFI_TYPE_SINT64:
352 case FFI_TYPE_UINT64:
353 cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);
354 break;
356 default:
357 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
358 break;
361 #endif
363 #if _MIPS_SIM == _ABIN32
364 /* Set the flags necessary for N32 processing */
366 unsigned shift = 0;
367 unsigned count = (cif->nargs < 8) ? cif->nargs : 8;
368 unsigned index = 0;
370 unsigned struct_flags = 0;
372 if (cif->rtype->type == FFI_TYPE_STRUCT)
374 struct_flags = calc_n32_return_struct_flags(cif->rtype);
376 if (struct_flags == 0)
378 /* This means that the structure is being passed as
379 a hidden argument */
381 shift = FFI_FLAG_BITS;
382 count = (cif->nargs < 7) ? cif->nargs : 7;
384 cif->rstruct_flag = !0;
386 else
387 cif->rstruct_flag = 0;
389 else
390 cif->rstruct_flag = 0;
392 while (count-- > 0)
394 switch ((cif->arg_types)[index]->type)
396 case FFI_TYPE_FLOAT:
397 case FFI_TYPE_DOUBLE:
398 cif->flags += ((cif->arg_types)[index]->type << shift);
399 shift += FFI_FLAG_BITS;
400 break;
402 case FFI_TYPE_STRUCT:
403 cif->flags += calc_n32_struct_flags((cif->arg_types)[index],
404 &shift);
405 break;
407 default:
408 shift += FFI_FLAG_BITS;
411 index++;
414 /* Set the return type flag */
415 switch (cif->rtype->type)
417 case FFI_TYPE_STRUCT:
419 if (struct_flags == 0)
421 /* The structure is returned through a hidden
422 first argument. Do nothing, 'cause FFI_TYPE_VOID
423 is 0 */
425 else
427 /* The structure is returned via some tricky
428 mechanism */
429 cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
430 cif->flags += struct_flags << (4 + (FFI_FLAG_BITS * 8));
432 break;
435 case FFI_TYPE_VOID:
436 /* Do nothing, 'cause FFI_TYPE_VOID is 0 */
437 break;
439 case FFI_TYPE_FLOAT:
440 case FFI_TYPE_DOUBLE:
441 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8);
442 break;
444 default:
445 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
446 break;
449 #endif
451 return FFI_OK;
454 /* Low level routine for calling O32 functions */
455 extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int),
456 extended_cif *, unsigned,
457 unsigned, unsigned *, void (*)());
459 /* Low level routine for calling N32 functions */
460 extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int),
461 extended_cif *, unsigned,
462 unsigned, unsigned *, void (*)());
464 void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
466 extended_cif ecif;
468 ecif.cif = cif;
469 ecif.avalue = avalue;
471 /* If the return value is a struct and we don't have a return */
472 /* value address then we need to make one */
474 if ((rvalue == NULL) &&
475 (cif->rtype->type == FFI_TYPE_STRUCT))
476 ecif.rvalue = alloca(cif->rtype->size);
477 else
478 ecif.rvalue = rvalue;
480 switch (cif->abi)
482 #if _MIPS_SIM == _ABIO32
483 case FFI_O32:
484 case FFI_O32_SOFT_FLOAT:
485 ffi_call_O32(ffi_prep_args, &ecif, cif->bytes,
486 cif->flags, ecif.rvalue, fn);
487 break;
488 #endif
490 #if _MIPS_SIM == _ABIN32
491 case FFI_N32:
492 ffi_call_N32(ffi_prep_args, &ecif, cif->bytes,
493 cif->flags, ecif.rvalue, fn);
494 break;
495 #endif
497 default:
498 FFI_ASSERT(0);
499 break;
503 #if FFI_CLOSURES /* N32 not implemented yet, FFI_CLOSURES not defined */
504 #if defined(FFI_MIPS_O32)
505 extern void ffi_closure_O32(void);
506 #endif /* FFI_MIPS_O32 */
508 ffi_status
509 ffi_prep_closure (ffi_closure *closure,
510 ffi_cif *cif,
511 void (*fun)(ffi_cif*,void*,void**,void*),
512 void *user_data)
514 unsigned int *tramp = (unsigned int *) &closure->tramp[0];
515 unsigned int fn;
516 unsigned int ctx = (unsigned int) closure;
518 #if defined(FFI_MIPS_O32)
519 FFI_ASSERT(cif->abi == FFI_O32 || cif->abi == FFI_O32_SOFT_FLOAT);
520 fn = (unsigned int) ffi_closure_O32;
521 #else /* FFI_MIPS_N32 */
522 FFI_ASSERT(cif->abi == FFI_N32);
523 FFI_ASSERT(!"not implemented");
524 #endif /* FFI_MIPS_O32 */
526 tramp[0] = 0x3c190000 | (fn >> 16); /* lui $25,high(fn) */
527 tramp[1] = 0x3c080000 | (ctx >> 16); /* lui $8,high(ctx) */
528 tramp[2] = 0x37390000 | (fn & 0xffff); /* ori $25,low(fn) */
529 tramp[3] = 0x03200008; /* jr $25 */
530 tramp[4] = 0x35080000 | (ctx & 0xffff); /* ori $8,low(ctx) */
532 closure->cif = cif;
533 closure->fun = fun;
534 closure->user_data = user_data;
536 /* XXX this is available on Linux, but anything else? */
537 cacheflush (tramp, FFI_TRAMPOLINE_SIZE, ICACHE);
539 return FFI_OK;
543 * Decodes the arguments to a function, which will be stored on the
544 * stack. AR is the pointer to the beginning of the integer arguments
545 * (and, depending upon the arguments, some floating-point arguments
546 * as well). FPR is a pointer to the area where floating point
547 * registers have been saved, if any.
549 * RVALUE is the location where the function return value will be
550 * stored. CLOSURE is the prepared closure to invoke.
552 * This function should only be called from assembly, which is in
553 * turn called from a trampoline.
555 * Returns the function return type.
557 * Based on the similar routine for sparc.
560 ffi_closure_mips_inner_O32 (ffi_closure *closure,
561 void *rvalue, unsigned long *ar,
562 double *fpr)
564 ffi_cif *cif;
565 void **avalue;
566 ffi_type **arg_types;
567 int i, avn, argn, seen_int;
569 cif = closure->cif;
570 avalue = alloca (cif->nargs * sizeof (void *));
572 seen_int = (cif->abi == FFI_O32_SOFT_FLOAT);
573 argn = 0;
575 if ((cif->flags >> (FFI_FLAG_BITS * 2)) == FFI_TYPE_STRUCT)
577 rvalue = (void *) ar[0];
578 argn = 1;
581 i = 0;
582 avn = cif->nargs;
583 arg_types = cif->arg_types;
585 while (i < avn)
587 if (i < 2 && !seen_int &&
588 (arg_types[i]->type == FFI_TYPE_FLOAT ||
589 arg_types[i]->type == FFI_TYPE_DOUBLE))
591 avalue[i] = ((char *) &fpr[i]);
593 else
595 if (arg_types[i]->alignment == 8 && (argn & 0x1))
596 argn++;
597 avalue[i] = ((char *) &ar[argn]);
598 seen_int = 1;
600 argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
601 i++;
604 /* Invoke the closure. */
605 (closure->fun) (cif, rvalue, avalue, closure->user_data);
607 if (cif->abi == FFI_O32_SOFT_FLOAT)
609 switch (cif->rtype->type)
611 case FFI_TYPE_FLOAT:
612 return FFI_TYPE_INT;
613 case FFI_TYPE_DOUBLE:
614 return FFI_TYPE_UINT64;
615 default:
616 return cif->rtype->type;
619 else
621 return cif->rtype->type;
625 #endif /* FFI_CLOSURES */