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

« back to all changes in this revision

Viewing changes to Modules/_ctypes/libffi/src/sparc/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) 1996, 2003, 2004, 2007, 2008 Red Hat, Inc.
 
3
   
 
4
   SPARC Foreign Function Interface 
 
5
 
 
6
   Permission is hereby granted, free of charge, to any person obtaining
 
7
   a copy of this software and associated documentation files (the
 
8
   ``Software''), to deal in the Software without restriction, including
 
9
   without limitation the rights to use, copy, modify, merge, publish,
 
10
   distribute, sublicense, and/or sell copies of the Software, and to
 
11
   permit persons to whom the Software is furnished to do so, subject to
 
12
   the following conditions:
 
13
 
 
14
   The above copyright notice and this permission notice shall be included
 
15
   in all copies or substantial portions of the Software.
 
16
 
 
17
   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
 
18
   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
19
   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 
20
   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 
21
   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 
22
   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
23
   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
24
   DEALINGS IN THE SOFTWARE.
 
25
   ----------------------------------------------------------------------- */
 
26
 
 
27
#include <ffi.h>
 
28
#include <ffi_common.h>
 
29
 
 
30
#include <stdlib.h>
 
31
 
 
32
 
 
33
/* ffi_prep_args is called by the assembly routine once stack space
 
34
   has been allocated for the function's arguments */
 
35
 
 
36
void ffi_prep_args_v8(char *stack, extended_cif *ecif)
 
37
{
 
38
  int i;
 
39
  void **p_argv;
 
40
  char *argp;
 
41
  ffi_type **p_arg;
 
42
 
 
43
  /* Skip 16 words for the window save area */
 
44
  argp = stack + 16*sizeof(int);
 
45
 
 
46
  /* This should only really be done when we are returning a structure,
 
47
     however, it's faster just to do it all the time...
 
48
 
 
49
  if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) */
 
50
  *(int *) argp = (long)ecif->rvalue;
 
51
 
 
52
  /* And 1 word for the  structure return value. */
 
53
  argp += sizeof(int);
 
54
 
 
55
#ifdef USING_PURIFY
 
56
  /* Purify will probably complain in our assembly routine, unless we
 
57
     zero out this memory. */
 
58
 
 
59
  ((int*)argp)[0] = 0;
 
60
  ((int*)argp)[1] = 0;
 
61
  ((int*)argp)[2] = 0;
 
62
  ((int*)argp)[3] = 0;
 
63
  ((int*)argp)[4] = 0;
 
64
  ((int*)argp)[5] = 0;
 
65
#endif
 
66
 
 
67
  p_argv = ecif->avalue;
 
68
 
 
69
  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++)
 
70
    {
 
71
      size_t z;
 
72
 
 
73
          if ((*p_arg)->type == FFI_TYPE_STRUCT
 
74
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
75
              || (*p_arg)->type == FFI_TYPE_LONGDOUBLE
 
76
#endif
 
77
              )
 
78
            {
 
79
              *(unsigned int *) argp = (unsigned long)(* p_argv);
 
80
              z = sizeof(int);
 
81
            }
 
82
          else
 
83
            {
 
84
              z = (*p_arg)->size;
 
85
              if (z < sizeof(int))
 
86
                {
 
87
                  z = sizeof(int);
 
88
                  switch ((*p_arg)->type)
 
89
                    {
 
90
                    case FFI_TYPE_SINT8:
 
91
                      *(signed int *) argp = *(SINT8 *)(* p_argv);
 
92
                      break;
 
93
                      
 
94
                    case FFI_TYPE_UINT8:
 
95
                      *(unsigned int *) argp = *(UINT8 *)(* p_argv);
 
96
                      break;
 
97
                      
 
98
                    case FFI_TYPE_SINT16:
 
99
                      *(signed int *) argp = *(SINT16 *)(* p_argv);
 
100
                      break;
 
101
                      
 
102
                    case FFI_TYPE_UINT16:
 
103
                      *(unsigned int *) argp = *(UINT16 *)(* p_argv);
 
104
                      break;
 
105
 
 
106
                    default:
 
107
                      FFI_ASSERT(0);
 
108
                    }
 
109
                }
 
110
              else
 
111
                {
 
112
                  memcpy(argp, *p_argv, z);
 
113
                }
 
114
            }
 
115
          p_argv++;
 
116
          argp += z;
 
117
    }
 
118
  
 
119
  return;
 
120
}
 
121
 
 
122
int ffi_prep_args_v9(char *stack, extended_cif *ecif)
 
123
{
 
124
  int i, ret = 0;
 
125
  int tmp;
 
126
  void **p_argv;
 
127
  char *argp;
 
128
  ffi_type **p_arg;
 
129
 
 
130
  tmp = 0;
 
131
 
 
132
  /* Skip 16 words for the window save area */
 
133
  argp = stack + 16*sizeof(long long);
 
134
 
 
135
#ifdef USING_PURIFY
 
136
  /* Purify will probably complain in our assembly routine, unless we
 
137
     zero out this memory. */
 
138
 
 
139
  ((long long*)argp)[0] = 0;
 
140
  ((long long*)argp)[1] = 0;
 
141
  ((long long*)argp)[2] = 0;
 
142
  ((long long*)argp)[3] = 0;
 
143
  ((long long*)argp)[4] = 0;
 
144
  ((long long*)argp)[5] = 0;
 
145
#endif
 
146
 
 
147
  p_argv = ecif->avalue;
 
148
 
 
149
  if (ecif->cif->rtype->type == FFI_TYPE_STRUCT &&
 
150
      ecif->cif->rtype->size > 32)
 
151
    {
 
152
      *(unsigned long long *) argp = (unsigned long)ecif->rvalue;
 
153
      argp += sizeof(long long);
 
154
      tmp = 1;
 
155
    }
 
156
 
 
157
  for (i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs;
 
158
       i++, p_arg++)
 
159
    {
 
160
      size_t z;
 
161
 
 
162
      z = (*p_arg)->size;
 
163
      switch ((*p_arg)->type)
 
164
        {
 
165
        case FFI_TYPE_STRUCT:
 
166
          if (z > 16)
 
167
            {
 
168
              /* For structures larger than 16 bytes we pass reference.  */
 
169
              *(unsigned long long *) argp = (unsigned long)* p_argv;
 
170
              argp += sizeof(long long);
 
171
              tmp++;
 
172
              p_argv++;
 
173
              continue;
 
174
            }
 
175
          /* FALLTHROUGH */
 
176
        case FFI_TYPE_FLOAT:
 
177
        case FFI_TYPE_DOUBLE:
 
178
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
179
        case FFI_TYPE_LONGDOUBLE:
 
180
#endif
 
181
          ret = 1; /* We should promote into FP regs as well as integer.  */
 
182
          break;
 
183
        }
 
184
      if (z < sizeof(long long))
 
185
        {
 
186
          switch ((*p_arg)->type)
 
187
            {
 
188
            case FFI_TYPE_SINT8:
 
189
              *(signed long long *) argp = *(SINT8 *)(* p_argv);
 
190
              break;
 
191
 
 
192
            case FFI_TYPE_UINT8:
 
193
              *(unsigned long long *) argp = *(UINT8 *)(* p_argv);
 
194
              break;
 
195
 
 
196
            case FFI_TYPE_SINT16:
 
197
              *(signed long long *) argp = *(SINT16 *)(* p_argv);
 
198
              break;
 
199
 
 
200
            case FFI_TYPE_UINT16:
 
201
              *(unsigned long long *) argp = *(UINT16 *)(* p_argv);
 
202
              break;
 
203
 
 
204
            case FFI_TYPE_SINT32:
 
205
              *(signed long long *) argp = *(SINT32 *)(* p_argv);
 
206
              break;
 
207
 
 
208
            case FFI_TYPE_UINT32:
 
209
              *(unsigned long long *) argp = *(UINT32 *)(* p_argv);
 
210
              break;
 
211
 
 
212
            case FFI_TYPE_FLOAT:
 
213
              *(float *) (argp + 4) = *(FLOAT32 *)(* p_argv); /* Right justify */
 
214
              break;
 
215
 
 
216
            case FFI_TYPE_STRUCT:
 
217
              memcpy(argp, *p_argv, z);
 
218
              break;
 
219
 
 
220
            default:
 
221
              FFI_ASSERT(0);
 
222
            }
 
223
          z = sizeof(long long);
 
224
          tmp++;
 
225
        }
 
226
      else if (z == sizeof(long long))
 
227
        {
 
228
          memcpy(argp, *p_argv, z);
 
229
          z = sizeof(long long);
 
230
          tmp++;
 
231
        }
 
232
      else
 
233
        {
 
234
          if ((tmp & 1) && (*p_arg)->alignment > 8)
 
235
            {
 
236
              tmp++;
 
237
              argp += sizeof(long long);
 
238
            }
 
239
          memcpy(argp, *p_argv, z);
 
240
          z = 2 * sizeof(long long);
 
241
          tmp += 2;
 
242
        }
 
243
      p_argv++;
 
244
      argp += z;
 
245
    }
 
246
 
 
247
  return ret;
 
248
}
 
249
 
 
250
/* Perform machine dependent cif processing */
 
251
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
 
252
{
 
253
  int wordsize;
 
254
 
 
255
  if (cif->abi != FFI_V9)
 
256
    {
 
257
      wordsize = 4;
 
258
 
 
259
      /* If we are returning a struct, this will already have been added.
 
260
         Otherwise we need to add it because it's always got to be there! */
 
261
 
 
262
      if (cif->rtype->type != FFI_TYPE_STRUCT)
 
263
        cif->bytes += wordsize;
 
264
 
 
265
      /* sparc call frames require that space is allocated for 6 args,
 
266
         even if they aren't used. Make that space if necessary. */
 
267
  
 
268
      if (cif->bytes < 4*6+4)
 
269
        cif->bytes = 4*6+4;
 
270
    }
 
271
  else
 
272
    {
 
273
      wordsize = 8;
 
274
 
 
275
      /* sparc call frames require that space is allocated for 6 args,
 
276
         even if they aren't used. Make that space if necessary. */
 
277
  
 
278
      if (cif->bytes < 8*6)
 
279
        cif->bytes = 8*6;
 
280
    }
 
281
 
 
282
  /* Adjust cif->bytes. to include 16 words for the window save area,
 
283
     and maybe the struct/union return pointer area, */
 
284
 
 
285
  cif->bytes += 16 * wordsize;
 
286
 
 
287
  /* The stack must be 2 word aligned, so round bytes up
 
288
     appropriately. */
 
289
 
 
290
  cif->bytes = ALIGN(cif->bytes, 2 * wordsize);
 
291
 
 
292
  /* Set the return type flag */
 
293
  switch (cif->rtype->type)
 
294
    {
 
295
    case FFI_TYPE_VOID:
 
296
    case FFI_TYPE_FLOAT:
 
297
    case FFI_TYPE_DOUBLE:
 
298
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
299
    case FFI_TYPE_LONGDOUBLE:
 
300
#endif
 
301
      cif->flags = cif->rtype->type;
 
302
      break;
 
303
 
 
304
    case FFI_TYPE_STRUCT:
 
305
      if (cif->abi == FFI_V9 && cif->rtype->size > 32)
 
306
        cif->flags = FFI_TYPE_VOID;
 
307
      else
 
308
        cif->flags = FFI_TYPE_STRUCT;
 
309
      break;
 
310
 
 
311
    case FFI_TYPE_SINT64:
 
312
    case FFI_TYPE_UINT64:
 
313
      if (cif->abi != FFI_V9)
 
314
        {
 
315
          cif->flags = FFI_TYPE_SINT64;
 
316
          break;
 
317
        }
 
318
      /* FALLTHROUGH */
 
319
    default:
 
320
      cif->flags = FFI_TYPE_INT;
 
321
      break;
 
322
    }
 
323
  return FFI_OK;
 
324
}
 
325
 
 
326
int ffi_v9_layout_struct(ffi_type *arg, int off, char *ret, char *intg, char *flt)
 
327
{
 
328
  ffi_type **ptr = &arg->elements[0];
 
329
 
 
330
  while (*ptr != NULL)
 
331
    {
 
332
      if (off & ((*ptr)->alignment - 1))
 
333
        off = ALIGN(off, (*ptr)->alignment);
 
334
 
 
335
      switch ((*ptr)->type)
 
336
        {
 
337
        case FFI_TYPE_STRUCT:
 
338
          off = ffi_v9_layout_struct(*ptr, off, ret, intg, flt);
 
339
          off = ALIGN(off, FFI_SIZEOF_ARG);
 
340
          break;
 
341
        case FFI_TYPE_FLOAT:
 
342
        case FFI_TYPE_DOUBLE:
 
343
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
344
        case FFI_TYPE_LONGDOUBLE:
 
345
#endif
 
346
          memmove(ret + off, flt + off, (*ptr)->size);
 
347
          off += (*ptr)->size;
 
348
          break;
 
349
        default:
 
350
          memmove(ret + off, intg + off, (*ptr)->size);
 
351
          off += (*ptr)->size;
 
352
          break;
 
353
        }
 
354
      ptr++;
 
355
    }
 
356
  return off;
 
357
}
 
358
 
 
359
 
 
360
#ifdef SPARC64
 
361
extern int ffi_call_v9(void *, extended_cif *, unsigned, 
 
362
                       unsigned, unsigned *, void (*fn)(void));
 
363
#else
 
364
extern int ffi_call_v8(void *, extended_cif *, unsigned, 
 
365
                       unsigned, unsigned *, void (*fn)(void));
 
366
#endif
 
367
 
 
368
void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
 
369
{
 
370
  extended_cif ecif;
 
371
  void *rval = rvalue;
 
372
 
 
373
  ecif.cif = cif;
 
374
  ecif.avalue = avalue;
 
375
 
 
376
  /* If the return value is a struct and we don't have a return */
 
377
  /* value address then we need to make one                     */
 
378
 
 
379
  ecif.rvalue = rvalue;
 
380
  if (cif->rtype->type == FFI_TYPE_STRUCT)
 
381
    {
 
382
      if (cif->rtype->size <= 32)
 
383
        rval = alloca(64);
 
384
      else
 
385
        {
 
386
          rval = NULL;
 
387
          if (rvalue == NULL)
 
388
            ecif.rvalue = alloca(cif->rtype->size);
 
389
        }
 
390
    }
 
391
 
 
392
  switch (cif->abi) 
 
393
    {
 
394
    case FFI_V8:
 
395
#ifdef SPARC64
 
396
      /* We don't yet support calling 32bit code from 64bit */
 
397
      FFI_ASSERT(0);
 
398
#else
 
399
      ffi_call_v8(ffi_prep_args_v8, &ecif, cif->bytes, 
 
400
                  cif->flags, rvalue, fn);
 
401
#endif
 
402
      break;
 
403
    case FFI_V9:
 
404
#ifdef SPARC64
 
405
      ffi_call_v9(ffi_prep_args_v9, &ecif, cif->bytes,
 
406
                  cif->flags, rval, fn);
 
407
      if (rvalue && rval && cif->rtype->type == FFI_TYPE_STRUCT)
 
408
        ffi_v9_layout_struct(cif->rtype, 0, (char *)rvalue, (char *)rval, ((char *)rval)+32);
 
409
#else
 
410
      /* And vice versa */
 
411
      FFI_ASSERT(0);
 
412
#endif
 
413
      break;
 
414
    default:
 
415
      FFI_ASSERT(0);
 
416
      break;
 
417
    }
 
418
 
 
419
}
 
420
 
 
421
 
 
422
#ifdef SPARC64
 
423
extern void ffi_closure_v9(void);
 
424
#else
 
425
extern void ffi_closure_v8(void);
 
426
#endif
 
427
 
 
428
ffi_status
 
429
ffi_prep_closure_loc (ffi_closure* closure,
 
430
                      ffi_cif* cif,
 
431
                      void (*fun)(ffi_cif*, void*, void**, void*),
 
432
                      void *user_data,
 
433
                      void *codeloc)
 
434
{
 
435
  unsigned int *tramp = (unsigned int *) &closure->tramp[0];
 
436
  unsigned long fn;
 
437
#ifdef SPARC64
 
438
  /* Trampoline address is equal to the closure address.  We take advantage
 
439
     of that to reduce the trampoline size by 8 bytes. */
 
440
  FFI_ASSERT (cif->abi == FFI_V9);
 
441
  fn = (unsigned long) ffi_closure_v9;
 
442
  tramp[0] = 0x83414000;        /* rd   %pc, %g1        */
 
443
  tramp[1] = 0xca586010;        /* ldx  [%g1+16], %g5   */
 
444
  tramp[2] = 0x81c14000;        /* jmp  %g5             */
 
445
  tramp[3] = 0x01000000;        /* nop                  */
 
446
  *((unsigned long *) &tramp[4]) = fn;
 
447
#else
 
448
  unsigned long ctx = (unsigned long) codeloc;
 
449
  FFI_ASSERT (cif->abi == FFI_V8);
 
450
  fn = (unsigned long) ffi_closure_v8;
 
451
  tramp[0] = 0x03000000 | fn >> 10;     /* sethi %hi(fn), %g1   */
 
452
  tramp[1] = 0x05000000 | ctx >> 10;    /* sethi %hi(ctx), %g2  */
 
453
  tramp[2] = 0x81c06000 | (fn & 0x3ff); /* jmp   %g1+%lo(fn)    */
 
454
  tramp[3] = 0x8410a000 | (ctx & 0x3ff);/* or    %g2, %lo(ctx)  */
 
455
#endif
 
456
 
 
457
  closure->cif = cif;
 
458
  closure->fun = fun;
 
459
  closure->user_data = user_data;
 
460
 
 
461
  /* Flush the Icache.  FIXME: alignment isn't certain, assume 8 bytes */
 
462
#ifdef SPARC64
 
463
  asm volatile ("flush  %0" : : "r" (closure) : "memory");
 
464
  asm volatile ("flush  %0" : : "r" (((char *) closure) + 8) : "memory");
 
465
#else
 
466
  asm volatile ("iflush %0" : : "r" (closure) : "memory");
 
467
  asm volatile ("iflush %0" : : "r" (((char *) closure) + 8) : "memory");
 
468
#endif
 
469
 
 
470
  return FFI_OK;
 
471
}
 
472
 
 
473
int
 
474
ffi_closure_sparc_inner_v8(ffi_closure *closure,
 
475
  void *rvalue, unsigned long *gpr, unsigned long *scratch)
 
476
{
 
477
  ffi_cif *cif;
 
478
  ffi_type **arg_types;
 
479
  void **avalue;
 
480
  int i, argn;
 
481
 
 
482
  cif = closure->cif;
 
483
  arg_types = cif->arg_types;
 
484
  avalue = alloca(cif->nargs * sizeof(void *));
 
485
 
 
486
  /* Copy the caller's structure return address so that the closure
 
487
     returns the data directly to the caller.  */
 
488
  if (cif->flags == FFI_TYPE_STRUCT
 
489
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE  
 
490
      || cif->flags == FFI_TYPE_LONGDOUBLE
 
491
#endif
 
492
     )
 
493
    rvalue = (void *) gpr[0];
 
494
 
 
495
  /* Always skip the structure return address.  */
 
496
  argn = 1;
 
497
 
 
498
  /* Grab the addresses of the arguments from the stack frame.  */
 
499
  for (i = 0; i < cif->nargs; i++)
 
500
    {
 
501
      if (arg_types[i]->type == FFI_TYPE_STRUCT
 
502
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
503
          || arg_types[i]->type == FFI_TYPE_LONGDOUBLE
 
504
#endif
 
505
         )
 
506
        {
 
507
          /* Straight copy of invisible reference.  */
 
508
          avalue[i] = (void *)gpr[argn++];
 
509
        }
 
510
      else if ((arg_types[i]->type == FFI_TYPE_DOUBLE
 
511
               || arg_types[i]->type == FFI_TYPE_SINT64
 
512
               || arg_types[i]->type == FFI_TYPE_UINT64)
 
513
               /* gpr is 8-byte aligned.  */
 
514
               && (argn % 2) != 0)
 
515
        {
 
516
          /* Align on a 8-byte boundary.  */
 
517
          scratch[0] = gpr[argn];
 
518
          scratch[1] = gpr[argn+1];
 
519
          avalue[i] = scratch;
 
520
          scratch -= 2;
 
521
          argn += 2;
 
522
        }
 
523
      else
 
524
        {
 
525
          /* Always right-justify.  */
 
526
          argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
 
527
          avalue[i] = ((char *) &gpr[argn]) - arg_types[i]->size;
 
528
        }
 
529
    }
 
530
 
 
531
  /* Invoke the closure.  */
 
532
  (closure->fun) (cif, rvalue, avalue, closure->user_data);
 
533
 
 
534
  /* Tell ffi_closure_sparc how to perform return type promotions.  */
 
535
  return cif->rtype->type;
 
536
}
 
537
 
 
538
int
 
539
ffi_closure_sparc_inner_v9(ffi_closure *closure,
 
540
  void *rvalue, unsigned long *gpr, double *fpr)
 
541
{
 
542
  ffi_cif *cif;
 
543
  ffi_type **arg_types;
 
544
  void **avalue;
 
545
  int i, argn, fp_slot_max;
 
546
 
 
547
  cif = closure->cif;
 
548
  arg_types = cif->arg_types;
 
549
  avalue = alloca(cif->nargs * sizeof(void *));
 
550
 
 
551
  /* Copy the caller's structure return address so that the closure
 
552
     returns the data directly to the caller.  */
 
553
  if (cif->flags == FFI_TYPE_VOID
 
554
      && cif->rtype->type == FFI_TYPE_STRUCT)
 
555
    {
 
556
      rvalue = (void *) gpr[0];
 
557
      /* Skip the structure return address.  */
 
558
      argn = 1;
 
559
    }
 
560
  else
 
561
    argn = 0;
 
562
 
 
563
  fp_slot_max = 16 - argn;
 
564
 
 
565
  /* Grab the addresses of the arguments from the stack frame.  */
 
566
  for (i = 0; i < cif->nargs; i++)
 
567
    {
 
568
      if (arg_types[i]->type == FFI_TYPE_STRUCT)
 
569
        {
 
570
          if (arg_types[i]->size > 16)
 
571
            {
 
572
              /* Straight copy of invisible reference.  */
 
573
              avalue[i] = (void *)gpr[argn++];
 
574
            }
 
575
          else
 
576
            {
 
577
              /* Left-justify.  */
 
578
              ffi_v9_layout_struct(arg_types[i],
 
579
                                   0,
 
580
                                   (char *) &gpr[argn],
 
581
                                   (char *) &gpr[argn],
 
582
                                   (char *) &fpr[argn]);
 
583
              avalue[i] = &gpr[argn];
 
584
              argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
 
585
            }
 
586
        }
 
587
      else
 
588
        {
 
589
          /* Right-justify.  */
 
590
          argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
 
591
 
 
592
          if (i < fp_slot_max
 
593
              && (arg_types[i]->type == FFI_TYPE_FLOAT
 
594
                  || arg_types[i]->type == FFI_TYPE_DOUBLE
 
595
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 
596
                  || arg_types[i]->type == FFI_TYPE_LONGDOUBLE
 
597
#endif
 
598
                  ))
 
599
            avalue[i] = ((char *) &fpr[argn]) - arg_types[i]->size;
 
600
          else
 
601
            avalue[i] = ((char *) &gpr[argn]) - arg_types[i]->size;
 
602
        }
 
603
    }
 
604
 
 
605
  /* Invoke the closure.  */
 
606
  (closure->fun) (cif, rvalue, avalue, closure->user_data);
 
607
 
 
608
  /* Tell ffi_closure_sparc how to perform return type promotions.  */
 
609
  return cif->rtype->type;
 
610
}