Remove old autovect-branch by moving to "dead" directory.
[official-gcc.git] / old-autovect-branch / libffi / src / mips / ffi.c
blob73bc952187d0e72374f913ce5fd6721c9606a620
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 int i;
54 void **p_argv;
55 char *argp;
56 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 * sizeof(ffi_arg))
63 argp = &stack[bytes - (8 * sizeof(ffi_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 int a;
90 /* Align if necessary. */
91 a = (*p_arg)->alignment;
92 if (a < sizeof(ffi_arg))
93 a = sizeof(ffi_arg);
95 if ((a - 1) & (unsigned int) argp)
97 argp = (char *) ALIGN(argp, a);
98 FIX_ARGP;
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 *(ffi_arg *)argp = *(SINT8 *)(* p_argv);
110 break;
112 case FFI_TYPE_UINT8:
113 *(ffi_arg *)argp = *(UINT8 *)(* p_argv);
114 break;
116 case FFI_TYPE_SINT16:
117 *(ffi_arg *)argp = *(SINT16 *)(* p_argv);
118 break;
120 case FFI_TYPE_UINT16:
121 *(ffi_arg *)argp = *(UINT16 *)(* p_argv);
122 break;
124 case FFI_TYPE_SINT32:
125 *(ffi_arg *)argp = *(SINT32 *)(* p_argv);
126 break;
128 case FFI_TYPE_UINT32:
129 case FFI_TYPE_POINTER:
130 *(ffi_arg *)argp = *(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 default:
141 memcpy(argp, *p_argv, (*p_arg)->size);
142 break;
145 else
147 #if _MIPS_SIM == _ABIO32
148 memcpy(argp, *p_argv, z);
149 #else
151 unsigned end = (unsigned) argp+z;
152 unsigned cap = (unsigned) stack+bytes;
154 /* Check if the data will fit within the register space.
155 Handle it if it doesn't. */
157 if (end <= cap)
158 memcpy(argp, *p_argv, z);
159 else
161 unsigned portion = end - cap;
163 memcpy(argp, *p_argv, portion);
164 argp = stack;
165 memcpy(argp,
166 (void*)((unsigned)(*p_argv)+portion), z - portion);
169 #endif
171 p_argv++;
172 argp += z;
173 FIX_ARGP;
177 #if _MIPS_SIM == _ABIN32
179 /* The n32 spec says that if "a chunk consists solely of a double
180 float field (but not a double, which is part of a union), it
181 is passed in a floating point register. Any other chunk is
182 passed in an integer register". This code traverses structure
183 definitions and generates the appropriate flags. */
185 unsigned calc_n32_struct_flags(ffi_type *arg, unsigned *shift)
187 unsigned flags = 0;
188 unsigned index = 0;
190 ffi_type *e;
192 while (e = arg->elements[index])
194 if (e->type == FFI_TYPE_DOUBLE)
196 flags += (FFI_TYPE_DOUBLE << *shift);
197 *shift += FFI_FLAG_BITS;
199 else if (e->type == FFI_TYPE_STRUCT)
200 flags += calc_n32_struct_flags(e, shift);
201 else
202 *shift += FFI_FLAG_BITS;
204 index++;
207 return flags;
210 unsigned calc_n32_return_struct_flags(ffi_type *arg)
212 unsigned flags = 0;
213 unsigned index = 0;
214 unsigned small = FFI_TYPE_SMALLSTRUCT;
215 ffi_type *e;
217 /* Returning structures under n32 is a tricky thing.
218 A struct with only one or two floating point fields
219 is returned in $f0 (and $f2 if necessary). Any other
220 struct results at most 128 bits are returned in $2
221 (the first 64 bits) and $3 (remainder, if necessary).
222 Larger structs are handled normally. */
224 if (arg->size > 16)
225 return 0;
227 if (arg->size > 8)
228 small = FFI_TYPE_SMALLSTRUCT2;
230 e = arg->elements[0];
231 if (e->type == FFI_TYPE_DOUBLE)
232 flags = FFI_TYPE_DOUBLE << FFI_FLAG_BITS;
233 else if (e->type == FFI_TYPE_FLOAT)
234 flags = FFI_TYPE_FLOAT << FFI_FLAG_BITS;
236 if (flags && (e = arg->elements[1]))
238 if (e->type == FFI_TYPE_DOUBLE)
239 flags += FFI_TYPE_DOUBLE;
240 else if (e->type == FFI_TYPE_FLOAT)
241 flags += FFI_TYPE_FLOAT;
242 else
243 return small;
245 if (flags && (arg->elements[2]))
247 /* There are three arguments and the first two are
248 floats! This must be passed the old way. */
249 return small;
252 else
253 if (!flags)
254 return small;
256 return flags;
259 #endif
261 /* Perform machine dependent cif processing */
262 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
264 cif->flags = 0;
266 #if _MIPS_SIM == _ABIO32
267 /* Set the flags necessary for O32 processing. FFI_O32_SOFT_FLOAT
268 * does not have special handling for floating point args.
271 if (cif->rtype->type != FFI_TYPE_STRUCT && cif->abi == FFI_O32)
273 if (cif->nargs > 0)
275 switch ((cif->arg_types)[0]->type)
277 case FFI_TYPE_FLOAT:
278 case FFI_TYPE_DOUBLE:
279 cif->flags += (cif->arg_types)[0]->type;
280 break;
282 default:
283 break;
286 if (cif->nargs > 1)
288 /* Only handle the second argument if the first
289 is a float or double. */
290 if (cif->flags)
292 switch ((cif->arg_types)[1]->type)
294 case FFI_TYPE_FLOAT:
295 case FFI_TYPE_DOUBLE:
296 cif->flags += (cif->arg_types)[1]->type << FFI_FLAG_BITS;
297 break;
299 default:
300 break;
307 /* Set the return type flag */
309 if (cif->abi == FFI_O32_SOFT_FLOAT)
311 switch (cif->rtype->type)
313 case FFI_TYPE_VOID:
314 case FFI_TYPE_STRUCT:
315 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
316 break;
318 case FFI_TYPE_SINT64:
319 case FFI_TYPE_UINT64:
320 case FFI_TYPE_DOUBLE:
321 cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);
322 break;
324 case FFI_TYPE_FLOAT:
325 default:
326 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
327 break;
330 else
332 /* FFI_O32 */
333 switch (cif->rtype->type)
335 case FFI_TYPE_VOID:
336 case FFI_TYPE_STRUCT:
337 case FFI_TYPE_FLOAT:
338 case FFI_TYPE_DOUBLE:
339 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
340 break;
342 case FFI_TYPE_SINT64:
343 case FFI_TYPE_UINT64:
344 cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);
345 break;
347 default:
348 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
349 break;
352 #endif
354 #if _MIPS_SIM == _ABIN32
355 /* Set the flags necessary for N32 processing */
357 unsigned shift = 0;
358 unsigned count = (cif->nargs < 8) ? cif->nargs : 8;
359 unsigned index = 0;
361 unsigned struct_flags = 0;
363 if (cif->rtype->type == FFI_TYPE_STRUCT)
365 struct_flags = calc_n32_return_struct_flags(cif->rtype);
367 if (struct_flags == 0)
369 /* This means that the structure is being passed as
370 a hidden argument */
372 shift = FFI_FLAG_BITS;
373 count = (cif->nargs < 7) ? cif->nargs : 7;
375 cif->rstruct_flag = !0;
377 else
378 cif->rstruct_flag = 0;
380 else
381 cif->rstruct_flag = 0;
383 while (count-- > 0)
385 switch ((cif->arg_types)[index]->type)
387 case FFI_TYPE_FLOAT:
388 case FFI_TYPE_DOUBLE:
389 cif->flags += ((cif->arg_types)[index]->type << shift);
390 shift += FFI_FLAG_BITS;
391 break;
393 case FFI_TYPE_STRUCT:
394 cif->flags += calc_n32_struct_flags((cif->arg_types)[index],
395 &shift);
396 break;
398 default:
399 shift += FFI_FLAG_BITS;
402 index++;
405 /* Set the return type flag */
406 switch (cif->rtype->type)
408 case FFI_TYPE_STRUCT:
410 if (struct_flags == 0)
412 /* The structure is returned through a hidden
413 first argument. Do nothing, 'cause FFI_TYPE_VOID
414 is 0 */
416 else
418 /* The structure is returned via some tricky
419 mechanism */
420 cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
421 cif->flags += struct_flags << (4 + (FFI_FLAG_BITS * 8));
423 break;
426 case FFI_TYPE_VOID:
427 /* Do nothing, 'cause FFI_TYPE_VOID is 0 */
428 break;
430 case FFI_TYPE_FLOAT:
431 case FFI_TYPE_DOUBLE:
432 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8);
433 break;
435 default:
436 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
437 break;
440 #endif
442 return FFI_OK;
445 /* Low level routine for calling O32 functions */
446 extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int),
447 extended_cif *, unsigned,
448 unsigned, unsigned *, void (*)());
450 /* Low level routine for calling N32 functions */
451 extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int),
452 extended_cif *, unsigned,
453 unsigned, unsigned *, void (*)());
455 void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
457 extended_cif ecif;
459 ecif.cif = cif;
460 ecif.avalue = avalue;
462 /* If the return value is a struct and we don't have a return */
463 /* value address then we need to make one */
465 if ((rvalue == NULL) &&
466 (cif->rtype->type == FFI_TYPE_STRUCT))
467 ecif.rvalue = alloca(cif->rtype->size);
468 else
469 ecif.rvalue = rvalue;
471 switch (cif->abi)
473 #if _MIPS_SIM == _ABIO32
474 case FFI_O32:
475 case FFI_O32_SOFT_FLOAT:
476 ffi_call_O32(ffi_prep_args, &ecif, cif->bytes,
477 cif->flags, ecif.rvalue, fn);
478 break;
479 #endif
481 #if _MIPS_SIM == _ABIN32
482 case FFI_N32:
483 ffi_call_N32(ffi_prep_args, &ecif, cif->bytes,
484 cif->flags, ecif.rvalue, fn);
485 break;
486 #endif
488 default:
489 FFI_ASSERT(0);
490 break;
494 #if FFI_CLOSURES /* N32 not implemented yet, FFI_CLOSURES not defined */
495 #if defined(FFI_MIPS_O32)
496 extern void ffi_closure_O32(void);
497 #endif /* FFI_MIPS_O32 */
499 ffi_status
500 ffi_prep_closure (ffi_closure *closure,
501 ffi_cif *cif,
502 void (*fun)(ffi_cif*,void*,void**,void*),
503 void *user_data)
505 unsigned int *tramp = (unsigned int *) &closure->tramp[0];
506 unsigned int fn;
507 unsigned int ctx = (unsigned int) closure;
509 #if defined(FFI_MIPS_O32)
510 FFI_ASSERT(cif->abi == FFI_O32 || cif->abi == FFI_O32_SOFT_FLOAT);
511 fn = (unsigned int) ffi_closure_O32;
512 #else /* FFI_MIPS_N32 */
513 FFI_ASSERT(cif->abi == FFI_N32);
514 FFI_ASSERT(!"not implemented");
515 #endif /* FFI_MIPS_O32 */
517 tramp[0] = 0x3c190000 | (fn >> 16); /* lui $25,high(fn) */
518 tramp[1] = 0x37390000 | (fn & 0xffff); /* ori $25,low(fn) */
519 tramp[2] = 0x3c080000 | (ctx >> 16); /* lui $8,high(ctx) */
520 tramp[3] = 0x03200008; /* jr $25 */
521 tramp[4] = 0x35080000 | (ctx & 0xffff); /* ori $8,low(ctx) */
523 closure->cif = cif;
524 closure->fun = fun;
525 closure->user_data = user_data;
527 /* XXX this is available on Linux, but anything else? */
528 cacheflush (tramp, FFI_TRAMPOLINE_SIZE, ICACHE);
530 return FFI_OK;
534 * Decodes the arguments to a function, which will be stored on the
535 * stack. AR is the pointer to the beginning of the integer arguments
536 * (and, depending upon the arguments, some floating-point arguments
537 * as well). FPR is a pointer to the area where floating point
538 * registers have been saved, if any.
540 * RVALUE is the location where the function return value will be
541 * stored. CLOSURE is the prepared closure to invoke.
543 * This function should only be called from assembly, which is in
544 * turn called from a trampoline.
546 * Returns the function return type.
548 * Based on the similar routine for sparc.
551 ffi_closure_mips_inner_O32 (ffi_closure *closure,
552 void *rvalue, ffi_arg *ar,
553 double *fpr)
555 ffi_cif *cif;
556 void **avaluep;
557 ffi_arg *avalue;
558 ffi_type **arg_types;
559 int i, avn, argn, seen_int;
561 cif = closure->cif;
562 avalue = alloca (cif->nargs * sizeof (ffi_arg));
563 avaluep = alloca (cif->nargs * sizeof (ffi_arg));
565 seen_int = (cif->abi == FFI_O32_SOFT_FLOAT);
566 argn = 0;
568 if ((cif->flags >> (FFI_FLAG_BITS * 2)) == FFI_TYPE_STRUCT)
570 rvalue = (void *) ar[0];
571 argn = 1;
574 i = 0;
575 avn = cif->nargs;
576 arg_types = cif->arg_types;
578 while (i < avn)
580 if (i < 2 && !seen_int &&
581 (arg_types[i]->type == FFI_TYPE_FLOAT ||
582 arg_types[i]->type == FFI_TYPE_DOUBLE))
584 #ifdef __MIPSEB__
585 if (arg_types[i]->type == FFI_TYPE_FLOAT)
586 avaluep[i] = ((char *) &fpr[i]) + sizeof (float);
587 else
588 #endif
589 avaluep[i] = (char *) &fpr[i];
591 else
593 if (arg_types[i]->alignment == 8 && (argn & 0x1))
594 argn++;
595 switch (arg_types[i]->type)
597 case FFI_TYPE_SINT8:
598 avaluep[i] = &avalue[i];
599 *(SINT8 *) &avalue[i] = (SINT8) ar[argn];
600 break;
602 case FFI_TYPE_UINT8:
603 avaluep[i] = &avalue[i];
604 *(UINT8 *) &avalue[i] = (UINT8) ar[argn];
605 break;
607 case FFI_TYPE_SINT16:
608 avaluep[i] = &avalue[i];
609 *(SINT16 *) &avalue[i] = (SINT16) ar[argn];
610 break;
612 case FFI_TYPE_UINT16:
613 avaluep[i] = &avalue[i];
614 *(UINT16 *) &avalue[i] = (UINT16) ar[argn];
615 break;
617 default:
618 avaluep[i] = (char *) &ar[argn];
619 break;
621 seen_int = 1;
623 argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
624 i++;
627 /* Invoke the closure. */
628 (closure->fun) (cif, rvalue, avaluep, closure->user_data);
630 if (cif->abi == FFI_O32_SOFT_FLOAT)
632 switch (cif->rtype->type)
634 case FFI_TYPE_FLOAT:
635 return FFI_TYPE_INT;
636 case FFI_TYPE_DOUBLE:
637 return FFI_TYPE_UINT64;
638 default:
639 return cif->rtype->type;
642 else
644 return cif->rtype->type;
648 #endif /* FFI_CLOSURES */