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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libffi/] [src/] [powerpc/] [ffi_darwin.c] - Blame information for rev 801

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 732 jeremybenn
/* -----------------------------------------------------------------------
2
   ffi_darwin.c
3
 
4
   Copyright (C) 1998 Geoffrey Keating
5
   Copyright (C) 2001 John Hornkvist
6
   Copyright (C) 2002, 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
7
 
8
   FFI support for Darwin and AIX.
9
 
10
   Permission is hereby granted, free of charge, to any person obtaining
11
   a copy of this software and associated documentation files (the
12
   ``Software''), to deal in the Software without restriction, including
13
   without limitation the rights to use, copy, modify, merge, publish,
14
   distribute, sublicense, and/or sell copies of the Software, and to
15
   permit persons to whom the Software is furnished to do so, subject to
16
   the following conditions:
17
 
18
   The above copyright notice and this permission notice shall be included
19
   in all copies or substantial portions of the Software.
20
 
21
   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
22
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23
   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24
   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
25
   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26
   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27
   OTHER DEALINGS IN THE SOFTWARE.
28
   ----------------------------------------------------------------------- */
29
 
30
#include <ffi.h>
31
#include <ffi_common.h>
32
 
33
#include <stdlib.h>
34
 
35
extern void ffi_closure_ASM (void);
36
 
37
enum {
38
  /* The assembly depends on these exact flags.
39
     For Darwin64 (when FLAG_RETURNS_STRUCT is set):
40
       FLAG_RETURNS_FP indicates that the structure embeds FP data.
41
       FLAG_RETURNS_128BITS signals a special struct size that is not
42
       expanded for float content.  */
43
  FLAG_RETURNS_128BITS  = 1 << (31-31), /* These go in cr7  */
44
  FLAG_RETURNS_NOTHING  = 1 << (31-30),
45
  FLAG_RETURNS_FP       = 1 << (31-29),
46
  FLAG_RETURNS_64BITS   = 1 << (31-28),
47
 
48
  FLAG_RETURNS_STRUCT   = 1 << (31-27), /* This goes in cr6  */
49
 
50
  FLAG_ARG_NEEDS_COPY   = 1 << (31- 7),
51
  FLAG_FP_ARGUMENTS     = 1 << (31- 6), /* cr1.eq; specified by ABI  */
52
  FLAG_4_GPR_ARGUMENTS  = 1 << (31- 5),
53
  FLAG_RETVAL_REFERENCE = 1 << (31- 4)
54
};
55
 
56
/* About the DARWIN ABI.  */
57
enum {
58
  NUM_GPR_ARG_REGISTERS = 8,
59
  NUM_FPR_ARG_REGISTERS = 13,
60
  LINKAGE_AREA_GPRS = 6
61
};
62
 
63
enum { ASM_NEEDS_REGISTERS = 4 }; /* r28-r31 */
64
 
65
/* ffi_prep_args is called by the assembly routine once stack space
66
   has been allocated for the function's arguments.
67
 
68
   m32/m64
69
 
70
   The stack layout we want looks like this:
71
 
72
   |   Return address from ffi_call_DARWIN      |       higher addresses
73
   |--------------------------------------------|
74
   |   Previous backchain pointer       4/8     |       stack pointer here
75
   |--------------------------------------------|<+ <<< on entry to
76
   |   ASM_NEEDS_REGISTERS=r28-r31   4*(4/8)    | |     ffi_call_DARWIN
77
   |--------------------------------------------| |
78
   |   When we have any FP activity... the      | |
79
   |   FPRs occupy NUM_FPR_ARG_REGISTERS slots  | |
80
   |   here fp13 .. fp1 from high to low addr.  | |
81
   ~                                            ~ ~
82
   |   Parameters      (at least 8*4/8=32/64)   | | NUM_GPR_ARG_REGISTERS
83
   |--------------------------------------------| |
84
   |   TOC=R2 (AIX) Reserved (Darwin)   4/8     | |
85
   |--------------------------------------------| |     stack   |
86
   |   Reserved                       2*4/8     | |     grows   |
87
   |--------------------------------------------| |     down    V
88
   |   Space for callee's LR            4/8     | |
89
   |--------------------------------------------| |     lower addresses
90
   |   Saved CR [low word for m64]      4/8     | |
91
   |--------------------------------------------| |     stack pointer here
92
   |   Current backchain pointer        4/8     |-/     during
93
   |--------------------------------------------|   <<< ffi_call_DARWIN
94
 
95
   */
96
 
97
#if defined(POWERPC_DARWIN64)
98
static void
99
darwin64_pass_struct_by_value
100
  (ffi_type *, char *, unsigned, unsigned *, double **, unsigned long **);
101
#endif
102
 
103
/* This depends on GPR_SIZE = sizeof (unsigned long) */
104
 
105
void
106
ffi_prep_args (extended_cif *ecif, unsigned long *const stack)
107
{
108
  const unsigned bytes = ecif->cif->bytes;
109
  const unsigned flags = ecif->cif->flags;
110
  const unsigned nargs = ecif->cif->nargs;
111
#if !defined(POWERPC_DARWIN64) 
112
  const ffi_abi abi = ecif->cif->abi;
113
#endif
114
 
115
  /* 'stacktop' points at the previous backchain pointer.  */
116
  unsigned long *const stacktop = stack + (bytes / sizeof(unsigned long));
117
 
118
  /* 'fpr_base' points at the space for fpr1, and grows upwards as
119
     we use FPR registers.  */
120
  double *fpr_base = (double *) (stacktop - ASM_NEEDS_REGISTERS) - NUM_FPR_ARG_REGISTERS;
121
  int gp_count = 0, fparg_count = 0;
122
 
123
  /* 'next_arg' grows up as we put parameters in it.  */
124
  unsigned long *next_arg = stack + LINKAGE_AREA_GPRS; /* 6 reserved positions.  */
125
 
126
  int i;
127
  double double_tmp;
128
  void **p_argv = ecif->avalue;
129
  unsigned long gprvalue;
130
  ffi_type** ptr = ecif->cif->arg_types;
131
#if !defined(POWERPC_DARWIN64) 
132
  char *dest_cpy;
133
#endif
134
  unsigned size_al = 0;
135
 
136
  /* Check that everything starts aligned properly.  */
137
  FFI_ASSERT(((unsigned) (char *) stack & 0xF) == 0);
138
  FFI_ASSERT(((unsigned) (char *) stacktop & 0xF) == 0);
139
  FFI_ASSERT((bytes & 0xF) == 0);
140
 
141
  /* Deal with return values that are actually pass-by-reference.
142
     Rule:
143
     Return values are referenced by r3, so r4 is the first parameter.  */
144
 
145
  if (flags & FLAG_RETVAL_REFERENCE)
146
    *next_arg++ = (unsigned long) (char *) ecif->rvalue;
147
 
148
  /* Now for the arguments.  */
149
  for (i = nargs; i > 0; i--, ptr++, p_argv++)
150
    {
151
      switch ((*ptr)->type)
152
        {
153
        /* If a floating-point parameter appears before all of the general-
154
           purpose registers are filled, the corresponding GPRs that match
155
           the size of the floating-point parameter are skipped.  */
156
        case FFI_TYPE_FLOAT:
157
          double_tmp = *(float *) *p_argv;
158
          if (fparg_count < NUM_FPR_ARG_REGISTERS)
159
            *fpr_base++ = double_tmp;
160
#if defined(POWERPC_DARWIN)
161
          *(float *)next_arg = *(float *) *p_argv;
162
#else
163
          *(double *)next_arg = double_tmp;
164
#endif
165
          next_arg++;
166
          gp_count++;
167
          fparg_count++;
168
          FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
169
          break;
170
 
171
        case FFI_TYPE_DOUBLE:
172
          double_tmp = *(double *) *p_argv;
173
          if (fparg_count < NUM_FPR_ARG_REGISTERS)
174
            *fpr_base++ = double_tmp;
175
          *(double *)next_arg = double_tmp;
176
#ifdef POWERPC64
177
          next_arg++;
178
          gp_count++;
179
#else
180
          next_arg += 2;
181
          gp_count += 2;
182
#endif
183
          fparg_count++;
184
          FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
185
          break;
186
 
187
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
188
 
189
        case FFI_TYPE_LONGDOUBLE:
190
#  if defined(POWERPC64) && !defined(POWERPC_DARWIN64)
191
          /* ??? This will exceed the regs count when the value starts at fp13
192
             and it will not put the extra bit on the stack.  */
193
          if (fparg_count < NUM_FPR_ARG_REGISTERS)
194
            *(long double *) fpr_base++ = *(long double *) *p_argv;
195
          else
196
            *(long double *) next_arg = *(long double *) *p_argv;
197
          next_arg += 2;
198
          fparg_count += 2;
199
#  else
200
          double_tmp = ((double *) *p_argv)[0];
201
          if (fparg_count < NUM_FPR_ARG_REGISTERS)
202
            *fpr_base++ = double_tmp;
203
          *(double *) next_arg = double_tmp;
204
#    if defined(POWERPC_DARWIN64)
205
          next_arg++;
206
          gp_count++;
207
#    else
208
          next_arg += 2;
209
          gp_count += 2;
210
#    endif
211
          fparg_count++;
212
          double_tmp = ((double *) *p_argv)[1];
213
          if (fparg_count < NUM_FPR_ARG_REGISTERS)
214
            *fpr_base++ = double_tmp;
215
          *(double *) next_arg = double_tmp;
216
#    if defined(POWERPC_DARWIN64)
217
          next_arg++;
218
          gp_count++;
219
#    else
220
          next_arg += 2;
221
          gp_count += 2;
222
#    endif
223
          fparg_count++;
224
#  endif
225
          FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
226
          break;
227
#endif
228
        case FFI_TYPE_UINT64:
229
        case FFI_TYPE_SINT64:
230
#ifdef POWERPC64
231
          gprvalue = *(long long *) *p_argv;
232
          goto putgpr;
233
#else
234
          *(long long *) next_arg = *(long long *) *p_argv;
235
          next_arg += 2;
236
          gp_count += 2;
237
#endif
238
          break;
239
        case FFI_TYPE_POINTER:
240
          gprvalue = *(unsigned long *) *p_argv;
241
          goto putgpr;
242
        case FFI_TYPE_UINT8:
243
          gprvalue = *(unsigned char *) *p_argv;
244
          goto putgpr;
245
        case FFI_TYPE_SINT8:
246
          gprvalue = *(signed char *) *p_argv;
247
          goto putgpr;
248
        case FFI_TYPE_UINT16:
249
          gprvalue = *(unsigned short *) *p_argv;
250
          goto putgpr;
251
        case FFI_TYPE_SINT16:
252
          gprvalue = *(signed short *) *p_argv;
253
          goto putgpr;
254
 
255
        case FFI_TYPE_STRUCT:
256
          size_al = (*ptr)->size;
257
#if defined(POWERPC_DARWIN64)
258
          next_arg = (unsigned long *)ALIGN((char *)next_arg, (*ptr)->alignment);
259
          darwin64_pass_struct_by_value (*ptr, (char *) *p_argv,
260
                                         (unsigned) size_al,
261
                                         (unsigned int *) &fparg_count,
262
                                         &fpr_base, &next_arg);
263
#else
264
          dest_cpy = (char *) next_arg;
265
 
266
          /* If the first member of the struct is a double, then include enough
267
             padding in the struct size to align it to double-word.  */
268
          if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE)
269
            size_al = ALIGN((*ptr)->size, 8);
270
 
271
#  if defined(POWERPC64) 
272
          FFI_ASSERT (abi != FFI_DARWIN);
273
          memcpy ((char *) dest_cpy, (char *) *p_argv, size_al);
274
          next_arg += (size_al + 7) / 8;
275
#  else
276
          /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
277
             SI 4 bytes) are aligned as if they were those modes.
278
             Structures with 3 byte in size are padded upwards.  */
279
          if (size_al < 3 && abi == FFI_DARWIN)
280
            dest_cpy += 4 - size_al;
281
 
282
          memcpy((char *) dest_cpy, (char *) *p_argv, size_al);
283
          next_arg += (size_al + 3) / 4;
284
#  endif
285
#endif
286
          break;
287
 
288
        case FFI_TYPE_INT:
289
        case FFI_TYPE_SINT32:
290
          gprvalue = *(signed int *) *p_argv;
291
          goto putgpr;
292
 
293
        case FFI_TYPE_UINT32:
294
          gprvalue = *(unsigned int *) *p_argv;
295
        putgpr:
296
          *next_arg++ = gprvalue;
297
          gp_count++;
298
          break;
299
        default:
300
          break;
301
        }
302
    }
303
 
304
  /* Check that we didn't overrun the stack...  */
305
  //FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS);
306
  //FFI_ASSERT((unsigned *)fpr_base
307
  //         <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
308
  //FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
309
}
310
 
311
#if defined(POWERPC_DARWIN64)
312
 
313
/* See if we can put some of the struct into fprs.
314
   This should not be called for structures of size 16 bytes, since these are not
315
   broken out this way.  */
316
static void
317
darwin64_scan_struct_for_floats (ffi_type *s, unsigned *nfpr)
318
{
319
  int i;
320
 
321
  FFI_ASSERT (s->type == FFI_TYPE_STRUCT)
322
 
323
  for (i = 0; s->elements[i] != NULL; i++)
324
    {
325
      ffi_type *p = s->elements[i];
326
      switch (p->type)
327
        {
328
          case FFI_TYPE_STRUCT:
329
            darwin64_scan_struct_for_floats (p, nfpr);
330
            break;
331
          case FFI_TYPE_LONGDOUBLE:
332
            (*nfpr) += 2;
333
            break;
334
          case FFI_TYPE_DOUBLE:
335
          case FFI_TYPE_FLOAT:
336
            (*nfpr) += 1;
337
            break;
338
          default:
339
            break;
340
        }
341
    }
342
}
343
 
344
static int
345
darwin64_struct_size_exceeds_gprs_p (ffi_type *s, char *src, unsigned *nfpr)
346
{
347
  unsigned struct_offset=0, i;
348
 
349
  for (i = 0; s->elements[i] != NULL; i++)
350
    {
351
      char *item_base;
352
      ffi_type *p = s->elements[i];
353
      /* Find the start of this item (0 for the first one).  */
354
      if (i > 0)
355
        struct_offset = ALIGN(struct_offset, p->alignment);
356
 
357
      item_base = src + struct_offset;
358
 
359
      switch (p->type)
360
        {
361
          case FFI_TYPE_STRUCT:
362
            if (darwin64_struct_size_exceeds_gprs_p (p, item_base, nfpr))
363
              return 1;
364
            break;
365
          case FFI_TYPE_LONGDOUBLE:
366
            if (*nfpr >= NUM_FPR_ARG_REGISTERS)
367
              return 1;
368
            (*nfpr) += 1;
369
            item_base += 8;
370
          /* FALL THROUGH */
371
          case FFI_TYPE_DOUBLE:
372
            if (*nfpr >= NUM_FPR_ARG_REGISTERS)
373
              return 1;
374
            (*nfpr) += 1;
375
            break;
376
          case FFI_TYPE_FLOAT:
377
            if (*nfpr >= NUM_FPR_ARG_REGISTERS)
378
              return 1;
379
            (*nfpr) += 1;
380
            break;
381
          default:
382
            /* If we try and place any item, that is non-float, once we've
383
               exceeded the 8 GPR mark, then we can't fit the struct.  */
384
            if ((unsigned long)item_base >= 8*8)
385
              return 1;
386
            break;
387
        }
388
      /* now count the size of what we just used.  */
389
      struct_offset += p->size;
390
    }
391
  return 0;
392
}
393
 
394
/* Can this struct be returned by value?  */
395
int
396
darwin64_struct_ret_by_value_p (ffi_type *s)
397
{
398
  unsigned nfp = 0;
399
 
400
  FFI_ASSERT (s && s->type == FFI_TYPE_STRUCT);
401
 
402
  /* The largest structure we can return is 8long + 13 doubles.  */
403
  if (s->size > 168)
404
    return 0;
405
 
406
  /* We can't pass more than 13 floats.  */
407
  darwin64_scan_struct_for_floats (s, &nfp);
408
  if (nfp > 13)
409
    return 0;
410
 
411
  /* If there are not too many floats, and the struct is
412
     small enough to accommodate in the GPRs, then it must be OK.  */
413
  if (s->size <= 64)
414
    return 1;
415
 
416
  /* Well, we have to look harder.  */
417
  nfp = 0;
418
  if (darwin64_struct_size_exceeds_gprs_p (s, NULL, &nfp))
419
    return 0;
420
 
421
  return 1;
422
}
423
 
424
void
425
darwin64_pass_struct_floats (ffi_type *s, char *src,
426
                             unsigned *nfpr, double **fprs)
427
{
428
  int i;
429
  double *fpr_base = *fprs;
430
  unsigned struct_offset = 0;
431
 
432
  /* We don't assume anything about the alignment of the source.  */
433
  for (i = 0; s->elements[i] != NULL; i++)
434
    {
435
      char *item_base;
436
      ffi_type *p = s->elements[i];
437
      /* Find the start of this item (0 for the first one).  */
438
      if (i > 0)
439
        struct_offset = ALIGN(struct_offset, p->alignment);
440
      item_base = src + struct_offset;
441
 
442
      switch (p->type)
443
        {
444
          case FFI_TYPE_STRUCT:
445
            darwin64_pass_struct_floats (p, item_base, nfpr,
446
                                           &fpr_base);
447
            break;
448
          case FFI_TYPE_LONGDOUBLE:
449
            if (*nfpr < NUM_FPR_ARG_REGISTERS)
450
              *fpr_base++ = *(double *)item_base;
451
            (*nfpr) += 1;
452
            item_base += 8;
453
          /* FALL THROUGH */
454
          case FFI_TYPE_DOUBLE:
455
            if (*nfpr < NUM_FPR_ARG_REGISTERS)
456
              *fpr_base++ = *(double *)item_base;
457
            (*nfpr) += 1;
458
            break;
459
          case FFI_TYPE_FLOAT:
460
            if (*nfpr < NUM_FPR_ARG_REGISTERS)
461
              *fpr_base++ = (double) *(float *)item_base;
462
            (*nfpr) += 1;
463
            break;
464
          default:
465
            break;
466
        }
467
      /* now count the size of what we just used.  */
468
      struct_offset += p->size;
469
    }
470
  /* Update the scores.  */
471
  *fprs = fpr_base;
472
}
473
 
474
/* Darwin64 special rules.
475
   Break out a struct into params and float registers.  */
476
static void
477
darwin64_pass_struct_by_value (ffi_type *s, char *src, unsigned size,
478
                               unsigned *nfpr, double **fprs, unsigned long **arg)
479
{
480
  unsigned long *next_arg = *arg;
481
  char *dest_cpy = (char *)next_arg;
482
 
483
  FFI_ASSERT (s->type == FFI_TYPE_STRUCT)
484
 
485
  if (!size)
486
    return;
487
 
488
  /* First... special cases.  */
489
  if (size < 3
490
      || (size == 4
491
          && s->elements[0]
492
          && s->elements[0]->type != FFI_TYPE_FLOAT))
493
    {
494
      /* Must be at least one GPR, padding is unspecified in value,
495
         let's make it zero.  */
496
      *next_arg = 0UL;
497
      dest_cpy += 8 - size;
498
      memcpy ((char *) dest_cpy, src, size);
499
      next_arg++;
500
    }
501
  else if (size == 16)
502
    {
503
      memcpy ((char *) dest_cpy, src, size);
504
      next_arg += 2;
505
    }
506
  else
507
    {
508
      /* now the general case, we consider embedded floats.  */
509
      memcpy ((char *) dest_cpy, src, size);
510
      darwin64_pass_struct_floats (s, src, nfpr, fprs);
511
      next_arg += (size+7)/8;
512
    }
513
 
514
  *arg = next_arg;
515
}
516
 
517
double *
518
darwin64_struct_floats_to_mem (ffi_type *s, char *dest, double *fprs, unsigned *nf)
519
{
520
  int i;
521
  unsigned struct_offset = 0;
522
 
523
  /* We don't assume anything about the alignment of the source.  */
524
  for (i = 0; s->elements[i] != NULL; i++)
525
    {
526
      char *item_base;
527
      ffi_type *p = s->elements[i];
528
      /* Find the start of this item (0 for the first one).  */
529
      if (i > 0)
530
        struct_offset = ALIGN(struct_offset, p->alignment);
531
      item_base = dest + struct_offset;
532
 
533
      switch (p->type)
534
        {
535
          case FFI_TYPE_STRUCT:
536
            fprs = darwin64_struct_floats_to_mem (p, item_base, fprs, nf);
537
            break;
538
          case FFI_TYPE_LONGDOUBLE:
539
            if (*nf < NUM_FPR_ARG_REGISTERS)
540
              {
541
                *(double *)item_base = *fprs++ ;
542
                (*nf) += 1;
543
              }
544
            item_base += 8;
545
          /* FALL THROUGH */
546
          case FFI_TYPE_DOUBLE:
547
            if (*nf < NUM_FPR_ARG_REGISTERS)
548
              {
549
                *(double *)item_base = *fprs++ ;
550
                (*nf) += 1;
551
              }
552
            break;
553
          case FFI_TYPE_FLOAT:
554
            if (*nf < NUM_FPR_ARG_REGISTERS)
555
              {
556
                *(float *)item_base = (float) *fprs++ ;
557
                (*nf) += 1;
558
              }
559
            break;
560
          default:
561
            break;
562
        }
563
      /* now count the size of what we just used.  */
564
      struct_offset += p->size;
565
    }
566
  return fprs;
567
}
568
 
569
#endif
570
 
571
/* Adjust the size of S to be correct for Darwin.
572
   On Darwin m32, the first field of a structure has natural alignment.
573
   On Darwin m64, all fields have natural alignment.  */
574
 
575
static void
576
darwin_adjust_aggregate_sizes (ffi_type *s)
577
{
578
  int i;
579
 
580
  if (s->type != FFI_TYPE_STRUCT)
581
    return;
582
 
583
  s->size = 0;
584
  for (i = 0; s->elements[i] != NULL; i++)
585
    {
586
      ffi_type *p;
587
      int align;
588
 
589
      p = s->elements[i];
590
      if (p->type == FFI_TYPE_STRUCT)
591
        darwin_adjust_aggregate_sizes (p);
592
#if defined(POWERPC_DARWIN64)
593
      /* Natural alignment for all items.  */
594
      align = p->alignment;
595
#else
596
      /* Natrual alignment for the first item... */
597
      if (i == 0)
598
        align = p->alignment;
599
      else if (p->alignment == 16 || p->alignment < 4)
600
        /* .. subsequent items with vector or align < 4 have natural align.  */
601
        align = p->alignment;
602
      else
603
        /* .. or align is 4.  */
604
        align = 4;
605
#endif
606
      /* Pad, if necessary, before adding the current item.  */
607
      s->size = ALIGN(s->size, align) + p->size;
608
    }
609
 
610
  s->size = ALIGN(s->size, s->alignment);
611
 
612
  /* This should not be necessary on m64, but harmless.  */
613
  if (s->elements[0]->type == FFI_TYPE_UINT64
614
      || s->elements[0]->type == FFI_TYPE_SINT64
615
      || s->elements[0]->type == FFI_TYPE_DOUBLE
616
      || s->elements[0]->alignment == 8)
617
    s->alignment = s->alignment > 8 ? s->alignment : 8;
618
  /* Do not add additional tail padding.  */
619
}
620
 
621
/* Adjust the size of S to be correct for AIX.
622
   Word-align double unless it is the first member of a structure.  */
623
 
624
static void
625
aix_adjust_aggregate_sizes (ffi_type *s)
626
{
627
  int i;
628
 
629
  if (s->type != FFI_TYPE_STRUCT)
630
    return;
631
 
632
  s->size = 0;
633
  for (i = 0; s->elements[i] != NULL; i++)
634
    {
635
      ffi_type *p;
636
      int align;
637
 
638
      p = s->elements[i];
639
      aix_adjust_aggregate_sizes (p);
640
      align = p->alignment;
641
      if (i != 0 && p->type == FFI_TYPE_DOUBLE)
642
        align = 4;
643
      s->size = ALIGN(s->size, align) + p->size;
644
    }
645
 
646
  s->size = ALIGN(s->size, s->alignment);
647
 
648
  if (s->elements[0]->type == FFI_TYPE_UINT64
649
      || s->elements[0]->type == FFI_TYPE_SINT64
650
      || s->elements[0]->type == FFI_TYPE_DOUBLE
651
      || s->elements[0]->alignment == 8)
652
    s->alignment = s->alignment > 8 ? s->alignment : 8;
653
  /* Do not add additional tail padding.  */
654
}
655
 
656
/* Perform machine dependent cif processing.  */
657
ffi_status
658
ffi_prep_cif_machdep (ffi_cif *cif)
659
{
660
  /* All this is for the DARWIN ABI.  */
661
  unsigned i;
662
  ffi_type **ptr;
663
  unsigned bytes;
664
  unsigned fparg_count = 0, intarg_count = 0;
665
  unsigned flags = 0;
666
  unsigned size_al = 0;
667
 
668
  /* All the machine-independent calculation of cif->bytes will be wrong.
669
     All the calculation of structure sizes will also be wrong.
670
     Redo the calculation for DARWIN.  */
671
 
672
  if (cif->abi == FFI_DARWIN)
673
    {
674
      darwin_adjust_aggregate_sizes (cif->rtype);
675
      for (i = 0; i < cif->nargs; i++)
676
        darwin_adjust_aggregate_sizes (cif->arg_types[i]);
677
    }
678
 
679
  if (cif->abi == FFI_AIX)
680
    {
681
      aix_adjust_aggregate_sizes (cif->rtype);
682
      for (i = 0; i < cif->nargs; i++)
683
        aix_adjust_aggregate_sizes (cif->arg_types[i]);
684
    }
685
 
686
  /* Space for the frame pointer, callee's LR, CR, etc, and for
687
     the asm's temp regs.  */
688
 
689
  bytes = (LINKAGE_AREA_GPRS + ASM_NEEDS_REGISTERS) * sizeof(unsigned long);
690
 
691
  /* Return value handling.
692
    The rules m32 are as follows:
693
     - 32-bit (or less) integer values are returned in gpr3;
694
     - structures of size <= 4 bytes also returned in gpr3;
695
     - 64-bit integer values [??? and structures between 5 and 8 bytes] are
696
       returned in gpr3 and gpr4;
697
     - Single/double FP values are returned in fpr1;
698
     - Long double FP (if not equivalent to double) values are returned in
699
       fpr1 and fpr2;
700
     m64:
701
     - 64-bit or smaller integral values are returned in GPR3
702
     - Single/double FP values are returned in fpr1;
703
     - Long double FP values are returned in fpr1 and fpr2;
704
     m64 Structures:
705
     - If the structure could be accommodated in registers were it to be the
706
       first argument to a routine, then it is returned in those registers.
707
     m32/m64 structures otherwise:
708
     - Larger structures values are allocated space and a pointer is passed
709
       as the first argument.  */
710
  switch (cif->rtype->type)
711
    {
712
 
713
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
714
    case FFI_TYPE_LONGDOUBLE:
715
      flags |= FLAG_RETURNS_128BITS;
716
      flags |= FLAG_RETURNS_FP;
717
      break;
718
#endif
719
 
720
    case FFI_TYPE_DOUBLE:
721
      flags |= FLAG_RETURNS_64BITS;
722
      /* Fall through.  */
723
    case FFI_TYPE_FLOAT:
724
      flags |= FLAG_RETURNS_FP;
725
      break;
726
 
727
    case FFI_TYPE_UINT64:
728
    case FFI_TYPE_SINT64:
729
#ifdef POWERPC64
730
    case FFI_TYPE_POINTER:
731
#endif
732
      flags |= FLAG_RETURNS_64BITS;
733
      break;
734
 
735
    case FFI_TYPE_STRUCT:
736
#if defined(POWERPC_DARWIN64)
737
      {
738
        /* Can we fit the struct into regs?  */
739
        if (darwin64_struct_ret_by_value_p (cif->rtype))
740
          {
741
            unsigned nfpr = 0;
742
            flags |= FLAG_RETURNS_STRUCT;
743
            if (cif->rtype->size != 16)
744
              darwin64_scan_struct_for_floats (cif->rtype, &nfpr) ;
745
            else
746
              flags |= FLAG_RETURNS_128BITS;
747
            /* Will be 0 for 16byte struct.  */
748
            if (nfpr)
749
              flags |= FLAG_RETURNS_FP;
750
          }
751
        else /* By ref. */
752
          {
753
            flags |= FLAG_RETVAL_REFERENCE;
754
            flags |= FLAG_RETURNS_NOTHING;
755
            intarg_count++;
756
          }
757
      }
758
#elif defined(DARWIN_PPC)
759
      if (cif->rtype->size <= 4)
760
        flags |= FLAG_RETURNS_STRUCT;
761
      else /* else by reference.  */
762
        {
763
          flags |= FLAG_RETVAL_REFERENCE;
764
          flags |= FLAG_RETURNS_NOTHING;
765
          intarg_count++;
766
        }
767
#else /* assume we pass by ref.  */
768
      flags |= FLAG_RETVAL_REFERENCE;
769
      flags |= FLAG_RETURNS_NOTHING;
770
      intarg_count++;
771
#endif
772
      break;
773
    case FFI_TYPE_VOID:
774
      flags |= FLAG_RETURNS_NOTHING;
775
      break;
776
 
777
    default:
778
      /* Returns 32-bit integer, or similar.  Nothing to do here.  */
779
      break;
780
    }
781
 
782
  /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
783
     first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
784
     goes on the stack.
785
     ??? Structures are passed as a pointer to a copy of the structure.
786
     Stuff on the stack needs to keep proper alignment.
787
     For m64 the count is effectively of half-GPRs.  */
788
  for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
789
    {
790
      unsigned align_words;
791
      switch ((*ptr)->type)
792
        {
793
        case FFI_TYPE_FLOAT:
794
        case FFI_TYPE_DOUBLE:
795
          fparg_count++;
796
#if !defined(POWERPC_DARWIN64)
797
          /* If this FP arg is going on the stack, it must be
798
             8-byte-aligned.  */
799
          if (fparg_count > NUM_FPR_ARG_REGISTERS
800
              && (intarg_count & 0x01) != 0)
801
            intarg_count++;
802
#endif
803
          break;
804
 
805
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
806
        case FFI_TYPE_LONGDOUBLE:
807
          fparg_count += 2;
808
          /* If this FP arg is going on the stack, it must be
809
             16-byte-aligned.  */
810
          if (fparg_count >= NUM_FPR_ARG_REGISTERS)
811
#if defined (POWERPC64)
812
            intarg_count = ALIGN(intarg_count, 2);
813
#else
814
            intarg_count = ALIGN(intarg_count, 4);
815
#endif
816
          break;
817
#endif
818
 
819
        case FFI_TYPE_UINT64:
820
        case FFI_TYPE_SINT64:
821
#if defined(POWERPC64)
822
          intarg_count++;
823
#else
824
          /* 'long long' arguments are passed as two words, but
825
             either both words must fit in registers or both go
826
             on the stack.  If they go on the stack, they must
827
             be 8-byte-aligned.  */
828
          if (intarg_count == NUM_GPR_ARG_REGISTERS-1
829
              || (intarg_count >= NUM_GPR_ARG_REGISTERS
830
                  && (intarg_count & 0x01) != 0))
831
            intarg_count++;
832
          intarg_count += 2;
833
#endif
834
          break;
835
 
836
        case FFI_TYPE_STRUCT:
837
          size_al = (*ptr)->size;
838
#if defined(POWERPC_DARWIN64)
839
          align_words = (*ptr)->alignment >> 3;
840
          if (align_words)
841
            intarg_count = ALIGN(intarg_count, align_words);
842
          /* Base size of the struct.  */
843
          intarg_count += (size_al + 7) / 8;
844
          /* If 16 bytes then don't worry about floats.  */
845
          if (size_al != 16)
846
            /* Scan through for floats to be placed in regs.  */
847
            darwin64_scan_struct_for_floats (*ptr, &fparg_count) ;
848
#else
849
          align_words = (*ptr)->alignment >> 2;
850
          if (align_words)
851
            intarg_count = ALIGN(intarg_count, align_words);
852
          /* If the first member of the struct is a double, then align
853
             the struct to double-word.
854
          if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE)
855
            size_al = ALIGN((*ptr)->size, 8); */
856
#  ifdef POWERPC64
857
          intarg_count += (size_al + 7) / 8;
858
#  else
859
          intarg_count += (size_al + 3) / 4;
860
#  endif
861
#endif
862
          break;
863
 
864
        default:
865
          /* Everything else is passed as a 4-byte word in a GPR, either
866
             the object itself or a pointer to it.  */
867
          intarg_count++;
868
          break;
869
        }
870
    }
871
 
872
  if (fparg_count != 0)
873
    flags |= FLAG_FP_ARGUMENTS;
874
 
875
#if defined(POWERPC_DARWIN64)
876
  /* Space to image the FPR registers, if needed - which includes when they might be
877
     used in a struct return.  */
878
  if (fparg_count != 0
879
      || ((flags & FLAG_RETURNS_STRUCT)
880
           && (flags & FLAG_RETURNS_FP)))
881
    bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
882
#else
883
  /* Space for the FPR registers, if needed.  */
884
  if (fparg_count != 0)
885
    bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
886
#endif
887
 
888
  /* Stack space.  */
889
#ifdef POWERPC64
890
  if ((intarg_count + fparg_count) > NUM_GPR_ARG_REGISTERS)
891
    bytes += (intarg_count + fparg_count) * sizeof(long);
892
#else
893
  if ((intarg_count + 2 * fparg_count) > NUM_GPR_ARG_REGISTERS)
894
    bytes += (intarg_count + 2 * fparg_count) * sizeof(long);
895
#endif
896
  else
897
    bytes += NUM_GPR_ARG_REGISTERS * sizeof(long);
898
 
899
  /* The stack space allocated needs to be a multiple of 16 bytes.  */
900
  bytes = ALIGN(bytes, 16) ;
901
 
902
  cif->flags = flags;
903
  cif->bytes = bytes;
904
 
905
  return FFI_OK;
906
}
907
 
908
extern void ffi_call_AIX(extended_cif *, long, unsigned, unsigned *,
909
                         void (*fn)(void), void (*fn2)(void));
910
 
911
extern void ffi_call_DARWIN(extended_cif *, long, unsigned, unsigned *,
912
                            void (*fn)(void), void (*fn2)(void), ffi_type*);
913
 
914
void
915
ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
916
{
917
  extended_cif ecif;
918
 
919
  ecif.cif = cif;
920
  ecif.avalue = avalue;
921
 
922
  /* If the return value is a struct and we don't have a return
923
     value address then we need to make one.  */
924
 
925
  if ((rvalue == NULL) &&
926
      (cif->rtype->type == FFI_TYPE_STRUCT))
927
    {
928
      ecif.rvalue = alloca (cif->rtype->size);
929
    }
930
  else
931
    ecif.rvalue = rvalue;
932
 
933
  switch (cif->abi)
934
    {
935
    case FFI_AIX:
936
      ffi_call_AIX(&ecif, -(long)cif->bytes, cif->flags, ecif.rvalue, fn,
937
                   FFI_FN(ffi_prep_args));
938
      break;
939
    case FFI_DARWIN:
940
      ffi_call_DARWIN(&ecif, -(long)cif->bytes, cif->flags, ecif.rvalue, fn,
941
                      FFI_FN(ffi_prep_args), cif->rtype);
942
      break;
943
    default:
944
      FFI_ASSERT(0);
945
      break;
946
    }
947
}
948
 
949
static void flush_icache(char *);
950
static void flush_range(char *, int);
951
 
952
/* The layout of a function descriptor.  A C function pointer really
953
   points to one of these.  */
954
 
955
typedef struct aix_fd_struct {
956
  void *code_pointer;
957
  void *toc;
958
} aix_fd;
959
 
960
/* here I'd like to add the stack frame layout we use in darwin_closure.S
961
   and aix_closure.S
962
 
963
   m32/m64
964
 
965
   The stack layout looks like this:
966
 
967
   |   Additional params...                     | |     Higher address
968
   ~                                            ~ ~
969
   |   Parameters      (at least 8*4/8=32/64)   | | NUM_GPR_ARG_REGISTERS
970
   |--------------------------------------------| |
971
   |   TOC=R2 (AIX) Reserved (Darwin)   4/8     | |
972
   |--------------------------------------------| |
973
   |   Reserved                       2*4/8     | |
974
   |--------------------------------------------| |
975
   |   Space for callee's LR            4/8     | |
976
   |--------------------------------------------| |
977
   |   Saved CR [low word for m64]      4/8     | |
978
   |--------------------------------------------| |
979
   |   Current backchain pointer        4/8     |-/ Parent's frame.
980
   |--------------------------------------------| <+ <<< on entry to ffi_closure_ASM
981
   |   Result Bytes                     16      | |
982
   |--------------------------------------------| |
983
   ~   padding to 16-byte alignment             ~ ~
984
   |--------------------------------------------| |
985
   |   NUM_FPR_ARG_REGISTERS slots              | |
986
   |   here fp13 .. fp1                13*8     | |
987
   |--------------------------------------------| |
988
   |   R3..R10                    8*4/8=32/64   | | NUM_GPR_ARG_REGISTERS
989
   |--------------------------------------------| |
990
   |   TOC=R2 (AIX) Reserved (Darwin)   4/8     | |
991
   |--------------------------------------------| |     stack   |
992
   |   Reserved [compiler,binder]     2*4/8     | |     grows   |
993
   |--------------------------------------------| |     down    V
994
   |   Space for callee's LR            4/8     | |
995
   |--------------------------------------------| |     lower addresses
996
   |   Saved CR [low word for m64]      4/8     | |
997
   |--------------------------------------------| |     stack pointer here
998
   |   Current backchain pointer        4/8     |-/     during
999
   |--------------------------------------------|   <<< ffi_closure_ASM.
1000
 
1001
*/
1002
 
1003
ffi_status
1004
ffi_prep_closure_loc (ffi_closure* closure,
1005
                      ffi_cif* cif,
1006
                      void (*fun)(ffi_cif*, void*, void**, void*),
1007
                      void *user_data,
1008
                      void *codeloc)
1009
{
1010
  unsigned int *tramp;
1011
  struct ffi_aix_trampoline_struct *tramp_aix;
1012
  aix_fd *fd;
1013
 
1014
  switch (cif->abi)
1015
    {
1016
      case FFI_DARWIN:
1017
 
1018
        FFI_ASSERT (cif->abi == FFI_DARWIN);
1019
 
1020
        tramp = (unsigned int *) &closure->tramp[0];
1021
#if defined(POWERPC_DARWIN64)
1022
        tramp[0] = 0x7c0802a6;  /*   mflr    r0  */
1023
        tramp[1] = 0x429f0015;  /*   bcl-    20,4*cr7+so,  +0x18 (L1)  */
1024
        /* We put the addresses here.  */
1025
        tramp[6] = 0x7d6802a6;  /*L1:   mflr    r11  */
1026
        tramp[7] = 0xe98b0000;  /*   ld     r12,0(r11) function address  */
1027
        tramp[8] = 0x7c0803a6;  /*   mtlr    r0   */
1028
        tramp[9] = 0x7d8903a6;  /*   mtctr   r12  */
1029
        tramp[10] = 0xe96b0008;  /*   lwz     r11,8(r11) static chain  */
1030
        tramp[11] = 0x4e800420;  /*   bctr  */
1031
 
1032
        *((unsigned long *)&tramp[2]) = (unsigned long) ffi_closure_ASM; /* function  */
1033
        *((unsigned long *)&tramp[4]) = (unsigned long) codeloc; /* context  */
1034
#else
1035
        tramp[0] = 0x7c0802a6;  /*   mflr    r0  */
1036
        tramp[1] = 0x429f000d;  /*   bcl-    20,4*cr7+so,0x10  */
1037
        tramp[4] = 0x7d6802a6;  /*   mflr    r11  */
1038
        tramp[5] = 0x818b0000;  /*   lwz     r12,0(r11) function address  */
1039
        tramp[6] = 0x7c0803a6;  /*   mtlr    r0   */
1040
        tramp[7] = 0x7d8903a6;  /*   mtctr   r12  */
1041
        tramp[8] = 0x816b0004;  /*   lwz     r11,4(r11) static chain  */
1042
        tramp[9] = 0x4e800420;  /*   bctr  */
1043
        tramp[2] = (unsigned long) ffi_closure_ASM; /* function  */
1044
        tramp[3] = (unsigned long) codeloc; /* context  */
1045
#endif
1046
        closure->cif = cif;
1047
        closure->fun = fun;
1048
        closure->user_data = user_data;
1049
 
1050
        /* Flush the icache. Only necessary on Darwin.  */
1051
        flush_range(codeloc, FFI_TRAMPOLINE_SIZE);
1052
 
1053
        break;
1054
 
1055
    case FFI_AIX:
1056
 
1057
      tramp_aix = (struct ffi_aix_trampoline_struct *) (closure->tramp);
1058
      fd = (aix_fd *)(void *)ffi_closure_ASM;
1059
 
1060
      FFI_ASSERT (cif->abi == FFI_AIX);
1061
 
1062
      tramp_aix->code_pointer = fd->code_pointer;
1063
      tramp_aix->toc = fd->toc;
1064
      tramp_aix->static_chain = codeloc;
1065
      closure->cif = cif;
1066
      closure->fun = fun;
1067
      closure->user_data = user_data;
1068
 
1069
    default:
1070
 
1071
      FFI_ASSERT(0);
1072
      break;
1073
    }
1074
  return FFI_OK;
1075
}
1076
 
1077
static void
1078
flush_icache(char *addr)
1079
{
1080
#ifndef _AIX
1081
  __asm__ volatile (
1082
                "dcbf 0,%0\n"
1083
                "\tsync\n"
1084
                "\ticbi 0,%0\n"
1085
                "\tsync\n"
1086
                "\tisync"
1087
                : : "r"(addr) : "memory");
1088
#endif
1089
}
1090
 
1091
static void
1092
flush_range(char * addr1, int size)
1093
{
1094
#define MIN_LINE_SIZE 32
1095
  int i;
1096
  for (i = 0; i < size; i += MIN_LINE_SIZE)
1097
    flush_icache(addr1+i);
1098
  flush_icache(addr1+size-1);
1099
}
1100
 
1101
typedef union
1102
{
1103
  float f;
1104
  double d;
1105
} ffi_dblfl;
1106
 
1107
ffi_type *
1108
ffi_closure_helper_DARWIN (ffi_closure *, void *,
1109
                           unsigned long *, ffi_dblfl *);
1110
 
1111
/* Basically the trampoline invokes ffi_closure_ASM, and on
1112
   entry, r11 holds the address of the closure.
1113
   After storing the registers that could possibly contain
1114
   parameters to be passed into the stack frame and setting
1115
   up space for a return value, ffi_closure_ASM invokes the
1116
   following helper function to do most of the work.  */
1117
 
1118
ffi_type *
1119
ffi_closure_helper_DARWIN (ffi_closure *closure, void *rvalue,
1120
                           unsigned long *pgr, ffi_dblfl *pfr)
1121
{
1122
  /* rvalue is the pointer to space for return value in closure assembly
1123
     pgr is the pointer to where r3-r10 are stored in ffi_closure_ASM
1124
     pfr is the pointer to where f1-f13 are stored in ffi_closure_ASM.  */
1125
 
1126
  typedef double ldbits[2];
1127
 
1128
  union ldu
1129
  {
1130
    ldbits lb;
1131
    long double ld;
1132
  };
1133
 
1134
  void **          avalue;
1135
  ffi_type **      arg_types;
1136
  long             i, avn;
1137
  ffi_cif *        cif;
1138
  ffi_dblfl *      end_pfr = pfr + NUM_FPR_ARG_REGISTERS;
1139
  unsigned         size_al;
1140
#if defined(POWERPC_DARWIN64)
1141
  unsigned         fpsused = 0;
1142
#endif
1143
 
1144
  cif = closure->cif;
1145
  avalue = alloca (cif->nargs * sizeof(void *));
1146
 
1147
  if (cif->rtype->type == FFI_TYPE_STRUCT)
1148
    {
1149
#if defined(POWERPC_DARWIN64)
1150
      if (!darwin64_struct_ret_by_value_p (cif->rtype))
1151
        {
1152
          /* Won't fit into the regs - return by ref.  */
1153
          rvalue = (void *) *pgr;
1154
          pgr++;
1155
        }
1156
#elif defined(DARWIN_PPC)
1157
      if (cif->rtype->size > 4)
1158
        {
1159
          rvalue = (void *) *pgr;
1160
          pgr++;
1161
        }
1162
#else /* assume we return by ref.  */
1163
      rvalue = (void *) *pgr;
1164
      pgr++;
1165
#endif
1166
    }
1167
 
1168
  i = 0;
1169
  avn = cif->nargs;
1170
  arg_types = cif->arg_types;
1171
 
1172
  /* Grab the addresses of the arguments from the stack frame.  */
1173
  while (i < avn)
1174
    {
1175
      switch (arg_types[i]->type)
1176
        {
1177
        case FFI_TYPE_SINT8:
1178
        case FFI_TYPE_UINT8:
1179
#if  defined(POWERPC64)
1180
          avalue[i] = (char *) pgr + 7;
1181
#else
1182
          avalue[i] = (char *) pgr + 3;
1183
#endif
1184
          pgr++;
1185
          break;
1186
 
1187
        case FFI_TYPE_SINT16:
1188
        case FFI_TYPE_UINT16:
1189
#if  defined(POWERPC64)
1190
          avalue[i] = (char *) pgr + 6;
1191
#else
1192
          avalue[i] = (char *) pgr + 2;
1193
#endif
1194
          pgr++;
1195
          break;
1196
 
1197
        case FFI_TYPE_SINT32:
1198
        case FFI_TYPE_UINT32:
1199
#if  defined(POWERPC64)
1200
          avalue[i] = (char *) pgr + 4;
1201
#else
1202
        case FFI_TYPE_POINTER:
1203
          avalue[i] = pgr;
1204
#endif
1205
          pgr++;
1206
          break;
1207
 
1208
        case FFI_TYPE_STRUCT:
1209
          size_al = arg_types[i]->size;
1210
#if defined(POWERPC_DARWIN64)
1211
          pgr = (unsigned long *)ALIGN((char *)pgr, arg_types[i]->alignment);
1212
          if (size_al < 3 || size_al == 4)
1213
            {
1214
              avalue[i] = ((char *)pgr)+8-size_al;
1215
              if (arg_types[i]->elements[0]->type == FFI_TYPE_FLOAT
1216
                  && fpsused < NUM_FPR_ARG_REGISTERS)
1217
                {
1218
                  *(float *)pgr = (float) *(double *)pfr;
1219
                  pfr++;
1220
                  fpsused++;
1221
                }
1222
            }
1223
          else
1224
            {
1225
              if (size_al != 16)
1226
                pfr = (ffi_dblfl *)
1227
                    darwin64_struct_floats_to_mem (arg_types[i], (char *)pgr,
1228
                                                   (double *)pfr, &fpsused);
1229
              avalue[i] = pgr;
1230
            }
1231
          pgr += (size_al + 7) / 8;
1232
#else
1233
          /* If the first member of the struct is a double, then align
1234
             the struct to double-word.  */
1235
          if (arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE)
1236
            size_al = ALIGN(arg_types[i]->size, 8);
1237
#  if defined(POWERPC64)
1238
          FFI_ASSERT (cif->abi != FFI_DARWIN)
1239
          avalue[i] = pgr;
1240
          pgr += (size_al + 7) / 8;
1241
#  else
1242
          /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
1243
             SI 4 bytes) are aligned as if they were those modes.  */
1244
          if (size_al < 3 && cif->abi == FFI_DARWIN)
1245
            avalue[i] = (char*) pgr + 4 - size_al;
1246
          else
1247
            avalue[i] = pgr;
1248
          pgr += (size_al + 3) / 4;
1249
#  endif
1250
#endif
1251
          break;
1252
 
1253
        case FFI_TYPE_SINT64:
1254
        case FFI_TYPE_UINT64:
1255
#if  defined(POWERPC64)
1256
        case FFI_TYPE_POINTER:
1257
          avalue[i] = pgr;
1258
          pgr++;
1259
          break;
1260
#else
1261
          /* Long long ints are passed in two gpr's.  */
1262
          avalue[i] = pgr;
1263
          pgr += 2;
1264
          break;
1265
#endif
1266
 
1267
        case FFI_TYPE_FLOAT:
1268
          /* A float value consumes a GPR.
1269
             There are 13 64bit floating point registers.  */
1270
          if (pfr < end_pfr)
1271
            {
1272
              double temp = pfr->d;
1273
              pfr->f = (float) temp;
1274
              avalue[i] = pfr;
1275
              pfr++;
1276
            }
1277
          else
1278
            {
1279
              avalue[i] = pgr;
1280
            }
1281
          pgr++;
1282
          break;
1283
 
1284
        case FFI_TYPE_DOUBLE:
1285
          /* A double value consumes two GPRs.
1286
             There are 13 64bit floating point registers.  */
1287
          if (pfr < end_pfr)
1288
            {
1289
              avalue[i] = pfr;
1290
              pfr++;
1291
            }
1292
          else
1293
            {
1294
              avalue[i] = pgr;
1295
            }
1296
#ifdef POWERPC64
1297
          pgr++;
1298
#else
1299
          pgr += 2;
1300
#endif
1301
          break;
1302
 
1303
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1304
 
1305
        case FFI_TYPE_LONGDOUBLE:
1306
#ifdef POWERPC64
1307
          if (pfr + 1 < end_pfr)
1308
            {
1309
              avalue[i] = pfr;
1310
              pfr += 2;
1311
            }
1312
          else
1313
            {
1314
              if (pfr < end_pfr)
1315
                {
1316
                  *pgr = *(unsigned long *) pfr;
1317
                  pfr++;
1318
                }
1319
              avalue[i] = pgr;
1320
            }
1321
          pgr += 2;
1322
#else  /* POWERPC64 */
1323
          /* A long double value consumes four GPRs and two FPRs.
1324
             There are 13 64bit floating point registers.  */
1325
          if (pfr + 1 < end_pfr)
1326
            {
1327
              avalue[i] = pfr;
1328
              pfr += 2;
1329
            }
1330
          /* Here we have the situation where one part of the long double
1331
             is stored in fpr13 and the other part is already on the stack.
1332
             We use a union to pass the long double to avalue[i].  */
1333
          else if (pfr + 1 == end_pfr)
1334
            {
1335
              union ldu temp_ld;
1336
              memcpy (&temp_ld.lb[0], pfr, sizeof(ldbits));
1337
              memcpy (&temp_ld.lb[1], pgr + 2, sizeof(ldbits));
1338
              avalue[i] = &temp_ld.ld;
1339
              pfr++;
1340
            }
1341
          else
1342
            {
1343
              avalue[i] = pgr;
1344
            }
1345
          pgr += 4;
1346
#endif  /* POWERPC64 */
1347
          break;
1348
#endif
1349
        default:
1350
          FFI_ASSERT(0);
1351
        }
1352
      i++;
1353
    }
1354
 
1355
  (closure->fun) (cif, rvalue, avalue, closure->user_data);
1356
 
1357
  /* Tell ffi_closure_ASM to perform return type promotions.  */
1358
  return cif->rtype;
1359
}

powered by: WebSVN 2.1.0

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