source: trunk/gcc/libffi/src/m68k/ffi.c

Last change on this file was 1392, checked in by bird, 21 years ago

This commit was generated by cvs2svn to compensate for changes in r1391,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 3.6 KB
Line 
1/* -----------------------------------------------------------------------
2 ffi.c
3
4 m68k Foreign Function Interface
5 ----------------------------------------------------------------------- */
6
7#include <ffi.h>
8#include <ffi_common.h>
9
10#include <stdlib.h>
11
12/* ffi_prep_args is called by the assembly routine once stack space has
13 been allocated for the function's arguments. */
14
15static void *
16ffi_prep_args (void *stack, extended_cif *ecif)
17{
18 unsigned int i;
19 void **p_argv;
20 char *argp;
21 ffi_type **p_arg;
22 void *struct_value_ptr;
23
24 argp = stack;
25
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;
31
32 p_argv = ecif->avalue;
33
34 for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
35 i != 0;
36 i--, p_arg++)
37 {
38 size_t z;
39
40 /* Align if necessary. */
41 if (((*p_arg)->alignment - 1) & (unsigned) argp)
42 argp = (char *) ALIGN (argp, (*p_arg)->alignment);
43
44 z = (*p_arg)->size;
45 if (z < sizeof (int))
46 {
47 switch ((*p_arg)->type)
48 {
49 case FFI_TYPE_SINT8:
50 *(signed int *) argp = (signed int) *(SINT8 *) *p_argv;
51 break;
52
53 case FFI_TYPE_UINT8:
54 *(unsigned int *) argp = (unsigned int) *(UINT8 *) *p_argv;
55 break;
56
57 case FFI_TYPE_SINT16:
58 *(signed int *) argp = (signed int) *(SINT16 *) *p_argv;
59 break;
60
61 case FFI_TYPE_UINT16:
62 *(unsigned int *) argp = (unsigned int) *(UINT16 *) *p_argv;
63 break;
64
65 case FFI_TYPE_STRUCT:
66 memcpy (argp + sizeof (int) - z, *p_argv, z);
67 break;
68
69 default:
70 FFI_ASSERT (0);
71 }
72 z = sizeof (int);
73 }
74 else
75 memcpy (argp, *p_argv, z);
76 p_argv++;
77 argp += z;
78 }
79
80 return struct_value_ptr;
81}
82
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
90
91/* Perform machine dependent cif processing */
92ffi_status
93ffi_prep_cif_machdep (ffi_cif *cif)
94{
95 /* Set the return type flag */
96 switch (cif->rtype->type)
97 {
98 case FFI_TYPE_VOID:
99 cif->flags = 0;
100 break;
101
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;
110
111 case FFI_TYPE_FLOAT:
112 cif->flags = CIF_FLAGS_FLOAT;
113 break;
114
115 case FFI_TYPE_DOUBLE:
116 cif->flags = CIF_FLAGS_DOUBLE;
117 break;
118
119 case FFI_TYPE_LONGDOUBLE:
120 cif->flags = CIF_FLAGS_LDOUBLE;
121 break;
122
123 case FFI_TYPE_POINTER:
124 cif->flags = CIF_FLAGS_POINTER;
125 break;
126
127 case FFI_TYPE_SINT64:
128 case FFI_TYPE_UINT64:
129 cif->flags = CIF_FLAGS_DINT;
130 break;
131
132 default:
133 cif->flags = CIF_FLAGS_INT;
134 break;
135 }
136
137 return FFI_OK;
138}
139
140extern void ffi_call_SYSV (void *(*) (void *, extended_cif *),
141 extended_cif *,
142 unsigned, unsigned, unsigned,
143 void *, void (*fn) ());
144
145void
146ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue)
147{
148 extended_cif ecif;
149
150 ecif.cif = cif;
151 ecif.avalue = avalue;
152
153 /* If the return value is a struct and we don't have a return value
154 address then we need to make one. */
155
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;
162
163
164 switch (cif->abi)
165 {
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;
171
172 default:
173 FFI_ASSERT (0);
174 break;
175 }
176}
Note: See TracBrowser for help on using the repository browser.