Remove old autovect-branch by moving to "dead" directory.
[official-gcc.git] / old-autovect-branch / libffi / src / m68k / ffi.c
blob55f3a988bc485ed5824b09a7d009f74b0a112010
1 /* -----------------------------------------------------------------------
2 ffi.c
4 m68k Foreign Function Interface
5 ----------------------------------------------------------------------- */
7 #include <ffi.h>
8 #include <ffi_common.h>
10 #include <stdlib.h>
12 /* ffi_prep_args is called by the assembly routine once stack space has
13 been allocated for the function's arguments. */
15 static void *
16 ffi_prep_args (void *stack, extended_cif *ecif)
18 unsigned int i;
19 void **p_argv;
20 char *argp;
21 ffi_type **p_arg;
22 void *struct_value_ptr;
24 argp = stack;
26 if (ecif->cif->rtype->type == FFI_TYPE_STRUCT
27 && ecif->cif->rtype->size > 8)
28 struct_value_ptr = ecif->rvalue;
29 else
30 struct_value_ptr = NULL;
32 p_argv = ecif->avalue;
34 for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
35 i != 0;
36 i--, p_arg++)
38 size_t z;
40 /* Align if necessary. */
41 if (((*p_arg)->alignment - 1) & (unsigned) argp)
42 argp = (char *) ALIGN (argp, (*p_arg)->alignment);
44 z = (*p_arg)->size;
45 if (z < sizeof (int))
47 switch ((*p_arg)->type)
49 case FFI_TYPE_SINT8:
50 *(signed int *) argp = (signed int) *(SINT8 *) *p_argv;
51 break;
53 case FFI_TYPE_UINT8:
54 *(unsigned int *) argp = (unsigned int) *(UINT8 *) *p_argv;
55 break;
57 case FFI_TYPE_SINT16:
58 *(signed int *) argp = (signed int) *(SINT16 *) *p_argv;
59 break;
61 case FFI_TYPE_UINT16:
62 *(unsigned int *) argp = (unsigned int) *(UINT16 *) *p_argv;
63 break;
65 case FFI_TYPE_STRUCT:
66 memcpy (argp + sizeof (int) - z, *p_argv, z);
67 break;
69 default:
70 FFI_ASSERT (0);
72 z = sizeof (int);
74 else
75 memcpy (argp, *p_argv, z);
76 p_argv++;
77 argp += z;
80 return struct_value_ptr;
83 #define CIF_FLAGS_INT 1
84 #define CIF_FLAGS_DINT 2
85 #define CIF_FLAGS_FLOAT 4
86 #define CIF_FLAGS_DOUBLE 8
87 #define CIF_FLAGS_LDOUBLE 16
88 #define CIF_FLAGS_POINTER 32
89 #define CIF_FLAGS_STRUCT 64
91 /* Perform machine dependent cif processing */
92 ffi_status
93 ffi_prep_cif_machdep (ffi_cif *cif)
95 /* Set the return type flag */
96 switch (cif->rtype->type)
98 case FFI_TYPE_VOID:
99 cif->flags = 0;
100 break;
102 case FFI_TYPE_STRUCT:
103 if (cif->rtype->size > 4 && cif->rtype->size <= 8)
104 cif->flags = CIF_FLAGS_DINT;
105 else if (cif->rtype->size <= 4)
106 cif->flags = CIF_FLAGS_STRUCT;
107 else
108 cif->flags = 0;
109 break;
111 case FFI_TYPE_FLOAT:
112 cif->flags = CIF_FLAGS_FLOAT;
113 break;
115 case FFI_TYPE_DOUBLE:
116 cif->flags = CIF_FLAGS_DOUBLE;
117 break;
119 case FFI_TYPE_LONGDOUBLE:
120 cif->flags = CIF_FLAGS_LDOUBLE;
121 break;
123 case FFI_TYPE_POINTER:
124 cif->flags = CIF_FLAGS_POINTER;
125 break;
127 case FFI_TYPE_SINT64:
128 case FFI_TYPE_UINT64:
129 cif->flags = CIF_FLAGS_DINT;
130 break;
132 default:
133 cif->flags = CIF_FLAGS_INT;
134 break;
137 return FFI_OK;
140 extern void ffi_call_SYSV (void *(*) (void *, extended_cif *),
141 extended_cif *,
142 unsigned, unsigned, unsigned,
143 void *, void (*fn) ());
145 void
146 ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue)
148 extended_cif ecif;
150 ecif.cif = cif;
151 ecif.avalue = avalue;
153 /* If the return value is a struct and we don't have a return value
154 address then we need to make one. */
156 if (rvalue == NULL
157 && cif->rtype->type == FFI_TYPE_STRUCT
158 && cif->rtype->size > 8)
159 ecif.rvalue = alloca (cif->rtype->size);
160 else
161 ecif.rvalue = rvalue;
164 switch (cif->abi)
166 case FFI_SYSV:
167 ffi_call_SYSV (ffi_prep_args, &ecif, cif->bytes,
168 cif->flags, cif->rtype->size * 8,
169 ecif.rvalue, fn);
170 break;
172 default:
173 FFI_ASSERT (0);
174 break;