~ubuntu-branches/ubuntu/lucid/gauche-c-wrapper/lucid

« back to all changes in this revision

Viewing changes to libffi/src/powerpc/ffi_darwin.c

  • Committer: Bazaar Package Importer
  • Author(s): NIIBE Yutaka
  • Date: 2008-04-07 09:15:03 UTC
  • Revision ID: james.westby@ubuntu.com-20080407091503-wu0h414koe95kj4i
Tags: upstream-0.5.2
ImportĀ upstreamĀ versionĀ 0.5.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -----------------------------------------------------------------------
 
2
   ffi.c - Copyright (c) 1998 Geoffrey Keating
 
3
 
 
4
   PowerPC Foreign Function Interface
 
5
 
 
6
   Darwin ABI support (c) 2001 John Hornkvist
 
7
   AIX ABI support (c) 2002 Free Software Foundation, Inc.
 
8
 
 
9
   Permission is hereby granted, free of charge, to any person obtaining
 
10
   a copy of this software and associated documentation files (the
 
11
   ``Software''), to deal in the Software without restriction, including
 
12
   without limitation the rights to use, copy, modify, merge, publish,
 
13
   distribute, sublicense, and/or sell copies of the Software, and to
 
14
   permit persons to whom the Software is furnished to do so, subject to
 
15
   the following conditions:
 
16
 
 
17
   The above copyright notice and this permission notice shall be included
 
18
   in all copies or substantial portions of the Software.
 
19
 
 
20
   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
 
21
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
22
   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 
23
   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
 
24
   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 
25
   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 
26
   OTHER DEALINGS IN THE SOFTWARE.
 
27
   ----------------------------------------------------------------------- */
 
28
 
 
29
#include <ffi.h>
 
30
#include <ffi_common.h>
 
31
 
 
32
#include <stdlib.h>
 
33
 
 
34
extern void ffi_closure_ASM(void);
 
35
 
 
36
enum {
 
37
  /* The assembly depends on these exact flags.  */
 
38
  FLAG_RETURNS_NOTHING  = 1 << (31-30), /* These go in cr7  */
 
39
  FLAG_RETURNS_FP       = 1 << (31-29),
 
40
  FLAG_RETURNS_64BITS   = 1 << (31-28),
 
41
  FLAG_RETURNS_128BITS  = 1 << (31-31),
 
42
 
 
43
  FLAG_ARG_NEEDS_COPY   = 1 << (31- 7),
 
44
  FLAG_FP_ARGUMENTS     = 1 << (31- 6), /* cr1.eq; specified by ABI  */
 
45
  FLAG_4_GPR_ARGUMENTS  = 1 << (31- 5),
 
46
  FLAG_RETVAL_REFERENCE = 1 << (31- 4)
 
47
};
 
48
 
 
49
/* About the DARWIN ABI.  */
 
50
enum {
 
51
  NUM_GPR_ARG_REGISTERS = 8,
 
52
  NUM_FPR_ARG_REGISTERS = 13
 
53
};
 
54
enum { ASM_NEEDS_REGISTERS = 4 };
 
55
 
 
56
/* ffi_prep_args is called by the assembly routine once stack space
 
57
   has been allocated for the function's arguments.
 
58
 
 
59
   The stack layout we want looks like this:
 
60
 
 
61
   |   Return address from ffi_call_DARWIN      |       higher addresses
 
62
   |--------------------------------------------|
 
63
   |   Previous backchain pointer       4       |       stack pointer here
 
64
   |--------------------------------------------|<+ <<< on entry to
 
65
   |   Saved r28-r31                    4*4     | |     ffi_call_DARWIN
 
66
   |--------------------------------------------| |
 
67
   |   Parameters             (at least 8*4=32) | |
 
68
   |--------------------------------------------| |
 
69
   |   Space for GPR2                   4       | |
 
70
   |--------------------------------------------| |     stack   |
 
71
   |   Reserved                       2*4       | |     grows   |
 
72
   |--------------------------------------------| |     down    V
 
73
   |   Space for callee's LR            4       | |
 
74
   |--------------------------------------------| |     lower addresses
 
75
   |   Saved CR                         4       | |
 
76
   |--------------------------------------------| |     stack pointer here
 
77
   |   Current backchain pointer        4       |-/     during
 
78
   |--------------------------------------------|   <<< ffi_call_DARWIN
 
79
 
 
80
   */
 
81
 
 
82
/*@-exportheader@*/
 
83
void ffi_prep_args(extended_cif *ecif, unsigned *const stack)
 
84
/*@=exportheader@*/
 
85
{
 
86
  const unsigned bytes = ecif->cif->bytes;
 
87
  const unsigned flags = ecif->cif->flags;
 
88
 
 
89
  /* 'stacktop' points at the previous backchain pointer.  */
 
90
  unsigned *const stacktop = stack + (bytes / sizeof(unsigned));
 
91
 
 
92
  /* 'fpr_base' points at the space for fpr1, and grows upwards as
 
93
     we use FPR registers.  */
 
94
  double *fpr_base = (double*) (stacktop - ASM_NEEDS_REGISTERS) - NUM_FPR_ARG_REGISTERS;
 
95
  int fparg_count = 0;
 
96
 
 
97
 
 
98
  /* 'next_arg' grows up as we put parameters in it.  */
 
99
  unsigned *next_arg = stack + 6; /* 6 reserved positions.  */
 
100
 
 
101
  int i = ecif->cif->nargs;
 
102
  double double_tmp;
 
103
  void **p_argv = ecif->avalue;
 
104
  unsigned gprvalue;
 
105
  ffi_type** ptr = ecif->cif->arg_types;
 
106
  char *dest_cpy;
 
107
  unsigned size_al = 0;
 
108
 
 
109
  /* Check that everything starts aligned properly.  */
 
110
  FFI_ASSERT(((unsigned)(char *)stack & 0xF) == 0);
 
111
  FFI_ASSERT(((unsigned)(char *)stacktop & 0xF) == 0);
 
112
  FFI_ASSERT((bytes & 0xF) == 0);
 
113
 
 
114
  /* Deal with return values that are actually pass-by-reference.
 
115
     Rule:
 
116
     Return values are referenced by r3, so r4 is the first parameter.  */
 
117
 
 
118
  if (flags & FLAG_RETVAL_REFERENCE)
 
119
    *next_arg++ = (unsigned)(char *)ecif->rvalue;
 
120
 
 
121
  /* Now for the arguments.  */
 
122
  for (;
 
123
       i > 0;
 
124
       i--, ptr++, p_argv++)
 
125
    {
 
126
      switch ((*ptr)->type)
 
127
        {
 
128
        /* If a floating-point parameter appears before all of the general-
 
129
           purpose registers are filled, the corresponding GPRs that match
 
130
           the size of the floating-point parameter are skipped.  */
 
131
        case FFI_TYPE_FLOAT:
 
132
          double_tmp = *(float *)*p_argv;
 
133
          *(double *)next_arg = double_tmp;
 
134
          if (fparg_count < NUM_FPR_ARG_REGISTERS)
 
135
            *fpr_base++ = double_tmp;
 
136
          next_arg++;
 
137
          fparg_count++;
 
138
          FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
 
139
          break;
 
140
 
 
141
        case FFI_TYPE_DOUBLE:
 
142
          double_tmp = *(double *)*p_argv;
 
143
          *(double *)next_arg = double_tmp;
 
144
          if (fparg_count < NUM_FPR_ARG_REGISTERS)
 
145
            *fpr_base++ = double_tmp;
 
146
          next_arg += 2;
 
147
          fparg_count++;
 
148
          FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
 
149
          break;
 
150
 
 
151
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
152
 
 
153
        case FFI_TYPE_LONGDOUBLE:
 
154
          double_tmp = ((double *)*p_argv)[0];
 
155
          *(double *)next_arg = double_tmp;
 
156
          if (fparg_count < NUM_FPR_ARG_REGISTERS)
 
157
            *fpr_base++ = double_tmp;
 
158
          next_arg += 2;
 
159
          fparg_count++;
 
160
          double_tmp = ((double *)*p_argv)[1];
 
161
          *(double *)next_arg = double_tmp;
 
162
          if (fparg_count < NUM_FPR_ARG_REGISTERS)
 
163
            *fpr_base++ = double_tmp;
 
164
          next_arg += 2;
 
165
          fparg_count++;
 
166
          FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
 
167
          break;
 
168
#endif
 
169
        case FFI_TYPE_UINT64:
 
170
        case FFI_TYPE_SINT64:
 
171
          *(long long *)next_arg = *(long long *)*p_argv;
 
172
          next_arg+=2;
 
173
          break;
 
174
        case FFI_TYPE_UINT8:
 
175
          gprvalue = *(unsigned char *)*p_argv;
 
176
          goto putgpr;
 
177
        case FFI_TYPE_SINT8:
 
178
          gprvalue = *(signed char *)*p_argv;
 
179
          goto putgpr;
 
180
        case FFI_TYPE_UINT16:
 
181
          gprvalue = *(unsigned short *)*p_argv;
 
182
          goto putgpr;
 
183
        case FFI_TYPE_SINT16:
 
184
          gprvalue = *(signed short *)*p_argv;
 
185
          goto putgpr;
 
186
 
 
187
        case FFI_TYPE_STRUCT:
 
188
          dest_cpy = (char *) next_arg;
 
189
 
 
190
          /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
 
191
             SI 4 bytes) are aligned as if they were those modes.
 
192
             Structures with 3 byte in size are padded upwards.  */
 
193
          size_al = (*ptr)->size;
 
194
          /* If the first member of the struct is a double, then align
 
195
             the struct to double-word.
 
196
             Type 3 is defined in include/ffi.h. #define FFI_TYPE_DOUBLE 3.  */
 
197
          if ((*ptr)->elements[0]->type == 3)
 
198
            size_al = ALIGN((*ptr)->size, 8);
 
199
          if (size_al < 3 && ecif->cif->abi == FFI_DARWIN)
 
200
            dest_cpy += 4 - size_al;
 
201
 
 
202
          memcpy((char *)dest_cpy, (char *)*p_argv, size_al);
 
203
          next_arg += (size_al + 3) / 4;
 
204
          break;
 
205
 
 
206
        case FFI_TYPE_INT:
 
207
        case FFI_TYPE_UINT32:
 
208
        case FFI_TYPE_SINT32:
 
209
        case FFI_TYPE_POINTER:
 
210
          gprvalue = *(unsigned *)*p_argv;
 
211
        putgpr:
 
212
          *next_arg++ = gprvalue;
 
213
          break;
 
214
        default:
 
215
          break;
 
216
        }
 
217
    }
 
218
 
 
219
  /* Check that we didn't overrun the stack...  */
 
220
  //FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS);
 
221
  //FFI_ASSERT((unsigned *)fpr_base
 
222
  //         <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
 
223
  //FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
 
224
}
 
225
 
 
226
/* Perform machine dependent cif processing.  */
 
227
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
 
228
{
 
229
  /* All this is for the DARWIN ABI.  */
 
230
  int i;
 
231
  ffi_type **ptr;
 
232
  unsigned bytes;
 
233
  int fparg_count = 0, intarg_count = 0;
 
234
  unsigned flags = 0;
 
235
  unsigned size_al = 0;
 
236
 
 
237
  /* All the machine-independent calculation of cif->bytes will be wrong.
 
238
     Redo the calculation for DARWIN.  */
 
239
 
 
240
  /* Space for the frame pointer, callee's LR, CR, etc, and for
 
241
     the asm's temp regs.  */
 
242
 
 
243
  bytes = (6 + ASM_NEEDS_REGISTERS) * sizeof(long);
 
244
 
 
245
  /* Return value handling.  The rules are as follows:
 
246
     - 32-bit (or less) integer values are returned in gpr3;
 
247
     - Structures of size <= 4 bytes also returned in gpr3;
 
248
     - 64-bit integer values and structures between 5 and 8 bytes are returned
 
249
       in gpr3 and gpr4;
 
250
     - Single/double FP values are returned in fpr1;
 
251
     - Long double FP (if not equivalent to double) values are returned in
 
252
       fpr1 and fpr2;
 
253
     - Larger structures values are allocated space and a pointer is passed
 
254
       as the first argument.  */
 
255
  switch (cif->rtype->type)
 
256
    {
 
257
 
 
258
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
259
    case FFI_TYPE_LONGDOUBLE:
 
260
      flags |= FLAG_RETURNS_128BITS;
 
261
      flags |= FLAG_RETURNS_FP;
 
262
      break;
 
263
#endif
 
264
 
 
265
    case FFI_TYPE_DOUBLE:
 
266
      flags |= FLAG_RETURNS_64BITS;
 
267
      /* Fall through.  */
 
268
    case FFI_TYPE_FLOAT:
 
269
      flags |= FLAG_RETURNS_FP;
 
270
      break;
 
271
 
 
272
    case FFI_TYPE_UINT64:
 
273
    case FFI_TYPE_SINT64:
 
274
      flags |= FLAG_RETURNS_64BITS;
 
275
      break;
 
276
 
 
277
    case FFI_TYPE_STRUCT:
 
278
      flags |= FLAG_RETVAL_REFERENCE;
 
279
      flags |= FLAG_RETURNS_NOTHING;
 
280
      intarg_count++;
 
281
      break;
 
282
    case FFI_TYPE_VOID:
 
283
      flags |= FLAG_RETURNS_NOTHING;
 
284
      break;
 
285
 
 
286
    default:
 
287
      /* Returns 32-bit integer, or similar.  Nothing to do here.  */
 
288
      break;
 
289
    }
 
290
 
 
291
  /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
 
292
     first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
 
293
     goes on the stack.  Structures are passed as a pointer to a copy of
 
294
     the structure. Stuff on the stack needs to keep proper alignment.  */
 
295
  for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
 
296
    {
 
297
      switch ((*ptr)->type)
 
298
        {
 
299
        case FFI_TYPE_FLOAT:
 
300
        case FFI_TYPE_DOUBLE:
 
301
          fparg_count++;
 
302
          /* If this FP arg is going on the stack, it must be
 
303
             8-byte-aligned.  */
 
304
          if (fparg_count > NUM_FPR_ARG_REGISTERS
 
305
              && intarg_count%2 != 0)
 
306
            intarg_count++;
 
307
          break;
 
308
 
 
309
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
310
 
 
311
        case FFI_TYPE_LONGDOUBLE:
 
312
          fparg_count += 2;
 
313
          /* If this FP arg is going on the stack, it must be
 
314
             8-byte-aligned.  */
 
315
          if (fparg_count > NUM_FPR_ARG_REGISTERS
 
316
              && intarg_count%2 != 0)
 
317
            intarg_count++;
 
318
          intarg_count +=2;
 
319
          break;
 
320
#endif
 
321
 
 
322
        case FFI_TYPE_UINT64:
 
323
        case FFI_TYPE_SINT64:
 
324
          /* 'long long' arguments are passed as two words, but
 
325
             either both words must fit in registers or both go
 
326
             on the stack.  If they go on the stack, they must
 
327
             be 8-byte-aligned.  */
 
328
          if (intarg_count == NUM_GPR_ARG_REGISTERS-1
 
329
              || (intarg_count >= NUM_GPR_ARG_REGISTERS && intarg_count%2 != 0))
 
330
            intarg_count++;
 
331
          intarg_count += 2;
 
332
          break;
 
333
 
 
334
        case FFI_TYPE_STRUCT:
 
335
          size_al = (*ptr)->size;
 
336
          /* If the first member of the struct is a double, then align
 
337
             the struct to double-word.
 
338
             Type 3 is defined in include/ffi.h. #define FFI_TYPE_DOUBLE 3.  */
 
339
          if ((*ptr)->elements[0]->type == 3)
 
340
            size_al = ALIGN((*ptr)->size, 8);
 
341
          intarg_count += (size_al + 3) / 4;
 
342
          break;
 
343
 
 
344
        default:
 
345
          /* Everything else is passed as a 4-byte word in a GPR, either
 
346
             the object itself or a pointer to it.  */
 
347
          intarg_count++;
 
348
          break;
 
349
        }
 
350
    }
 
351
 
 
352
  if (fparg_count != 0)
 
353
    flags |= FLAG_FP_ARGUMENTS;
 
354
 
 
355
  /* Space for the FPR registers, if needed.  */
 
356
  if (fparg_count != 0)
 
357
    bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
 
358
 
 
359
  /* Stack space.  */
 
360
  if ((intarg_count + 2 * fparg_count) > NUM_GPR_ARG_REGISTERS)
 
361
    bytes += (intarg_count + 2 * fparg_count) * sizeof(long);
 
362
  else
 
363
    bytes += NUM_GPR_ARG_REGISTERS * sizeof(long);
 
364
 
 
365
  /* The stack space allocated needs to be a multiple of 16 bytes.  */
 
366
  bytes = (bytes + 15) & ~0xF;
 
367
 
 
368
  cif->flags = flags;
 
369
  cif->bytes = bytes;
 
370
 
 
371
  return FFI_OK;
 
372
}
 
373
 
 
374
/*@-declundef@*/
 
375
/*@-exportheader@*/
 
376
extern void ffi_call_AIX(/*@out@*/ extended_cif *,
 
377
                         unsigned, unsigned,
 
378
                         /*@out@*/ unsigned *,
 
379
                         void (*fn)(),
 
380
                         void (*fn2)());
 
381
extern void ffi_call_DARWIN(/*@out@*/ extended_cif *,
 
382
                            unsigned, unsigned,
 
383
                            /*@out@*/ unsigned *,
 
384
                            void (*fn)(),
 
385
                            void (*fn2)());
 
386
/*@=declundef@*/
 
387
/*@=exportheader@*/
 
388
 
 
389
void ffi_call(/*@dependent@*/ ffi_cif *cif,
 
390
              void (*fn)(),
 
391
              /*@out@*/ void *rvalue,
 
392
              /*@dependent@*/ void **avalue)
 
393
{
 
394
  extended_cif ecif;
 
395
 
 
396
  ecif.cif = cif;
 
397
  ecif.avalue = avalue;
 
398
 
 
399
  /* If the return value is a struct and we don't have a return
 
400
     value address then we need to make one.  */
 
401
 
 
402
  if ((rvalue == NULL) &&
 
403
      (cif->rtype->type == FFI_TYPE_STRUCT))
 
404
    {
 
405
      /*@-sysunrecog@*/
 
406
      ecif.rvalue = alloca(cif->rtype->size);
 
407
      /*@=sysunrecog@*/
 
408
    }
 
409
  else
 
410
    ecif.rvalue = rvalue;
 
411
 
 
412
  switch (cif->abi)
 
413
    {
 
414
    case FFI_AIX:
 
415
      /*@-usedef@*/
 
416
      ffi_call_AIX(&ecif, -cif->bytes,
 
417
                   cif->flags, ecif.rvalue, fn, ffi_prep_args);
 
418
      /*@=usedef@*/
 
419
      break;
 
420
    case FFI_DARWIN:
 
421
      /*@-usedef@*/
 
422
      ffi_call_DARWIN(&ecif, -cif->bytes,
 
423
                      cif->flags, ecif.rvalue, fn, ffi_prep_args);
 
424
      /*@=usedef@*/
 
425
      break;
 
426
    default:
 
427
      FFI_ASSERT(0);
 
428
      break;
 
429
    }
 
430
}
 
431
 
 
432
static void flush_icache(char *);
 
433
static void flush_range(char *, int);
 
434
 
 
435
/* The layout of a function descriptor.  A C function pointer really
 
436
   points to one of these.  */
 
437
 
 
438
typedef struct aix_fd_struct {
 
439
  void *code_pointer;
 
440
  void *toc;
 
441
} aix_fd;
 
442
 
 
443
/* here I'd like to add the stack frame layout we use in darwin_closure.S
 
444
   and aix_clsoure.S
 
445
 
 
446
   SP previous -> +---------------------------------------+ <--- child frame
 
447
                  | back chain to caller 4                |
 
448
                  +---------------------------------------+ 4
 
449
                  | saved CR 4                            |
 
450
                  +---------------------------------------+ 8
 
451
                  | saved LR 4                            |
 
452
                  +---------------------------------------+ 12
 
453
                  | reserved for compilers 4              |
 
454
                  +---------------------------------------+ 16
 
455
                  | reserved for binders 4                |
 
456
                  +---------------------------------------+ 20
 
457
                  | saved TOC pointer 4                   |
 
458
                  +---------------------------------------+ 24
 
459
                  | always reserved 8*4=32 (previous GPRs)|
 
460
                  | according to the linkage convention   |
 
461
                  | from AIX                              |
 
462
                  +---------------------------------------+ 56
 
463
                  | our FPR area 13*8=104                 |
 
464
                  | f1                                    |
 
465
                  | .                                     |
 
466
                  | f13                                   |
 
467
                  +---------------------------------------+ 160
 
468
                  | result area 8                         |
 
469
                  +---------------------------------------+ 168
 
470
                  | alignement to the next multiple of 16 |
 
471
SP current -->    +---------------------------------------+ 176 <- parent frame
 
472
                  | back chain to caller 4                |
 
473
                  +---------------------------------------+ 180
 
474
                  | saved CR 4                            |
 
475
                  +---------------------------------------+ 184
 
476
                  | saved LR 4                            |
 
477
                  +---------------------------------------+ 188
 
478
                  | reserved for compilers 4              |
 
479
                  +---------------------------------------+ 192
 
480
                  | reserved for binders 4                |
 
481
                  +---------------------------------------+ 196
 
482
                  | saved TOC pointer 4                   |
 
483
                  +---------------------------------------+ 200
 
484
                  | always reserved 8*4=32  we store our  |
 
485
                  | GPRs here                             |
 
486
                  | r3                                    |
 
487
                  | .                                     |
 
488
                  | r10                                   |
 
489
                  +---------------------------------------+ 232
 
490
                  | overflow part                         |
 
491
                  +---------------------------------------+ xxx
 
492
                  | ????                                  |
 
493
                  +---------------------------------------+ xxx
 
494
 
 
495
*/
 
496
ffi_status
 
497
ffi_prep_closure (ffi_closure* closure,
 
498
                  ffi_cif* cif,
 
499
                  void (*fun)(ffi_cif*, void*, void**, void*),
 
500
                  void *user_data)
 
501
{
 
502
  unsigned int *tramp;
 
503
  struct ffi_aix_trampoline_struct *tramp_aix;
 
504
  aix_fd *fd;
 
505
 
 
506
  switch (cif->abi)
 
507
    {
 
508
    case FFI_DARWIN:
 
509
 
 
510
      FFI_ASSERT (cif->abi == FFI_DARWIN);
 
511
 
 
512
      tramp = (unsigned int *) &closure->tramp[0];
 
513
      tramp[0] = 0x7c0802a6;  /*   mflr    r0  */
 
514
      tramp[1] = 0x429f000d;  /*   bcl-    20,4*cr7+so,0x10  */
 
515
      tramp[4] = 0x7d6802a6;  /*   mflr    r11  */
 
516
      tramp[5] = 0x818b0000;  /*   lwz     r12,0(r11) function address  */
 
517
      tramp[6] = 0x7c0803a6;  /*   mtlr    r0   */
 
518
      tramp[7] = 0x7d8903a6;  /*   mtctr   r12  */
 
519
      tramp[8] = 0x816b0004;  /*   lwz     r11,4(r11) static chain  */
 
520
      tramp[9] = 0x4e800420;  /*   bctr  */
 
521
      tramp[2] = (unsigned long) ffi_closure_ASM; /* function  */
 
522
      tramp[3] = (unsigned long) closure; /* context  */
 
523
 
 
524
      closure->cif = cif;
 
525
      closure->fun = fun;
 
526
      closure->user_data = user_data;
 
527
 
 
528
      /* Flush the icache. Only necessary on Darwin.  */
 
529
      flush_range(&closure->tramp[0],FFI_TRAMPOLINE_SIZE);
 
530
 
 
531
      break;
 
532
 
 
533
    case FFI_AIX:
 
534
 
 
535
      tramp_aix = (struct ffi_aix_trampoline_struct *) (closure->tramp);
 
536
      fd = (aix_fd *)(void *)ffi_closure_ASM;
 
537
 
 
538
      FFI_ASSERT (cif->abi == FFI_AIX);
 
539
 
 
540
      tramp_aix->code_pointer = fd->code_pointer;
 
541
      tramp_aix->toc = fd->toc;
 
542
      tramp_aix->static_chain = closure;
 
543
      closure->cif = cif;
 
544
      closure->fun = fun;
 
545
      closure->user_data = user_data;
 
546
 
 
547
    default:
 
548
 
 
549
      FFI_ASSERT(0);
 
550
      break;
 
551
    }
 
552
  return FFI_OK;
 
553
}
 
554
 
 
555
static void
 
556
flush_icache(char *addr)
 
557
{
 
558
#ifndef _AIX
 
559
  __asm__ volatile (
 
560
                "dcbf 0,%0\n"
 
561
                "\tsync\n"
 
562
                "\ticbi 0,%0\n"
 
563
                "\tsync\n"
 
564
                "\tisync"
 
565
                : : "r"(addr) : "memory");
 
566
#endif
 
567
}
 
568
 
 
569
static void
 
570
flush_range(char * addr1, int size)
 
571
{
 
572
#define MIN_LINE_SIZE 32
 
573
  int i;
 
574
  for (i = 0; i < size; i += MIN_LINE_SIZE)
 
575
    flush_icache(addr1+i);
 
576
  flush_icache(addr1+size-1);
 
577
}
 
578
 
 
579
typedef union
 
580
{
 
581
  float f;
 
582
  double d;
 
583
} ffi_dblfl;
 
584
 
 
585
int ffi_closure_helper_DARWIN (ffi_closure*, void*,
 
586
                               unsigned long*, ffi_dblfl*);
 
587
 
 
588
/* Basically the trampoline invokes ffi_closure_ASM, and on
 
589
   entry, r11 holds the address of the closure.
 
590
   After storing the registers that could possibly contain
 
591
   parameters to be passed into the stack frame and setting
 
592
   up space for a return value, ffi_closure_ASM invokes the
 
593
   following helper function to do most of the work.  */
 
594
 
 
595
int ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,
 
596
                               unsigned long * pgr, ffi_dblfl * pfr)
 
597
{
 
598
  /* rvalue is the pointer to space for return value in closure assembly
 
599
     pgr is the pointer to where r3-r10 are stored in ffi_closure_ASM
 
600
     pfr is the pointer to where f1-f13 are stored in ffi_closure_ASM.  */
 
601
 
 
602
  typedef double ldbits[2];
 
603
 
 
604
  union ldu
 
605
  {
 
606
    ldbits lb;
 
607
    long double ld;
 
608
  };
 
609
 
 
610
  void **          avalue;
 
611
  ffi_type **      arg_types;
 
612
  long             i, avn;
 
613
  long             nf;   /* number of floating registers already used.  */
 
614
  long             ng;   /* number of general registers already used.  */
 
615
  ffi_cif *        cif;
 
616
  double           temp;
 
617
  unsigned         size_al;
 
618
  union ldu        temp_ld;
 
619
 
 
620
  cif = closure->cif;
 
621
  avalue = alloca(cif->nargs * sizeof(void *));
 
622
 
 
623
  nf = 0;
 
624
  ng = 0;
 
625
 
 
626
  /* Copy the caller's structure return value address so that the closure
 
627
     returns the data directly to the caller.  */
 
628
  if (cif->rtype->type == FFI_TYPE_STRUCT)
 
629
    {
 
630
      rvalue = (void *) *pgr;
 
631
      pgr++;
 
632
      ng++;
 
633
    }
 
634
 
 
635
  i = 0;
 
636
  avn = cif->nargs;
 
637
  arg_types = cif->arg_types;
 
638
 
 
639
  /* Grab the addresses of the arguments from the stack frame.  */
 
640
  while (i < avn)
 
641
    {
 
642
      switch (arg_types[i]->type)
 
643
        {
 
644
        case FFI_TYPE_SINT8:
 
645
        case FFI_TYPE_UINT8:
 
646
          avalue[i] = (char *) pgr + 3;
 
647
          ng++;
 
648
          pgr++;
 
649
          break;
 
650
 
 
651
        case FFI_TYPE_SINT16:
 
652
        case FFI_TYPE_UINT16:
 
653
          avalue[i] = (char *) pgr + 2;
 
654
          ng++;
 
655
          pgr++;
 
656
          break;
 
657
 
 
658
        case FFI_TYPE_SINT32:
 
659
        case FFI_TYPE_UINT32:
 
660
        case FFI_TYPE_POINTER:
 
661
          avalue[i] = pgr;
 
662
          ng++;
 
663
          pgr++;
 
664
          break;
 
665
 
 
666
        case FFI_TYPE_STRUCT:
 
667
          /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
 
668
             SI 4 bytes) are aligned as if they were those modes.  */
 
669
          size_al = arg_types[i]->size;
 
670
          /* If the first member of the struct is a double, then align
 
671
             the struct to double-word.
 
672
             Type 3 is defined in include/ffi.h. #define FFI_TYPE_DOUBLE 3.  */
 
673
          if (arg_types[i]->elements[0]->type == 3)
 
674
            size_al = ALIGN(arg_types[i]->size, 8);
 
675
          if (size_al < 3 && cif->abi == FFI_DARWIN)
 
676
            avalue[i] = (void*) pgr + 4 - size_al;
 
677
          else
 
678
            avalue[i] = (void*) pgr;
 
679
          ng += (size_al + 3) / 4;
 
680
          pgr += (size_al + 3) / 4;
 
681
          break;
 
682
 
 
683
        case FFI_TYPE_SINT64:
 
684
        case FFI_TYPE_UINT64:
 
685
          /* Long long ints are passed in two gpr's.  */
 
686
          avalue[i] = pgr;
 
687
          ng += 2;
 
688
          pgr += 2;
 
689
          break;
 
690
 
 
691
        case FFI_TYPE_FLOAT:
 
692
          /* A float value consumes a GPR.
 
693
             There are 13 64bit floating point registers.  */
 
694
          if (nf < NUM_FPR_ARG_REGISTERS)
 
695
            {
 
696
              temp = pfr->d;
 
697
              pfr->f = (float)temp;
 
698
              avalue[i] = pfr;
 
699
              pfr++;
 
700
            }
 
701
          else
 
702
            {
 
703
              avalue[i] = pgr;
 
704
            }
 
705
          nf++;
 
706
          ng++;
 
707
          pgr++;
 
708
          break;
 
709
 
 
710
        case FFI_TYPE_DOUBLE:
 
711
          /* A double value consumes two GPRs.
 
712
             There are 13 64bit floating point registers.  */
 
713
          if (nf < NUM_FPR_ARG_REGISTERS)
 
714
            {
 
715
              avalue[i] = pfr;
 
716
              pfr++;
 
717
            }
 
718
          else
 
719
            {
 
720
              avalue[i] = pgr;
 
721
            }
 
722
          nf++;
 
723
          ng += 2;
 
724
          pgr += 2;
 
725
          break;
 
726
 
 
727
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
728
 
 
729
        case FFI_TYPE_LONGDOUBLE:
 
730
          /* A long double value consumes four GPRs and two FPRs.
 
731
             There are 13 64bit floating point registers.  */
 
732
          if (nf < NUM_FPR_ARG_REGISTERS - 1)
 
733
            {
 
734
              avalue[i] = pfr;
 
735
              pfr += 2;
 
736
            }
 
737
          /* Here we have the situation where one part of the long double
 
738
             is stored in fpr13 and the other part is already on the stack.
 
739
             We use a union to pass the long double to avalue[i].  */
 
740
          else if (nf == NUM_FPR_ARG_REGISTERS - 1)
 
741
            {
 
742
              memcpy (&temp_ld.lb[0], pfr, sizeof(ldbits));
 
743
              memcpy (&temp_ld.lb[1], pgr + 2, sizeof(ldbits));
 
744
              avalue[i] = &temp_ld.ld;
 
745
            }
 
746
          else
 
747
            {
 
748
              avalue[i] = pgr;
 
749
            }
 
750
          nf += 2;
 
751
          ng += 4;
 
752
          pgr += 4;
 
753
          break;
 
754
#endif
 
755
        default:
 
756
          FFI_ASSERT(0);
 
757
        }
 
758
      i++;
 
759
    }
 
760
 
 
761
  (closure->fun) (cif, rvalue, avalue, closure->user_data);
 
762
 
 
763
  /* Tell ffi_closure_ASM to perform return type promotions.  */
 
764
  return cif->rtype->type;
 
765
}