github.com/prattmic/llgo-embedded@v0.0.0-20150820070356-41cfecea0e1e/third_party/gofrontend/libffi/src/x86/darwin64_c.c (about)

     1  /* -----------------------------------------------------------------------
     2     ffi64.c - Copyright (c) 20011  Anthony Green
     3               Copyright (c) 2008, 2010  Red Hat, Inc.
     4               Copyright (c) 2002, 2007  Bo Thorsen <bo@suse.de>
     5               
     6     x86-64 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,
    20     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    21     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    22     NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
    23     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
    24     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    25     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    26     DEALINGS IN THE SOFTWARE.
    27     ----------------------------------------------------------------------- */
    28  
    29  #include <ffi.h>
    30  #include <ffi_common.h>
    31  
    32  #include <stdlib.h>
    33  #include <stdarg.h>
    34  
    35  #ifdef __x86_64__
    36  
    37  #define MAX_GPR_REGS 6
    38  #define MAX_SSE_REGS 8
    39  
    40  #ifdef __INTEL_COMPILER
    41  #define UINT128 __m128
    42  #else
    43  #define UINT128 __int128_t
    44  #endif
    45  
    46  struct register_args
    47  {
    48    /* Registers for argument passing.  */
    49    UINT64 gpr[MAX_GPR_REGS];
    50    UINT128 sse[MAX_SSE_REGS];
    51  };
    52  
    53  extern void ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags,
    54  			     void *raddr, void (*fnaddr)(void), unsigned ssecount);
    55  
    56  /* All reference to register classes here is identical to the code in
    57     gcc/config/i386/i386.c. Do *not* change one without the other.  */
    58  
    59  /* Register class used for passing given 64bit part of the argument.
    60     These represent classes as documented by the PS ABI, with the
    61     exception of SSESF, SSEDF classes, that are basically SSE class,
    62     just gcc will use SF or DFmode move instead of DImode to avoid
    63     reformatting penalties.
    64  
    65     Similary we play games with INTEGERSI_CLASS to use cheaper SImode moves
    66     whenever possible (upper half does contain padding).  */
    67  enum x86_64_reg_class
    68    {
    69      X86_64_NO_CLASS,
    70      X86_64_INTEGER_CLASS,
    71      X86_64_INTEGERSI_CLASS,
    72      X86_64_SSE_CLASS,
    73      X86_64_SSESF_CLASS,
    74      X86_64_SSEDF_CLASS,
    75      X86_64_SSEUP_CLASS,
    76      X86_64_X87_CLASS,
    77      X86_64_X87UP_CLASS,
    78      X86_64_COMPLEX_X87_CLASS,
    79      X86_64_MEMORY_CLASS
    80    };
    81  
    82  #define MAX_CLASSES 4
    83  
    84  #define SSE_CLASS_P(X)	((X) >= X86_64_SSE_CLASS && X <= X86_64_SSEUP_CLASS)
    85  
    86  /* x86-64 register passing implementation.  See x86-64 ABI for details.  Goal
    87     of this code is to classify each 8bytes of incoming argument by the register
    88     class and assign registers accordingly.  */
    89  
    90  /* Return the union class of CLASS1 and CLASS2.
    91     See the x86-64 PS ABI for details.  */
    92  
    93  static enum x86_64_reg_class
    94  merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)
    95  {
    96    /* Rule #1: If both classes are equal, this is the resulting class.  */
    97    if (class1 == class2)
    98      return class1;
    99  
   100    /* Rule #2: If one of the classes is NO_CLASS, the resulting class is
   101       the other class.  */
   102    if (class1 == X86_64_NO_CLASS)
   103      return class2;
   104    if (class2 == X86_64_NO_CLASS)
   105      return class1;
   106  
   107    /* Rule #3: If one of the classes is MEMORY, the result is MEMORY.  */
   108    if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
   109      return X86_64_MEMORY_CLASS;
   110  
   111    /* Rule #4: If one of the classes is INTEGER, the result is INTEGER.  */
   112    if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS)
   113        || (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS))
   114      return X86_64_INTEGERSI_CLASS;
   115    if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS
   116        || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)
   117      return X86_64_INTEGER_CLASS;
   118  
   119    /* Rule #5: If one of the classes is X87, X87UP, or COMPLEX_X87 class,
   120       MEMORY is used.  */
   121    if (class1 == X86_64_X87_CLASS
   122        || class1 == X86_64_X87UP_CLASS
   123        || class1 == X86_64_COMPLEX_X87_CLASS
   124        || class2 == X86_64_X87_CLASS
   125        || class2 == X86_64_X87UP_CLASS
   126        || class2 == X86_64_COMPLEX_X87_CLASS)
   127      return X86_64_MEMORY_CLASS;
   128  
   129    /* Rule #6: Otherwise class SSE is used.  */
   130    return X86_64_SSE_CLASS;
   131  }
   132  
   133  /* Classify the argument of type TYPE and mode MODE.
   134     CLASSES will be filled by the register class used to pass each word
   135     of the operand.  The number of words is returned.  In case the parameter
   136     should be passed in memory, 0 is returned. As a special case for zero
   137     sized containers, classes[0] will be NO_CLASS and 1 is returned.
   138  
   139     See the x86-64 PS ABI for details.
   140  */
   141  static int
   142  classify_argument (ffi_type *type, enum x86_64_reg_class classes[],
   143  		   size_t byte_offset)
   144  {
   145    switch (type->type)
   146      {
   147      case FFI_TYPE_UINT8:
   148      case FFI_TYPE_SINT8:
   149      case FFI_TYPE_UINT16:
   150      case FFI_TYPE_SINT16:
   151      case FFI_TYPE_UINT32:
   152      case FFI_TYPE_SINT32:
   153      case FFI_TYPE_UINT64:
   154      case FFI_TYPE_SINT64:
   155      case FFI_TYPE_POINTER:
   156        {
   157  	int size = byte_offset + type->size;
   158  
   159  	if (size <= 4)
   160  	  {
   161  	    classes[0] = X86_64_INTEGERSI_CLASS;
   162  	    return 1;
   163  	  }
   164  	else if (size <= 8)
   165  	  {
   166  	    classes[0] = X86_64_INTEGER_CLASS;
   167  	    return 1;
   168  	  }
   169  	else if (size <= 12)
   170  	  {
   171  	    classes[0] = X86_64_INTEGER_CLASS;
   172  	    classes[1] = X86_64_INTEGERSI_CLASS;
   173  	    return 2;
   174  	  }
   175  	else if (size <= 16)
   176  	  {
   177  	    classes[0] = classes[1] = X86_64_INTEGERSI_CLASS;
   178  	    return 2;
   179  	  }
   180  	else
   181  	  FFI_ASSERT (0);
   182        }
   183      case FFI_TYPE_FLOAT:
   184        if (!(byte_offset % 8))
   185  	classes[0] = X86_64_SSESF_CLASS;
   186        else
   187  	classes[0] = X86_64_SSE_CLASS;
   188        return 1;
   189      case FFI_TYPE_DOUBLE:
   190        classes[0] = X86_64_SSEDF_CLASS;
   191        return 1;
   192      case FFI_TYPE_LONGDOUBLE:
   193        classes[0] = X86_64_X87_CLASS;
   194        classes[1] = X86_64_X87UP_CLASS;
   195        return 2;
   196      case FFI_TYPE_STRUCT:
   197        {
   198  	const int UNITS_PER_WORD = 8;
   199  	int words = (type->size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
   200  	ffi_type **ptr; 
   201  	int i;
   202  	enum x86_64_reg_class subclasses[MAX_CLASSES];
   203  
   204  	/* If the struct is larger than 32 bytes, pass it on the stack.  */
   205  	if (type->size > 32)
   206  	  return 0;
   207  
   208  	for (i = 0; i < words; i++)
   209  	  classes[i] = X86_64_NO_CLASS;
   210  
   211  	/* Zero sized arrays or structures are NO_CLASS.  We return 0 to
   212  	   signalize memory class, so handle it as special case.  */
   213  	if (!words)
   214  	  {
   215  	    classes[0] = X86_64_NO_CLASS;
   216  	    return 1;
   217  	  }
   218  
   219  	/* Merge the fields of structure.  */
   220  	for (ptr = type->elements; *ptr != NULL; ptr++)
   221  	  {
   222  	    int num;
   223  
   224  	    byte_offset = ALIGN (byte_offset, (*ptr)->alignment);
   225  
   226  	    num = classify_argument (*ptr, subclasses, byte_offset % 8);
   227  	    if (num == 0)
   228  	      return 0;
   229  	    for (i = 0; i < num; i++)
   230  	      {
   231  		int pos = byte_offset / 8;
   232  		classes[i + pos] =
   233  		  merge_classes (subclasses[i], classes[i + pos]);
   234  	      }
   235  
   236  	    byte_offset += (*ptr)->size;
   237  	  }
   238  
   239  	if (words > 2)
   240  	  {
   241  	    /* When size > 16 bytes, if the first one isn't
   242  	       X86_64_SSE_CLASS or any other ones aren't
   243  	       X86_64_SSEUP_CLASS, everything should be passed in
   244  	       memory.  */
   245  	    if (classes[0] != X86_64_SSE_CLASS)
   246  	      return 0;
   247  
   248  	    for (i = 1; i < words; i++)
   249  	      if (classes[i] != X86_64_SSEUP_CLASS)
   250  		return 0;
   251  	  }
   252  
   253  	/* Final merger cleanup.  */
   254  	for (i = 0; i < words; i++)
   255  	  {
   256  	    /* If one class is MEMORY, everything should be passed in
   257  	       memory.  */
   258  	    if (classes[i] == X86_64_MEMORY_CLASS)
   259  	      return 0;
   260  
   261  	    /* The X86_64_SSEUP_CLASS should be always preceded by
   262  	       X86_64_SSE_CLASS or X86_64_SSEUP_CLASS.  */
   263  	    if (classes[i] == X86_64_SSEUP_CLASS
   264  		&& classes[i - 1] != X86_64_SSE_CLASS
   265  		&& classes[i - 1] != X86_64_SSEUP_CLASS)
   266  	      {
   267  		/* The first one should never be X86_64_SSEUP_CLASS.  */
   268  		FFI_ASSERT (i != 0);
   269  		classes[i] = X86_64_SSE_CLASS;
   270  	      }
   271  
   272  	    /*  If X86_64_X87UP_CLASS isn't preceded by X86_64_X87_CLASS,
   273  		everything should be passed in memory.  */
   274  	    if (classes[i] == X86_64_X87UP_CLASS
   275  		&& (classes[i - 1] != X86_64_X87_CLASS))
   276  	      {
   277  		/* The first one should never be X86_64_X87UP_CLASS.  */
   278  		FFI_ASSERT (i != 0);
   279  		return 0;
   280  	      }
   281  	  }
   282  	return words;
   283        }
   284  
   285      default:
   286        FFI_ASSERT(0);
   287      }
   288    return 0; /* Never reached.  */
   289  }
   290  
   291  /* Examine the argument and return set number of register required in each
   292     class.  Return zero iff parameter should be passed in memory, otherwise
   293     the number of registers.  */
   294  
   295  static int
   296  examine_argument (ffi_type *type, enum x86_64_reg_class classes[MAX_CLASSES],
   297  		  _Bool in_return, int *pngpr, int *pnsse)
   298  {
   299    int i, n, ngpr, nsse;
   300  
   301    n = classify_argument (type, classes, 0);
   302    if (n == 0)
   303      return 0;
   304  
   305    ngpr = nsse = 0;
   306    for (i = 0; i < n; ++i)
   307      switch (classes[i])
   308        {
   309        case X86_64_INTEGER_CLASS:
   310        case X86_64_INTEGERSI_CLASS:
   311  	ngpr++;
   312  	break;
   313        case X86_64_SSE_CLASS:
   314        case X86_64_SSESF_CLASS:
   315        case X86_64_SSEDF_CLASS:
   316  	nsse++;
   317  	break;
   318        case X86_64_NO_CLASS:
   319        case X86_64_SSEUP_CLASS:
   320  	break;
   321        case X86_64_X87_CLASS:
   322        case X86_64_X87UP_CLASS:
   323        case X86_64_COMPLEX_X87_CLASS:
   324  	return in_return != 0;
   325        default:
   326  	abort ();
   327        }
   328  
   329    *pngpr = ngpr;
   330    *pnsse = nsse;
   331  
   332    return n;
   333  }
   334  
   335  /* Perform machine dependent cif processing.  */
   336  
   337  ffi_status
   338  ffi_prep_cif_machdep (ffi_cif *cif)
   339  {
   340    int gprcount, ssecount, i, avn, n, ngpr, nsse, flags;
   341    enum x86_64_reg_class classes[MAX_CLASSES];
   342    size_t bytes;
   343  
   344    gprcount = ssecount = 0;
   345  
   346    flags = cif->rtype->type;
   347    if (flags != FFI_TYPE_VOID)
   348      {
   349        n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse);
   350        if (n == 0)
   351  	{
   352  	  /* The return value is passed in memory.  A pointer to that
   353  	     memory is the first argument.  Allocate a register for it.  */
   354  	  gprcount++;
   355  	  /* We don't have to do anything in asm for the return.  */
   356  	  flags = FFI_TYPE_VOID;
   357  	}
   358        else if (flags == FFI_TYPE_STRUCT)
   359  	{
   360  	  /* Mark which registers the result appears in.  */
   361  	  _Bool sse0 = SSE_CLASS_P (classes[0]);
   362  	  _Bool sse1 = n == 2 && SSE_CLASS_P (classes[1]);
   363  	  if (sse0 && !sse1)
   364  	    flags |= 1 << 8;
   365  	  else if (!sse0 && sse1)
   366  	    flags |= 1 << 9;
   367  	  else if (sse0 && sse1)
   368  	    flags |= 1 << 10;
   369  	  /* Mark the true size of the structure.  */
   370  	  flags |= cif->rtype->size << 12;
   371  	}
   372      }
   373  
   374    /* Go over all arguments and determine the way they should be passed.
   375       If it's in a register and there is space for it, let that be so. If
   376       not, add it's size to the stack byte count.  */
   377    for (bytes = 0, i = 0, avn = cif->nargs; i < avn; i++)
   378      {
   379        if (examine_argument (cif->arg_types[i], classes, 0, &ngpr, &nsse) == 0
   380  	  || gprcount + ngpr > MAX_GPR_REGS
   381  	  || ssecount + nsse > MAX_SSE_REGS)
   382  	{
   383  	  long align = cif->arg_types[i]->alignment;
   384  
   385  	  if (align < 8)
   386  	    align = 8;
   387  
   388  	  bytes = ALIGN (bytes, align);
   389  	  bytes += cif->arg_types[i]->size;
   390  	}
   391        else
   392  	{
   393  	  gprcount += ngpr;
   394  	  ssecount += nsse;
   395  	}
   396      }
   397    if (ssecount)
   398      flags |= 1 << 11;
   399    cif->flags = flags;
   400    cif->bytes = ALIGN (bytes, 8);
   401  
   402    return FFI_OK;
   403  }
   404  
   405  void
   406  ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
   407  {
   408    enum x86_64_reg_class classes[MAX_CLASSES];
   409    char *stack, *argp;
   410    ffi_type **arg_types;
   411    int gprcount, ssecount, ngpr, nsse, i, avn;
   412    _Bool ret_in_memory;
   413    struct register_args *reg_args;
   414  
   415    /* Can't call 32-bit mode from 64-bit mode.  */
   416    FFI_ASSERT (cif->abi == FFI_UNIX64);
   417  
   418    /* If the return value is a struct and we don't have a return value
   419       address then we need to make one.  Note the setting of flags to
   420       VOID above in ffi_prep_cif_machdep.  */
   421    ret_in_memory = (cif->rtype->type == FFI_TYPE_STRUCT
   422  		   && (cif->flags & 0xff) == FFI_TYPE_VOID);
   423    if (rvalue == NULL && ret_in_memory)
   424      rvalue = alloca (cif->rtype->size);
   425  
   426    /* Allocate the space for the arguments, plus 4 words of temp space.  */
   427    stack = alloca (sizeof (struct register_args) + cif->bytes + 4*8);
   428    reg_args = (struct register_args *) stack;
   429    argp = stack + sizeof (struct register_args);
   430  
   431    gprcount = ssecount = 0;
   432  
   433    /* If the return value is passed in memory, add the pointer as the
   434       first integer argument.  */
   435    if (ret_in_memory)
   436      reg_args->gpr[gprcount++] = (unsigned long) rvalue;
   437  
   438    avn = cif->nargs;
   439    arg_types = cif->arg_types;
   440  
   441    for (i = 0; i < avn; ++i)
   442      {
   443        size_t size = arg_types[i]->size;
   444        int n;
   445  
   446        n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse);
   447        if (n == 0
   448  	  || gprcount + ngpr > MAX_GPR_REGS
   449  	  || ssecount + nsse > MAX_SSE_REGS)
   450  	{
   451  	  long align = arg_types[i]->alignment;
   452  
   453  	  /* Stack arguments are *always* at least 8 byte aligned.  */
   454  	  if (align < 8)
   455  	    align = 8;
   456  
   457  	  /* Pass this argument in memory.  */
   458  	  argp = (void *) ALIGN (argp, align);
   459  	  memcpy (argp, avalue[i], size);
   460  	  argp += size;
   461  	}
   462        else
   463  	{
   464  	  /* The argument is passed entirely in registers.  */
   465  	  char *a = (char *) avalue[i];
   466  	  int j;
   467  
   468  	  for (j = 0; j < n; j++, a += 8, size -= 8)
   469  	    {
   470  	      switch (classes[j])
   471  		{
   472  		case X86_64_INTEGER_CLASS:
   473  		case X86_64_INTEGERSI_CLASS:
   474  		  reg_args->gpr[gprcount] = 0;
   475  		  memcpy (&reg_args->gpr[gprcount], a, size < 8 ? size : 8);
   476  		  gprcount++;
   477  		  break;
   478  		case X86_64_SSE_CLASS:
   479  		case X86_64_SSEDF_CLASS:
   480  		  reg_args->sse[ssecount++] = *(UINT64 *) a;
   481  		  break;
   482  		case X86_64_SSESF_CLASS:
   483  		  reg_args->sse[ssecount++] = *(UINT32 *) a;
   484  		  break;
   485  		default:
   486  		  abort();
   487  		}
   488  	    }
   489  	}
   490      }
   491  
   492    ffi_call_unix64 (stack, cif->bytes + sizeof (struct register_args),
   493  		   cif->flags, rvalue, fn, ssecount);
   494  }
   495  
   496  
   497  extern void ffi_closure_unix64(void);
   498  
   499  ffi_status
   500  ffi_prep_closure_loc (ffi_closure* closure,
   501  		      ffi_cif* cif,
   502  		      void (*fun)(ffi_cif*, void*, void**, void*),
   503  		      void *user_data,
   504  		      void *codeloc)
   505  {
   506    volatile unsigned short *tramp;
   507  
   508    /* Sanity check on the cif ABI.  */
   509    {
   510      int abi = cif->abi;
   511      if (UNLIKELY (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI)))
   512        return FFI_BAD_ABI;
   513    }
   514  
   515    tramp = (volatile unsigned short *) &closure->tramp[0];
   516  
   517    tramp[0] = 0xbb49;		/* mov <code>, %r11	*/
   518    *((unsigned long long * volatile) &tramp[1])
   519      = (unsigned long) ffi_closure_unix64;
   520    tramp[5] = 0xba49;		/* mov <data>, %r10	*/
   521    *((unsigned long long * volatile) &tramp[6])
   522      = (unsigned long) codeloc;
   523  
   524    /* Set the carry bit iff the function uses any sse registers.
   525       This is clc or stc, together with the first byte of the jmp.  */
   526    tramp[10] = cif->flags & (1 << 11) ? 0x49f9 : 0x49f8;
   527  
   528    tramp[11] = 0xe3ff;			/* jmp *%r11    */
   529  
   530    closure->cif = cif;
   531    closure->fun = fun;
   532    closure->user_data = user_data;
   533  
   534    return FFI_OK;
   535  }
   536  
   537  int
   538  ffi_closure_unix64_inner(ffi_closure *closure, void *rvalue,
   539  			 struct register_args *reg_args, char *argp)
   540  {
   541    ffi_cif *cif;
   542    void **avalue;
   543    ffi_type **arg_types;
   544    long i, avn;
   545    int gprcount, ssecount, ngpr, nsse;
   546    int ret;
   547  
   548    cif = closure->cif;
   549    avalue = alloca(cif->nargs * sizeof(void *));
   550    gprcount = ssecount = 0;
   551  
   552    ret = cif->rtype->type;
   553    if (ret != FFI_TYPE_VOID)
   554      {
   555        enum x86_64_reg_class classes[MAX_CLASSES];
   556        int n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse);
   557        if (n == 0)
   558  	{
   559  	  /* The return value goes in memory.  Arrange for the closure
   560  	     return value to go directly back to the original caller.  */
   561  	  rvalue = (void *) (unsigned long) reg_args->gpr[gprcount++];
   562  	  /* We don't have to do anything in asm for the return.  */
   563  	  ret = FFI_TYPE_VOID;
   564  	}
   565        else if (ret == FFI_TYPE_STRUCT && n == 2)
   566  	{
   567  	  /* Mark which register the second word of the structure goes in.  */
   568  	  _Bool sse0 = SSE_CLASS_P (classes[0]);
   569  	  _Bool sse1 = SSE_CLASS_P (classes[1]);
   570  	  if (!sse0 && sse1)
   571  	    ret |= 1 << 8;
   572  	  else if (sse0 && !sse1)
   573  	    ret |= 1 << 9;
   574  	}
   575      }
   576  
   577    avn = cif->nargs;
   578    arg_types = cif->arg_types;
   579    
   580    for (i = 0; i < avn; ++i)
   581      {
   582        enum x86_64_reg_class classes[MAX_CLASSES];
   583        int n;
   584  
   585        n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse);
   586        if (n == 0
   587  	  || gprcount + ngpr > MAX_GPR_REGS
   588  	  || ssecount + nsse > MAX_SSE_REGS)
   589  	{
   590  	  long align = arg_types[i]->alignment;
   591  
   592  	  /* Stack arguments are *always* at least 8 byte aligned.  */
   593  	  if (align < 8)
   594  	    align = 8;
   595  
   596  	  /* Pass this argument in memory.  */
   597  	  argp = (void *) ALIGN (argp, align);
   598  	  avalue[i] = argp;
   599  	  argp += arg_types[i]->size;
   600  	}
   601        /* If the argument is in a single register, or two consecutive
   602  	 integer registers, then we can use that address directly.  */
   603        else if (n == 1
   604  	       || (n == 2 && !(SSE_CLASS_P (classes[0])
   605  			       || SSE_CLASS_P (classes[1]))))
   606  	{
   607  	  /* The argument is in a single register.  */
   608  	  if (SSE_CLASS_P (classes[0]))
   609  	    {
   610  	      avalue[i] = &reg_args->sse[ssecount];
   611  	      ssecount += n;
   612  	    }
   613  	  else
   614  	    {
   615  	      avalue[i] = &reg_args->gpr[gprcount];
   616  	      gprcount += n;
   617  	    }
   618  	}
   619        /* Otherwise, allocate space to make them consecutive.  */
   620        else
   621  	{
   622  	  char *a = alloca (16);
   623  	  int j;
   624  
   625  	  avalue[i] = a;
   626  	  for (j = 0; j < n; j++, a += 8)
   627  	    {
   628  	      if (SSE_CLASS_P (classes[j]))
   629  		memcpy (a, &reg_args->sse[ssecount++], 8);
   630  	      else
   631  		memcpy (a, &reg_args->gpr[gprcount++], 8);
   632  	    }
   633  	}
   634      }
   635  
   636    /* Invoke the closure.  */
   637    closure->fun (cif, rvalue, avalue, closure->user_data);
   638  
   639    /* Tell assembly how to perform return type promotions.  */
   640    return ret;
   641  }
   642  
   643  #endif /* __x86_64__ */