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

Subversion Repositories scarts

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* -----------------------------------------------------------------------
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
 
15
static void *
16
ffi_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 */
92
ffi_status
93
ffi_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
 
140
extern void ffi_call_SYSV (void *(*) (void *, extended_cif *),
141
                           extended_cif *,
142
                           unsigned, unsigned, unsigned,
143
                           void *, void (*fn) ());
144
 
145
void
146
ffi_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
}

powered by: WebSVN 2.1.0

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