* cfgloop.c (flow_loop_entry_edges_find): Fix typo.
[official-gcc.git] / libffi / src / mips / ffi.c
blobca3971fe6f6582d8a362b211f2ebae5154f7f1fa
1 /* -----------------------------------------------------------------------
2 ffi.c - Copyright (c) 1996 Cygnus Solutions
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>
31 #if _MIPS_SIM == _MIPS_SIM_NABI32
32 #define FIX_ARGP \
33 FFI_ASSERT(argp <= &stack[bytes]); \
34 if (argp == &stack[bytes]) \
35 { \
36 argp = stack; \
37 ffi_stop_here(); \
39 #else
40 #define FIX_ARGP
41 #endif
44 /* ffi_prep_args is called by the assembly routine once stack space
45 has been allocated for the function's arguments */
47 static void ffi_prep_args(char *stack,
48 extended_cif *ecif,
49 int bytes,
50 int flags)
52 register int i;
53 register int avn;
54 register void **p_argv;
55 register char *argp;
56 register ffi_type **p_arg;
58 #if _MIPS_SIM == _MIPS_SIM_NABI32
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_ARG)
63 argp = &stack[bytes - (8 * SIZEOF_ARG)];
64 else
65 argp = stack;
66 #else
67 argp = stack;
68 #endif
70 memset(stack, 0, bytes);
72 #if _MIPS_SIM == _MIPS_SIM_NABI32
73 if ( ecif->cif->rstruct_flag != 0 )
74 #else
75 if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT )
76 #endif
78 *(SLOT_TYPE_UNSIGNED *) argp = (SLOT_TYPE_UNSIGNED) ecif->rvalue;
79 argp += sizeof(SLOT_TYPE_UNSIGNED);
80 FIX_ARGP;
83 avn = ecif->cif->nargs;
84 p_argv = ecif->avalue;
86 for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
87 i && avn;
88 i--, p_arg++)
90 size_t z;
92 /* Align if necessary */
93 if (((*p_arg)->alignment - 1) & (unsigned) argp) {
94 argp = (char *) ALIGN(argp, (*p_arg)->alignment);
95 FIX_ARGP;
98 #if _MIPS_SIM == _MIPS_SIM_ABI32
99 #define OFFSET 0
100 #else
101 #define OFFSET sizeof(int)
102 #endif
104 if (avn)
106 avn--;
107 z = (*p_arg)->size;
108 if (z < sizeof(SLOT_TYPE_UNSIGNED))
110 z = sizeof(SLOT_TYPE_UNSIGNED);
112 switch ((*p_arg)->type)
114 case FFI_TYPE_SINT8:
115 *(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT8 *)(* p_argv);
116 break;
118 case FFI_TYPE_UINT8:
119 *(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT8 *)(* p_argv);
120 break;
122 case FFI_TYPE_SINT16:
123 *(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT16 *)(* p_argv);
124 break;
126 case FFI_TYPE_UINT16:
127 *(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT16 *)(* p_argv);
128 break;
130 case FFI_TYPE_SINT32:
131 *(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT32 *)(* p_argv);
132 break;
134 case FFI_TYPE_UINT32:
135 case FFI_TYPE_POINTER:
136 *(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT32 *)(* p_argv);
137 break;
139 /* This can only happen with 64bit slots */
140 case FFI_TYPE_FLOAT:
141 *(float *) argp = *(float *)(* p_argv);
142 break;
144 /* Handle small structures */
145 case FFI_TYPE_STRUCT:
146 memcpy(argp, *p_argv, (*p_arg)->size);
147 break;
149 default:
150 FFI_ASSERT(0);
153 else
155 #if _MIPS_SIM == _MIPS_SIM_ABI32
156 memcpy(argp, *p_argv, z);
157 #else
159 unsigned end = (unsigned) argp+z;
160 unsigned cap = (unsigned) stack+bytes;
162 /* Check if the data will fit within the register
163 space. Handle it if it doesn't. */
165 if (end <= cap)
166 memcpy(argp, *p_argv, z);
167 else
169 unsigned portion = end - cap;
171 memcpy(argp, *p_argv, portion);
172 argp = stack;
173 memcpy(argp,
174 (void*)((unsigned)(*p_argv)+portion), z - portion);
177 #endif
179 p_argv++;
180 argp += z;
181 FIX_ARGP;
185 return;
188 #if _MIPS_SIM == _MIPS_SIM_NABI32
190 /* The n32 spec says that if "a chunk consists solely of a double
191 float field (but not a double, which is part of a union), it
192 is passed in a floating point register. Any other chunk is
193 passed in an integer register". This code traverses structure
194 definitions and generates the appropriate flags. */
196 unsigned calc_n32_struct_flags(ffi_type *arg, unsigned *shift)
198 unsigned flags = 0;
199 unsigned index = 0;
201 ffi_type *e;
203 while (e = arg->elements[index])
205 if (e->type == FFI_TYPE_DOUBLE)
207 flags += (FFI_TYPE_DOUBLE << *shift);
208 *shift += FFI_FLAG_BITS;
210 else if (e->type == FFI_TYPE_STRUCT)
211 flags += calc_n32_struct_flags(e, shift);
212 else
213 *shift += FFI_FLAG_BITS;
215 index++;
218 return flags;
221 unsigned calc_n32_return_struct_flags(ffi_type *arg)
223 unsigned flags = 0;
224 unsigned index = 0;
225 unsigned small = FFI_TYPE_SMALLSTRUCT;
226 ffi_type *e;
228 /* Returning structures under n32 is a tricky thing.
229 A struct with only one or two floating point fields
230 is returned in $f0 (and $f2 if necessary). Any other
231 struct results at most 128 bits are returned in $2
232 (the first 64 bits) and $3 (remainder, if necessary).
233 Larger structs are handled normally. */
235 if (arg->size > 16)
236 return 0;
238 if (arg->size > 8)
239 small = FFI_TYPE_SMALLSTRUCT2;
241 e = arg->elements[0];
242 if (e->type == FFI_TYPE_DOUBLE)
243 flags = FFI_TYPE_DOUBLE << FFI_FLAG_BITS;
244 else if (e->type == FFI_TYPE_FLOAT)
245 flags = FFI_TYPE_FLOAT << FFI_FLAG_BITS;
247 if (flags && (e = arg->elements[1]))
249 if (e->type == FFI_TYPE_DOUBLE)
250 flags += FFI_TYPE_DOUBLE;
251 else if (e->type == FFI_TYPE_FLOAT)
252 flags += FFI_TYPE_FLOAT;
253 else
254 return small;
256 if (flags && (arg->elements[2]))
258 /* There are three arguments and the first two are
259 floats! This must be passed the old way. */
260 return small;
263 else
264 if (!flags)
265 return small;
267 return flags;
270 #endif
272 /* Perform machine dependent cif processing */
273 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
275 cif->flags = 0;
277 #if _MIPS_SIM == _MIPS_SIM_ABI32
278 /* Set the flags necessary for O32 processing */
280 if (cif->rtype->type != FFI_TYPE_STRUCT)
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 */
317 switch (cif->rtype->type)
319 case FFI_TYPE_VOID:
320 case FFI_TYPE_STRUCT:
321 case FFI_TYPE_FLOAT:
322 case FFI_TYPE_DOUBLE:
323 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
324 break;
326 default:
327 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
328 break;
330 #endif
332 #if _MIPS_SIM == _MIPS_SIM_NABI32
333 /* Set the flags necessary for N32 processing */
335 unsigned shift = 0;
336 unsigned count = (cif->nargs < 8) ? cif->nargs : 8;
337 unsigned index = 0;
339 unsigned struct_flags = 0;
341 if (cif->rtype->type == FFI_TYPE_STRUCT)
343 struct_flags = calc_n32_return_struct_flags(cif->rtype);
345 if (struct_flags == 0)
347 /* This means that the structure is being passed as
348 a hidden argument */
350 shift = FFI_FLAG_BITS;
351 count = (cif->nargs < 7) ? cif->nargs : 7;
353 cif->rstruct_flag = !0;
355 else
356 cif->rstruct_flag = 0;
358 else
359 cif->rstruct_flag = 0;
361 while (count-- > 0)
363 switch ((cif->arg_types)[index]->type)
365 case FFI_TYPE_FLOAT:
366 case FFI_TYPE_DOUBLE:
367 cif->flags += ((cif->arg_types)[index]->type << shift);
368 shift += FFI_FLAG_BITS;
369 break;
371 case FFI_TYPE_STRUCT:
372 cif->flags += calc_n32_struct_flags((cif->arg_types)[index],
373 &shift);
374 break;
376 default:
377 shift += FFI_FLAG_BITS;
380 index++;
383 /* Set the return type flag */
384 switch (cif->rtype->type)
386 case FFI_TYPE_STRUCT:
388 if (struct_flags == 0)
390 /* The structure is returned through a hidden
391 first argument. Do nothing, 'cause FFI_TYPE_VOID
392 is 0 */
394 else
396 /* The structure is returned via some tricky
397 mechanism */
398 cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
399 cif->flags += struct_flags << (4 + (FFI_FLAG_BITS * 8));
401 break;
404 case FFI_TYPE_VOID:
405 /* Do nothing, 'cause FFI_TYPE_VOID is 0 */
406 break;
408 case FFI_TYPE_FLOAT:
409 case FFI_TYPE_DOUBLE:
410 cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8);
411 break;
413 default:
414 cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
415 break;
418 #endif
420 return FFI_OK;
423 /* Low level routine for calling O32 functions */
424 extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int),
425 extended_cif *, unsigned,
426 unsigned, unsigned *, void (*)());
428 /* Low level routine for calling N32 functions */
429 extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int),
430 extended_cif *, unsigned,
431 unsigned, unsigned *, void (*)());
433 void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
435 extended_cif ecif;
437 ecif.cif = cif;
438 ecif.avalue = avalue;
440 /* If the return value is a struct and we don't have a return */
441 /* value address then we need to make one */
443 if ((rvalue == NULL) &&
444 (cif->rtype->type == FFI_TYPE_STRUCT))
445 ecif.rvalue = alloca(cif->rtype->size);
446 else
447 ecif.rvalue = rvalue;
449 switch (cif->abi)
451 #if _MIPS_SIM == _MIPS_SIM_ABI32
452 case FFI_O32:
453 ffi_call_O32(ffi_prep_args, &ecif, cif->bytes,
454 cif->flags, ecif.rvalue, fn);
455 break;
456 #endif
458 #if _MIPS_SIM == _MIPS_SIM_NABI32
459 case FFI_N32:
460 ffi_call_N32(ffi_prep_args, &ecif, cif->bytes,
461 cif->flags, ecif.rvalue, fn);
462 break;
463 #endif
465 default:
466 FFI_ASSERT(0);
467 break;