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 ----------------------------------------------------------------------- */
27 #include <ffi_common.h>
30 #include <sys/cachectl.h>
32 #if _MIPS_SIM == _ABIN32
34 FFI_ASSERT(argp <= &stack[bytes]); \
35 if (argp == &stack[bytes]) \
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
,
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
))];
70 memset(stack
, 0, bytes
);
72 #if _MIPS_SIM == _ABIN32
73 if ( ecif
->cif
->rstruct_flag
!= 0 )
75 if ( ecif
->cif
->rtype
->type
== FFI_TYPE_STRUCT
)
78 *(ffi_arg
*) argp
= (ffi_arg
) ecif
->rvalue
;
79 argp
+= sizeof(ffi_arg
);
83 p_argv
= ecif
->avalue
;
85 for (i
= ecif
->cif
->nargs
, p_arg
= ecif
->cif
->arg_types
; i
; i
--, p_arg
++)
90 /* Align if necessary. */
91 a
= (*p_arg
)->alignment
;
92 if (a
< sizeof(ffi_arg
))
95 if ((a
- 1) & (unsigned int) argp
)
97 argp
= (char *) ALIGN(argp
, a
);
102 if (z
<= sizeof(ffi_arg
))
106 switch ((*p_arg
)->type
)
109 *(ffi_arg
*)argp
= *(SINT8
*)(* p_argv
);
113 *(ffi_arg
*)argp
= *(UINT8
*)(* p_argv
);
116 case FFI_TYPE_SINT16
:
117 *(ffi_arg
*)argp
= *(SINT16
*)(* p_argv
);
120 case FFI_TYPE_UINT16
:
121 *(ffi_arg
*)argp
= *(UINT16
*)(* p_argv
);
124 case FFI_TYPE_SINT32
:
125 *(ffi_arg
*)argp
= *(SINT32
*)(* p_argv
);
128 case FFI_TYPE_UINT32
:
129 case FFI_TYPE_POINTER
:
130 *(ffi_arg
*)argp
= *(UINT32
*)(* p_argv
);
133 /* This can only happen with 64bit slots. */
135 *(float *) argp
= *(float *)(* p_argv
);
138 /* Handle small structures. */
139 case FFI_TYPE_STRUCT
:
141 memcpy(argp
, *p_argv
, (*p_arg
)->size
);
147 #if _MIPS_SIM == _ABIO32
148 memcpy(argp
, *p_argv
, z
);
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. */
158 memcpy(argp
, *p_argv
, z
);
161 unsigned portion
= end
- cap
;
163 memcpy(argp
, *p_argv
, portion
);
166 (void*)((unsigned)(*p_argv
)+portion
), z
- portion
);
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
)
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
);
202 *shift
+= FFI_FLAG_BITS
;
210 unsigned calc_n32_return_struct_flags(ffi_type
*arg
)
214 unsigned small
= FFI_TYPE_SMALLSTRUCT
;
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. */
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
;
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. */
261 /* Perform machine dependent cif processing */
262 ffi_status
ffi_prep_cif_machdep(ffi_cif
*cif
)
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
)
275 switch ((cif
->arg_types
)[0]->type
)
278 case FFI_TYPE_DOUBLE
:
279 cif
->flags
+= (cif
->arg_types
)[0]->type
;
288 /* Only handle the second argument if the first
289 is a float or double. */
292 switch ((cif
->arg_types
)[1]->type
)
295 case FFI_TYPE_DOUBLE
:
296 cif
->flags
+= (cif
->arg_types
)[1]->type
<< FFI_FLAG_BITS
;
307 /* Set the return type flag */
309 if (cif
->abi
== FFI_O32_SOFT_FLOAT
)
311 switch (cif
->rtype
->type
)
314 case FFI_TYPE_STRUCT
:
315 cif
->flags
+= cif
->rtype
->type
<< (FFI_FLAG_BITS
* 2);
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);
326 cif
->flags
+= FFI_TYPE_INT
<< (FFI_FLAG_BITS
* 2);
333 switch (cif
->rtype
->type
)
336 case FFI_TYPE_STRUCT
:
338 case FFI_TYPE_DOUBLE
:
339 cif
->flags
+= cif
->rtype
->type
<< (FFI_FLAG_BITS
* 2);
342 case FFI_TYPE_SINT64
:
343 case FFI_TYPE_UINT64
:
344 cif
->flags
+= FFI_TYPE_UINT64
<< (FFI_FLAG_BITS
* 2);
348 cif
->flags
+= FFI_TYPE_INT
<< (FFI_FLAG_BITS
* 2);
354 #if _MIPS_SIM == _ABIN32
355 /* Set the flags necessary for N32 processing */
358 unsigned count
= (cif
->nargs
< 8) ? cif
->nargs
: 8;
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
372 shift
= FFI_FLAG_BITS
;
373 count
= (cif
->nargs
< 7) ? cif
->nargs
: 7;
375 cif
->rstruct_flag
= !0;
378 cif
->rstruct_flag
= 0;
381 cif
->rstruct_flag
= 0;
385 switch ((cif
->arg_types
)[index
]->type
)
388 case FFI_TYPE_DOUBLE
:
389 cif
->flags
+= ((cif
->arg_types
)[index
]->type
<< shift
);
390 shift
+= FFI_FLAG_BITS
;
393 case FFI_TYPE_STRUCT
:
394 cif
->flags
+= calc_n32_struct_flags((cif
->arg_types
)[index
],
399 shift
+= FFI_FLAG_BITS
;
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
418 /* The structure is returned via some tricky
420 cif
->flags
+= FFI_TYPE_STRUCT
<< (FFI_FLAG_BITS
* 8);
421 cif
->flags
+= struct_flags
<< (4 + (FFI_FLAG_BITS
* 8));
427 /* Do nothing, 'cause FFI_TYPE_VOID is 0 */
431 case FFI_TYPE_DOUBLE
:
432 cif
->flags
+= cif
->rtype
->type
<< (FFI_FLAG_BITS
* 8);
436 cif
->flags
+= FFI_TYPE_INT
<< (FFI_FLAG_BITS
* 8);
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
)
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
);
469 ecif
.rvalue
= rvalue
;
473 #if _MIPS_SIM == _ABIO32
475 case FFI_O32_SOFT_FLOAT
:
476 ffi_call_O32(ffi_prep_args
, &ecif
, cif
->bytes
,
477 cif
->flags
, ecif
.rvalue
, fn
);
481 #if _MIPS_SIM == _ABIN32
483 ffi_call_N32(ffi_prep_args
, &ecif
, cif
->bytes
,
484 cif
->flags
, ecif
.rvalue
, fn
);
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 */
500 ffi_prep_closure (ffi_closure
*closure
,
502 void (*fun
)(ffi_cif
*,void*,void**,void*),
505 unsigned int *tramp
= (unsigned int *) &closure
->tramp
[0];
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) */
525 closure
->user_data
= user_data
;
527 /* XXX this is available on Linux, but anything else? */
528 cacheflush (tramp
, FFI_TRAMPOLINE_SIZE
, ICACHE
);
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
,
558 ffi_type
**arg_types
;
559 int i
, avn
, argn
, seen_int
;
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
);
568 if ((cif
->flags
>> (FFI_FLAG_BITS
* 2)) == FFI_TYPE_STRUCT
)
570 rvalue
= (void *) ar
[0];
576 arg_types
= cif
->arg_types
;
580 if (i
< 2 && !seen_int
&&
581 (arg_types
[i
]->type
== FFI_TYPE_FLOAT
||
582 arg_types
[i
]->type
== FFI_TYPE_DOUBLE
))
585 if (arg_types
[i
]->type
== FFI_TYPE_FLOAT
)
586 avaluep
[i
] = ((char *) &fpr
[i
]) + sizeof (float);
589 avaluep
[i
] = (char *) &fpr
[i
];
593 if (arg_types
[i
]->alignment
== 8 && (argn
& 0x1))
595 switch (arg_types
[i
]->type
)
598 avaluep
[i
] = &avalue
[i
];
599 *(SINT8
*) &avalue
[i
] = (SINT8
) ar
[argn
];
603 avaluep
[i
] = &avalue
[i
];
604 *(UINT8
*) &avalue
[i
] = (UINT8
) ar
[argn
];
607 case FFI_TYPE_SINT16
:
608 avaluep
[i
] = &avalue
[i
];
609 *(SINT16
*) &avalue
[i
] = (SINT16
) ar
[argn
];
612 case FFI_TYPE_UINT16
:
613 avaluep
[i
] = &avalue
[i
];
614 *(UINT16
*) &avalue
[i
] = (UINT16
) ar
[argn
];
618 avaluep
[i
] = (char *) &ar
[argn
];
623 argn
+= ALIGN(arg_types
[i
]->size
, FFI_SIZEOF_ARG
) / FFI_SIZEOF_ARG
;
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
)
636 case FFI_TYPE_DOUBLE
:
637 return FFI_TYPE_UINT64
;
639 return cif
->rtype
->type
;
644 return cif
->rtype
->type
;
648 #endif /* FFI_CLOSURES */