~ubuntu-branches/ubuntu/trusty/python3.4/trusty-proposed

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2013-11-25 09:44:27 UTC
  • Revision ID: package-import@ubuntu.com-20131125094427-lzxj8ap5w01lmo7f
Tags: upstream-3.4~b1
ImportĀ upstreamĀ versionĀ 3.4~b1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -----------------------------------------------------------------------
 
2
   ffi.c - Copyright (c) 2002-2008, 2012 Kaz Kojima
 
3
           Copyright (c) 2008 Red Hat, Inc.
 
4
   
 
5
   SuperH Foreign Function Interface 
 
6
 
 
7
   Permission is hereby granted, free of charge, to any person obtaining
 
8
   a copy of this software and associated documentation files (the
 
9
   ``Software''), to deal in the Software without restriction, including
 
10
   without limitation the rights to use, copy, modify, merge, publish,
 
11
   distribute, sublicense, and/or sell copies of the Software, and to
 
12
   permit persons to whom the Software is furnished to do so, subject to
 
13
   the following conditions:
 
14
 
 
15
   The above copyright notice and this permission notice shall be included
 
16
   in all copies or substantial portions of the Software.
 
17
 
 
18
   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
 
19
   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
20
   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 
21
   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 
22
   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 
23
   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
24
   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
25
   DEALINGS IN THE SOFTWARE.
 
26
   ----------------------------------------------------------------------- */
 
27
 
 
28
#include <ffi.h>
 
29
#include <ffi_common.h>
 
30
 
 
31
#include <stdlib.h>
 
32
 
 
33
#define NGREGARG 4
 
34
#if defined(__SH4__)
 
35
#define NFREGARG 8
 
36
#endif
 
37
 
 
38
#if defined(__HITACHI__)
 
39
#define STRUCT_VALUE_ADDRESS_WITH_ARG 1
 
40
#else
 
41
#define STRUCT_VALUE_ADDRESS_WITH_ARG 0
 
42
#endif
 
43
 
 
44
/* If the structure has essentialy an unique element, return its type.  */
 
45
static int
 
46
simple_type (ffi_type *arg)
 
47
{
 
48
  if (arg->type != FFI_TYPE_STRUCT)
 
49
    return arg->type;
 
50
  else if (arg->elements[1])
 
51
    return FFI_TYPE_STRUCT;
 
52
 
 
53
  return simple_type (arg->elements[0]);
 
54
}
 
55
 
 
56
static int
 
57
return_type (ffi_type *arg)
 
58
{
 
59
  unsigned short type;
 
60
 
 
61
  if (arg->type != FFI_TYPE_STRUCT)
 
62
    return arg->type;
 
63
 
 
64
  type = simple_type (arg->elements[0]);
 
65
  if (! arg->elements[1])
 
66
    {
 
67
      switch (type)
 
68
        {
 
69
        case FFI_TYPE_SINT8:
 
70
        case FFI_TYPE_UINT8:
 
71
        case FFI_TYPE_SINT16:
 
72
        case FFI_TYPE_UINT16:
 
73
        case FFI_TYPE_SINT32:
 
74
        case FFI_TYPE_UINT32:
 
75
          return FFI_TYPE_INT;
 
76
 
 
77
        default:
 
78
          return type;
 
79
        }
 
80
    }
 
81
 
 
82
  /* gcc uses r0/r1 pair for some kind of structures.  */
 
83
  if (arg->size <= 2 * sizeof (int))
 
84
    {
 
85
      int i = 0;
 
86
      ffi_type *e;
 
87
 
 
88
      while ((e = arg->elements[i++]))
 
89
        {
 
90
          type = simple_type (e);
 
91
          switch (type)
 
92
            {
 
93
            case FFI_TYPE_SINT32:
 
94
            case FFI_TYPE_UINT32:
 
95
            case FFI_TYPE_INT:
 
96
            case FFI_TYPE_FLOAT:
 
97
              return FFI_TYPE_UINT64;
 
98
 
 
99
            default:
 
100
              break;
 
101
            }
 
102
        }
 
103
    }
 
104
 
 
105
  return FFI_TYPE_STRUCT;
 
106
}
 
107
 
 
108
/* ffi_prep_args is called by the assembly routine once stack space
 
109
   has been allocated for the function's arguments */
 
110
 
 
111
void ffi_prep_args(char *stack, extended_cif *ecif)
 
112
{
 
113
  register unsigned int i;
 
114
  register int tmp;
 
115
  register unsigned int avn;
 
116
  register void **p_argv;
 
117
  register char *argp;
 
118
  register ffi_type **p_arg;
 
119
  int greg, ireg;
 
120
#if defined(__SH4__)
 
121
  int freg = 0;
 
122
#endif
 
123
 
 
124
  tmp = 0;
 
125
  argp = stack;
 
126
 
 
127
  if (return_type (ecif->cif->rtype) == FFI_TYPE_STRUCT)
 
128
    {
 
129
      *(void **) argp = ecif->rvalue;
 
130
      argp += 4;
 
131
      ireg = STRUCT_VALUE_ADDRESS_WITH_ARG ? 1 : 0;
 
132
    }
 
133
  else
 
134
    ireg = 0;
 
135
 
 
136
  /* Set arguments for registers.  */
 
137
  greg = ireg;
 
138
  avn = ecif->cif->nargs;
 
139
  p_argv = ecif->avalue;
 
140
 
 
141
  for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++)
 
142
    {
 
143
      size_t z;
 
144
 
 
145
      z = (*p_arg)->size;
 
146
      if (z < sizeof(int))
 
147
        {
 
148
          if (greg++ >= NGREGARG)
 
149
            continue;
 
150
 
 
151
          z = sizeof(int);
 
152
          switch ((*p_arg)->type)
 
153
            {
 
154
            case FFI_TYPE_SINT8:
 
155
              *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
 
156
              break;
 
157
  
 
158
            case FFI_TYPE_UINT8:
 
159
              *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
 
160
              break;
 
161
  
 
162
            case FFI_TYPE_SINT16:
 
163
              *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
 
164
              break;
 
165
  
 
166
            case FFI_TYPE_UINT16:
 
167
              *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
 
168
              break;
 
169
  
 
170
            case FFI_TYPE_STRUCT:
 
171
              *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
 
172
              break;
 
173
 
 
174
            default:
 
175
              FFI_ASSERT(0);
 
176
            }
 
177
          argp += z;
 
178
        }
 
179
      else if (z == sizeof(int))
 
180
        {
 
181
#if defined(__SH4__)
 
182
          if ((*p_arg)->type == FFI_TYPE_FLOAT)
 
183
            {
 
184
              if (freg++ >= NFREGARG)
 
185
                continue;
 
186
            }
 
187
          else
 
188
#endif
 
189
            {
 
190
              if (greg++ >= NGREGARG)
 
191
                continue;
 
192
            }
 
193
          *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
 
194
          argp += z;
 
195
        }
 
196
#if defined(__SH4__)
 
197
      else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
 
198
        {
 
199
          if (freg + 1 >= NFREGARG)
 
200
            continue;
 
201
          freg = (freg + 1) & ~1;
 
202
          freg += 2;
 
203
          memcpy (argp, *p_argv, z);
 
204
          argp += z;
 
205
        }
 
206
#endif
 
207
      else
 
208
        {
 
209
          int n = (z + sizeof (int) - 1) / sizeof (int);
 
210
#if defined(__SH4__)
 
211
          if (greg + n - 1 >= NGREGARG)
 
212
            continue;
 
213
#else
 
214
          if (greg >= NGREGARG)
 
215
            continue;
 
216
#endif
 
217
          greg += n;
 
218
          memcpy (argp, *p_argv, z);
 
219
          argp += n * sizeof (int);
 
220
        }
 
221
    }
 
222
 
 
223
  /* Set arguments on stack.  */
 
224
  greg = ireg;
 
225
#if defined(__SH4__)
 
226
  freg = 0;
 
227
#endif
 
228
  p_argv = ecif->avalue;
 
229
 
 
230
  for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++)
 
231
    {
 
232
      size_t z;
 
233
 
 
234
      z = (*p_arg)->size;
 
235
      if (z < sizeof(int))
 
236
        {
 
237
          if (greg++ < NGREGARG)
 
238
            continue;
 
239
 
 
240
          z = sizeof(int);
 
241
          switch ((*p_arg)->type)
 
242
            {
 
243
            case FFI_TYPE_SINT8:
 
244
              *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
 
245
              break;
 
246
  
 
247
            case FFI_TYPE_UINT8:
 
248
              *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
 
249
              break;
 
250
  
 
251
            case FFI_TYPE_SINT16:
 
252
              *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
 
253
              break;
 
254
  
 
255
            case FFI_TYPE_UINT16:
 
256
              *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
 
257
              break;
 
258
  
 
259
            case FFI_TYPE_STRUCT:
 
260
              *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
 
261
              break;
 
262
 
 
263
            default:
 
264
              FFI_ASSERT(0);
 
265
            }
 
266
          argp += z;
 
267
        }
 
268
      else if (z == sizeof(int))
 
269
        {
 
270
#if defined(__SH4__)
 
271
          if ((*p_arg)->type == FFI_TYPE_FLOAT)
 
272
            {
 
273
              if (freg++ < NFREGARG)
 
274
                continue;
 
275
            }
 
276
          else
 
277
#endif
 
278
            {
 
279
              if (greg++ < NGREGARG)
 
280
                continue;
 
281
            }
 
282
          *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
 
283
          argp += z;
 
284
        }
 
285
#if defined(__SH4__)
 
286
      else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
 
287
        {
 
288
          if (freg + 1 < NFREGARG)
 
289
            {
 
290
              freg = (freg + 1) & ~1;
 
291
              freg += 2;
 
292
              continue;
 
293
            }
 
294
          memcpy (argp, *p_argv, z);
 
295
          argp += z;
 
296
        }
 
297
#endif
 
298
      else
 
299
        {
 
300
          int n = (z + sizeof (int) - 1) / sizeof (int);
 
301
          if (greg + n - 1 < NGREGARG)
 
302
            {
 
303
              greg += n;
 
304
              continue;
 
305
            }
 
306
#if (! defined(__SH4__))
 
307
          else if (greg < NGREGARG)
 
308
            {
 
309
              greg = NGREGARG;
 
310
              continue;
 
311
            }
 
312
#endif
 
313
          memcpy (argp, *p_argv, z);
 
314
          argp += n * sizeof (int);
 
315
        }
 
316
    }
 
317
 
 
318
  return;
 
319
}
 
320
 
 
321
/* Perform machine dependent cif processing */
 
322
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
 
323
{
 
324
  int i, j;
 
325
  int size, type;
 
326
  int n, m;
 
327
  int greg;
 
328
#if defined(__SH4__)
 
329
  int freg = 0;
 
330
#endif
 
331
 
 
332
  cif->flags = 0;
 
333
 
 
334
  greg = ((return_type (cif->rtype) == FFI_TYPE_STRUCT) &&
 
335
          STRUCT_VALUE_ADDRESS_WITH_ARG) ? 1 : 0;
 
336
 
 
337
#if defined(__SH4__)
 
338
  for (i = j = 0; i < cif->nargs && j < 12; i++)
 
339
    {
 
340
      type = (cif->arg_types)[i]->type;
 
341
      switch (type)
 
342
        {
 
343
        case FFI_TYPE_FLOAT:
 
344
          if (freg >= NFREGARG)
 
345
            continue;
 
346
          freg++;
 
347
          cif->flags += ((cif->arg_types)[i]->type) << (2 * j);
 
348
          j++;
 
349
          break;
 
350
 
 
351
        case FFI_TYPE_DOUBLE:
 
352
          if ((freg + 1) >= NFREGARG)
 
353
            continue;
 
354
          freg = (freg + 1) & ~1;
 
355
          freg += 2;
 
356
          cif->flags += ((cif->arg_types)[i]->type) << (2 * j);
 
357
          j++;
 
358
          break;
 
359
              
 
360
        default:
 
361
          size = (cif->arg_types)[i]->size;
 
362
          n = (size + sizeof (int) - 1) / sizeof (int);
 
363
          if (greg + n - 1 >= NGREGARG)
 
364
                continue;
 
365
          greg += n;
 
366
          for (m = 0; m < n; m++)
 
367
            cif->flags += FFI_TYPE_INT << (2 * j++);
 
368
          break;
 
369
        }
 
370
    }
 
371
#else
 
372
  for (i = j = 0; i < cif->nargs && j < 4; i++)
 
373
    {
 
374
      size = (cif->arg_types)[i]->size;
 
375
      n = (size + sizeof (int) - 1) / sizeof (int);
 
376
      if (greg >= NGREGARG)
 
377
        continue;
 
378
      else if (greg + n - 1 >= NGREGARG)
 
379
        n = NGREGARG - greg;
 
380
      greg += n;
 
381
      for (m = 0; m < n; m++)
 
382
        cif->flags += FFI_TYPE_INT << (2 * j++);
 
383
    }
 
384
#endif
 
385
 
 
386
  /* Set the return type flag */
 
387
  switch (cif->rtype->type)
 
388
    {
 
389
    case FFI_TYPE_STRUCT:
 
390
      cif->flags += (unsigned) (return_type (cif->rtype)) << 24;
 
391
      break;
 
392
 
 
393
    case FFI_TYPE_VOID:
 
394
    case FFI_TYPE_FLOAT:
 
395
    case FFI_TYPE_DOUBLE:
 
396
    case FFI_TYPE_SINT64:
 
397
    case FFI_TYPE_UINT64:
 
398
      cif->flags += (unsigned) cif->rtype->type << 24;
 
399
      break;
 
400
 
 
401
    default:
 
402
      cif->flags += FFI_TYPE_INT << 24;
 
403
      break;
 
404
    }
 
405
 
 
406
  return FFI_OK;
 
407
}
 
408
 
 
409
extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
 
410
                          unsigned, unsigned, unsigned *, void (*fn)(void));
 
411
 
 
412
void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
 
413
{
 
414
  extended_cif ecif;
 
415
  UINT64 trvalue;
 
416
 
 
417
  ecif.cif = cif;
 
418
  ecif.avalue = avalue;
 
419
  
 
420
  /* If the return value is a struct and we don't have a return */
 
421
  /* value address then we need to make one                     */
 
422
 
 
423
  if (cif->rtype->type == FFI_TYPE_STRUCT
 
424
      && return_type (cif->rtype) != FFI_TYPE_STRUCT)
 
425
    ecif.rvalue = &trvalue;
 
426
  else if ((rvalue == NULL) && 
 
427
      (cif->rtype->type == FFI_TYPE_STRUCT))
 
428
    {
 
429
      ecif.rvalue = alloca(cif->rtype->size);
 
430
    }
 
431
  else
 
432
    ecif.rvalue = rvalue;
 
433
 
 
434
  switch (cif->abi) 
 
435
    {
 
436
    case FFI_SYSV:
 
437
      ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
 
438
                    fn);
 
439
      break;
 
440
    default:
 
441
      FFI_ASSERT(0);
 
442
      break;
 
443
    }
 
444
 
 
445
  if (rvalue
 
446
      && cif->rtype->type == FFI_TYPE_STRUCT
 
447
      && return_type (cif->rtype) != FFI_TYPE_STRUCT)
 
448
    memcpy (rvalue, &trvalue, cif->rtype->size);
 
449
}
 
450
 
 
451
extern void ffi_closure_SYSV (void);
 
452
#if defined(__SH4__)
 
453
extern void __ic_invalidate (void *line);
 
454
#endif
 
455
 
 
456
ffi_status
 
457
ffi_prep_closure_loc (ffi_closure* closure,
 
458
                      ffi_cif* cif,
 
459
                      void (*fun)(ffi_cif*, void*, void**, void*),
 
460
                      void *user_data,
 
461
                      void *codeloc)
 
462
{
 
463
  unsigned int *tramp;
 
464
  unsigned int insn;
 
465
 
 
466
  if (cif->abi != FFI_SYSV)
 
467
    return FFI_BAD_ABI;
 
468
 
 
469
  tramp = (unsigned int *) &closure->tramp[0];
 
470
  /* Set T bit if the function returns a struct pointed with R2.  */
 
471
  insn = (return_type (cif->rtype) == FFI_TYPE_STRUCT
 
472
          ? 0x0018 /* sett */
 
473
          : 0x0008 /* clrt */);
 
474
 
 
475
#ifdef __LITTLE_ENDIAN__
 
476
  tramp[0] = 0xd301d102;
 
477
  tramp[1] = 0x0000412b | (insn << 16);
 
478
#else
 
479
  tramp[0] = 0xd102d301;
 
480
  tramp[1] = 0x412b0000 | insn;
 
481
#endif
 
482
  *(void **) &tramp[2] = (void *)codeloc;          /* ctx */
 
483
  *(void **) &tramp[3] = (void *)ffi_closure_SYSV; /* funaddr */
 
484
 
 
485
  closure->cif = cif;
 
486
  closure->fun = fun;
 
487
  closure->user_data = user_data;
 
488
 
 
489
#if defined(__SH4__)
 
490
  /* Flush the icache.  */
 
491
  __ic_invalidate(codeloc);
 
492
#endif
 
493
 
 
494
  return FFI_OK;
 
495
}
 
496
 
 
497
/* Basically the trampoline invokes ffi_closure_SYSV, and on 
 
498
 * entry, r3 holds the address of the closure.
 
499
 * After storing the registers that could possibly contain
 
500
 * parameters to be passed into the stack frame and setting
 
501
 * up space for a return value, ffi_closure_SYSV invokes the 
 
502
 * following helper function to do most of the work.
 
503
 */
 
504
 
 
505
#ifdef __LITTLE_ENDIAN__
 
506
#define OFS_INT8        0
 
507
#define OFS_INT16       0
 
508
#else
 
509
#define OFS_INT8        3
 
510
#define OFS_INT16       2
 
511
#endif
 
512
 
 
513
int
 
514
ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue, 
 
515
                         unsigned long *pgr, unsigned long *pfr, 
 
516
                         unsigned long *pst)
 
517
{
 
518
  void **avalue;
 
519
  ffi_type **p_arg;
 
520
  int i, avn;
 
521
  int ireg, greg = 0;
 
522
#if defined(__SH4__)
 
523
  int freg = 0;
 
524
#endif
 
525
  ffi_cif *cif; 
 
526
 
 
527
  cif = closure->cif;
 
528
  avalue = alloca(cif->nargs * sizeof(void *));
 
529
 
 
530
  /* Copy the caller's structure return value address so that the closure
 
531
     returns the data directly to the caller.  */
 
532
  if (cif->rtype->type == FFI_TYPE_STRUCT && STRUCT_VALUE_ADDRESS_WITH_ARG)
 
533
    {
 
534
      rvalue = (void *) *pgr++;
 
535
      ireg = 1;
 
536
    }
 
537
  else
 
538
    ireg = 0;
 
539
 
 
540
  cif = closure->cif;
 
541
  greg = ireg;
 
542
  avn = cif->nargs;
 
543
 
 
544
  /* Grab the addresses of the arguments from the stack frame.  */
 
545
  for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
 
546
    {
 
547
      size_t z;
 
548
 
 
549
      z = (*p_arg)->size;
 
550
      if (z < sizeof(int))
 
551
        {
 
552
          if (greg++ >= NGREGARG)
 
553
            continue;
 
554
 
 
555
          z = sizeof(int);
 
556
          switch ((*p_arg)->type)
 
557
            {
 
558
            case FFI_TYPE_SINT8:
 
559
            case FFI_TYPE_UINT8:
 
560
              avalue[i] = (((char *)pgr) + OFS_INT8);
 
561
              break;
 
562
  
 
563
            case FFI_TYPE_SINT16:
 
564
            case FFI_TYPE_UINT16:
 
565
              avalue[i] = (((char *)pgr) + OFS_INT16);
 
566
              break;
 
567
  
 
568
            case FFI_TYPE_STRUCT:
 
569
              avalue[i] = pgr;
 
570
              break;
 
571
 
 
572
            default:
 
573
              FFI_ASSERT(0);
 
574
            }
 
575
          pgr++;
 
576
        }
 
577
      else if (z == sizeof(int))
 
578
        {
 
579
#if defined(__SH4__)
 
580
          if ((*p_arg)->type == FFI_TYPE_FLOAT)
 
581
            {
 
582
              if (freg++ >= NFREGARG)
 
583
                continue;
 
584
              avalue[i] = pfr;
 
585
              pfr++;
 
586
            }
 
587
          else
 
588
#endif
 
589
            {
 
590
              if (greg++ >= NGREGARG)
 
591
                continue;
 
592
              avalue[i] = pgr;
 
593
              pgr++;
 
594
            }
 
595
        }
 
596
#if defined(__SH4__)
 
597
      else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
 
598
        {
 
599
          if (freg + 1 >= NFREGARG)
 
600
            continue;
 
601
          if (freg & 1)
 
602
            pfr++;
 
603
          freg = (freg + 1) & ~1;
 
604
          freg += 2;
 
605
          avalue[i] = pfr;
 
606
          pfr += 2;
 
607
        }
 
608
#endif
 
609
      else
 
610
        {
 
611
          int n = (z + sizeof (int) - 1) / sizeof (int);
 
612
#if defined(__SH4__)
 
613
          if (greg + n - 1 >= NGREGARG)
 
614
            continue;
 
615
#else
 
616
          if (greg >= NGREGARG)
 
617
            continue;
 
618
#endif
 
619
          greg += n;
 
620
          avalue[i] = pgr;
 
621
          pgr += n;
 
622
        }
 
623
    }
 
624
 
 
625
  greg = ireg;
 
626
#if defined(__SH4__)
 
627
  freg = 0;
 
628
#endif
 
629
 
 
630
  for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
 
631
    {
 
632
      size_t z;
 
633
 
 
634
      z = (*p_arg)->size;
 
635
      if (z < sizeof(int))
 
636
        {
 
637
          if (greg++ < NGREGARG)
 
638
            continue;
 
639
 
 
640
          z = sizeof(int);
 
641
          switch ((*p_arg)->type)
 
642
            {
 
643
            case FFI_TYPE_SINT8:
 
644
            case FFI_TYPE_UINT8:
 
645
              avalue[i] = (((char *)pst) + OFS_INT8);
 
646
              break;
 
647
  
 
648
            case FFI_TYPE_SINT16:
 
649
            case FFI_TYPE_UINT16:
 
650
              avalue[i] = (((char *)pst) + OFS_INT16);
 
651
              break;
 
652
  
 
653
            case FFI_TYPE_STRUCT:
 
654
              avalue[i] = pst;
 
655
              break;
 
656
 
 
657
            default:
 
658
              FFI_ASSERT(0);
 
659
            }
 
660
          pst++;
 
661
        }
 
662
      else if (z == sizeof(int))
 
663
        {
 
664
#if defined(__SH4__)
 
665
          if ((*p_arg)->type == FFI_TYPE_FLOAT)
 
666
            {
 
667
              if (freg++ < NFREGARG)
 
668
                continue;
 
669
            }
 
670
          else
 
671
#endif
 
672
            {
 
673
              if (greg++ < NGREGARG)
 
674
                continue;
 
675
            }
 
676
          avalue[i] = pst;
 
677
          pst++;
 
678
        }
 
679
#if defined(__SH4__)
 
680
      else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
 
681
        {
 
682
          if (freg + 1 < NFREGARG)
 
683
            {
 
684
              freg = (freg + 1) & ~1;
 
685
              freg += 2;
 
686
              continue;
 
687
            }
 
688
          avalue[i] = pst;
 
689
          pst += 2;
 
690
        }
 
691
#endif
 
692
      else
 
693
        {
 
694
          int n = (z + sizeof (int) - 1) / sizeof (int);
 
695
          if (greg + n - 1 < NGREGARG)
 
696
            {
 
697
              greg += n;
 
698
              continue;
 
699
            }
 
700
#if (! defined(__SH4__))
 
701
          else if (greg < NGREGARG)
 
702
            {
 
703
              greg += n;
 
704
              pst += greg - NGREGARG;
 
705
              continue;
 
706
            }
 
707
#endif
 
708
          avalue[i] = pst;
 
709
          pst += n;
 
710
        }
 
711
    }
 
712
 
 
713
  (closure->fun) (cif, rvalue, avalue, closure->user_data);
 
714
 
 
715
  /* Tell ffi_closure_SYSV how to perform return type promotions.  */
 
716
  return return_type (cif->rtype);
 
717
}