OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libffi/] [src/] [raw_api.c] - Blame information for rev 801

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 732 jeremybenn
/* -----------------------------------------------------------------------
2
   raw_api.c - Copyright (c) 1999, 2008  Red Hat, Inc.
3
 
4
   Author: Kresten Krab Thorup <krab@gnu.org>
5
 
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:
13
 
14
   The above copyright notice and this permission notice shall be included
15
   in all copies or substantial portions of the Software.
16
 
17
   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
18
   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21
   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22
   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24
   DEALINGS IN THE SOFTWARE.
25
   ----------------------------------------------------------------------- */
26
 
27
/* This file defines generic functions for use with the raw api. */
28
 
29
#include <ffi.h>
30
#include <ffi_common.h>
31
 
32
#if !FFI_NO_RAW_API
33
 
34
size_t
35
ffi_raw_size (ffi_cif *cif)
36
{
37
  size_t result = 0;
38
  int i;
39
 
40
  ffi_type **at = cif->arg_types;
41
 
42
  for (i = cif->nargs-1; i >= 0; i--, at++)
43
    {
44
#if !FFI_NO_STRUCTS
45
      if ((*at)->type == FFI_TYPE_STRUCT)
46
        result += ALIGN (sizeof (void*), FFI_SIZEOF_ARG);
47
      else
48
#endif
49
        result += ALIGN ((*at)->size, FFI_SIZEOF_ARG);
50
    }
51
 
52
  return result;
53
}
54
 
55
 
56
void
57
ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args)
58
{
59
  unsigned i;
60
  ffi_type **tp = cif->arg_types;
61
 
62
#if WORDS_BIGENDIAN
63
 
64
  for (i = 0; i < cif->nargs; i++, tp++, args++)
65
    {
66
      switch ((*tp)->type)
67
        {
68
        case FFI_TYPE_UINT8:
69
        case FFI_TYPE_SINT8:
70
          *args = (void*) ((char*)(raw++) + FFI_SIZEOF_ARG - 1);
71
          break;
72
 
73
        case FFI_TYPE_UINT16:
74
        case FFI_TYPE_SINT16:
75
          *args = (void*) ((char*)(raw++) + FFI_SIZEOF_ARG - 2);
76
          break;
77
 
78
#if FFI_SIZEOF_ARG >= 4   
79
        case FFI_TYPE_UINT32:
80
        case FFI_TYPE_SINT32:
81
          *args = (void*) ((char*)(raw++) + FFI_SIZEOF_ARG - 4);
82
          break;
83
#endif
84
 
85
#if !FFI_NO_STRUCTS  
86
        case FFI_TYPE_STRUCT:
87
          *args = (raw++)->ptr;
88
          break;
89
#endif
90
 
91
        case FFI_TYPE_POINTER:
92
          *args = (void*) &(raw++)->ptr;
93
          break;
94
 
95
        default:
96
          *args = raw;
97
          raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
98
        }
99
    }
100
 
101
#else /* WORDS_BIGENDIAN */
102
 
103
#if !PDP
104
 
105
  /* then assume little endian */
106
  for (i = 0; i < cif->nargs; i++, tp++, args++)
107
    {
108
#if !FFI_NO_STRUCTS
109
      if ((*tp)->type == FFI_TYPE_STRUCT)
110
        {
111
          *args = (raw++)->ptr;
112
        }
113
      else
114
#endif
115
        {
116
          *args = (void*) raw;
117
          raw += ALIGN ((*tp)->size, sizeof (void*)) / sizeof (void*);
118
        }
119
    }
120
 
121
#else
122
#error "pdp endian not supported"
123
#endif /* ! PDP */
124
 
125
#endif /* WORDS_BIGENDIAN */
126
}
127
 
128
void
129
ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw)
130
{
131
  unsigned i;
132
  ffi_type **tp = cif->arg_types;
133
 
134
  for (i = 0; i < cif->nargs; i++, tp++, args++)
135
    {
136
      switch ((*tp)->type)
137
        {
138
        case FFI_TYPE_UINT8:
139
          (raw++)->uint = *(UINT8*) (*args);
140
          break;
141
 
142
        case FFI_TYPE_SINT8:
143
          (raw++)->sint = *(SINT8*) (*args);
144
          break;
145
 
146
        case FFI_TYPE_UINT16:
147
          (raw++)->uint = *(UINT16*) (*args);
148
          break;
149
 
150
        case FFI_TYPE_SINT16:
151
          (raw++)->sint = *(SINT16*) (*args);
152
          break;
153
 
154
#if FFI_SIZEOF_ARG >= 4
155
        case FFI_TYPE_UINT32:
156
          (raw++)->uint = *(UINT32*) (*args);
157
          break;
158
 
159
        case FFI_TYPE_SINT32:
160
          (raw++)->sint = *(SINT32*) (*args);
161
          break;
162
#endif
163
 
164
#if !FFI_NO_STRUCTS
165
        case FFI_TYPE_STRUCT:
166
          (raw++)->ptr = *args;
167
          break;
168
#endif
169
 
170
        case FFI_TYPE_POINTER:
171
          (raw++)->ptr = **(void***) args;
172
          break;
173
 
174
        default:
175
          memcpy ((void*) raw->data, (void*)*args, (*tp)->size);
176
          raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
177
        }
178
    }
179
}
180
 
181
#if !FFI_NATIVE_RAW_API
182
 
183
 
184
/* This is a generic definition of ffi_raw_call, to be used if the
185
 * native system does not provide a machine-specific implementation.
186
 * Having this, allows code to be written for the raw API, without
187
 * the need for system-specific code to handle input in that format;
188
 * these following couple of functions will handle the translation forth
189
 * and back automatically. */
190
 
191
void ffi_raw_call (ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *raw)
192
{
193
  void **avalue = (void**) alloca (cif->nargs * sizeof (void*));
194
  ffi_raw_to_ptrarray (cif, raw, avalue);
195
  ffi_call (cif, fn, rvalue, avalue);
196
}
197
 
198
#if FFI_CLOSURES                /* base system provides closures */
199
 
200
static void
201
ffi_translate_args (ffi_cif *cif, void *rvalue,
202
                    void **avalue, void *user_data)
203
{
204
  ffi_raw *raw = (ffi_raw*)alloca (ffi_raw_size (cif));
205
  ffi_raw_closure *cl = (ffi_raw_closure*)user_data;
206
 
207
  ffi_ptrarray_to_raw (cif, avalue, raw);
208
  (*cl->fun) (cif, rvalue, raw, cl->user_data);
209
}
210
 
211
ffi_status
212
ffi_prep_raw_closure_loc (ffi_raw_closure* cl,
213
                          ffi_cif *cif,
214
                          void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
215
                          void *user_data,
216
                          void *codeloc)
217
{
218
  ffi_status status;
219
 
220
  status = ffi_prep_closure_loc ((ffi_closure*) cl,
221
                                 cif,
222
                                 &ffi_translate_args,
223
                                 codeloc,
224
                                 codeloc);
225
  if (status == FFI_OK)
226
    {
227
      cl->fun       = fun;
228
      cl->user_data = user_data;
229
    }
230
 
231
  return status;
232
}
233
 
234
#endif /* FFI_CLOSURES */
235
#endif /* !FFI_NATIVE_RAW_API */
236
 
237
#if FFI_CLOSURES
238
 
239
/* Again, here is the generic version of ffi_prep_raw_closure, which
240
 * will install an intermediate "hub" for translation of arguments from
241
 * the pointer-array format, to the raw format */
242
 
243
ffi_status
244
ffi_prep_raw_closure (ffi_raw_closure* cl,
245
                      ffi_cif *cif,
246
                      void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
247
                      void *user_data)
248
{
249
  return ffi_prep_raw_closure_loc (cl, cif, fun, user_data, cl);
250
}
251
 
252
#endif /* FFI_CLOSURES */
253
 
254
#endif /* !FFI_NO_RAW_API */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.