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

« back to all changes in this revision

Viewing changes to libffi/src/powerpc/ffi.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
   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 THE AUTHOR 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
#include <stdio.h>
 
31
 
 
32
 
 
33
extern void ffi_closure_SYSV(void);
 
34
extern void FFI_HIDDEN ffi_closure_LINUX64(void);
 
35
 
 
36
enum {
 
37
  /* The assembly depends on these exact flags.  */
 
38
  FLAG_RETURNS_SMST     = 1 << (31-31), /* Used for FFI_SYSV small structs.  */
 
39
  FLAG_RETURNS_NOTHING  = 1 << (31-30), /* These go in cr7 */
 
40
  FLAG_RETURNS_FP       = 1 << (31-29),
 
41
  FLAG_RETURNS_64BITS   = 1 << (31-28),
 
42
  FLAG_RETURNS_128BITS  = 1 << (31-27),
 
43
 
 
44
  FLAG_ARG_NEEDS_COPY   = 1 << (31- 7),
 
45
  FLAG_FP_ARGUMENTS     = 1 << (31- 6), /* cr1.eq; specified by ABI */
 
46
  FLAG_4_GPR_ARGUMENTS  = 1 << (31- 5),
 
47
  FLAG_RETVAL_REFERENCE = 1 << (31- 4)
 
48
};
 
49
 
 
50
/* About the SYSV ABI.  */
 
51
enum {
 
52
  NUM_GPR_ARG_REGISTERS = 8,
 
53
  NUM_FPR_ARG_REGISTERS = 8
 
54
};
 
55
enum { ASM_NEEDS_REGISTERS = 4 };
 
56
 
 
57
/* ffi_prep_args_SYSV is called by the assembly routine once stack space
 
58
   has been allocated for the function's arguments.
 
59
 
 
60
   The stack layout we want looks like this:
 
61
 
 
62
   |   Return address from ffi_call_SYSV 4bytes |       higher addresses
 
63
   |--------------------------------------------|
 
64
   |   Previous backchain pointer       4       |       stack pointer here
 
65
   |--------------------------------------------|<+ <<< on entry to
 
66
   |   Saved r28-r31                    4*4     | |     ffi_call_SYSV
 
67
   |--------------------------------------------| |
 
68
   |   GPR registers r3-r10             8*4     | |     ffi_call_SYSV
 
69
   |--------------------------------------------| |
 
70
   |   FPR registers f1-f8 (optional)   8*8     | |
 
71
   |--------------------------------------------| |     stack   |
 
72
   |   Space for copied structures              | |     grows   |
 
73
   |--------------------------------------------| |     down    V
 
74
   |   Parameters that didn't fit in registers  | |
 
75
   |--------------------------------------------| |     lower addresses
 
76
   |   Space for callee's LR            4       | |
 
77
   |--------------------------------------------| |     stack pointer here
 
78
   |   Current backchain pointer        4       |-/     during
 
79
   |--------------------------------------------|   <<< ffi_call_SYSV
 
80
 
 
81
*/
 
82
 
 
83
/*@-exportheader@*/
 
84
void ffi_prep_args_SYSV(extended_cif *ecif, unsigned *const stack)
 
85
/*@=exportheader@*/
 
86
{
 
87
  const unsigned bytes = ecif->cif->bytes;
 
88
  const unsigned flags = ecif->cif->flags;
 
89
 
 
90
  /* 'stacktop' points at the previous backchain pointer.  */
 
91
  unsigned *const stacktop = stack + (bytes / sizeof(unsigned));
 
92
 
 
93
  /* 'gpr_base' points at the space for gpr3, and grows upwards as
 
94
     we use GPR registers.  */
 
95
  unsigned *gpr_base = stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS;
 
96
  int intarg_count = 0;
 
97
 
 
98
  /* 'fpr_base' points at the space for fpr1, and grows upwards as
 
99
     we use FPR registers.  */
 
100
  double *fpr_base = (double *)gpr_base - NUM_FPR_ARG_REGISTERS;
 
101
  int fparg_count = 0;
 
102
 
 
103
  /* 'copy_space' grows down as we put structures in it.  It should
 
104
     stay 16-byte aligned.  */
 
105
  char *copy_space = ((flags & FLAG_FP_ARGUMENTS)
 
106
                      ? (char *)fpr_base
 
107
                      : (char *)gpr_base);
 
108
 
 
109
  /* 'next_arg' grows up as we put parameters in it.  */
 
110
  unsigned *next_arg = stack + 2;
 
111
 
 
112
  int i;
 
113
  ffi_type **ptr;
 
114
  double double_tmp;
 
115
  void **p_argv;
 
116
  size_t struct_copy_size;
 
117
  unsigned gprvalue;
 
118
 
 
119
  /* Check that everything starts aligned properly.  */
 
120
  FFI_ASSERT(((unsigned)(char *)stack & 0xF) == 0);
 
121
  FFI_ASSERT(((unsigned)(char *)copy_space & 0xF) == 0);
 
122
  FFI_ASSERT(((unsigned)(char *)stacktop & 0xF) == 0);
 
123
  FFI_ASSERT((bytes & 0xF) == 0);
 
124
  FFI_ASSERT(copy_space >= (char *)next_arg);
 
125
 
 
126
  /* Deal with return values that are actually pass-by-reference.  */
 
127
  if (flags & FLAG_RETVAL_REFERENCE)
 
128
    {
 
129
      *gpr_base++ = (unsigned long)(char *)ecif->rvalue;
 
130
      intarg_count++;
 
131
    }
 
132
 
 
133
  /* Now for the arguments.  */
 
134
  p_argv = ecif->avalue;
 
135
  for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
 
136
       i > 0;
 
137
       i--, ptr++, p_argv++)
 
138
    {
 
139
      switch ((*ptr)->type)
 
140
        {
 
141
        case FFI_TYPE_FLOAT:
 
142
          double_tmp = *(float *)*p_argv;
 
143
          if (fparg_count >= NUM_FPR_ARG_REGISTERS)
 
144
            {
 
145
              *(float *)next_arg = (float)double_tmp;
 
146
              next_arg += 1;
 
147
            }
 
148
          else
 
149
            *fpr_base++ = double_tmp;
 
150
          fparg_count++;
 
151
          FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
 
152
          break;
 
153
 
 
154
        case FFI_TYPE_DOUBLE:
 
155
          double_tmp = *(double *)*p_argv;
 
156
 
 
157
          if (fparg_count >= NUM_FPR_ARG_REGISTERS)
 
158
            {
 
159
              if (intarg_count >= NUM_GPR_ARG_REGISTERS
 
160
                  && intarg_count % 2 != 0)
 
161
                {
 
162
                  intarg_count++;
 
163
                  next_arg++;
 
164
                }
 
165
              *(double *)next_arg = double_tmp;
 
166
              next_arg += 2;
 
167
            }
 
168
          else
 
169
            *fpr_base++ = double_tmp;
 
170
          fparg_count++;
 
171
          FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
 
172
          break;
 
173
 
 
174
        case FFI_TYPE_UINT64:
 
175
        case FFI_TYPE_SINT64:
 
176
          if (intarg_count == NUM_GPR_ARG_REGISTERS-1)
 
177
            intarg_count++;
 
178
          if (intarg_count >= NUM_GPR_ARG_REGISTERS)
 
179
            {
 
180
              if (intarg_count%2 != 0)
 
181
                {
 
182
                  intarg_count++;
 
183
                  next_arg++;
 
184
                }
 
185
              *(long long *)next_arg = *(long long *)*p_argv;
 
186
              next_arg += 2;
 
187
            }
 
188
          else
 
189
            {
 
190
              /* whoops: abi states only certain register pairs
 
191
               * can be used for passing long long int
 
192
               * specifically (r3,r4), (r5,r6), (r7,r8),
 
193
               * (r9,r10) and if next arg is long long but
 
194
               * not correct starting register of pair then skip
 
195
               * until the proper starting register
 
196
               */
 
197
              if (intarg_count%2 != 0)
 
198
                {
 
199
                  intarg_count ++;
 
200
                  gpr_base++;
 
201
                }
 
202
              *(long long *)gpr_base = *(long long *)*p_argv;
 
203
              gpr_base += 2;
 
204
            }
 
205
          intarg_count += 2;
 
206
          break;
 
207
 
 
208
        case FFI_TYPE_STRUCT:
 
209
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
210
        case FFI_TYPE_LONGDOUBLE:
 
211
#endif
 
212
          struct_copy_size = ((*ptr)->size + 15) & ~0xF;
 
213
          copy_space -= struct_copy_size;
 
214
          memcpy(copy_space, (char *)*p_argv, (*ptr)->size);
 
215
 
 
216
          gprvalue = (unsigned long)copy_space;
 
217
 
 
218
          FFI_ASSERT(copy_space > (char *)next_arg);
 
219
          FFI_ASSERT(flags & FLAG_ARG_NEEDS_COPY);
 
220
          goto putgpr;
 
221
 
 
222
        case FFI_TYPE_UINT8:
 
223
          gprvalue = *(unsigned char *)*p_argv;
 
224
          goto putgpr;
 
225
        case FFI_TYPE_SINT8:
 
226
          gprvalue = *(signed char *)*p_argv;
 
227
          goto putgpr;
 
228
        case FFI_TYPE_UINT16:
 
229
          gprvalue = *(unsigned short *)*p_argv;
 
230
          goto putgpr;
 
231
        case FFI_TYPE_SINT16:
 
232
          gprvalue = *(signed short *)*p_argv;
 
233
          goto putgpr;
 
234
 
 
235
        case FFI_TYPE_INT:
 
236
        case FFI_TYPE_UINT32:
 
237
        case FFI_TYPE_SINT32:
 
238
        case FFI_TYPE_POINTER:
 
239
          gprvalue = *(unsigned *)*p_argv;
 
240
        putgpr:
 
241
          if (intarg_count >= NUM_GPR_ARG_REGISTERS)
 
242
            *next_arg++ = gprvalue;
 
243
          else
 
244
            *gpr_base++ = gprvalue;
 
245
          intarg_count++;
 
246
          break;
 
247
        }
 
248
    }
 
249
 
 
250
  /* Check that we didn't overrun the stack...  */
 
251
  FFI_ASSERT(copy_space >= (char *)next_arg);
 
252
  FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS);
 
253
  FFI_ASSERT((unsigned *)fpr_base
 
254
             <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
 
255
  FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
 
256
}
 
257
 
 
258
/* About the LINUX64 ABI.  */
 
259
enum {
 
260
  NUM_GPR_ARG_REGISTERS64 = 8,
 
261
  NUM_FPR_ARG_REGISTERS64 = 13
 
262
};
 
263
enum { ASM_NEEDS_REGISTERS64 = 4 };
 
264
 
 
265
/* ffi_prep_args64 is called by the assembly routine once stack space
 
266
   has been allocated for the function's arguments.
 
267
 
 
268
   The stack layout we want looks like this:
 
269
 
 
270
   |   Ret addr from ffi_call_LINUX64   8bytes  |       higher addresses
 
271
   |--------------------------------------------|
 
272
   |   CR save area                     8bytes  |
 
273
   |--------------------------------------------|
 
274
   |   Previous backchain pointer       8       |       stack pointer here
 
275
   |--------------------------------------------|<+ <<< on entry to
 
276
   |   Saved r28-r31                    4*8     | |     ffi_call_LINUX64
 
277
   |--------------------------------------------| |
 
278
   |   GPR registers r3-r10             8*8     | |
 
279
   |--------------------------------------------| |
 
280
   |   FPR registers f1-f13 (optional)  13*8    | |
 
281
   |--------------------------------------------| |
 
282
   |   Parameter save area                      | |
 
283
   |--------------------------------------------| |
 
284
   |   TOC save area                    8       | |
 
285
   |--------------------------------------------| |     stack   |
 
286
   |   Linker doubleword                8       | |     grows   |
 
287
   |--------------------------------------------| |     down    V
 
288
   |   Compiler doubleword              8       | |
 
289
   |--------------------------------------------| |     lower addresses
 
290
   |   Space for callee's LR            8       | |
 
291
   |--------------------------------------------| |
 
292
   |   CR save area                     8       | |
 
293
   |--------------------------------------------| |     stack pointer here
 
294
   |   Current backchain pointer        8       |-/     during
 
295
   |--------------------------------------------|   <<< ffi_call_LINUX64
 
296
 
 
297
*/
 
298
 
 
299
/*@-exportheader@*/
 
300
void FFI_HIDDEN ffi_prep_args64(extended_cif *ecif, unsigned long *const stack)
 
301
/*@=exportheader@*/
 
302
{
 
303
  const unsigned long bytes = ecif->cif->bytes;
 
304
  const unsigned long flags = ecif->cif->flags;
 
305
 
 
306
  /* 'stacktop' points at the previous backchain pointer.  */
 
307
  unsigned long *const stacktop = stack + (bytes / sizeof(unsigned long));
 
308
 
 
309
  /* 'next_arg' points at the space for gpr3, and grows upwards as
 
310
     we use GPR registers, then continues at rest.  */
 
311
  unsigned long *const gpr_base = stacktop - ASM_NEEDS_REGISTERS64
 
312
    - NUM_GPR_ARG_REGISTERS64;
 
313
  unsigned long *const gpr_end = gpr_base + NUM_GPR_ARG_REGISTERS64;
 
314
  unsigned long *const rest = stack + 6 + NUM_GPR_ARG_REGISTERS64;
 
315
  unsigned long *next_arg = gpr_base;
 
316
 
 
317
  /* 'fpr_base' points at the space for fpr3, and grows upwards as
 
318
     we use FPR registers.  */
 
319
  double *fpr_base = (double *)gpr_base - NUM_FPR_ARG_REGISTERS64;
 
320
  int fparg_count = 0;
 
321
 
 
322
  int i, words;
 
323
  ffi_type **ptr;
 
324
  double double_tmp;
 
325
  void **p_argv;
 
326
  unsigned long gprvalue;
 
327
 
 
328
  /* Check that everything starts aligned properly.  */
 
329
  FFI_ASSERT(((unsigned long)(char *)stack & 0xF) == 0);
 
330
  FFI_ASSERT(((unsigned long)(char *)stacktop & 0xF) == 0);
 
331
  FFI_ASSERT((bytes & 0xF) == 0);
 
332
 
 
333
  /* Deal with return values that are actually pass-by-reference.  */
 
334
  if (flags & FLAG_RETVAL_REFERENCE)
 
335
    *next_arg++ = (unsigned long)(char *)ecif->rvalue;
 
336
 
 
337
  /* Now for the arguments.  */
 
338
  p_argv = ecif->avalue;
 
339
  for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
 
340
       i > 0;
 
341
       i--, ptr++, p_argv++)
 
342
    {
 
343
      switch ((*ptr)->type)
 
344
        {
 
345
        case FFI_TYPE_FLOAT:
 
346
          double_tmp = *(float *)*p_argv;
 
347
          *(float *)next_arg = (float)double_tmp;
 
348
          if (++next_arg == gpr_end)
 
349
            next_arg = rest;
 
350
          if (fparg_count < NUM_FPR_ARG_REGISTERS64)
 
351
            *fpr_base++ = double_tmp;
 
352
          fparg_count++;
 
353
          FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
 
354
          break;
 
355
 
 
356
        case FFI_TYPE_DOUBLE:
 
357
          double_tmp = *(double *)*p_argv;
 
358
          *(double *)next_arg = double_tmp;
 
359
          if (++next_arg == gpr_end)
 
360
            next_arg = rest;
 
361
          if (fparg_count < NUM_FPR_ARG_REGISTERS64)
 
362
            *fpr_base++ = double_tmp;
 
363
          fparg_count++;
 
364
          FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
 
365
          break;
 
366
 
 
367
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
368
        case FFI_TYPE_LONGDOUBLE:
 
369
          double_tmp = ((double *) *p_argv)[0];
 
370
          *(double *) next_arg = double_tmp;
 
371
          if (++next_arg == gpr_end)
 
372
            next_arg = rest;
 
373
          if (fparg_count < NUM_FPR_ARG_REGISTERS64)
 
374
            *fpr_base++ = double_tmp;
 
375
          fparg_count++;
 
376
          double_tmp = ((double *) *p_argv)[1];
 
377
          *(double *) next_arg = double_tmp;
 
378
          if (++next_arg == gpr_end)
 
379
            next_arg = rest;
 
380
          if (fparg_count < NUM_FPR_ARG_REGISTERS64)
 
381
            *fpr_base++ = double_tmp;
 
382
          fparg_count++;
 
383
          FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
 
384
          break;
 
385
#endif
 
386
 
 
387
        case FFI_TYPE_STRUCT:
 
388
          words = ((*ptr)->size + 7) / 8;
 
389
          if (next_arg >= gpr_base && next_arg + words > gpr_end)
 
390
            {
 
391
              size_t first = (char *) gpr_end - (char *) next_arg;
 
392
              memcpy((char *) next_arg, (char *) *p_argv, first);
 
393
              memcpy((char *) rest, (char *) *p_argv + first,
 
394
                     (*ptr)->size - first);
 
395
              next_arg = (unsigned long *) ((char *) rest + words * 8 - first);
 
396
            }
 
397
          else
 
398
            {
 
399
              char *where = (char *) next_arg;
 
400
 
 
401
              /* Structures with size less than eight bytes are passed
 
402
                 left-padded.  */
 
403
              if ((*ptr)->size < 8)
 
404
                where += 8 - (*ptr)->size;
 
405
 
 
406
              memcpy (where, (char *) *p_argv, (*ptr)->size);
 
407
              next_arg += words;
 
408
              if (next_arg == gpr_end)
 
409
                next_arg = rest;
 
410
            }
 
411
          break;
 
412
 
 
413
        case FFI_TYPE_UINT8:
 
414
          gprvalue = *(unsigned char *)*p_argv;
 
415
          goto putgpr;
 
416
        case FFI_TYPE_SINT8:
 
417
          gprvalue = *(signed char *)*p_argv;
 
418
          goto putgpr;
 
419
        case FFI_TYPE_UINT16:
 
420
          gprvalue = *(unsigned short *)*p_argv;
 
421
          goto putgpr;
 
422
        case FFI_TYPE_SINT16:
 
423
          gprvalue = *(signed short *)*p_argv;
 
424
          goto putgpr;
 
425
        case FFI_TYPE_UINT32:
 
426
          gprvalue = *(unsigned int *)*p_argv;
 
427
          goto putgpr;
 
428
        case FFI_TYPE_INT:
 
429
        case FFI_TYPE_SINT32:
 
430
          gprvalue = *(signed int *)*p_argv;
 
431
          goto putgpr;
 
432
 
 
433
        case FFI_TYPE_UINT64:
 
434
        case FFI_TYPE_SINT64:
 
435
        case FFI_TYPE_POINTER:
 
436
          gprvalue = *(unsigned long *)*p_argv;
 
437
        putgpr:
 
438
          *next_arg++ = gprvalue;
 
439
          if (next_arg == gpr_end)
 
440
            next_arg = rest;
 
441
          break;
 
442
        }
 
443
    }
 
444
 
 
445
  FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS
 
446
             || (next_arg >= gpr_base && next_arg <= gpr_base + 4));
 
447
}
 
448
 
 
449
 
 
450
 
 
451
/* Perform machine dependent cif processing */
 
452
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
 
453
{
 
454
  /* All this is for the SYSV and LINUX64 ABI.  */
 
455
  int i;
 
456
  ffi_type **ptr;
 
457
  unsigned bytes;
 
458
  int fparg_count = 0, intarg_count = 0;
 
459
  unsigned flags = 0;
 
460
  unsigned struct_copy_size = 0;
 
461
  unsigned type = cif->rtype->type;
 
462
  unsigned size = cif->rtype->size;
 
463
 
 
464
  if (cif->abi != FFI_LINUX64)
 
465
    {
 
466
      /* All the machine-independent calculation of cif->bytes will be wrong.
 
467
         Redo the calculation for SYSV.  */
 
468
 
 
469
      /* Space for the frame pointer, callee's LR, and the asm's temp regs.  */
 
470
      bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof(int);
 
471
 
 
472
      /* Space for the GPR registers.  */
 
473
      bytes += NUM_GPR_ARG_REGISTERS * sizeof(int);
 
474
    }
 
475
  else
 
476
    {
 
477
      /* 64-bit ABI.  */
 
478
 
 
479
      /* Space for backchain, CR, LR, cc/ld doubleword, TOC and the asm's temp
 
480
         regs.  */
 
481
      bytes = (6 + ASM_NEEDS_REGISTERS64) * sizeof(long);
 
482
 
 
483
      /* Space for the mandatory parm save area and general registers.  */
 
484
      bytes += 2 * NUM_GPR_ARG_REGISTERS64 * sizeof(long);
 
485
 
 
486
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
487
      if (type == FFI_TYPE_LONGDOUBLE)
 
488
        type = FFI_TYPE_DOUBLE;
 
489
#endif
 
490
    }
 
491
 
 
492
  /* Return value handling.  The rules for SYSV are as follows:
 
493
     - 32-bit (or less) integer values are returned in gpr3;
 
494
     - Structures of size <= 4 bytes also returned in gpr3;
 
495
     - 64-bit integer values and structures between 5 and 8 bytes are returned
 
496
     in gpr3 and gpr4;
 
497
     - Single/double FP values are returned in fpr1;
 
498
     - Larger structures and long double (if not equivalent to double) values
 
499
     are allocated space and a pointer is passed as the first argument.
 
500
     For LINUX64:
 
501
     - integer values in gpr3;
 
502
     - Structures/Unions by reference;
 
503
     - Single/double FP values in fpr1, long double in fpr1,fpr2.  */
 
504
  switch (type)
 
505
    {
 
506
    case FFI_TYPE_DOUBLE:
 
507
      flags |= FLAG_RETURNS_64BITS;
 
508
      /* Fall through.  */
 
509
    case FFI_TYPE_FLOAT:
 
510
      flags |= FLAG_RETURNS_FP;
 
511
      break;
 
512
 
 
513
    case FFI_TYPE_UINT64:
 
514
    case FFI_TYPE_SINT64:
 
515
      flags |= FLAG_RETURNS_64BITS;
 
516
      break;
 
517
 
 
518
    case FFI_TYPE_STRUCT:
 
519
      if (cif->abi == FFI_SYSV)
 
520
        {
 
521
          /* The final SYSV ABI says that structures smaller or equal 8 bytes
 
522
             are returned in r3/r4. The FFI_GCC_SYSV ABI instead returns them
 
523
             in memory.  */
 
524
 
 
525
          /* Treat structs with size <= 8 bytes.  */
 
526
          if (size <= 8) {
 
527
            flags |= FLAG_RETURNS_SMST;
 
528
            /* These structs are returned in r3. We pack the type and the
 
529
               precalculated shift value (needed in the sysv.S) into flags.
 
530
               The same applies for the structs returned in r3/r4.  */
 
531
            if (size <= 4) {
 
532
              flags |= 1 << (31 - FFI_SYSV_TYPE_SMALL_STRUCT - 1 )
 
533
                | (8 * (4 - size) << 4);
 
534
              break;
 
535
            }
 
536
            /* These structs are returned in r3 and r4. See above.   */
 
537
            if  (size <= 8) {
 
538
              flags |= 1 << (31 - FFI_SYSV_TYPE_SMALL_STRUCT - 2 )
 
539
                | (8 * (8 - size) << 4);
 
540
            break;
 
541
            }
 
542
          }
 
543
        }
 
544
      /* else fall through.  */
 
545
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
546
    case FFI_TYPE_LONGDOUBLE:
 
547
      if (type == FFI_TYPE_LONGDOUBLE && cif->abi == FFI_LINUX64)
 
548
        {
 
549
          flags |= FLAG_RETURNS_128BITS;
 
550
          flags |= FLAG_RETURNS_FP;
 
551
          break;
 
552
        }
 
553
#endif
 
554
      intarg_count++;
 
555
      flags |= FLAG_RETVAL_REFERENCE;
 
556
      /* Fall through.  */
 
557
    case FFI_TYPE_VOID:
 
558
      flags |= FLAG_RETURNS_NOTHING;
 
559
      break;
 
560
 
 
561
    default:
 
562
      /* Returns 32-bit integer, or similar.  Nothing to do here.  */
 
563
      break;
 
564
    }
 
565
 
 
566
  if (cif->abi != FFI_LINUX64)
 
567
    /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
 
568
       first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
 
569
       goes on the stack.  Structures and long doubles (if not equivalent
 
570
       to double) are passed as a pointer to a copy of the structure.
 
571
       Stuff on the stack needs to keep proper alignment.  */
 
572
    for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
 
573
      {
 
574
        switch ((*ptr)->type)
 
575
          {
 
576
          case FFI_TYPE_FLOAT:
 
577
            fparg_count++;
 
578
            /* floating singles are not 8-aligned on stack */
 
579
            break;
 
580
 
 
581
          case FFI_TYPE_DOUBLE:
 
582
            fparg_count++;
 
583
            /* If this FP arg is going on the stack, it must be
 
584
               8-byte-aligned.  */
 
585
            if (fparg_count > NUM_FPR_ARG_REGISTERS
 
586
                && intarg_count >= NUM_GPR_ARG_REGISTERS
 
587
                && intarg_count % 2 != 0)
 
588
              intarg_count++;
 
589
            break;
 
590
 
 
591
          case FFI_TYPE_UINT64:
 
592
          case FFI_TYPE_SINT64:
 
593
            /* 'long long' arguments are passed as two words, but
 
594
               either both words must fit in registers or both go
 
595
               on the stack.  If they go on the stack, they must
 
596
               be 8-byte-aligned.
 
597
 
 
598
               Also, only certain register pairs can be used for
 
599
               passing long long int -- specifically (r3,r4), (r5,r6),
 
600
               (r7,r8), (r9,r10).
 
601
            */
 
602
            if (intarg_count == NUM_GPR_ARG_REGISTERS-1
 
603
                || intarg_count%2 != 0)
 
604
              intarg_count++;
 
605
            intarg_count += 2;
 
606
            break;
 
607
 
 
608
          case FFI_TYPE_STRUCT:
 
609
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
610
          case FFI_TYPE_LONGDOUBLE:
 
611
#endif
 
612
            /* We must allocate space for a copy of these to enforce
 
613
               pass-by-value.  Pad the space up to a multiple of 16
 
614
               bytes (the maximum alignment required for anything under
 
615
               the SYSV ABI).  */
 
616
            struct_copy_size += ((*ptr)->size + 15) & ~0xF;
 
617
            /* Fall through (allocate space for the pointer).  */
 
618
 
 
619
          default:
 
620
            /* Everything else is passed as a 4-byte word in a GPR, either
 
621
               the object itself or a pointer to it.  */
 
622
            intarg_count++;
 
623
            break;
 
624
          }
 
625
      }
 
626
  else
 
627
    for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
 
628
      {
 
629
        switch ((*ptr)->type)
 
630
          {
 
631
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
632
          case FFI_TYPE_LONGDOUBLE:
 
633
            fparg_count += 2;
 
634
            intarg_count += 2;
 
635
            break;
 
636
#endif
 
637
          case FFI_TYPE_FLOAT:
 
638
          case FFI_TYPE_DOUBLE:
 
639
            fparg_count++;
 
640
            intarg_count++;
 
641
            break;
 
642
 
 
643
          case FFI_TYPE_STRUCT:
 
644
            intarg_count += ((*ptr)->size + 7) / 8;
 
645
            break;
 
646
 
 
647
          default:
 
648
            /* Everything else is passed as a 8-byte word in a GPR, either
 
649
               the object itself or a pointer to it.  */
 
650
            intarg_count++;
 
651
            break;
 
652
          }
 
653
      }
 
654
 
 
655
  if (fparg_count != 0)
 
656
    flags |= FLAG_FP_ARGUMENTS;
 
657
  if (intarg_count > 4)
 
658
    flags |= FLAG_4_GPR_ARGUMENTS;
 
659
  if (struct_copy_size != 0)
 
660
    flags |= FLAG_ARG_NEEDS_COPY;
 
661
 
 
662
  if (cif->abi != FFI_LINUX64)
 
663
    {
 
664
      /* Space for the FPR registers, if needed.  */
 
665
      if (fparg_count != 0)
 
666
        bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
 
667
 
 
668
      /* Stack space.  */
 
669
      if (intarg_count > NUM_GPR_ARG_REGISTERS)
 
670
        bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof(int);
 
671
      if (fparg_count > NUM_FPR_ARG_REGISTERS)
 
672
        bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof(double);
 
673
    }
 
674
  else
 
675
    {
 
676
      /* Space for the FPR registers, if needed.  */
 
677
      if (fparg_count != 0)
 
678
        bytes += NUM_FPR_ARG_REGISTERS64 * sizeof(double);
 
679
 
 
680
      /* Stack space.  */
 
681
      if (intarg_count > NUM_GPR_ARG_REGISTERS64)
 
682
        bytes += (intarg_count - NUM_GPR_ARG_REGISTERS64) * sizeof(long);
 
683
    }
 
684
 
 
685
  /* The stack space allocated needs to be a multiple of 16 bytes.  */
 
686
  bytes = (bytes + 15) & ~0xF;
 
687
 
 
688
  /* Add in the space for the copied structures.  */
 
689
  bytes += struct_copy_size;
 
690
 
 
691
  cif->flags = flags;
 
692
  cif->bytes = bytes;
 
693
 
 
694
  return FFI_OK;
 
695
}
 
696
 
 
697
/*@-declundef@*/
 
698
/*@-exportheader@*/
 
699
extern void ffi_call_SYSV(/*@out@*/ extended_cif *,
 
700
                          unsigned, unsigned,
 
701
                          /*@out@*/ unsigned *,
 
702
                          void (*fn)());
 
703
extern void FFI_HIDDEN ffi_call_LINUX64(/*@out@*/ extended_cif *,
 
704
                                        unsigned long, unsigned long,
 
705
                                        /*@out@*/ unsigned long *,
 
706
                                        void (*fn)());
 
707
/*@=declundef@*/
 
708
/*@=exportheader@*/
 
709
 
 
710
void ffi_call(/*@dependent@*/ ffi_cif *cif,
 
711
              void (*fn)(),
 
712
              /*@out@*/ void *rvalue,
 
713
              /*@dependent@*/ void **avalue)
 
714
{
 
715
  extended_cif ecif;
 
716
 
 
717
  ecif.cif = cif;
 
718
  ecif.avalue = avalue;
 
719
 
 
720
  /* If the return value is a struct and we don't have a return */
 
721
  /* value address then we need to make one                     */
 
722
 
 
723
  if ((rvalue == NULL) &&
 
724
      (cif->rtype->type == FFI_TYPE_STRUCT))
 
725
    {
 
726
      /*@-sysunrecog@*/
 
727
      ecif.rvalue = alloca(cif->rtype->size);
 
728
      /*@=sysunrecog@*/
 
729
    }
 
730
  else
 
731
    ecif.rvalue = rvalue;
 
732
 
 
733
 
 
734
  switch (cif->abi)
 
735
    {
 
736
#ifndef POWERPC64
 
737
    case FFI_SYSV:
 
738
    case FFI_GCC_SYSV:
 
739
      /*@-usedef@*/
 
740
      ffi_call_SYSV(&ecif, -cif->bytes,
 
741
                    cif->flags, ecif.rvalue, fn);
 
742
      /*@=usedef@*/
 
743
      break;
 
744
#else
 
745
    case FFI_LINUX64:
 
746
      /*@-usedef@*/
 
747
      ffi_call_LINUX64(&ecif, -(long) cif->bytes,
 
748
                       cif->flags, ecif.rvalue, fn);
 
749
      /*@=usedef@*/
 
750
      break;
 
751
#endif
 
752
    default:
 
753
      FFI_ASSERT(0);
 
754
      break;
 
755
    }
 
756
}
 
757
 
 
758
 
 
759
#ifndef POWERPC64
 
760
static void flush_icache(char *, int);
 
761
 
 
762
#define MIN_CACHE_LINE_SIZE 8
 
763
 
 
764
static void flush_icache(char * addr1, int size)
 
765
{
 
766
  int i;
 
767
  char * addr;
 
768
  for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE) {
 
769
    addr = addr1 + i;
 
770
    __asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;" : : "r"(addr) : "memory");
 
771
  }
 
772
  addr = addr1 + size - 1;
 
773
  __asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;" "sync;" "isync;" : : "r"(addr) : "memory");
 
774
}
 
775
#endif
 
776
 
 
777
ffi_status
 
778
ffi_prep_closure (ffi_closure* closure,
 
779
                  ffi_cif* cif,
 
780
                  void (*fun)(ffi_cif*, void*, void**, void*),
 
781
                  void *user_data)
 
782
{
 
783
#ifdef POWERPC64
 
784
  void **tramp = (void **) &closure->tramp[0];
 
785
 
 
786
  FFI_ASSERT (cif->abi == FFI_LINUX64);
 
787
  /* Copy function address and TOC from ffi_closure_LINUX64.  */
 
788
  memcpy (tramp, (char *) ffi_closure_LINUX64, 16);
 
789
  tramp[2] = (void *) closure;
 
790
#else
 
791
  unsigned int *tramp;
 
792
 
 
793
  FFI_ASSERT (cif->abi == FFI_GCC_SYSV || cif->abi == FFI_SYSV);
 
794
 
 
795
  tramp = (unsigned int *) &closure->tramp[0];
 
796
  tramp[0] = 0x7c0802a6;  /*   mflr    r0 */
 
797
  tramp[1] = 0x4800000d;  /*   bl      10 <trampoline_initial+0x10> */
 
798
  tramp[4] = 0x7d6802a6;  /*   mflr    r11 */
 
799
  tramp[5] = 0x7c0803a6;  /*   mtlr    r0 */
 
800
  tramp[6] = 0x800b0000;  /*   lwz     r0,0(r11) */
 
801
  tramp[7] = 0x816b0004;  /*   lwz     r11,4(r11) */
 
802
  tramp[8] = 0x7c0903a6;  /*   mtctr   r0 */
 
803
  tramp[9] = 0x4e800420;  /*   bctr */
 
804
  *(void **) &tramp[2] = (void *)ffi_closure_SYSV; /* function */
 
805
  *(void **) &tramp[3] = (void *)closure;          /* context */
 
806
 
 
807
  /* Flush the icache.  */
 
808
  flush_icache(&closure->tramp[0],FFI_TRAMPOLINE_SIZE);
 
809
#endif
 
810
 
 
811
  closure->cif = cif;
 
812
  closure->fun = fun;
 
813
  closure->user_data = user_data;
 
814
 
 
815
  return FFI_OK;
 
816
}
 
817
 
 
818
typedef union
 
819
{
 
820
  float f;
 
821
  double d;
 
822
} ffi_dblfl;
 
823
 
 
824
int ffi_closure_helper_SYSV (ffi_closure*, void*, unsigned long*,
 
825
                             ffi_dblfl*, unsigned long*);
 
826
 
 
827
/* Basically the trampoline invokes ffi_closure_SYSV, and on
 
828
 * entry, r11 holds the address of the closure.
 
829
 * After storing the registers that could possibly contain
 
830
 * parameters to be passed into the stack frame and setting
 
831
 * up space for a return value, ffi_closure_SYSV invokes the
 
832
 * following helper function to do most of the work
 
833
 */
 
834
 
 
835
int
 
836
ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
 
837
                         unsigned long * pgr, ffi_dblfl * pfr,
 
838
                         unsigned long * pst)
 
839
{
 
840
  /* rvalue is the pointer to space for return value in closure assembly */
 
841
  /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */
 
842
  /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV  */
 
843
  /* pst is the pointer to outgoing parameter stack in original caller */
 
844
 
 
845
  void **          avalue;
 
846
  ffi_type **      arg_types;
 
847
  long             i, avn;
 
848
  long             nf;   /* number of floating registers already used */
 
849
  long             ng;   /* number of general registers already used */
 
850
  ffi_cif *        cif;
 
851
  double           temp;
 
852
  unsigned         size;
 
853
 
 
854
  cif = closure->cif;
 
855
  avalue = alloca(cif->nargs * sizeof(void *));
 
856
  size = cif->rtype->size;
 
857
 
 
858
  nf = 0;
 
859
  ng = 0;
 
860
 
 
861
  /* Copy the caller's structure return value address so that the closure
 
862
     returns the data directly to the caller.
 
863
     For FFI_SYSV the result is passed in r3/r4 if the struct size is less
 
864
     or equal 8 bytes.  */
 
865
 
 
866
  if (cif->rtype->type == FFI_TYPE_STRUCT)
 
867
    {
 
868
      if (!((cif->abi == FFI_SYSV) && (size <= 8))) {
 
869
        rvalue = (void *) *pgr;
 
870
        ng++;
 
871
        pgr++;
 
872
      }
 
873
    }
 
874
 
 
875
  i = 0;
 
876
  avn = cif->nargs;
 
877
  arg_types = cif->arg_types;
 
878
 
 
879
  /* Grab the addresses of the arguments from the stack frame.  */
 
880
  while (i < avn)
 
881
    {
 
882
      switch (arg_types[i]->type)
 
883
        {
 
884
        case FFI_TYPE_SINT8:
 
885
        case FFI_TYPE_UINT8:
 
886
          /* there are 8 gpr registers used to pass values */
 
887
          if (ng < 8) {
 
888
            avalue[i] = (((char *)pgr)+3);
 
889
            ng++;
 
890
            pgr++;
 
891
          } else {
 
892
            avalue[i] = (((char *)pst)+3);
 
893
            pst++;
 
894
          }
 
895
          break;
 
896
 
 
897
        case FFI_TYPE_SINT16:
 
898
        case FFI_TYPE_UINT16:
 
899
          /* there are 8 gpr registers used to pass values */
 
900
          if (ng < 8) {
 
901
            avalue[i] = (((char *)pgr)+2);
 
902
            ng++;
 
903
            pgr++;
 
904
          } else {
 
905
            avalue[i] = (((char *)pst)+2);
 
906
            pst++;
 
907
          }
 
908
          break;
 
909
 
 
910
        case FFI_TYPE_SINT32:
 
911
        case FFI_TYPE_UINT32:
 
912
        case FFI_TYPE_POINTER:
 
913
          /* there are 8 gpr registers used to pass values */
 
914
          if (ng < 8) {
 
915
            avalue[i] = pgr;
 
916
            ng++;
 
917
            pgr++;
 
918
          } else {
 
919
            avalue[i] = pst;
 
920
            pst++;
 
921
          }
 
922
          break;
 
923
 
 
924
        case FFI_TYPE_STRUCT:
 
925
          /* Structs are passed by reference. The address will appear in a
 
926
             gpr if it is one of the first 8 arguments.  */
 
927
          if (ng < 8) {
 
928
            avalue[i] = (void *) *pgr;
 
929
            ng++;
 
930
            pgr++;
 
931
          } else {
 
932
            avalue[i] = (void *) *pst;
 
933
            pst++;
 
934
          }
 
935
          break;
 
936
 
 
937
        case FFI_TYPE_SINT64:
 
938
        case FFI_TYPE_UINT64:
 
939
          /* passing long long ints are complex, they must
 
940
           * be passed in suitable register pairs such as
 
941
           * (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10)
 
942
           * and if the entire pair aren't available then the outgoing
 
943
           * parameter stack is used for both but an alignment of 8
 
944
           * must will be kept.  So we must either look in pgr
 
945
           * or pst to find the correct address for this type
 
946
           * of parameter.
 
947
           */
 
948
          if (ng < 7) {
 
949
            if (ng & 0x01) {
 
950
              /* skip r4, r6, r8 as starting points */
 
951
              ng++;
 
952
              pgr++;
 
953
            }
 
954
            avalue[i] = pgr;
 
955
            ng+=2;
 
956
            pgr+=2;
 
957
          } else {
 
958
            if (((long)pst) & 4) pst++;
 
959
            avalue[i] = pst;
 
960
            pst+=2;
 
961
          }
 
962
          break;
 
963
 
 
964
        case FFI_TYPE_FLOAT:
 
965
          /* unfortunately float values are stored as doubles
 
966
           * in the ffi_closure_SYSV code (since we don't check
 
967
           * the type in that routine).
 
968
           */
 
969
 
 
970
          /* there are 8 64bit floating point registers */
 
971
 
 
972
          if (nf < 8) {
 
973
            temp = pfr->d;
 
974
            pfr->f = (float)temp;
 
975
            avalue[i] = pfr;
 
976
            nf++;
 
977
            pfr++;
 
978
          } else {
 
979
            /* FIXME? here we are really changing the values
 
980
             * stored in the original calling routines outgoing
 
981
             * parameter stack.  This is probably a really
 
982
             * naughty thing to do but...
 
983
             */
 
984
            avalue[i] = pst;
 
985
            nf++;
 
986
            pst+=1;
 
987
          }
 
988
          break;
 
989
 
 
990
        case FFI_TYPE_DOUBLE:
 
991
          /* On the outgoing stack all values are aligned to 8 */
 
992
          /* there are 8 64bit floating point registers */
 
993
 
 
994
          if (nf < 8) {
 
995
            avalue[i] = pfr;
 
996
            nf++;
 
997
            pfr++;
 
998
          } else {
 
999
            if (((long)pst) & 4) pst++;
 
1000
            avalue[i] = pst;
 
1001
            nf++;
 
1002
            pst+=2;
 
1003
          }
 
1004
          break;
 
1005
 
 
1006
        default:
 
1007
          FFI_ASSERT(0);
 
1008
        }
 
1009
 
 
1010
      i++;
 
1011
    }
 
1012
 
 
1013
 
 
1014
  (closure->fun) (cif, rvalue, avalue, closure->user_data);
 
1015
 
 
1016
  /* Tell ffi_closure_SYSV how to perform return type promotions.
 
1017
     Because the FFI_SYSV ABI returns the structures <= 8 bytes in r3/r4
 
1018
     we have to tell ffi_closure_SYSV how to treat them.  */
 
1019
  if (cif->abi == FFI_SYSV && cif->rtype->type == FFI_TYPE_STRUCT
 
1020
      && size <= 8)
 
1021
    return FFI_SYSV_TYPE_SMALL_STRUCT + size;
 
1022
  return cif->rtype->type;
 
1023
 
 
1024
}
 
1025
 
 
1026
int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure*, void*, unsigned long*,
 
1027
                                           ffi_dblfl*);
 
1028
 
 
1029
int FFI_HIDDEN
 
1030
ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
 
1031
                            unsigned long *pst, ffi_dblfl *pfr)
 
1032
{
 
1033
  /* rvalue is the pointer to space for return value in closure assembly */
 
1034
  /* pst is the pointer to parameter save area
 
1035
     (r3-r10 are stored into its first 8 slots by ffi_closure_LINUX64) */
 
1036
  /* pfr is the pointer to where f1-f13 are stored in ffi_closure_LINUX64 */
 
1037
 
 
1038
  void **avalue;
 
1039
  ffi_type **arg_types;
 
1040
  long i, avn;
 
1041
  ffi_cif *cif;
 
1042
  ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS64;
 
1043
 
 
1044
  cif = closure->cif;
 
1045
  avalue = alloca (cif->nargs * sizeof (void *));
 
1046
 
 
1047
  /* Copy the caller's structure return value address so that the closure
 
1048
     returns the data directly to the caller.  */
 
1049
  if (cif->rtype->type == FFI_TYPE_STRUCT)
 
1050
    {
 
1051
      rvalue = (void *) *pst;
 
1052
      pst++;
 
1053
    }
 
1054
 
 
1055
  i = 0;
 
1056
  avn = cif->nargs;
 
1057
  arg_types = cif->arg_types;
 
1058
 
 
1059
  /* Grab the addresses of the arguments from the stack frame.  */
 
1060
  while (i < avn)
 
1061
    {
 
1062
      switch (arg_types[i]->type)
 
1063
        {
 
1064
        case FFI_TYPE_SINT8:
 
1065
        case FFI_TYPE_UINT8:
 
1066
          avalue[i] = (char *) pst + 7;
 
1067
          pst++;
 
1068
          break;
 
1069
 
 
1070
        case FFI_TYPE_SINT16:
 
1071
        case FFI_TYPE_UINT16:
 
1072
          avalue[i] = (char *) pst + 6;
 
1073
          pst++;
 
1074
          break;
 
1075
 
 
1076
        case FFI_TYPE_SINT32:
 
1077
        case FFI_TYPE_UINT32:
 
1078
          avalue[i] = (char *) pst + 4;
 
1079
          pst++;
 
1080
          break;
 
1081
 
 
1082
        case FFI_TYPE_SINT64:
 
1083
        case FFI_TYPE_UINT64:
 
1084
        case FFI_TYPE_POINTER:
 
1085
          avalue[i] = pst;
 
1086
          pst++;
 
1087
          break;
 
1088
 
 
1089
        case FFI_TYPE_STRUCT:
 
1090
          /* Structures with size less than eight bytes are passed
 
1091
             left-padded.  */
 
1092
          if (arg_types[i]->size < 8)
 
1093
            avalue[i] = (char *) pst + 8 - arg_types[i]->size;
 
1094
          else
 
1095
            avalue[i] = pst;
 
1096
          pst += (arg_types[i]->size + 7) / 8;
 
1097
          break;
 
1098
 
 
1099
        case FFI_TYPE_FLOAT:
 
1100
          /* unfortunately float values are stored as doubles
 
1101
           * in the ffi_closure_LINUX64 code (since we don't check
 
1102
           * the type in that routine).
 
1103
           */
 
1104
 
 
1105
          /* there are 13 64bit floating point registers */
 
1106
 
 
1107
          if (pfr < end_pfr)
 
1108
            {
 
1109
              double temp = pfr->d;
 
1110
              pfr->f = (float) temp;
 
1111
              avalue[i] = pfr;
 
1112
              pfr++;
 
1113
            }
 
1114
          else
 
1115
            avalue[i] = pst;
 
1116
          pst++;
 
1117
          break;
 
1118
 
 
1119
        case FFI_TYPE_DOUBLE:
 
1120
          /* On the outgoing stack all values are aligned to 8 */
 
1121
          /* there are 13 64bit floating point registers */
 
1122
 
 
1123
          if (pfr < end_pfr)
 
1124
            {
 
1125
              avalue[i] = pfr;
 
1126
              pfr++;
 
1127
            }
 
1128
          else
 
1129
            avalue[i] = pst;
 
1130
          pst++;
 
1131
          break;
 
1132
 
 
1133
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
1134
        case FFI_TYPE_LONGDOUBLE:
 
1135
          if (pfr + 1 < end_pfr)
 
1136
            {
 
1137
              avalue[i] = pfr;
 
1138
              pfr += 2;
 
1139
            }
 
1140
          else
 
1141
            {
 
1142
              if (pfr < end_pfr)
 
1143
                {
 
1144
                  /* Passed partly in f13 and partly on the stack.
 
1145
                     Move it all to the stack.  */
 
1146
                  *pst = *(unsigned long *) pfr;
 
1147
                  pfr++;
 
1148
                }
 
1149
              avalue[i] = pst;
 
1150
            }
 
1151
          pst += 2;
 
1152
          break;
 
1153
#endif
 
1154
 
 
1155
        default:
 
1156
          FFI_ASSERT(0);
 
1157
        }
 
1158
 
 
1159
      i++;
 
1160
    }
 
1161
 
 
1162
 
 
1163
  (closure->fun) (cif, rvalue, avalue, closure->user_data);
 
1164
 
 
1165
  /* Tell ffi_closure_LINUX64 how to perform return type promotions.  */
 
1166
  return cif->rtype->type;
 
1167
}