~ubuntu-branches/ubuntu/maverick/python3.1/maverick

« back to all changes in this revision

Viewing changes to Modules/_ctypes/libffi/src/powerpc/ffi.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-03-23 00:01:27 UTC
  • Revision ID: james.westby@ubuntu.com-20090323000127-5fstfxju4ufrhthq
Tags: upstream-3.1~a1+20090322
ImportĀ upstreamĀ versionĀ 3.1~a1+20090322

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -----------------------------------------------------------------------
 
2
   ffi.c - Copyright (c) 1998 Geoffrey Keating
 
3
   Copyright (C) 2007 Free Software Foundation, Inc
 
4
   Copyright (C) 2008 Red Hat, Inc
 
5
 
 
6
   PowerPC Foreign Function Interface
 
7
 
 
8
   Permission is hereby granted, free of charge, to any person obtaining
 
9
   a copy of this software and associated documentation files (the
 
10
   ``Software''), to deal in the Software without restriction, including
 
11
   without limitation the rights to use, copy, modify, merge, publish,
 
12
   distribute, sublicense, and/or sell copies of the Software, and to
 
13
   permit persons to whom the Software is furnished to do so, subject to
 
14
   the following conditions:
 
15
 
 
16
   The above copyright notice and this permission notice shall be included
 
17
   in all copies or substantial portions of the Software.
 
18
 
 
19
   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
 
20
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
21
   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 
22
   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
 
23
   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 
24
   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 
25
   OTHER DEALINGS IN THE SOFTWARE.
 
26
   ----------------------------------------------------------------------- */
 
27
 
 
28
#include <ffi.h>
 
29
#include <ffi_common.h>
 
30
 
 
31
#include <stdlib.h>
 
32
#include <stdio.h>
 
33
 
 
34
 
 
35
extern void ffi_closure_SYSV (void);
 
36
extern void FFI_HIDDEN ffi_closure_LINUX64 (void);
 
37
 
 
38
enum {
 
39
  /* The assembly depends on these exact flags.  */
 
40
  FLAG_RETURNS_SMST     = 1 << (31-31), /* Used for FFI_SYSV small structs.  */
 
41
  FLAG_RETURNS_NOTHING  = 1 << (31-30), /* These go in cr7 */
 
42
  FLAG_RETURNS_FP       = 1 << (31-29),
 
43
  FLAG_RETURNS_64BITS   = 1 << (31-28),
 
44
 
 
45
  FLAG_RETURNS_128BITS  = 1 << (31-27), /* cr6  */
 
46
 
 
47
  FLAG_ARG_NEEDS_COPY   = 1 << (31- 7),
 
48
  FLAG_FP_ARGUMENTS     = 1 << (31- 6), /* cr1.eq; specified by ABI */
 
49
  FLAG_4_GPR_ARGUMENTS  = 1 << (31- 5),
 
50
  FLAG_RETVAL_REFERENCE = 1 << (31- 4)
 
51
};
 
52
 
 
53
/* About the SYSV ABI.  */
 
54
unsigned int NUM_GPR_ARG_REGISTERS = 8;
 
55
#ifndef __NO_FPRS__
 
56
unsigned int NUM_FPR_ARG_REGISTERS = 8;
 
57
#else
 
58
unsigned int NUM_FPR_ARG_REGISTERS = 0;
 
59
#endif
 
60
 
 
61
enum { ASM_NEEDS_REGISTERS = 4 };
 
62
 
 
63
/* ffi_prep_args_SYSV is called by the assembly routine once stack space
 
64
   has been allocated for the function's arguments.
 
65
 
 
66
   The stack layout we want looks like this:
 
67
 
 
68
   |   Return address from ffi_call_SYSV 4bytes |       higher addresses
 
69
   |--------------------------------------------|
 
70
   |   Previous backchain pointer       4       |       stack pointer here
 
71
   |--------------------------------------------|<+ <<< on entry to
 
72
   |   Saved r28-r31                    4*4     | |     ffi_call_SYSV
 
73
   |--------------------------------------------| |
 
74
   |   GPR registers r3-r10             8*4     | |     ffi_call_SYSV
 
75
   |--------------------------------------------| |
 
76
   |   FPR registers f1-f8 (optional)   8*8     | |
 
77
   |--------------------------------------------| |     stack   |
 
78
   |   Space for copied structures              | |     grows   |
 
79
   |--------------------------------------------| |     down    V
 
80
   |   Parameters that didn't fit in registers  | |
 
81
   |--------------------------------------------| |     lower addresses
 
82
   |   Space for callee's LR            4       | |
 
83
   |--------------------------------------------| |     stack pointer here
 
84
   |   Current backchain pointer        4       |-/     during
 
85
   |--------------------------------------------|   <<< ffi_call_SYSV
 
86
 
 
87
*/
 
88
 
 
89
void
 
90
ffi_prep_args_SYSV (extended_cif *ecif, unsigned *const stack)
 
91
{
 
92
  const unsigned bytes = ecif->cif->bytes;
 
93
  const unsigned flags = ecif->cif->flags;
 
94
 
 
95
  typedef union {
 
96
    char *c;
 
97
    unsigned *u;
 
98
    long long *ll;
 
99
    float *f;
 
100
    double *d;
 
101
  } valp;
 
102
 
 
103
  /* 'stacktop' points at the previous backchain pointer.  */
 
104
  valp stacktop;
 
105
 
 
106
  /* 'gpr_base' points at the space for gpr3, and grows upwards as
 
107
     we use GPR registers.  */
 
108
  valp gpr_base;
 
109
  int intarg_count;
 
110
 
 
111
  /* 'fpr_base' points at the space for fpr1, and grows upwards as
 
112
     we use FPR registers.  */
 
113
  valp fpr_base;
 
114
  int fparg_count;
 
115
 
 
116
  /* 'copy_space' grows down as we put structures in it.  It should
 
117
     stay 16-byte aligned.  */
 
118
  valp copy_space;
 
119
 
 
120
  /* 'next_arg' grows up as we put parameters in it.  */
 
121
  valp next_arg;
 
122
 
 
123
  int i, ii MAYBE_UNUSED;
 
124
  ffi_type **ptr;
 
125
  double double_tmp;
 
126
  union {
 
127
    void **v;
 
128
    char **c;
 
129
    signed char **sc;
 
130
    unsigned char **uc;
 
131
    signed short **ss;
 
132
    unsigned short **us;
 
133
    unsigned int **ui;
 
134
    long long **ll;
 
135
    float **f;
 
136
    double **d;
 
137
  } p_argv;
 
138
  size_t struct_copy_size;
 
139
  unsigned gprvalue;
 
140
 
 
141
  if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
 
142
    NUM_FPR_ARG_REGISTERS = 0;
 
143
 
 
144
  stacktop.c = (char *) stack + bytes;
 
145
  gpr_base.u = stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS;
 
146
  intarg_count = 0;
 
147
  fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS;
 
148
  fparg_count = 0;
 
149
  copy_space.c = ((flags & FLAG_FP_ARGUMENTS) ? fpr_base.c : gpr_base.c);
 
150
  next_arg.u = stack + 2;
 
151
 
 
152
  /* Check that everything starts aligned properly.  */
 
153
  FFI_ASSERT (((unsigned) (char *) stack & 0xF) == 0);
 
154
  FFI_ASSERT (((unsigned) copy_space.c & 0xF) == 0);
 
155
  FFI_ASSERT (((unsigned) stacktop.c & 0xF) == 0);
 
156
  FFI_ASSERT ((bytes & 0xF) == 0);
 
157
  FFI_ASSERT (copy_space.c >= next_arg.c);
 
158
 
 
159
  /* Deal with return values that are actually pass-by-reference.  */
 
160
  if (flags & FLAG_RETVAL_REFERENCE)
 
161
    {
 
162
      *gpr_base.u++ = (unsigned long) (char *) ecif->rvalue;
 
163
      intarg_count++;
 
164
    }
 
165
 
 
166
  /* Now for the arguments.  */
 
167
  p_argv.v = ecif->avalue;
 
168
  for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
 
169
       i > 0;
 
170
       i--, ptr++, p_argv.v++)
 
171
    {
 
172
      switch ((*ptr)->type)
 
173
        {
 
174
        case FFI_TYPE_FLOAT:
 
175
          /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32.  */
 
176
          if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
 
177
            goto soft_float_prep;
 
178
          double_tmp = **p_argv.f;
 
179
          if (fparg_count >= NUM_FPR_ARG_REGISTERS)
 
180
            {
 
181
              *next_arg.f = (float) double_tmp;
 
182
              next_arg.u += 1;
 
183
            }
 
184
          else
 
185
            *fpr_base.d++ = double_tmp;
 
186
          fparg_count++;
 
187
          FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
 
188
          break;
 
189
 
 
190
        case FFI_TYPE_DOUBLE:
 
191
          /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64.  */
 
192
          if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
 
193
            goto soft_double_prep;
 
194
          double_tmp = **p_argv.d;
 
195
 
 
196
          if (fparg_count >= NUM_FPR_ARG_REGISTERS)
 
197
            {
 
198
              if (intarg_count >= NUM_GPR_ARG_REGISTERS
 
199
                  && intarg_count % 2 != 0)
 
200
                {
 
201
                  intarg_count++;
 
202
                  next_arg.u++;
 
203
                }
 
204
              *next_arg.d = double_tmp;
 
205
              next_arg.u += 2;
 
206
            }
 
207
          else
 
208
            *fpr_base.d++ = double_tmp;
 
209
          fparg_count++;
 
210
          FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
 
211
          break;
 
212
 
 
213
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
214
        case FFI_TYPE_LONGDOUBLE:
 
215
          if ((ecif->cif->abi != FFI_LINUX)
 
216
                && (ecif->cif->abi != FFI_LINUX_SOFT_FLOAT))
 
217
            goto do_struct;
 
218
          /* The soft float ABI for long doubles works like this,
 
219
             a long double is passed in four consecutive gprs if available.
 
220
             A maximum of 2 long doubles can be passed in gprs.
 
221
             If we do not have 4 gprs left, the long double is passed on the
 
222
             stack, 4-byte aligned.  */
 
223
          if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
 
224
            {
 
225
              unsigned int int_tmp = (*p_argv.ui)[0];
 
226
              if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3)
 
227
                {
 
228
                  if (intarg_count < NUM_GPR_ARG_REGISTERS)
 
229
                    intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count;
 
230
                  *next_arg.u = int_tmp;
 
231
                  next_arg.u++;
 
232
                  for (ii = 1; ii < 4; ii++)
 
233
                    {
 
234
                      int_tmp = (*p_argv.ui)[ii];
 
235
                      *next_arg.u = int_tmp;
 
236
                      next_arg.u++;
 
237
                    }
 
238
                }
 
239
              else
 
240
                {
 
241
                  *gpr_base.u++ = int_tmp;
 
242
                  for (ii = 1; ii < 4; ii++)
 
243
                    {
 
244
                      int_tmp = (*p_argv.ui)[ii];
 
245
                      *gpr_base.u++ = int_tmp;
 
246
                    }
 
247
                }
 
248
              intarg_count +=4;
 
249
            }
 
250
          else
 
251
            {
 
252
              double_tmp = (*p_argv.d)[0];
 
253
 
 
254
              if (fparg_count >= NUM_FPR_ARG_REGISTERS - 1)
 
255
                {
 
256
                  if (intarg_count >= NUM_GPR_ARG_REGISTERS
 
257
                      && intarg_count % 2 != 0)
 
258
                    {
 
259
                      intarg_count++;
 
260
                      next_arg.u++;
 
261
                    }
 
262
                  *next_arg.d = double_tmp;
 
263
                  next_arg.u += 2;
 
264
                  double_tmp = (*p_argv.d)[1];
 
265
                  *next_arg.d = double_tmp;
 
266
                  next_arg.u += 2;
 
267
                }
 
268
              else
 
269
                {
 
270
                  *fpr_base.d++ = double_tmp;
 
271
                  double_tmp = (*p_argv.d)[1];
 
272
                  *fpr_base.d++ = double_tmp;
 
273
                }
 
274
 
 
275
              fparg_count += 2;
 
276
              FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
 
277
            }
 
278
          break;
 
279
#endif
 
280
 
 
281
        case FFI_TYPE_UINT64:
 
282
        case FFI_TYPE_SINT64:
 
283
        soft_double_prep:
 
284
          if (intarg_count == NUM_GPR_ARG_REGISTERS-1)
 
285
            intarg_count++;
 
286
          if (intarg_count >= NUM_GPR_ARG_REGISTERS)
 
287
            {
 
288
              if (intarg_count % 2 != 0)
 
289
                {
 
290
                  intarg_count++;
 
291
                  next_arg.u++;
 
292
                }
 
293
              *next_arg.ll = **p_argv.ll;
 
294
              next_arg.u += 2;
 
295
            }
 
296
          else
 
297
            {
 
298
              /* whoops: abi states only certain register pairs
 
299
               * can be used for passing long long int
 
300
               * specifically (r3,r4), (r5,r6), (r7,r8),
 
301
               * (r9,r10) and if next arg is long long but
 
302
               * not correct starting register of pair then skip
 
303
               * until the proper starting register
 
304
               */
 
305
              if (intarg_count % 2 != 0)
 
306
                {
 
307
                  intarg_count ++;
 
308
                  gpr_base.u++;
 
309
                }
 
310
              *gpr_base.ll++ = **p_argv.ll;
 
311
            }
 
312
          intarg_count += 2;
 
313
          break;
 
314
 
 
315
        case FFI_TYPE_STRUCT:
 
316
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
317
        do_struct:
 
318
#endif
 
319
          struct_copy_size = ((*ptr)->size + 15) & ~0xF;
 
320
          copy_space.c -= struct_copy_size;
 
321
          memcpy (copy_space.c, *p_argv.c, (*ptr)->size);
 
322
 
 
323
          gprvalue = (unsigned long) copy_space.c;
 
324
 
 
325
          FFI_ASSERT (copy_space.c > next_arg.c);
 
326
          FFI_ASSERT (flags & FLAG_ARG_NEEDS_COPY);
 
327
          goto putgpr;
 
328
 
 
329
        case FFI_TYPE_UINT8:
 
330
          gprvalue = **p_argv.uc;
 
331
          goto putgpr;
 
332
        case FFI_TYPE_SINT8:
 
333
          gprvalue = **p_argv.sc;
 
334
          goto putgpr;
 
335
        case FFI_TYPE_UINT16:
 
336
          gprvalue = **p_argv.us;
 
337
          goto putgpr;
 
338
        case FFI_TYPE_SINT16:
 
339
          gprvalue = **p_argv.ss;
 
340
          goto putgpr;
 
341
 
 
342
        case FFI_TYPE_INT:
 
343
        case FFI_TYPE_UINT32:
 
344
        case FFI_TYPE_SINT32:
 
345
        case FFI_TYPE_POINTER:
 
346
        soft_float_prep:
 
347
 
 
348
          gprvalue = **p_argv.ui;
 
349
 
 
350
        putgpr:
 
351
          if (intarg_count >= NUM_GPR_ARG_REGISTERS)
 
352
            *next_arg.u++ = gprvalue;
 
353
          else
 
354
            *gpr_base.u++ = gprvalue;
 
355
          intarg_count++;
 
356
          break;
 
357
        }
 
358
    }
 
359
 
 
360
  /* Check that we didn't overrun the stack...  */
 
361
  FFI_ASSERT (copy_space.c >= next_arg.c);
 
362
  FFI_ASSERT (gpr_base.u <= stacktop.u - ASM_NEEDS_REGISTERS);
 
363
  FFI_ASSERT (fpr_base.u
 
364
              <= stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
 
365
  FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
 
366
}
 
367
 
 
368
/* About the LINUX64 ABI.  */
 
369
enum {
 
370
  NUM_GPR_ARG_REGISTERS64 = 8,
 
371
  NUM_FPR_ARG_REGISTERS64 = 13
 
372
};
 
373
enum { ASM_NEEDS_REGISTERS64 = 4 };
 
374
 
 
375
/* ffi_prep_args64 is called by the assembly routine once stack space
 
376
   has been allocated for the function's arguments.
 
377
 
 
378
   The stack layout we want looks like this:
 
379
 
 
380
   |   Ret addr from ffi_call_LINUX64   8bytes  |       higher addresses
 
381
   |--------------------------------------------|
 
382
   |   CR save area                     8bytes  |
 
383
   |--------------------------------------------|
 
384
   |   Previous backchain pointer       8       |       stack pointer here
 
385
   |--------------------------------------------|<+ <<< on entry to
 
386
   |   Saved r28-r31                    4*8     | |     ffi_call_LINUX64
 
387
   |--------------------------------------------| |
 
388
   |   GPR registers r3-r10             8*8     | |
 
389
   |--------------------------------------------| |
 
390
   |   FPR registers f1-f13 (optional)  13*8    | |
 
391
   |--------------------------------------------| |
 
392
   |   Parameter save area                      | |
 
393
   |--------------------------------------------| |
 
394
   |   TOC save area                    8       | |
 
395
   |--------------------------------------------| |     stack   |
 
396
   |   Linker doubleword                8       | |     grows   |
 
397
   |--------------------------------------------| |     down    V
 
398
   |   Compiler doubleword              8       | |
 
399
   |--------------------------------------------| |     lower addresses
 
400
   |   Space for callee's LR            8       | |
 
401
   |--------------------------------------------| |
 
402
   |   CR save area                     8       | |
 
403
   |--------------------------------------------| |     stack pointer here
 
404
   |   Current backchain pointer        8       |-/     during
 
405
   |--------------------------------------------|   <<< ffi_call_LINUX64
 
406
 
 
407
*/
 
408
 
 
409
void FFI_HIDDEN
 
410
ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack)
 
411
{
 
412
  const unsigned long bytes = ecif->cif->bytes;
 
413
  const unsigned long flags = ecif->cif->flags;
 
414
 
 
415
  typedef union {
 
416
    char *c;
 
417
    unsigned long *ul;
 
418
    float *f;
 
419
    double *d;
 
420
  } valp;
 
421
 
 
422
  /* 'stacktop' points at the previous backchain pointer.  */
 
423
  valp stacktop;
 
424
 
 
425
  /* 'next_arg' points at the space for gpr3, and grows upwards as
 
426
     we use GPR registers, then continues at rest.  */
 
427
  valp gpr_base;
 
428
  valp gpr_end;
 
429
  valp rest;
 
430
  valp next_arg;
 
431
 
 
432
  /* 'fpr_base' points at the space for fpr3, and grows upwards as
 
433
     we use FPR registers.  */
 
434
  valp fpr_base;
 
435
  int fparg_count;
 
436
 
 
437
  int i, words;
 
438
  ffi_type **ptr;
 
439
  double double_tmp;
 
440
  union {
 
441
    void **v;
 
442
    char **c;
 
443
    signed char **sc;
 
444
    unsigned char **uc;
 
445
    signed short **ss;
 
446
    unsigned short **us;
 
447
    signed int **si;
 
448
    unsigned int **ui;
 
449
    unsigned long **ul;
 
450
    float **f;
 
451
    double **d;
 
452
  } p_argv;
 
453
  unsigned long gprvalue;
 
454
 
 
455
  stacktop.c = (char *) stack + bytes;
 
456
  gpr_base.ul = stacktop.ul - ASM_NEEDS_REGISTERS64 - NUM_GPR_ARG_REGISTERS64;
 
457
  gpr_end.ul = gpr_base.ul + NUM_GPR_ARG_REGISTERS64;
 
458
  rest.ul = stack + 6 + NUM_GPR_ARG_REGISTERS64;
 
459
  fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS64;
 
460
  fparg_count = 0;
 
461
  next_arg.ul = gpr_base.ul;
 
462
 
 
463
  /* Check that everything starts aligned properly.  */
 
464
  FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0);
 
465
  FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0);
 
466
  FFI_ASSERT ((bytes & 0xF) == 0);
 
467
 
 
468
  /* Deal with return values that are actually pass-by-reference.  */
 
469
  if (flags & FLAG_RETVAL_REFERENCE)
 
470
    *next_arg.ul++ = (unsigned long) (char *) ecif->rvalue;
 
471
 
 
472
  /* Now for the arguments.  */
 
473
  p_argv.v = ecif->avalue;
 
474
  for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
 
475
       i > 0;
 
476
       i--, ptr++, p_argv.v++)
 
477
    {
 
478
      switch ((*ptr)->type)
 
479
        {
 
480
        case FFI_TYPE_FLOAT:
 
481
          double_tmp = **p_argv.f;
 
482
          *next_arg.f = (float) double_tmp;
 
483
          if (++next_arg.ul == gpr_end.ul)
 
484
            next_arg.ul = rest.ul;
 
485
          if (fparg_count < NUM_FPR_ARG_REGISTERS64)
 
486
            *fpr_base.d++ = double_tmp;
 
487
          fparg_count++;
 
488
          FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
 
489
          break;
 
490
 
 
491
        case FFI_TYPE_DOUBLE:
 
492
          double_tmp = **p_argv.d;
 
493
          *next_arg.d = double_tmp;
 
494
          if (++next_arg.ul == gpr_end.ul)
 
495
            next_arg.ul = rest.ul;
 
496
          if (fparg_count < NUM_FPR_ARG_REGISTERS64)
 
497
            *fpr_base.d++ = double_tmp;
 
498
          fparg_count++;
 
499
          FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
 
500
          break;
 
501
 
 
502
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
503
        case FFI_TYPE_LONGDOUBLE:
 
504
          double_tmp = (*p_argv.d)[0];
 
505
          *next_arg.d = double_tmp;
 
506
          if (++next_arg.ul == gpr_end.ul)
 
507
            next_arg.ul = rest.ul;
 
508
          if (fparg_count < NUM_FPR_ARG_REGISTERS64)
 
509
            *fpr_base.d++ = double_tmp;
 
510
          fparg_count++;
 
511
          double_tmp = (*p_argv.d)[1];
 
512
          *next_arg.d = double_tmp;
 
513
          if (++next_arg.ul == gpr_end.ul)
 
514
            next_arg.ul = rest.ul;
 
515
          if (fparg_count < NUM_FPR_ARG_REGISTERS64)
 
516
            *fpr_base.d++ = double_tmp;
 
517
          fparg_count++;
 
518
          FFI_ASSERT (__LDBL_MANT_DIG__ == 106);
 
519
          FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
 
520
          break;
 
521
#endif
 
522
 
 
523
        case FFI_TYPE_STRUCT:
 
524
          words = ((*ptr)->size + 7) / 8;
 
525
          if (next_arg.ul >= gpr_base.ul && next_arg.ul + words > gpr_end.ul)
 
526
            {
 
527
              size_t first = gpr_end.c - next_arg.c;
 
528
              memcpy (next_arg.c, *p_argv.c, first);
 
529
              memcpy (rest.c, *p_argv.c + first, (*ptr)->size - first);
 
530
              next_arg.c = rest.c + words * 8 - first;
 
531
            }
 
532
          else
 
533
            {
 
534
              char *where = next_arg.c;
 
535
 
 
536
              /* Structures with size less than eight bytes are passed
 
537
                 left-padded.  */
 
538
              if ((*ptr)->size < 8)
 
539
                where += 8 - (*ptr)->size;
 
540
 
 
541
              memcpy (where, *p_argv.c, (*ptr)->size);
 
542
              next_arg.ul += words;
 
543
              if (next_arg.ul == gpr_end.ul)
 
544
                next_arg.ul = rest.ul;
 
545
            }
 
546
          break;
 
547
 
 
548
        case FFI_TYPE_UINT8:
 
549
          gprvalue = **p_argv.uc;
 
550
          goto putgpr;
 
551
        case FFI_TYPE_SINT8:
 
552
          gprvalue = **p_argv.sc;
 
553
          goto putgpr;
 
554
        case FFI_TYPE_UINT16:
 
555
          gprvalue = **p_argv.us;
 
556
          goto putgpr;
 
557
        case FFI_TYPE_SINT16:
 
558
          gprvalue = **p_argv.ss;
 
559
          goto putgpr;
 
560
        case FFI_TYPE_UINT32:
 
561
          gprvalue = **p_argv.ui;
 
562
          goto putgpr;
 
563
        case FFI_TYPE_INT:
 
564
        case FFI_TYPE_SINT32:
 
565
          gprvalue = **p_argv.si;
 
566
          goto putgpr;
 
567
 
 
568
        case FFI_TYPE_UINT64:
 
569
        case FFI_TYPE_SINT64:
 
570
        case FFI_TYPE_POINTER:
 
571
          gprvalue = **p_argv.ul;
 
572
        putgpr:
 
573
          *next_arg.ul++ = gprvalue;
 
574
          if (next_arg.ul == gpr_end.ul)
 
575
            next_arg.ul = rest.ul;
 
576
          break;
 
577
        }
 
578
    }
 
579
 
 
580
  FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS
 
581
              || (next_arg.ul >= gpr_base.ul
 
582
                  && next_arg.ul <= gpr_base.ul + 4));
 
583
}
 
584
 
 
585
 
 
586
 
 
587
/* Perform machine dependent cif processing */
 
588
ffi_status
 
589
ffi_prep_cif_machdep (ffi_cif *cif)
 
590
{
 
591
  /* All this is for the SYSV and LINUX64 ABI.  */
 
592
  int i;
 
593
  ffi_type **ptr;
 
594
  unsigned bytes;
 
595
  int fparg_count = 0, intarg_count = 0;
 
596
  unsigned flags = 0;
 
597
  unsigned struct_copy_size = 0;
 
598
  unsigned type = cif->rtype->type;
 
599
  unsigned size = cif->rtype->size;
 
600
 
 
601
  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
 
602
    NUM_FPR_ARG_REGISTERS = 0;
 
603
 
 
604
  if (cif->abi != FFI_LINUX64)
 
605
    {
 
606
      /* All the machine-independent calculation of cif->bytes will be wrong.
 
607
         Redo the calculation for SYSV.  */
 
608
 
 
609
      /* Space for the frame pointer, callee's LR, and the asm's temp regs.  */
 
610
      bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof (int);
 
611
 
 
612
      /* Space for the GPR registers.  */
 
613
      bytes += NUM_GPR_ARG_REGISTERS * sizeof (int);
 
614
    }
 
615
  else
 
616
    {
 
617
      /* 64-bit ABI.  */
 
618
 
 
619
      /* Space for backchain, CR, LR, cc/ld doubleword, TOC and the asm's temp
 
620
         regs.  */
 
621
      bytes = (6 + ASM_NEEDS_REGISTERS64) * sizeof (long);
 
622
 
 
623
      /* Space for the mandatory parm save area and general registers.  */
 
624
      bytes += 2 * NUM_GPR_ARG_REGISTERS64 * sizeof (long);
 
625
    }
 
626
 
 
627
  /* Return value handling.  The rules for SYSV are as follows:
 
628
     - 32-bit (or less) integer values are returned in gpr3;
 
629
     - Structures of size <= 4 bytes also returned in gpr3;
 
630
     - 64-bit integer values and structures between 5 and 8 bytes are returned
 
631
     in gpr3 and gpr4;
 
632
     - Single/double FP values are returned in fpr1;
 
633
     - Larger structures are allocated space and a pointer is passed as
 
634
     the first argument.
 
635
     - long doubles (if not equivalent to double) are returned in
 
636
     fpr1,fpr2 for Linux and as for large structs for SysV.
 
637
     For LINUX64:
 
638
     - integer values in gpr3;
 
639
     - Structures/Unions by reference;
 
640
     - Single/double FP values in fpr1, long double in fpr1,fpr2.
 
641
     - soft-float float/doubles are treated as UINT32/UINT64 respectivley.
 
642
     - soft-float long doubles are returned in gpr3-gpr6.  */
 
643
  switch (type)
 
644
    {
 
645
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
646
    case FFI_TYPE_LONGDOUBLE:
 
647
      if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64
 
648
        && cif->abi != FFI_LINUX_SOFT_FLOAT)
 
649
        goto byref;
 
650
      flags |= FLAG_RETURNS_128BITS;
 
651
      /* Fall through.  */
 
652
#endif
 
653
    case FFI_TYPE_DOUBLE:
 
654
      flags |= FLAG_RETURNS_64BITS;
 
655
      /* Fall through.  */
 
656
    case FFI_TYPE_FLOAT:
 
657
      /* With FFI_LINUX_SOFT_FLOAT no fp registers are used.  */
 
658
      if (cif->abi != FFI_LINUX_SOFT_FLOAT)
 
659
        flags |= FLAG_RETURNS_FP;
 
660
      break;
 
661
 
 
662
    case FFI_TYPE_UINT64:
 
663
    case FFI_TYPE_SINT64:
 
664
      flags |= FLAG_RETURNS_64BITS;
 
665
      break;
 
666
 
 
667
    case FFI_TYPE_STRUCT:
 
668
      if (cif->abi == FFI_SYSV)
 
669
        {
 
670
          /* The final SYSV ABI says that structures smaller or equal 8 bytes
 
671
             are returned in r3/r4. The FFI_GCC_SYSV ABI instead returns them
 
672
             in memory.  */
 
673
 
 
674
          /* Treat structs with size <= 8 bytes.  */
 
675
          if (size <= 8)
 
676
            {
 
677
              flags |= FLAG_RETURNS_SMST;
 
678
              /* These structs are returned in r3. We pack the type and the
 
679
                 precalculated shift value (needed in the sysv.S) into flags.
 
680
                 The same applies for the structs returned in r3/r4.  */
 
681
              if (size <= 4)
 
682
                {
 
683
                  flags |= 1 << (31 - FFI_SYSV_TYPE_SMALL_STRUCT - 1);
 
684
                  flags |= 8 * (4 - size) << 4;
 
685
                  break;
 
686
                }
 
687
              /* These structs are returned in r3 and r4. See above.   */
 
688
              if  (size <= 8)
 
689
                {
 
690
                  flags |= 1 << (31 - FFI_SYSV_TYPE_SMALL_STRUCT - 2);
 
691
                  flags |= 8 * (8 - size) << 4;
 
692
                  break;
 
693
                }
 
694
            }
 
695
        }
 
696
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
697
    byref:
 
698
#endif
 
699
      intarg_count++;
 
700
      flags |= FLAG_RETVAL_REFERENCE;
 
701
      /* Fall through.  */
 
702
    case FFI_TYPE_VOID:
 
703
      flags |= FLAG_RETURNS_NOTHING;
 
704
      break;
 
705
 
 
706
    default:
 
707
      /* Returns 32-bit integer, or similar.  Nothing to do here.  */
 
708
      break;
 
709
    }
 
710
 
 
711
  if (cif->abi != FFI_LINUX64)
 
712
    /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
 
713
       first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
 
714
       goes on the stack.  Structures and long doubles (if not equivalent
 
715
       to double) are passed as a pointer to a copy of the structure.
 
716
       Stuff on the stack needs to keep proper alignment.  */
 
717
    for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
 
718
      {
 
719
        switch ((*ptr)->type)
 
720
          {
 
721
          case FFI_TYPE_FLOAT:
 
722
            /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32.  */
 
723
            if (cif->abi == FFI_LINUX_SOFT_FLOAT)
 
724
              goto soft_float_cif;
 
725
            fparg_count++;
 
726
            /* floating singles are not 8-aligned on stack */
 
727
            break;
 
728
 
 
729
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
730
          case FFI_TYPE_LONGDOUBLE:
 
731
            if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
 
732
              goto do_struct;
 
733
            if (cif->abi == FFI_LINUX_SOFT_FLOAT)
 
734
              {
 
735
                if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3
 
736
                  || intarg_count < NUM_GPR_ARG_REGISTERS)
 
737
                  /* A long double in FFI_LINUX_SOFT_FLOAT can use only
 
738
                     a set of four consecutive gprs. If we have not enough,
 
739
                     we have to adjust the intarg_count value.  */
 
740
                  intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count;
 
741
                intarg_count += 4;
 
742
                break;
 
743
              }
 
744
            else
 
745
              fparg_count++;
 
746
            /* Fall thru */
 
747
#endif
 
748
          case FFI_TYPE_DOUBLE:
 
749
            /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64.  */
 
750
            if (cif->abi == FFI_LINUX_SOFT_FLOAT)
 
751
              goto soft_double_cif;
 
752
            fparg_count++;
 
753
            /* If this FP arg is going on the stack, it must be
 
754
               8-byte-aligned.  */
 
755
            if (fparg_count > NUM_FPR_ARG_REGISTERS
 
756
                && intarg_count >= NUM_GPR_ARG_REGISTERS
 
757
                && intarg_count % 2 != 0)
 
758
              intarg_count++;
 
759
            break;
 
760
 
 
761
          case FFI_TYPE_UINT64:
 
762
          case FFI_TYPE_SINT64:
 
763
          soft_double_cif:
 
764
            /* 'long long' arguments are passed as two words, but
 
765
               either both words must fit in registers or both go
 
766
               on the stack.  If they go on the stack, they must
 
767
               be 8-byte-aligned.
 
768
 
 
769
               Also, only certain register pairs can be used for
 
770
               passing long long int -- specifically (r3,r4), (r5,r6),
 
771
               (r7,r8), (r9,r10).
 
772
            */
 
773
            if (intarg_count == NUM_GPR_ARG_REGISTERS-1
 
774
                || intarg_count % 2 != 0)
 
775
              intarg_count++;
 
776
            intarg_count += 2;
 
777
            break;
 
778
 
 
779
          case FFI_TYPE_STRUCT:
 
780
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
781
          do_struct:
 
782
#endif
 
783
            /* We must allocate space for a copy of these to enforce
 
784
               pass-by-value.  Pad the space up to a multiple of 16
 
785
               bytes (the maximum alignment required for anything under
 
786
               the SYSV ABI).  */
 
787
            struct_copy_size += ((*ptr)->size + 15) & ~0xF;
 
788
            /* Fall through (allocate space for the pointer).  */
 
789
 
 
790
          default:
 
791
          soft_float_cif:
 
792
            /* Everything else is passed as a 4-byte word in a GPR, either
 
793
               the object itself or a pointer to it.  */
 
794
            intarg_count++;
 
795
            break;
 
796
          }
 
797
      }
 
798
  else
 
799
    for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
 
800
      {
 
801
        switch ((*ptr)->type)
 
802
          {
 
803
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
804
          case FFI_TYPE_LONGDOUBLE:
 
805
            if (cif->abi == FFI_LINUX_SOFT_FLOAT)
 
806
              intarg_count += 4;
 
807
            else
 
808
              {
 
809
                fparg_count += 2;
 
810
                intarg_count += 2;
 
811
              }
 
812
            break;
 
813
#endif
 
814
          case FFI_TYPE_FLOAT:
 
815
          case FFI_TYPE_DOUBLE:
 
816
            fparg_count++;
 
817
            intarg_count++;
 
818
            break;
 
819
 
 
820
          case FFI_TYPE_STRUCT:
 
821
            intarg_count += ((*ptr)->size + 7) / 8;
 
822
            break;
 
823
 
 
824
          default:
 
825
            /* Everything else is passed as a 8-byte word in a GPR, either
 
826
               the object itself or a pointer to it.  */
 
827
            intarg_count++;
 
828
            break;
 
829
          }
 
830
      }
 
831
 
 
832
  if (fparg_count != 0)
 
833
    flags |= FLAG_FP_ARGUMENTS;
 
834
  if (intarg_count > 4)
 
835
    flags |= FLAG_4_GPR_ARGUMENTS;
 
836
  if (struct_copy_size != 0)
 
837
    flags |= FLAG_ARG_NEEDS_COPY;
 
838
 
 
839
  if (cif->abi != FFI_LINUX64)
 
840
    {
 
841
      /* Space for the FPR registers, if needed.  */
 
842
      if (fparg_count != 0)
 
843
        bytes += NUM_FPR_ARG_REGISTERS * sizeof (double);
 
844
 
 
845
      /* Stack space.  */
 
846
      if (intarg_count > NUM_GPR_ARG_REGISTERS)
 
847
        bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof (int);
 
848
      if (fparg_count > NUM_FPR_ARG_REGISTERS)
 
849
        bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof (double);
 
850
    }
 
851
  else
 
852
    {
 
853
      /* Space for the FPR registers, if needed.  */
 
854
      if (fparg_count != 0)
 
855
        bytes += NUM_FPR_ARG_REGISTERS64 * sizeof (double);
 
856
 
 
857
      /* Stack space.  */
 
858
      if (intarg_count > NUM_GPR_ARG_REGISTERS64)
 
859
        bytes += (intarg_count - NUM_GPR_ARG_REGISTERS64) * sizeof (long);
 
860
    }
 
861
 
 
862
  /* The stack space allocated needs to be a multiple of 16 bytes.  */
 
863
  bytes = (bytes + 15) & ~0xF;
 
864
 
 
865
  /* Add in the space for the copied structures.  */
 
866
  bytes += struct_copy_size;
 
867
 
 
868
  cif->flags = flags;
 
869
  cif->bytes = bytes;
 
870
 
 
871
  return FFI_OK;
 
872
}
 
873
 
 
874
extern void ffi_call_SYSV(extended_cif *, unsigned, unsigned, unsigned *,
 
875
                          void (*fn)(void));
 
876
extern void FFI_HIDDEN ffi_call_LINUX64(extended_cif *, unsigned long,
 
877
                                        unsigned long, unsigned long *,
 
878
                                        void (*fn)(void));
 
879
 
 
880
void
 
881
ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
 
882
{
 
883
  extended_cif ecif;
 
884
 
 
885
  ecif.cif = cif;
 
886
  ecif.avalue = avalue;
 
887
 
 
888
  /* If the return value is a struct and we don't have a return */
 
889
  /* value address then we need to make one                     */
 
890
 
 
891
  if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT))
 
892
    {
 
893
      ecif.rvalue = alloca(cif->rtype->size);
 
894
    }
 
895
  else
 
896
    ecif.rvalue = rvalue;
 
897
 
 
898
 
 
899
  switch (cif->abi)
 
900
    {
 
901
#ifndef POWERPC64
 
902
    case FFI_SYSV:
 
903
    case FFI_GCC_SYSV:
 
904
    case FFI_LINUX:
 
905
    case FFI_LINUX_SOFT_FLOAT:
 
906
      ffi_call_SYSV (&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn);
 
907
      break;
 
908
#else
 
909
    case FFI_LINUX64:
 
910
      ffi_call_LINUX64 (&ecif, -(long) cif->bytes, cif->flags, ecif.rvalue, fn);
 
911
      break;
 
912
#endif
 
913
    default:
 
914
      FFI_ASSERT (0);
 
915
      break;
 
916
    }
 
917
}
 
918
 
 
919
 
 
920
#ifndef POWERPC64
 
921
#define MIN_CACHE_LINE_SIZE 8
 
922
 
 
923
static void
 
924
flush_icache (char *wraddr, char *xaddr, int size)
 
925
{
 
926
  int i;
 
927
  for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE)
 
928
    __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;"
 
929
                      : : "r" (xaddr + i), "r" (wraddr + i) : "memory");
 
930
  __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;" "sync;" "isync;"
 
931
                    : : "r"(xaddr + size - 1), "r"(wraddr + size - 1)
 
932
                    : "memory");
 
933
}
 
934
#endif
 
935
 
 
936
ffi_status
 
937
ffi_prep_closure_loc (ffi_closure *closure,
 
938
                      ffi_cif *cif,
 
939
                      void (*fun) (ffi_cif *, void *, void **, void *),
 
940
                      void *user_data,
 
941
                      void *codeloc)
 
942
{
 
943
#ifdef POWERPC64
 
944
  void **tramp = (void **) &closure->tramp[0];
 
945
 
 
946
  FFI_ASSERT (cif->abi == FFI_LINUX64);
 
947
  /* Copy function address and TOC from ffi_closure_LINUX64.  */
 
948
  memcpy (tramp, (char *) ffi_closure_LINUX64, 16);
 
949
  tramp[2] = codeloc;
 
950
#else
 
951
  unsigned int *tramp;
 
952
 
 
953
  FFI_ASSERT (cif->abi == FFI_GCC_SYSV || cif->abi == FFI_SYSV);
 
954
 
 
955
  tramp = (unsigned int *) &closure->tramp[0];
 
956
  tramp[0] = 0x7c0802a6;  /*   mflr    r0 */
 
957
  tramp[1] = 0x4800000d;  /*   bl      10 <trampoline_initial+0x10> */
 
958
  tramp[4] = 0x7d6802a6;  /*   mflr    r11 */
 
959
  tramp[5] = 0x7c0803a6;  /*   mtlr    r0 */
 
960
  tramp[6] = 0x800b0000;  /*   lwz     r0,0(r11) */
 
961
  tramp[7] = 0x816b0004;  /*   lwz     r11,4(r11) */
 
962
  tramp[8] = 0x7c0903a6;  /*   mtctr   r0 */
 
963
  tramp[9] = 0x4e800420;  /*   bctr */
 
964
  *(void **) &tramp[2] = (void *) ffi_closure_SYSV; /* function */
 
965
  *(void **) &tramp[3] = codeloc;                   /* context */
 
966
 
 
967
  /* Flush the icache.  */
 
968
  flush_icache ((char *)tramp, (char *)codeloc, FFI_TRAMPOLINE_SIZE);
 
969
#endif
 
970
 
 
971
  closure->cif = cif;
 
972
  closure->fun = fun;
 
973
  closure->user_data = user_data;
 
974
 
 
975
  return FFI_OK;
 
976
}
 
977
 
 
978
typedef union
 
979
{
 
980
  float f;
 
981
  double d;
 
982
} ffi_dblfl;
 
983
 
 
984
int ffi_closure_helper_SYSV (ffi_closure *, void *, unsigned long *,
 
985
                             ffi_dblfl *, unsigned long *);
 
986
 
 
987
/* Basically the trampoline invokes ffi_closure_SYSV, and on
 
988
 * entry, r11 holds the address of the closure.
 
989
 * After storing the registers that could possibly contain
 
990
 * parameters to be passed into the stack frame and setting
 
991
 * up space for a return value, ffi_closure_SYSV invokes the
 
992
 * following helper function to do most of the work
 
993
 */
 
994
 
 
995
int
 
996
ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue,
 
997
                         unsigned long *pgr, ffi_dblfl *pfr,
 
998
                         unsigned long *pst)
 
999
{
 
1000
  /* rvalue is the pointer to space for return value in closure assembly */
 
1001
  /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */
 
1002
  /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV  */
 
1003
  /* pst is the pointer to outgoing parameter stack in original caller */
 
1004
 
 
1005
  void **          avalue;
 
1006
  ffi_type **      arg_types;
 
1007
  long             i, avn;
 
1008
  long             nf;   /* number of floating registers already used */
 
1009
  long             ng;   /* number of general registers already used */
 
1010
  ffi_cif *        cif;
 
1011
  double           temp;
 
1012
  unsigned         size;
 
1013
 
 
1014
  cif = closure->cif;
 
1015
  avalue = alloca (cif->nargs * sizeof (void *));
 
1016
  size = cif->rtype->size;
 
1017
 
 
1018
  nf = 0;
 
1019
  ng = 0;
 
1020
 
 
1021
  /* Copy the caller's structure return value address so that the closure
 
1022
     returns the data directly to the caller.
 
1023
     For FFI_SYSV the result is passed in r3/r4 if the struct size is less
 
1024
     or equal 8 bytes.  */
 
1025
 
 
1026
  if ((cif->rtype->type == FFI_TYPE_STRUCT
 
1027
       && !((cif->abi == FFI_SYSV) && (size <= 8)))
 
1028
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
1029
      || (cif->rtype->type == FFI_TYPE_LONGDOUBLE
 
1030
          && cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
 
1031
#endif
 
1032
      )
 
1033
    {
 
1034
      rvalue = (void *) *pgr;
 
1035
      ng++;
 
1036
      pgr++;
 
1037
    }
 
1038
 
 
1039
  i = 0;
 
1040
  avn = cif->nargs;
 
1041
  arg_types = cif->arg_types;
 
1042
 
 
1043
  /* Grab the addresses of the arguments from the stack frame.  */
 
1044
  while (i < avn)
 
1045
    {
 
1046
      switch (arg_types[i]->type)
 
1047
        {
 
1048
        case FFI_TYPE_SINT8:
 
1049
        case FFI_TYPE_UINT8:
 
1050
          /* there are 8 gpr registers used to pass values */
 
1051
          if (ng < 8)
 
1052
            {
 
1053
              avalue[i] = (char *) pgr + 3;
 
1054
              ng++;
 
1055
              pgr++;
 
1056
            }
 
1057
          else
 
1058
            {
 
1059
              avalue[i] = (char *) pst + 3;
 
1060
              pst++;
 
1061
            }
 
1062
          break;
 
1063
 
 
1064
        case FFI_TYPE_SINT16:
 
1065
        case FFI_TYPE_UINT16:
 
1066
          /* there are 8 gpr registers used to pass values */
 
1067
          if (ng < 8)
 
1068
            {
 
1069
              avalue[i] = (char *) pgr + 2;
 
1070
              ng++;
 
1071
              pgr++;
 
1072
            }
 
1073
          else
 
1074
            {
 
1075
              avalue[i] = (char *) pst + 2;
 
1076
              pst++;
 
1077
            }
 
1078
          break;
 
1079
 
 
1080
        case FFI_TYPE_SINT32:
 
1081
        case FFI_TYPE_UINT32:
 
1082
        case FFI_TYPE_POINTER:
 
1083
        soft_float_closure:
 
1084
          /* there are 8 gpr registers used to pass values */
 
1085
          if (ng < 8)
 
1086
            {
 
1087
              avalue[i] = pgr;
 
1088
              ng++;
 
1089
              pgr++;
 
1090
            }
 
1091
          else
 
1092
            {
 
1093
              avalue[i] = pst;
 
1094
              pst++;
 
1095
            }
 
1096
          break;
 
1097
 
 
1098
        case FFI_TYPE_STRUCT:
 
1099
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
1100
        do_struct:
 
1101
#endif
 
1102
          /* Structs are passed by reference. The address will appear in a
 
1103
             gpr if it is one of the first 8 arguments.  */
 
1104
          if (ng < 8)
 
1105
            {
 
1106
              avalue[i] = (void *) *pgr;
 
1107
              ng++;
 
1108
              pgr++;
 
1109
            }
 
1110
          else
 
1111
            {
 
1112
              avalue[i] = (void *) *pst;
 
1113
              pst++;
 
1114
            }
 
1115
          break;
 
1116
 
 
1117
        case FFI_TYPE_SINT64:
 
1118
        case FFI_TYPE_UINT64:
 
1119
        soft_double_closure:
 
1120
          /* passing long long ints are complex, they must
 
1121
           * be passed in suitable register pairs such as
 
1122
           * (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10)
 
1123
           * and if the entire pair aren't available then the outgoing
 
1124
           * parameter stack is used for both but an alignment of 8
 
1125
           * must will be kept.  So we must either look in pgr
 
1126
           * or pst to find the correct address for this type
 
1127
           * of parameter.
 
1128
           */
 
1129
          if (ng < 7)
 
1130
            {
 
1131
              if (ng & 0x01)
 
1132
                {
 
1133
                  /* skip r4, r6, r8 as starting points */
 
1134
                  ng++;
 
1135
                  pgr++;
 
1136
                }
 
1137
              avalue[i] = pgr;
 
1138
              ng += 2;
 
1139
              pgr += 2;
 
1140
            }
 
1141
          else
 
1142
            {
 
1143
              if (((long) pst) & 4)
 
1144
                pst++;
 
1145
              avalue[i] = pst;
 
1146
              pst += 2;
 
1147
            }
 
1148
          break;
 
1149
 
 
1150
        case FFI_TYPE_FLOAT:
 
1151
          /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32.  */
 
1152
          if (cif->abi == FFI_LINUX_SOFT_FLOAT)
 
1153
            goto soft_float_closure;
 
1154
          /* unfortunately float values are stored as doubles
 
1155
           * in the ffi_closure_SYSV code (since we don't check
 
1156
           * the type in that routine).
 
1157
           */
 
1158
 
 
1159
          /* there are 8 64bit floating point registers */
 
1160
 
 
1161
          if (nf < 8)
 
1162
            {
 
1163
              temp = pfr->d;
 
1164
              pfr->f = (float) temp;
 
1165
              avalue[i] = pfr;
 
1166
              nf++;
 
1167
              pfr++;
 
1168
            }
 
1169
          else
 
1170
            {
 
1171
              /* FIXME? here we are really changing the values
 
1172
               * stored in the original calling routines outgoing
 
1173
               * parameter stack.  This is probably a really
 
1174
               * naughty thing to do but...
 
1175
               */
 
1176
              avalue[i] = pst;
 
1177
              pst += 1;
 
1178
            }
 
1179
          break;
 
1180
 
 
1181
        case FFI_TYPE_DOUBLE:
 
1182
          /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64.  */
 
1183
          if (cif->abi == FFI_LINUX_SOFT_FLOAT)
 
1184
            goto soft_double_closure;
 
1185
          /* On the outgoing stack all values are aligned to 8 */
 
1186
          /* there are 8 64bit floating point registers */
 
1187
 
 
1188
          if (nf < 8)
 
1189
            {
 
1190
              avalue[i] = pfr;
 
1191
              nf++;
 
1192
              pfr++;
 
1193
            }
 
1194
          else
 
1195
            {
 
1196
              if (((long) pst) & 4)
 
1197
                pst++;
 
1198
              avalue[i] = pst;
 
1199
              pst += 2;
 
1200
            }
 
1201
          break;
 
1202
 
 
1203
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
1204
        case FFI_TYPE_LONGDOUBLE:
 
1205
          if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
 
1206
            goto do_struct;
 
1207
          if (cif->abi == FFI_LINUX_SOFT_FLOAT)
 
1208
            { /* Test if for the whole long double, 4 gprs are available.
 
1209
                 otherwise the stuff ends up on the stack.  */
 
1210
              if (ng < 5)
 
1211
                {
 
1212
                  avalue[i] = pgr;
 
1213
                  pgr += 4;
 
1214
                  ng += 4;
 
1215
                }
 
1216
              else
 
1217
                {
 
1218
                  avalue[i] = pst;
 
1219
                  pst += 4;
 
1220
                }
 
1221
              break;
 
1222
            }
 
1223
          if (nf < 7)
 
1224
            {
 
1225
              avalue[i] = pfr;
 
1226
              pfr += 2;
 
1227
              nf += 2;
 
1228
            }
 
1229
          else
 
1230
            {
 
1231
              if (((long) pst) & 4)
 
1232
                pst++;
 
1233
              avalue[i] = pst;
 
1234
              pst += 4;
 
1235
              nf = 8;
 
1236
            }
 
1237
          break;
 
1238
#endif
 
1239
 
 
1240
        default:
 
1241
          FFI_ASSERT (0);
 
1242
        }
 
1243
 
 
1244
      i++;
 
1245
    }
 
1246
 
 
1247
 
 
1248
  (closure->fun) (cif, rvalue, avalue, closure->user_data);
 
1249
 
 
1250
  /* Tell ffi_closure_SYSV how to perform return type promotions.
 
1251
     Because the FFI_SYSV ABI returns the structures <= 8 bytes in r3/r4
 
1252
     we have to tell ffi_closure_SYSV how to treat them.  */
 
1253
  if (cif->abi == FFI_SYSV && cif->rtype->type == FFI_TYPE_STRUCT
 
1254
      && size <= 8)
 
1255
    return FFI_SYSV_TYPE_SMALL_STRUCT + size;
 
1256
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
1257
  else if (cif->rtype->type == FFI_TYPE_LONGDOUBLE
 
1258
           && cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
 
1259
    return FFI_TYPE_STRUCT;
 
1260
#endif
 
1261
  /* With FFI_LINUX_SOFT_FLOAT floats and doubles are handled like UINT32
 
1262
     respectivley UINT64.  */
 
1263
  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
 
1264
    {
 
1265
      switch (cif->rtype->type)
 
1266
        {
 
1267
        case FFI_TYPE_FLOAT:
 
1268
          return FFI_TYPE_UINT32;
 
1269
          break;
 
1270
        case FFI_TYPE_DOUBLE:
 
1271
          return FFI_TYPE_UINT64;
 
1272
          break;
 
1273
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
1274
        case FFI_TYPE_LONGDOUBLE:
 
1275
          return FFI_TYPE_UINT128;
 
1276
          break;
 
1277
#endif
 
1278
        default:
 
1279
          return cif->rtype->type;
 
1280
        }
 
1281
    }
 
1282
  else
 
1283
    {
 
1284
      return cif->rtype->type;
 
1285
    }
 
1286
}
 
1287
 
 
1288
int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure *, void *,
 
1289
                                           unsigned long *, ffi_dblfl *);
 
1290
 
 
1291
int FFI_HIDDEN
 
1292
ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
 
1293
                            unsigned long *pst, ffi_dblfl *pfr)
 
1294
{
 
1295
  /* rvalue is the pointer to space for return value in closure assembly */
 
1296
  /* pst is the pointer to parameter save area
 
1297
     (r3-r10 are stored into its first 8 slots by ffi_closure_LINUX64) */
 
1298
  /* pfr is the pointer to where f1-f13 are stored in ffi_closure_LINUX64 */
 
1299
 
 
1300
  void **avalue;
 
1301
  ffi_type **arg_types;
 
1302
  long i, avn;
 
1303
  ffi_cif *cif;
 
1304
  ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS64;
 
1305
 
 
1306
  cif = closure->cif;
 
1307
  avalue = alloca (cif->nargs * sizeof (void *));
 
1308
 
 
1309
  /* Copy the caller's structure return value address so that the closure
 
1310
     returns the data directly to the caller.  */
 
1311
  if (cif->rtype->type == FFI_TYPE_STRUCT)
 
1312
    {
 
1313
      rvalue = (void *) *pst;
 
1314
      pst++;
 
1315
    }
 
1316
 
 
1317
  i = 0;
 
1318
  avn = cif->nargs;
 
1319
  arg_types = cif->arg_types;
 
1320
 
 
1321
  /* Grab the addresses of the arguments from the stack frame.  */
 
1322
  while (i < avn)
 
1323
    {
 
1324
      switch (arg_types[i]->type)
 
1325
        {
 
1326
        case FFI_TYPE_SINT8:
 
1327
        case FFI_TYPE_UINT8:
 
1328
          avalue[i] = (char *) pst + 7;
 
1329
          pst++;
 
1330
          break;
 
1331
 
 
1332
        case FFI_TYPE_SINT16:
 
1333
        case FFI_TYPE_UINT16:
 
1334
          avalue[i] = (char *) pst + 6;
 
1335
          pst++;
 
1336
          break;
 
1337
 
 
1338
        case FFI_TYPE_SINT32:
 
1339
        case FFI_TYPE_UINT32:
 
1340
          avalue[i] = (char *) pst + 4;
 
1341
          pst++;
 
1342
          break;
 
1343
 
 
1344
        case FFI_TYPE_SINT64:
 
1345
        case FFI_TYPE_UINT64:
 
1346
        case FFI_TYPE_POINTER:
 
1347
          avalue[i] = pst;
 
1348
          pst++;
 
1349
          break;
 
1350
 
 
1351
        case FFI_TYPE_STRUCT:
 
1352
          /* Structures with size less than eight bytes are passed
 
1353
             left-padded.  */
 
1354
          if (arg_types[i]->size < 8)
 
1355
            avalue[i] = (char *) pst + 8 - arg_types[i]->size;
 
1356
          else
 
1357
            avalue[i] = pst;
 
1358
          pst += (arg_types[i]->size + 7) / 8;
 
1359
          break;
 
1360
 
 
1361
        case FFI_TYPE_FLOAT:
 
1362
          /* unfortunately float values are stored as doubles
 
1363
           * in the ffi_closure_LINUX64 code (since we don't check
 
1364
           * the type in that routine).
 
1365
           */
 
1366
 
 
1367
          /* there are 13 64bit floating point registers */
 
1368
 
 
1369
          if (pfr < end_pfr)
 
1370
            {
 
1371
              double temp = pfr->d;
 
1372
              pfr->f = (float) temp;
 
1373
              avalue[i] = pfr;
 
1374
              pfr++;
 
1375
            }
 
1376
          else
 
1377
            avalue[i] = pst;
 
1378
          pst++;
 
1379
          break;
 
1380
 
 
1381
        case FFI_TYPE_DOUBLE:
 
1382
          /* On the outgoing stack all values are aligned to 8 */
 
1383
          /* there are 13 64bit floating point registers */
 
1384
 
 
1385
          if (pfr < end_pfr)
 
1386
            {
 
1387
              avalue[i] = pfr;
 
1388
              pfr++;
 
1389
            }
 
1390
          else
 
1391
            avalue[i] = pst;
 
1392
          pst++;
 
1393
          break;
 
1394
 
 
1395
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
1396
        case FFI_TYPE_LONGDOUBLE:
 
1397
          if (pfr + 1 < end_pfr)
 
1398
            {
 
1399
              avalue[i] = pfr;
 
1400
              pfr += 2;
 
1401
            }
 
1402
          else
 
1403
            {
 
1404
              if (pfr < end_pfr)
 
1405
                {
 
1406
                  /* Passed partly in f13 and partly on the stack.
 
1407
                     Move it all to the stack.  */
 
1408
                  *pst = *(unsigned long *) pfr;
 
1409
                  pfr++;
 
1410
                }
 
1411
              avalue[i] = pst;
 
1412
            }
 
1413
          pst += 2;
 
1414
          break;
 
1415
#endif
 
1416
 
 
1417
        default:
 
1418
          FFI_ASSERT (0);
 
1419
        }
 
1420
 
 
1421
      i++;
 
1422
    }
 
1423
 
 
1424
 
 
1425
  (closure->fun) (cif, rvalue, avalue, closure->user_data);
 
1426
 
 
1427
  /* Tell ffi_closure_LINUX64 how to perform return type promotions.  */
 
1428
  return cif->rtype->type;
 
1429
}