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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libffi/] [src/] [arm/] [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) 1998  Red Hat, Inc.
3
 
4
   ARM 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 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
   ----------------------------------------------------------------------- */
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 space
32
   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
  register unsigned int i;
39
  register void **p_argv;
40
  register char *argp;
41
  register ffi_type **p_arg;
42
 
43
  argp = stack;
44
 
45
  if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) {
46
    *(void **) argp = ecif->rvalue;
47
    argp += 4;
48
  }
49
 
50
  p_argv = ecif->avalue;
51
 
52
  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
53
       (i != 0);
54
       i--, p_arg++)
55
    {
56
      size_t z;
57
 
58
      /* Align if necessary */
59
      if (((*p_arg)->alignment - 1) & (unsigned) argp) {
60
        argp = (char *) ALIGN(argp, (*p_arg)->alignment);
61
      }
62
 
63
          z = (*p_arg)->size;
64
          if (z < sizeof(int))
65
            {
66
              z = sizeof(int);
67
              switch ((*p_arg)->type)
68
                {
69
                case FFI_TYPE_SINT8:
70
                  *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
71
                  break;
72
 
73
                case FFI_TYPE_UINT8:
74
                  *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
75
                  break;
76
 
77
                case FFI_TYPE_SINT16:
78
                  *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
79
                  break;
80
 
81
                case FFI_TYPE_UINT16:
82
                  *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
83
                  break;
84
 
85
                case FFI_TYPE_STRUCT:
86
                  *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
87
                  break;
88
 
89
                default:
90
                  FFI_ASSERT(0);
91
                }
92
            }
93
          else if (z == sizeof(int))
94
            {
95
              *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
96
            }
97
          else
98
            {
99
              memcpy(argp, *p_argv, z);
100
            }
101
          p_argv++;
102
          argp += z;
103
    }
104
 
105
  return;
106
}
107
 
108
/* Perform machine dependent cif processing */
109
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
110
{
111
  /* Round the stack up to a multiple of 8 bytes.  This isn't needed
112
     everywhere, but it is on some platforms, and it doesn't harm anything
113
     when it isn't needed.  */
114
  cif->bytes = (cif->bytes + 7) & ~7;
115
 
116
  /* Set the return type flag */
117
  switch (cif->rtype->type)
118
    {
119
    case FFI_TYPE_VOID:
120
    case FFI_TYPE_STRUCT:
121
    case FFI_TYPE_FLOAT:
122
    case FFI_TYPE_DOUBLE:
123
      cif->flags = (unsigned) cif->rtype->type;
124
      break;
125
 
126
    case FFI_TYPE_SINT64:
127
    case FFI_TYPE_UINT64:
128
      cif->flags = (unsigned) FFI_TYPE_SINT64;
129
      break;
130
 
131
    default:
132
      cif->flags = FFI_TYPE_INT;
133
      break;
134
    }
135
 
136
  return FFI_OK;
137
}
138
 
139
/*@-declundef@*/
140
/*@-exportheader@*/
141
extern void ffi_call_SYSV(void (*)(char *, extended_cif *),
142
                          /*@out@*/ extended_cif *,
143
                          unsigned, unsigned,
144
                          /*@out@*/ unsigned *,
145
                          void (*fn)());
146
/*@=declundef@*/
147
/*@=exportheader@*/
148
 
149
void ffi_call(/*@dependent@*/ ffi_cif *cif,
150
              void (*fn)(),
151
              /*@out@*/ void *rvalue,
152
              /*@dependent@*/ void **avalue)
153
{
154
  extended_cif ecif;
155
 
156
  ecif.cif = cif;
157
  ecif.avalue = avalue;
158
 
159
  /* If the return value is a struct and we don't have a return */
160
  /* value address then we need to make one                     */
161
 
162
  if ((rvalue == NULL) &&
163
      (cif->rtype->type == FFI_TYPE_STRUCT))
164
    {
165
      /*@-sysunrecog@*/
166
      ecif.rvalue = alloca(cif->rtype->size);
167
      /*@=sysunrecog@*/
168
    }
169
  else
170
    ecif.rvalue = rvalue;
171
 
172
 
173
  switch (cif->abi)
174
    {
175
    case FFI_SYSV:
176
      /*@-usedef@*/
177
      ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes,
178
                    cif->flags, ecif.rvalue, fn);
179
      /*@=usedef@*/
180
      break;
181
    default:
182
      FFI_ASSERT(0);
183
      break;
184
    }
185
}

powered by: WebSVN 2.1.0

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