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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libffi/] [src/] [m32r/] [ffi.c] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* -----------------------------------------------------------------------
2
   ffi.c - Copyright (c) 2004  Renesas Technology
3
 
4
   M32R Foreign Function Interface
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, 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 RENESAS TECHNOLOGY 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
   ----------------------------------------------------------------------- */
25
 
26
#include <ffi.h>
27
#include <ffi_common.h>
28
 
29
#include <stdlib.h>
30
 
31
/* ffi_prep_args is called by the assembly routine once stack
32
   space has been allocated for the function's arguments.  */
33
 
34
/*@-exportheader@*/
35
void ffi_prep_args(char *stack, extended_cif *ecif)
36
/*@=exportheader@*/
37
{
38
  unsigned int i;
39
  int tmp;
40
  unsigned int avn;
41
  void **p_argv;
42
  char *argp;
43
  ffi_type **p_arg;
44
 
45
  tmp = 0;
46
  argp = stack;
47
 
48
  if (ecif->cif->rtype->type == FFI_TYPE_STRUCT && ecif->cif->rtype->size > 8)
49
    {
50
      *(void **) argp = ecif->rvalue;
51
      argp += 4;
52
    }
53
 
54
  avn = ecif->cif->nargs;
55
  p_argv = ecif->avalue;
56
 
57
  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
58
       (i != 0) && (avn != 0);
59
       i--, p_arg++)
60
    {
61
      size_t z;
62
 
63
      /* Align if necessary.  */
64
      if (((*p_arg)->alignment - 1) & (unsigned) argp)
65
        argp = (char *) ALIGN (argp, (*p_arg)->alignment);
66
 
67
      if (avn != 0)
68
        {
69
          avn--;
70
          z = (*p_arg)->size;
71
          if (z < sizeof (int))
72
            {
73
              z = sizeof (int);
74
 
75
              switch ((*p_arg)->type)
76
                {
77
                case FFI_TYPE_SINT8:
78
                  *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
79
                  break;
80
 
81
                case FFI_TYPE_UINT8:
82
                  *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
83
                  break;
84
 
85
                case FFI_TYPE_SINT16:
86
                  *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
87
                  break;
88
 
89
                case FFI_TYPE_UINT16:
90
                  *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
91
                  break;
92
 
93
                case FFI_TYPE_STRUCT:
94
                  z = (*p_arg)->size;
95
                  if ((*p_arg)->alignment != 1)
96
                    memcpy (argp, *p_argv, z);
97
                  else
98
                    memcpy (argp + 4 - z, *p_argv, z);
99
                  z = sizeof (int);
100
                  break;
101
 
102
                default:
103
                  FFI_ASSERT(0);
104
                }
105
            }
106
          else if (z == sizeof (int))
107
            {
108
               *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
109
            }
110
          else
111
            {
112
              if ((*p_arg)->type == FFI_TYPE_STRUCT)
113
                {
114
                  if (z > 8)
115
                    {
116
                      *(unsigned int *) argp = (unsigned int)(void *)(* p_argv);
117
                      z = sizeof(void *);
118
                    }
119
                  else
120
                    {
121
                      memcpy(argp, *p_argv, z);
122
                      z = 8;
123
                    }
124
                }
125
              else
126
                {
127
                  /* Double or long long 64bit.  */
128
                  memcpy (argp, *p_argv, z);
129
                }
130
            }
131
          p_argv++;
132
          argp += z;
133
        }
134
    }
135
 
136
  return;
137
}
138
 
139
/* Perform machine dependent cif processing.  */
140
ffi_status
141
ffi_prep_cif_machdep(ffi_cif *cif)
142
{
143
  /* Set the return type flag.  */
144
  switch (cif->rtype->type)
145
    {
146
    case FFI_TYPE_VOID:
147
      cif->flags = (unsigned) cif->rtype->type;
148
      break;
149
 
150
    case FFI_TYPE_STRUCT:
151
      if (cif->rtype->size <= 4)
152
        cif->flags = FFI_TYPE_INT;
153
 
154
      else if (cif->rtype->size <= 8)
155
        cif->flags = FFI_TYPE_DOUBLE;
156
 
157
      else
158
        cif->flags = (unsigned) cif->rtype->type;
159
      break;
160
 
161
    case FFI_TYPE_SINT64:
162
    case FFI_TYPE_UINT64:
163
    case FFI_TYPE_DOUBLE:
164
      cif->flags = FFI_TYPE_DOUBLE;
165
      break;
166
 
167
    case FFI_TYPE_FLOAT:
168
    default:
169
      cif->flags = FFI_TYPE_INT;
170
      break;
171
    }
172
 
173
  return FFI_OK;
174
}
175
 
176
/*@-declundef@*/
177
/*@-exportheader@*/
178
extern void ffi_call_SYSV(void (*)(char *, extended_cif *),
179
                          /*@out@*/ extended_cif *,
180
                          unsigned, unsigned,
181
                          /*@out@*/ unsigned *,
182
                          void (*fn)());
183
/*@=declundef@*/
184
/*@=exportheader@*/
185
 
186
void ffi_call(/*@dependent@*/ ffi_cif *cif,
187
              void (*fn)(),
188
              /*@out@*/ void *rvalue,
189
              /*@dependent@*/ void **avalue)
190
{
191
  extended_cif ecif;
192
 
193
  ecif.cif = cif;
194
  ecif.avalue = avalue;
195
 
196
  /* If the return value is a struct and we don't have
197
     a return value address then we need to make one.  */
198
  if ((rvalue == NULL) &&
199
      (cif->rtype->type == FFI_TYPE_STRUCT))
200
    {
201
      /*@-sysunrecog@*/
202
      ecif.rvalue = alloca (cif->rtype->size);
203
      /*@=sysunrecog@*/
204
    }
205
  else
206
    ecif.rvalue = rvalue;
207
 
208
  switch (cif->abi)
209
    {
210
    case FFI_SYSV:
211
      /*@-usedef@*/
212
      ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes,
213
                    cif->flags, ecif.rvalue, fn);
214
      if (cif->rtype->type == FFI_TYPE_STRUCT)
215
        {
216
          int size = cif->rtype->size;
217
          int align = cif->rtype->alignment;
218
 
219
          if (size < 4)
220
            {
221
              if (align == 1)
222
                *(unsigned long *)(ecif.rvalue) <<= (4 - size) * 8;
223
            }
224
          else if (4 < size && size < 8)
225
            {
226
              if (align == 1)
227
                {
228
                  memcpy (ecif.rvalue, ecif.rvalue + 8-size, size);
229
                }
230
              else if (align == 2)
231
                {
232
                  if (size & 1)
233
                    size += 1;
234
 
235
                  if (size != 8)
236
                    memcpy (ecif.rvalue, ecif.rvalue + 8-size, size);
237
                }
238
            }
239
        }
240
      /*@=usedef@*/
241
      break;
242
 
243
    default:
244
      FFI_ASSERT(0);
245
      break;
246
    }
247
}

powered by: WebSVN 2.1.0

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