ffi.c (ffi_pref_cif_machdep): set `cif->flags' to contain `FFI_TYPE_UINT64' as return...
[official-gcc.git] / libffi / src / mips / ffi.c
blobe12922aa0465b6c1a6c99c0abd918f5ed5336b7e
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;
89 /* Align if necessary */
90 if (((*p_arg)->alignment - 1) & (unsigned) argp) {
91 argp = (char *) ALIGN(argp, (*p_arg)->alignment);
92 FIX_ARGP;
95 #if _MIPS_SIM == _ABIO32
96 #define OFFSET 0
97 #else
98 #define OFFSET sizeof(int)
99 #endif
101 z = (*p_arg)->size;
102 if (z < sizeof(ffi_arg))
104 z = sizeof(ffi_arg);
106 switch ((*p_arg)->type)
108 case FFI_TYPE_SINT8:
109 *(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT8 *)(* p_argv);
110 break;
112 case FFI_TYPE_UINT8:
113 *(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT8 *)(* p_argv);
114 break;
116 case FFI_TYPE_SINT16:
117 *(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT16 *)(* p_argv);
118 break;
120 case FFI_TYPE_UINT16:
121 *(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT16 *)(* p_argv);
122 break;
124 case FFI_TYPE_SINT32:
125 *(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT32 *)(* p_argv);
126 break;
128 case FFI_TYPE_UINT32:
129 case FFI_TYPE_POINTER:
130 *(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT32 *)(* p_argv);
131 break;
133 /* This can only happen with 64bit slots */
134 case FFI_TYPE_FLOAT:
135 *(float *) argp = *(float *)(* p_argv);
136 break;
138 /* Handle small structures */
139 case FFI_TYPE_STRUCT:
140 memcpy(argp, *p_argv, (*p_arg)->size);
141 break;
143 default:
144 FFI_ASSERT(0);
147 else
149 #if _MIPS_SIM == _ABIO32
150 memcpy(argp, *p_argv, z);
151 #else
153 unsigned end = (unsigned) argp+z;
154 unsigned cap = (unsigned) stack+bytes;
156 /* Check if the data will fit within the register
157 space. Handle it if it doesn't. */
159 if (end <= cap)
160 memcpy(argp, *p_argv, z);
161 else
163 unsigned portion = end - cap;
165 memcpy(argp, *p_argv, portion);
166 argp = stack;
167 memcpy(argp,
168 (void*)((unsigned)(*p_argv)+portion), z - portion);
171 #endif
173 p_argv++;
174 argp += z;
175 FIX_ARGP;
178 return;
181 #if _MIPS_SIM == _ABIN32
183 /* The n32 spec says that if "a chunk consists solely of a double
184 float field (but not a double, which is part of a union), it
185 is passed in a floating point register. Any other chunk is
186 passed in an integer register". This code traverses structure
187 definitions and generates the appropriate flags. */
189 unsigned calc_n32_struct_flags(ffi_type *arg, unsigned *shift)
191 unsigned flags = 0;
192 unsigned index = 0;
194 ffi_type *e;
196 while (e = arg->elements[index])
198 if (e->type == FFI_TYPE_DOUBLE)
200 flags += (FFI_TYPE_DOUBLE << *shift);
201 *shift += FFI_FLAG_BITS;
203 else if (e->type == FFI_TYPE_STRUCT)
204 flags += calc_n32_struct_flags(e, shift);
205 else
206 *shift += FFI_FLAG_BITS;
208 index++;
211 return flags;
214 unsigned calc_n32_return_struct_flags(ffi_type *arg)
216 unsigned flags = 0;
217 unsigned index = 0;
218 unsigned small = FFI_TYPE_SMALLSTRUCT;
219 ffi_type *e;
221 /* Returning structures under n32 is a tricky thing.
222 A struct with only one or two floating point fields
223 is returned in $f0 (and $f2 if necessary). Any other
224 struct results at most 128 bits are returned in $2
225 (the first 64 bits) and $3 (remainder, if necessary).
226 Larger structs are handled normally. */
228 if (arg->size > 16)
229 return 0;
231 if (arg->size > 8)
232 small = FFI_TYPE_SMALLSTRUCT2;
234 e = arg->elements[0];
235 if (e->type == FFI_TYPE_DOUBLE)
236 flags = FFI_TYPE_DOUBLE << FFI_FLAG_BITS;
237 else if (e->type == FFI_TYPE_FLOAT)
238 flags = FFI_TYPE_FLOAT << FFI_FLAG_BITS;
240 if (flags && (e = arg->elements[1]))
242 if (e->type == FFI_TYPE_DOUBLE)
243 flags += FFI_TYPE_DOUBLE;
244 else if (e->type == FFI_TYPE_FLOAT)
245 flags += FFI_TYPE_FLOAT;
246 else
247 return small;
249 if (flags && (arg->elements[2]))
251 /* There are three arguments and the first two are
252 floats! This must be passed the old way. */
253 return small;
256 else
257 if (!flags)
258 return small;
260 return flags;
263 #endif
265 /* Perform machine dependent cif processing */
266 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
268 cif->flags = 0;
270 #if _MIPS_SIM == _ABIO32
271 /* Set the flags necessary for O32 processing */
273 if (cif->rtype->type != FFI_TYPE_STRUCT)
275 if (cif->nargs > 0)
277 switch ((cif->arg_types)[0]->type)
279 case FFI_TYPE_FLOAT:
280 case FFI_TYPE_DOUBLE:
281 cif->flags += (cif->arg_types)[0]->type;
282 break;
284 default:
285 break;
288 if (cif->nargs > 1)
290 /* Only handle the second argument if the first
291 is a float or double. */
292 if (cif->flags)
294 switch ((cif->arg_types)[1]->type)
296 case FFI_TYPE_FLOAT:
297 case FFI_TYPE_DOUBLE:
298 cif->flags += (cif->arg_types)[1]->type << FFI_FLAG_BITS;
299 break;
301 default:
302 break;
309 /* Set the return type flag */
310 switch (cif->rtype->type)
312 case FFI_TYPE_VOID:
313 case FFI_TYPE_STRUCT:
314 case FFI_TYPE_FLOAT:
315 case FFI_TYPE_DOUBLE:
316 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
317 break;
319 case FFI_TYPE_SINT64:
320 case FFI_TYPE_UINT64:
321 cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);
322 break;
324 default:
325 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
326 break;
328 #endif
330 #if _MIPS_SIM == _ABIN32
331 /* Set the flags necessary for N32 processing */
333 unsigned shift = 0;
334 unsigned count = (cif->nargs < 8) ? cif->nargs : 8;
335 unsigned index = 0;
337 unsigned struct_flags = 0;
339 if (cif->rtype->type == FFI_TYPE_STRUCT)
341 struct_flags = calc_n32_return_struct_flags(cif->rtype);
343 if (struct_flags == 0)
345 /* This means that the structure is being passed as
346 a hidden argument */
348 shift = FFI_FLAG_BITS;
349 count = (cif->nargs < 7) ? cif->nargs : 7;
351 cif->rstruct_flag = !0;
353 else
354 cif->rstruct_flag = 0;
356 else
357 cif->rstruct_flag = 0;
359 while (count-- > 0)
361 switch ((cif->arg_types)[index]->type)
363 case FFI_TYPE_FLOAT:
364 case FFI_TYPE_DOUBLE:
365 cif->flags += ((cif->arg_types)[index]->type << shift);
366 shift += FFI_FLAG_BITS;
367 break;
369 case FFI_TYPE_STRUCT:
370 cif->flags += calc_n32_struct_flags((cif->arg_types)[index],
371 &shift);
372 break;
374 default:
375 shift += FFI_FLAG_BITS;
378 index++;
381 /* Set the return type flag */
382 switch (cif->rtype->type)
384 case FFI_TYPE_STRUCT:
386 if (struct_flags == 0)
388 /* The structure is returned through a hidden
389 first argument. Do nothing, 'cause FFI_TYPE_VOID
390 is 0 */
392 else
394 /* The structure is returned via some tricky
395 mechanism */
396 cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
397 cif->flags += struct_flags << (4 + (FFI_FLAG_BITS * 8));
399 break;
402 case FFI_TYPE_VOID:
403 /* Do nothing, 'cause FFI_TYPE_VOID is 0 */
404 break;
406 case FFI_TYPE_FLOAT:
407 case FFI_TYPE_DOUBLE:
408 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8);
409 break;
411 default:
412 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
413 break;
416 #endif
418 return FFI_OK;
421 /* Low level routine for calling O32 functions */
422 extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int),
423 extended_cif *, unsigned,
424 unsigned, unsigned *, void (*)());
426 /* Low level routine for calling N32 functions */
427 extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int),
428 extended_cif *, unsigned,
429 unsigned, unsigned *, void (*)());
431 void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
433 extended_cif ecif;
435 ecif.cif = cif;
436 ecif.avalue = avalue;
438 /* If the return value is a struct and we don't have a return */
439 /* value address then we need to make one */
441 if ((rvalue == NULL) &&
442 (cif->rtype->type == FFI_TYPE_STRUCT))
443 ecif.rvalue = alloca(cif->rtype->size);
444 else
445 ecif.rvalue = rvalue;
447 switch (cif->abi)
449 #if _MIPS_SIM == _ABIO32
450 case FFI_O32:
451 ffi_call_O32(ffi_prep_args, &ecif, cif->bytes,
452 cif->flags, ecif.rvalue, fn);
453 break;
454 #endif
456 #if _MIPS_SIM == _ABIN32
457 case FFI_N32:
458 ffi_call_N32(ffi_prep_args, &ecif, cif->bytes,
459 cif->flags, ecif.rvalue, fn);
460 break;
461 #endif
463 default:
464 FFI_ASSERT(0);
465 break;
469 #if FFI_CLOSURES /* N32 not implemented yet, FFI_CLOSURES not defined */
470 #if defined(FFI_MIPS_O32)
471 extern void ffi_closure_O32(void);
472 #endif /* FFI_MIPS_O32 */
474 ffi_status
475 ffi_prep_closure (ffi_closure *closure,
476 ffi_cif *cif,
477 void (*fun)(ffi_cif*,void*,void**,void*),
478 void *user_data)
480 unsigned int *tramp = (unsigned int *) &closure->tramp[0];
481 unsigned int fn;
482 unsigned int ctx = (unsigned int) closure;
484 #if defined(FFI_MIPS_O32)
485 FFI_ASSERT(cif->abi == FFI_O32);
486 fn = (unsigned int) ffi_closure_O32;
487 #else /* FFI_MIPS_N32 */
488 FFI_ASSERT(cif->abi == FFI_N32);
489 FFI_ASSERT(!"not implemented");
490 #endif /* FFI_MIPS_O32 */
492 tramp[0] = 0x3c190000 | (fn >> 16); /* lui $25,high(fn) */
493 tramp[1] = 0x3c080000 | (ctx >> 16); /* lui $8,high(ctx) */
494 tramp[2] = 0x37390000 | (fn & 0xffff); /* ori $25,low(fn) */
495 tramp[3] = 0x03200008; /* jr $25 */
496 tramp[4] = 0x35080000 | (ctx & 0xffff); /* ori $8,low(ctx) */
498 closure->cif = cif;
499 closure->fun = fun;
500 closure->user_data = user_data;
502 /* XXX this is available on Linux, but anything else? */
503 cacheflush (tramp, FFI_TRAMPOLINE_SIZE, ICACHE);
505 return FFI_OK;
509 * Decodes the arguments to a function, which will be stored on the
510 * stack. AR is the pointer to the beginning of the integer arguments
511 * (and, depending upon the arguments, some floating-point arguments
512 * as well). FPR is a pointer to the area where floating point
513 * registers have been saved, if any.
515 * RVALUE is the location where the function return value will be
516 * stored. CLOSURE is the prepared closure to invoke.
518 * This function should only be called from assembly, which is in
519 * turn called from a trampoline.
521 * Returns the function return type.
523 * Based on the similar routine for sparc.
526 ffi_closure_mips_inner_O32 (ffi_closure *closure,
527 void *rvalue, unsigned long *ar,
528 double *fpr)
530 ffi_cif *cif;
531 void **avalue;
532 ffi_type **arg_types;
533 int i, avn, argn, seen_int;
535 cif = closure->cif;
536 avalue = alloca (cif->nargs * sizeof (void *));
538 seen_int = 0;
539 argn = 0;
541 if (cif->flags == FFI_TYPE_STRUCT)
543 rvalue = (void *) ar[0];
544 argn = 1;
547 i = 0;
548 avn = cif->nargs;
549 arg_types = cif->arg_types;
551 while (i < avn)
553 if (i < 2 && !seen_int &&
554 (arg_types[i]->type == FFI_TYPE_FLOAT ||
555 arg_types[i]->type == FFI_TYPE_DOUBLE))
557 avalue[i] = ((char *) &fpr[i]);
559 else
561 /* 8-byte arguments are always 8-byte aligned. */
562 if (arg_types[i]->size == 8 && (argn & 0x1))
563 argn++;
564 /* Float arguments take up two register slots. The float word
565 is the upper one. */
566 if (argn == 2 && arg_types[i]->type == FFI_TYPE_FLOAT)
567 argn++;
568 avalue[i] = ((char *) &ar[argn]);
569 seen_int = 1;
571 argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
572 i++;
575 /* Invoke the closure. */
576 (closure->fun) (cif, rvalue, avalue, closure->user_data);
578 return cif->rtype->type;
581 #endif /* FFI_CLOSURES */