PageRenderTime 78ms CodeModel.GetById 20ms app.highlight 49ms RepoModel.GetById 1ms app.codeStats 0ms

/Modules/_ctypes/libffi/src/powerpc/ffi.c

http://unladen-swallow.googlecode.com/
C | 1429 lines | 1004 code | 151 blank | 274 comment | 213 complexity | cf9067966101c83870b90ce82fac84b2 MD5 | raw file
   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
  35extern void ffi_closure_SYSV (void);
  36extern void FFI_HIDDEN ffi_closure_LINUX64 (void);
  37
  38enum {
  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.  */
  54unsigned int NUM_GPR_ARG_REGISTERS = 8;
  55#ifndef __NO_FPRS__
  56unsigned int NUM_FPR_ARG_REGISTERS = 8;
  57#else
  58unsigned int NUM_FPR_ARG_REGISTERS = 0;
  59#endif
  60
  61enum { 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
  89void
  90ffi_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.  */
 369enum {
 370  NUM_GPR_ARG_REGISTERS64 = 8,
 371  NUM_FPR_ARG_REGISTERS64 = 13
 372};
 373enum { 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
 409void FFI_HIDDEN
 410ffi_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 */
 588ffi_status
 589ffi_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
 874extern void ffi_call_SYSV(extended_cif *, unsigned, unsigned, unsigned *,
 875			  void (*fn)(void));
 876extern void FFI_HIDDEN ffi_call_LINUX64(extended_cif *, unsigned long,
 877					unsigned long, unsigned long *,
 878					void (*fn)(void));
 879
 880void
 881ffi_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
 923static void
 924flush_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
 936ffi_status
 937ffi_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
 978typedef union
 979{
 980  float f;
 981  double d;
 982} ffi_dblfl;
 983
 984int 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
 995int
 996ffi_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
1288int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure *, void *,
1289					   unsigned long *, ffi_dblfl *);
1290
1291int FFI_HIDDEN
1292ffi_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}