Static tramp v5 (#624)
[platform/upstream/libffi.git] / src / x86 / ffi.c
1 /* -----------------------------------------------------------------------
2    ffi.c - Copyright (c) 2017  Anthony Green
3            Copyright (c) 1996, 1998, 1999, 2001, 2007, 2008  Red Hat, Inc.
4            Copyright (c) 2002  Ranjit Mathew
5            Copyright (c) 2002  Bo Thorsen
6            Copyright (c) 2002  Roger Sayle
7            Copyright (C) 2008, 2010  Free Software Foundation, Inc.
8
9    x86 Foreign Function Interface
10
11    Permission is hereby granted, free of charge, to any person obtaining
12    a copy of this software and associated documentation files (the
13    ``Software''), to deal in the Software without restriction, including
14    without limitation the rights to use, copy, modify, merge, publish,
15    distribute, sublicense, and/or sell copies of the Software, and to
16    permit persons to whom the Software is furnished to do so, subject to
17    the following conditions:
18
19    The above copyright notice and this permission notice shall be included
20    in all copies or substantial portions of the Software.
21
22    THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
23    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25    NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
27    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29    DEALINGS IN THE SOFTWARE.
30    ----------------------------------------------------------------------- */
31
32 #if defined(__i386__) || defined(_M_IX86)
33 #include <ffi.h>
34 #include <ffi_common.h>
35 #include <stdint.h>
36 #include <stdlib.h>
37 #include <tramp.h>
38 #include "internal.h"
39
40 /* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE;
41    all further uses in this file will refer to the 80-bit type.  */
42 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
43 # if FFI_TYPE_LONGDOUBLE != 4
44 #  error FFI_TYPE_LONGDOUBLE out of date
45 # endif
46 #else
47 # undef FFI_TYPE_LONGDOUBLE
48 # define FFI_TYPE_LONGDOUBLE 4
49 #endif
50
51 #if defined(__GNUC__) && !defined(__declspec)
52 # define __declspec(x)  __attribute__((x))
53 #endif
54
55 #if defined(_MSC_VER) && defined(_M_IX86)
56 /* Stack is not 16-byte aligned on Windows.  */
57 #define STACK_ALIGN(bytes) (bytes)
58 #else
59 #define STACK_ALIGN(bytes) FFI_ALIGN (bytes, 16)
60 #endif
61
62 /* Perform machine dependent cif processing.  */
63 ffi_status FFI_HIDDEN
64 ffi_prep_cif_machdep(ffi_cif *cif)
65 {
66   size_t bytes = 0;
67   int i, n, flags, cabi = cif->abi;
68
69   switch (cabi)
70     {
71     case FFI_SYSV:
72     case FFI_STDCALL:
73     case FFI_THISCALL:
74     case FFI_FASTCALL:
75     case FFI_MS_CDECL:
76     case FFI_PASCAL:
77     case FFI_REGISTER:
78       break;
79     default:
80       return FFI_BAD_ABI;
81     }
82
83   switch (cif->rtype->type)
84     {
85     case FFI_TYPE_VOID:
86       flags = X86_RET_VOID;
87       break;
88     case FFI_TYPE_FLOAT:
89       flags = X86_RET_FLOAT;
90       break;
91     case FFI_TYPE_DOUBLE:
92       flags = X86_RET_DOUBLE;
93       break;
94     case FFI_TYPE_LONGDOUBLE:
95       flags = X86_RET_LDOUBLE;
96       break;
97     case FFI_TYPE_UINT8:
98       flags = X86_RET_UINT8;
99       break;
100     case FFI_TYPE_UINT16:
101       flags = X86_RET_UINT16;
102       break;
103     case FFI_TYPE_SINT8:
104       flags = X86_RET_SINT8;
105       break;
106     case FFI_TYPE_SINT16:
107       flags = X86_RET_SINT16;
108       break;
109     case FFI_TYPE_INT:
110     case FFI_TYPE_SINT32:
111     case FFI_TYPE_UINT32:
112     case FFI_TYPE_POINTER:
113       flags = X86_RET_INT32;
114       break;
115     case FFI_TYPE_SINT64:
116     case FFI_TYPE_UINT64:
117       flags = X86_RET_INT64;
118       break;
119     case FFI_TYPE_STRUCT:
120 #ifndef X86
121       /* ??? This should be a different ABI rather than an ifdef.  */
122       if (cif->rtype->size == 1)
123         flags = X86_RET_STRUCT_1B;
124       else if (cif->rtype->size == 2)
125         flags = X86_RET_STRUCT_2B;
126       else if (cif->rtype->size == 4)
127         flags = X86_RET_INT32;
128       else if (cif->rtype->size == 8)
129         flags = X86_RET_INT64;
130       else
131 #endif
132         {
133         do_struct:
134           switch (cabi)
135             {
136             case FFI_THISCALL:
137             case FFI_FASTCALL:
138             case FFI_STDCALL:
139             case FFI_MS_CDECL:
140               flags = X86_RET_STRUCTARG;
141               break;
142             default:
143               flags = X86_RET_STRUCTPOP;
144               break;
145             }
146           /* Allocate space for return value pointer.  */
147           bytes += FFI_ALIGN (sizeof(void*), FFI_SIZEOF_ARG);
148         }
149       break;
150     case FFI_TYPE_COMPLEX:
151       switch (cif->rtype->elements[0]->type)
152         {
153         case FFI_TYPE_DOUBLE:
154         case FFI_TYPE_LONGDOUBLE:
155         case FFI_TYPE_SINT64:
156         case FFI_TYPE_UINT64:
157           goto do_struct;
158         case FFI_TYPE_FLOAT:
159         case FFI_TYPE_INT:
160         case FFI_TYPE_SINT32:
161         case FFI_TYPE_UINT32:
162           flags = X86_RET_INT64;
163           break;
164         case FFI_TYPE_SINT16:
165         case FFI_TYPE_UINT16:
166           flags = X86_RET_INT32;
167           break;
168         case FFI_TYPE_SINT8:
169         case FFI_TYPE_UINT8:
170           flags = X86_RET_STRUCT_2B;
171           break;
172         default:
173           return FFI_BAD_TYPEDEF;
174         }
175       break;
176     default:
177       return FFI_BAD_TYPEDEF;
178     }
179   cif->flags = flags;
180
181   for (i = 0, n = cif->nargs; i < n; i++)
182     {
183       ffi_type *t = cif->arg_types[i];
184
185       bytes = FFI_ALIGN (bytes, t->alignment);
186       bytes += FFI_ALIGN (t->size, FFI_SIZEOF_ARG);
187     }
188   cif->bytes = bytes;
189
190   return FFI_OK;
191 }
192
193 static ffi_arg
194 extend_basic_type(void *arg, int type)
195 {
196   switch (type)
197     {
198     case FFI_TYPE_SINT8:
199       return *(SINT8 *)arg;
200     case FFI_TYPE_UINT8:
201       return *(UINT8 *)arg;
202     case FFI_TYPE_SINT16:
203       return *(SINT16 *)arg;
204     case FFI_TYPE_UINT16:
205       return *(UINT16 *)arg;
206
207     case FFI_TYPE_SINT32:
208     case FFI_TYPE_UINT32:
209     case FFI_TYPE_POINTER:
210     case FFI_TYPE_FLOAT:
211       return *(UINT32 *)arg;
212
213     default:
214       abort();
215     }
216 }
217
218 struct call_frame
219 {
220   void *ebp;            /* 0 */
221   void *retaddr;        /* 4 */
222   void (*fn)(void);     /* 8 */
223   int flags;            /* 12 */
224   void *rvalue;         /* 16 */
225   unsigned regs[3];     /* 20-28 */
226 };
227
228 struct abi_params
229 {
230   int dir;              /* parameter growth direction */
231   int static_chain;     /* the static chain register used by gcc */
232   int nregs;            /* number of register parameters */
233   int regs[3];
234 };
235
236 static const struct abi_params abi_params[FFI_LAST_ABI] = {
237   [FFI_SYSV] = { 1, R_ECX, 0 },
238   [FFI_THISCALL] = { 1, R_EAX, 1, { R_ECX } },
239   [FFI_FASTCALL] = { 1, R_EAX, 2, { R_ECX, R_EDX } },
240   [FFI_STDCALL] = { 1, R_ECX, 0 },
241   [FFI_PASCAL] = { -1, R_ECX, 0 },
242   /* ??? No defined static chain; gcc does not support REGISTER.  */
243   [FFI_REGISTER] = { -1, R_ECX, 3, { R_EAX, R_EDX, R_ECX } },
244   [FFI_MS_CDECL] = { 1, R_ECX, 0 }
245 };
246
247 #ifdef HAVE_FASTCALL
248   #ifdef _MSC_VER
249     #define FFI_DECLARE_FASTCALL __fastcall
250   #else
251     #define FFI_DECLARE_FASTCALL __declspec(fastcall)
252   #endif
253 #else
254   #define FFI_DECLARE_FASTCALL
255 #endif
256
257 extern void FFI_DECLARE_FASTCALL ffi_call_i386(struct call_frame *, char *) FFI_HIDDEN;
258
259 static void
260 ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
261               void **avalue, void *closure)
262 {
263   size_t rsize, bytes;
264   struct call_frame *frame;
265   char *stack, *argp;
266   ffi_type **arg_types;
267   int flags, cabi, i, n, dir, narg_reg;
268   const struct abi_params *pabi;
269
270   flags = cif->flags;
271   cabi = cif->abi;
272   pabi = &abi_params[cabi];
273   dir = pabi->dir;
274
275   rsize = 0;
276   if (rvalue == NULL)
277     {
278       switch (flags)
279         {
280         case X86_RET_FLOAT:
281         case X86_RET_DOUBLE:
282         case X86_RET_LDOUBLE:
283         case X86_RET_STRUCTPOP:
284         case X86_RET_STRUCTARG:
285           /* The float cases need to pop the 387 stack.
286              The struct cases need to pass a valid pointer to the callee.  */
287           rsize = cif->rtype->size;
288           break;
289         default:
290           /* We can pretend that the callee returns nothing.  */
291           flags = X86_RET_VOID;
292           break;
293         }
294     }
295
296   bytes = STACK_ALIGN (cif->bytes);
297   stack = alloca(bytes + sizeof(*frame) + rsize);
298   argp = (dir < 0 ? stack + bytes : stack);
299   frame = (struct call_frame *)(stack + bytes);
300   if (rsize)
301     rvalue = frame + 1;
302
303   frame->fn = fn;
304   frame->flags = flags;
305   frame->rvalue = rvalue;
306   frame->regs[pabi->static_chain] = (unsigned)closure;
307
308   narg_reg = 0;
309   switch (flags)
310     {
311     case X86_RET_STRUCTARG:
312       /* The pointer is passed as the first argument.  */
313       if (pabi->nregs > 0)
314         {
315           frame->regs[pabi->regs[0]] = (unsigned)rvalue;
316           narg_reg = 1;
317           break;
318         }
319       /* fallthru */
320     case X86_RET_STRUCTPOP:
321       *(void **)argp = rvalue;
322       argp += sizeof(void *);
323       break;
324     }
325
326   arg_types = cif->arg_types;
327   for (i = 0, n = cif->nargs; i < n; i++)
328     {
329       ffi_type *ty = arg_types[i];
330       void *valp = avalue[i];
331       size_t z = ty->size;
332       int t = ty->type;
333
334       if (z <= FFI_SIZEOF_ARG && t != FFI_TYPE_STRUCT)
335         {
336           ffi_arg val = extend_basic_type (valp, t);
337
338           if (t != FFI_TYPE_FLOAT && narg_reg < pabi->nregs)
339             frame->regs[pabi->regs[narg_reg++]] = val;
340           else if (dir < 0)
341             {
342               argp -= 4;
343               *(ffi_arg *)argp = val;
344             }
345           else
346             {
347               *(ffi_arg *)argp = val;
348               argp += 4;
349             }
350         }
351       else
352         {
353           size_t za = FFI_ALIGN (z, FFI_SIZEOF_ARG);
354           size_t align = FFI_SIZEOF_ARG;
355
356           /* Issue 434: For thiscall and fastcall, if the paramter passed
357              as 64-bit integer or struct, all following integer parameters
358              will be passed on stack.  */
359           if ((cabi == FFI_THISCALL || cabi == FFI_FASTCALL)
360               && (t == FFI_TYPE_SINT64
361                   || t == FFI_TYPE_UINT64
362                   || t == FFI_TYPE_STRUCT))
363             narg_reg = 2;
364
365           /* Alignment rules for arguments are quite complex.  Vectors and
366              structures with 16 byte alignment get it.  Note that long double
367              on Darwin does have 16 byte alignment, and does not get this
368              alignment if passed directly; a structure with a long double
369              inside, however, would get 16 byte alignment.  Since libffi does
370              not support vectors, we need non concern ourselves with other
371              cases.  */
372           if (t == FFI_TYPE_STRUCT && ty->alignment >= 16)
373             align = 16;
374             
375           if (dir < 0)
376             {
377               /* ??? These reverse argument ABIs are probably too old
378                  to have cared about alignment.  Someone should check.  */
379               argp -= za;
380               memcpy (argp, valp, z);
381             }
382           else
383             {
384               argp = (char *)FFI_ALIGN (argp, align);
385               memcpy (argp, valp, z);
386               argp += za;
387             }
388         }
389     }
390   FFI_ASSERT (dir > 0 || argp == stack);
391
392   ffi_call_i386 (frame, stack);
393 }
394
395 void
396 ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
397 {
398   ffi_call_int (cif, fn, rvalue, avalue, NULL);
399 }
400
401 #ifdef FFI_GO_CLOSURES
402 void
403 ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
404              void **avalue, void *closure)
405 {
406   ffi_call_int (cif, fn, rvalue, avalue, closure);
407 }
408 #endif
409
410 /** private members **/
411
412 void FFI_HIDDEN ffi_closure_i386(void);
413 void FFI_HIDDEN ffi_closure_STDCALL(void);
414 void FFI_HIDDEN ffi_closure_REGISTER(void);
415 #if defined(FFI_EXEC_STATIC_TRAMP)
416 void FFI_HIDDEN ffi_closure_i386_alt(void);
417 void FFI_HIDDEN ffi_closure_STDCALL_alt(void);
418 void FFI_HIDDEN ffi_closure_REGISTER_alt(void);
419 #endif
420
421 struct closure_frame
422 {
423   unsigned rettemp[4];                          /* 0 */
424   unsigned regs[3];                             /* 16-24 */
425   ffi_cif *cif;                                 /* 28 */
426   void (*fun)(ffi_cif*,void*,void**,void*);     /* 32 */
427   void *user_data;                              /* 36 */
428 };
429
430 int FFI_HIDDEN FFI_DECLARE_FASTCALL
431 ffi_closure_inner (struct closure_frame *frame, char *stack)
432 {
433   ffi_cif *cif = frame->cif;
434   int cabi, i, n, flags, dir, narg_reg;
435   const struct abi_params *pabi;
436   ffi_type **arg_types;
437   char *argp;
438   void *rvalue;
439   void **avalue;
440
441   cabi = cif->abi;
442   flags = cif->flags;
443   narg_reg = 0;
444   rvalue = frame->rettemp;
445   pabi = &abi_params[cabi];
446   dir = pabi->dir;
447   argp = (dir < 0 ? stack + STACK_ALIGN (cif->bytes) : stack);
448
449   switch (flags)
450     {
451     case X86_RET_STRUCTARG:
452       if (pabi->nregs > 0)
453         {
454           rvalue = (void *)frame->regs[pabi->regs[0]];
455           narg_reg = 1;
456           frame->rettemp[0] = (unsigned)rvalue;
457           break;
458         }
459       /* fallthru */
460     case X86_RET_STRUCTPOP:
461       rvalue = *(void **)argp;
462       argp += sizeof(void *);
463       frame->rettemp[0] = (unsigned)rvalue;
464       break;
465     }
466
467   n = cif->nargs;
468   avalue = alloca(sizeof(void *) * n);
469
470   arg_types = cif->arg_types;
471   for (i = 0; i < n; ++i)
472     {
473       ffi_type *ty = arg_types[i];
474       size_t z = ty->size;
475       int t = ty->type;
476       void *valp;
477
478       if (z <= FFI_SIZEOF_ARG && t != FFI_TYPE_STRUCT)
479         {
480           if (t != FFI_TYPE_FLOAT && narg_reg < pabi->nregs)
481             valp = &frame->regs[pabi->regs[narg_reg++]];
482           else if (dir < 0)
483             {
484               argp -= 4;
485               valp = argp;
486             }
487           else
488             {
489               valp = argp;
490               argp += 4;
491             }
492         }
493       else
494         {
495           size_t za = FFI_ALIGN (z, FFI_SIZEOF_ARG);
496           size_t align = FFI_SIZEOF_ARG;
497
498           /* See the comment in ffi_call_int.  */
499           if (t == FFI_TYPE_STRUCT && ty->alignment >= 16)
500             align = 16;
501
502           /* Issue 434: For thiscall and fastcall, if the paramter passed
503              as 64-bit integer or struct, all following integer parameters
504              will be passed on stack.  */
505           if ((cabi == FFI_THISCALL || cabi == FFI_FASTCALL)
506               && (t == FFI_TYPE_SINT64
507                   || t == FFI_TYPE_UINT64
508                   || t == FFI_TYPE_STRUCT))
509             narg_reg = 2;
510
511           if (dir < 0)
512             {
513               /* ??? These reverse argument ABIs are probably too old
514                  to have cared about alignment.  Someone should check.  */
515               argp -= za;
516               valp = argp;
517             }
518           else
519             {
520               argp = (char *)FFI_ALIGN (argp, align);
521               valp = argp;
522               argp += za;
523             }
524         }
525
526       avalue[i] = valp;
527     }
528
529   frame->fun (cif, rvalue, avalue, frame->user_data);
530
531   if (cabi == FFI_STDCALL)
532     return flags + (cif->bytes << X86_RET_POP_SHIFT);
533   else
534     return flags;
535 }
536
537 ffi_status
538 ffi_prep_closure_loc (ffi_closure* closure,
539                       ffi_cif* cif,
540                       void (*fun)(ffi_cif*,void*,void**,void*),
541                       void *user_data,
542                       void *codeloc)
543 {
544   char *tramp = closure->tramp;
545   void (*dest)(void);
546   int op = 0xb8;  /* movl imm, %eax */
547
548   switch (cif->abi)
549     {
550     case FFI_SYSV:
551     case FFI_THISCALL:
552     case FFI_FASTCALL:
553     case FFI_MS_CDECL:
554       dest = ffi_closure_i386;
555       break;
556     case FFI_STDCALL:
557     case FFI_PASCAL:
558       dest = ffi_closure_STDCALL;
559       break;
560     case FFI_REGISTER:
561       dest = ffi_closure_REGISTER;
562       op = 0x68;  /* pushl imm */
563       break;
564     default:
565       return FFI_BAD_ABI;
566     }
567
568 #if defined(FFI_EXEC_STATIC_TRAMP)
569   if (ffi_tramp_is_present(closure))
570     {
571       /* Initialize the static trampoline's parameters. */
572       if (dest == ffi_closure_i386)
573         dest = ffi_closure_i386_alt;
574       else if (dest == ffi_closure_STDCALL)
575         dest = ffi_closure_STDCALL_alt;
576       else
577         dest = ffi_closure_REGISTER_alt;
578       ffi_tramp_set_parms (closure->ftramp, dest, closure);
579       goto out;
580     }
581 #endif
582
583   /* Initialize the dynamic trampoline. */
584   /* endbr32.  */
585   *(UINT32 *) tramp = 0xfb1e0ff3;
586
587   /* movl or pushl immediate.  */
588   tramp[4] = op;
589   *(void **)(tramp + 5) = codeloc;
590
591   /* jmp dest */
592   tramp[9] = 0xe9;
593   *(unsigned *)(tramp + 10) = (unsigned)dest - ((unsigned)codeloc + 14);
594
595 out:
596   closure->cif = cif;
597   closure->fun = fun;
598   closure->user_data = user_data;
599
600   return FFI_OK;
601 }
602
603 #ifdef FFI_GO_CLOSURES
604
605 void FFI_HIDDEN ffi_go_closure_EAX(void);
606 void FFI_HIDDEN ffi_go_closure_ECX(void);
607 void FFI_HIDDEN ffi_go_closure_STDCALL(void);
608
609 ffi_status
610 ffi_prep_go_closure (ffi_go_closure* closure, ffi_cif* cif,
611                      void (*fun)(ffi_cif*,void*,void**,void*))
612 {
613   void (*dest)(void);
614
615   switch (cif->abi)
616     {
617     case FFI_SYSV:
618     case FFI_MS_CDECL:
619       dest = ffi_go_closure_ECX;
620       break;
621     case FFI_THISCALL:
622     case FFI_FASTCALL:
623       dest = ffi_go_closure_EAX;
624       break;
625     case FFI_STDCALL:
626     case FFI_PASCAL:
627       dest = ffi_go_closure_STDCALL;
628       break;
629     case FFI_REGISTER:
630     default:
631       return FFI_BAD_ABI;
632     }
633
634   closure->tramp = dest;
635   closure->cif = cif;
636   closure->fun = fun;
637
638   return FFI_OK;
639 }
640
641 #endif /* FFI_GO_CLOSURES */
642
643 /* ------- Native raw API support -------------------------------- */
644
645 #if !FFI_NO_RAW_API
646
647 void FFI_HIDDEN ffi_closure_raw_SYSV(void);
648 void FFI_HIDDEN ffi_closure_raw_THISCALL(void);
649
650 ffi_status
651 ffi_prep_raw_closure_loc (ffi_raw_closure *closure,
652                           ffi_cif *cif,
653                           void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
654                           void *user_data,
655                           void *codeloc)
656 {
657   char *tramp = closure->tramp;
658   void (*dest)(void);
659   int i;
660
661   /* We currently don't support certain kinds of arguments for raw
662      closures.  This should be implemented by a separate assembly
663      language routine, since it would require argument processing,
664      something we don't do now for performance.  */
665   for (i = cif->nargs-1; i >= 0; i--)
666     switch (cif->arg_types[i]->type)
667       {
668       case FFI_TYPE_STRUCT:
669       case FFI_TYPE_LONGDOUBLE:
670         return FFI_BAD_TYPEDEF;
671       }
672
673   switch (cif->abi)
674     {
675     case FFI_THISCALL:
676       dest = ffi_closure_raw_THISCALL;
677       break;
678     case FFI_SYSV:
679       dest = ffi_closure_raw_SYSV;
680       break;
681     default:
682       return FFI_BAD_ABI;
683     }
684
685   /* movl imm, %eax.  */
686   tramp[0] = 0xb8;
687   *(void **)(tramp + 1) = codeloc;
688
689   /* jmp dest */
690   tramp[5] = 0xe9;
691   *(unsigned *)(tramp + 6) = (unsigned)dest - ((unsigned)codeloc + 10);
692
693   closure->cif = cif;
694   closure->fun = fun;
695   closure->user_data = user_data;
696
697   return FFI_OK;
698 }
699
700 void
701 ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *avalue)
702 {
703   size_t rsize, bytes;
704   struct call_frame *frame;
705   char *stack, *argp;
706   ffi_type **arg_types;
707   int flags, cabi, i, n, narg_reg;
708   const struct abi_params *pabi;
709
710   flags = cif->flags;
711   cabi = cif->abi;
712   pabi = &abi_params[cabi];
713
714   rsize = 0;
715   if (rvalue == NULL)
716     {
717       switch (flags)
718         {
719         case X86_RET_FLOAT:
720         case X86_RET_DOUBLE:
721         case X86_RET_LDOUBLE:
722         case X86_RET_STRUCTPOP:
723         case X86_RET_STRUCTARG:
724           /* The float cases need to pop the 387 stack.
725              The struct cases need to pass a valid pointer to the callee.  */
726           rsize = cif->rtype->size;
727           break;
728         default:
729           /* We can pretend that the callee returns nothing.  */
730           flags = X86_RET_VOID;
731           break;
732         }
733     }
734
735   bytes = STACK_ALIGN (cif->bytes);
736   argp = stack =
737       (void *)((uintptr_t)alloca(bytes + sizeof(*frame) + rsize + 15) & ~16);
738   frame = (struct call_frame *)(stack + bytes);
739   if (rsize)
740     rvalue = frame + 1;
741
742   frame->fn = fn;
743   frame->flags = flags;
744   frame->rvalue = rvalue;
745
746   narg_reg = 0;
747   switch (flags)
748     {
749     case X86_RET_STRUCTARG:
750       /* The pointer is passed as the first argument.  */
751       if (pabi->nregs > 0)
752         {
753           frame->regs[pabi->regs[0]] = (unsigned)rvalue;
754           narg_reg = 1;
755           break;
756         }
757       /* fallthru */
758     case X86_RET_STRUCTPOP:
759       *(void **)argp = rvalue;
760       argp += sizeof(void *);
761       bytes -= sizeof(void *);
762       break;
763     }
764
765   arg_types = cif->arg_types;
766   for (i = 0, n = cif->nargs; narg_reg < pabi->nregs && i < n; i++)
767     {
768       ffi_type *ty = arg_types[i];
769       size_t z = ty->size;
770       int t = ty->type;
771
772       if (z <= FFI_SIZEOF_ARG && t != FFI_TYPE_STRUCT && t != FFI_TYPE_FLOAT)
773         {
774           ffi_arg val = extend_basic_type (avalue, t);
775           frame->regs[pabi->regs[narg_reg++]] = val;
776           z = FFI_SIZEOF_ARG;
777         }
778       else
779         {
780           memcpy (argp, avalue, z);
781           z = FFI_ALIGN (z, FFI_SIZEOF_ARG);
782           argp += z;
783         }
784       avalue += z;
785       bytes -= z;
786     }
787   if (i < n)
788     memcpy (argp, avalue, bytes);
789
790   ffi_call_i386 (frame, stack);
791 }
792 #endif /* !FFI_NO_RAW_API */
793
794 #if defined(FFI_EXEC_STATIC_TRAMP)
795 void *
796 ffi_tramp_arch (size_t *tramp_size, size_t *map_size)
797 {
798   extern void *trampoline_code_table;
799
800   *map_size = X86_TRAMP_MAP_SIZE;
801   *tramp_size = X86_TRAMP_SIZE;
802   return &trampoline_code_table;
803 }
804 #endif
805
806 #endif /* __i386__ */