eda/EDASQLite: Improved SQL Custom Functions support, now taking an arbitrary set...
[sdk] / deps / libffi-3.0.11 / src / sh / ffi.c
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 }