ยปCore Development>Code coverage>Modules/_ctypes/libffi/src/s390/ffi.c

Python code coverage for Modules/_ctypes/libffi/src/s390/ffi.c

#countcontent
1n/a/* -----------------------------------------------------------------------
2n/a ffi.c - Copyright (c) 2000, 2007 Software AG
3n/a Copyright (c) 2008 Red Hat, Inc
4n/a
5n/a S390 Foreign Function Interface
6n/a
7n/a Permission is hereby granted, free of charge, to any person obtaining
8n/a a copy of this software and associated documentation files (the
9n/a ``Software''), to deal in the Software without restriction, including
10n/a without limitation the rights to use, copy, modify, merge, publish,
11n/a distribute, sublicense, and/or sell copies of the Software, and to
12n/a permit persons to whom the Software is furnished to do so, subject to
13n/a the following conditions:
14n/a
15n/a The above copyright notice and this permission notice shall be included
16n/a in all copies or substantial portions of the Software.
17n/a
18n/a THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
19n/a OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20n/a MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21n/a IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
22n/a OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23n/a ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24n/a OTHER DEALINGS IN THE SOFTWARE.
25n/a ----------------------------------------------------------------------- */
26n/a/*====================================================================*/
27n/a/* Includes */
28n/a/* -------- */
29n/a/*====================================================================*/
30n/a
31n/a#include <ffi.h>
32n/a#include <ffi_common.h>
33n/a
34n/a#include <stdlib.h>
35n/a#include <stdio.h>
36n/a
37n/a/*====================== End of Includes =============================*/
38n/a
39n/a/*====================================================================*/
40n/a/* Defines */
41n/a/* ------- */
42n/a/*====================================================================*/
43n/a
44n/a/* Maximum number of GPRs available for argument passing. */
45n/a#define MAX_GPRARGS 5
46n/a
47n/a/* Maximum number of FPRs available for argument passing. */
48n/a#ifdef __s390x__
49n/a#define MAX_FPRARGS 4
50n/a#else
51n/a#define MAX_FPRARGS 2
52n/a#endif
53n/a
54n/a/* Round to multiple of 16. */
55n/a#define ROUND_SIZE(size) (((size) + 15) & ~15)
56n/a
57n/a/* If these values change, sysv.S must be adapted! */
58n/a#define FFI390_RET_VOID 0
59n/a#define FFI390_RET_STRUCT 1
60n/a#define FFI390_RET_FLOAT 2
61n/a#define FFI390_RET_DOUBLE 3
62n/a#define FFI390_RET_INT32 4
63n/a#define FFI390_RET_INT64 5
64n/a
65n/a/*===================== End of Defines ===============================*/
66n/a
67n/a/*====================================================================*/
68n/a/* Prototypes */
69n/a/* ---------- */
70n/a/*====================================================================*/
71n/a
72n/astatic void ffi_prep_args (unsigned char *, extended_cif *);
73n/avoid
74n/a#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
75n/a__attribute__ ((visibility ("hidden")))
76n/a#endif
77n/affi_closure_helper_SYSV (ffi_closure *, unsigned long *,
78n/a unsigned long long *, unsigned long *);
79n/a
80n/a/*====================== End of Prototypes ===========================*/
81n/a
82n/a/*====================================================================*/
83n/a/* Externals */
84n/a/* --------- */
85n/a/*====================================================================*/
86n/a
87n/aextern void ffi_call_SYSV(unsigned,
88n/a extended_cif *,
89n/a void (*)(unsigned char *, extended_cif *),
90n/a unsigned,
91n/a void *,
92n/a void (*fn)(void));
93n/a
94n/aextern void ffi_closure_SYSV(void);
95n/a
96n/a/*====================== End of Externals ============================*/
97n/a
98n/a/*====================================================================*/
99n/a/* */
100n/a/* Name - ffi_check_struct_type. */
101n/a/* */
102n/a/* Function - Determine if a structure can be passed within a */
103n/a/* general purpose or floating point register. */
104n/a/* */
105n/a/*====================================================================*/
106n/a
107n/astatic int
108n/affi_check_struct_type (ffi_type *arg)
109n/a{
110n/a size_t size = arg->size;
111n/a
112n/a /* If the struct has just one element, look at that element
113n/a to find out whether to consider the struct as floating point. */
114n/a while (arg->type == FFI_TYPE_STRUCT
115n/a && arg->elements[0] && !arg->elements[1])
116n/a arg = arg->elements[0];
117n/a
118n/a /* Structs of size 1, 2, 4, and 8 are passed in registers,
119n/a just like the corresponding int/float types. */
120n/a switch (size)
121n/a {
122n/a case 1:
123n/a return FFI_TYPE_UINT8;
124n/a
125n/a case 2:
126n/a return FFI_TYPE_UINT16;
127n/a
128n/a case 4:
129n/a if (arg->type == FFI_TYPE_FLOAT)
130n/a return FFI_TYPE_FLOAT;
131n/a else
132n/a return FFI_TYPE_UINT32;
133n/a
134n/a case 8:
135n/a if (arg->type == FFI_TYPE_DOUBLE)
136n/a return FFI_TYPE_DOUBLE;
137n/a else
138n/a return FFI_TYPE_UINT64;
139n/a
140n/a default:
141n/a break;
142n/a }
143n/a
144n/a /* Other structs are passed via a pointer to the data. */
145n/a return FFI_TYPE_POINTER;
146n/a}
147n/a
148n/a/*======================== End of Routine ============================*/
149n/a
150n/a/*====================================================================*/
151n/a/* */
152n/a/* Name - ffi_prep_args. */
153n/a/* */
154n/a/* Function - Prepare parameters for call to function. */
155n/a/* */
156n/a/* ffi_prep_args is called by the assembly routine once stack space */
157n/a/* has been allocated for the function's arguments. */
158n/a/* */
159n/a/*====================================================================*/
160n/a
161n/astatic void
162n/affi_prep_args (unsigned char *stack, extended_cif *ecif)
163n/a{
164n/a /* The stack space will be filled with those areas:
165n/a
166n/a FPR argument register save area (highest addresses)
167n/a GPR argument register save area
168n/a temporary struct copies
169n/a overflow argument area (lowest addresses)
170n/a
171n/a We set up the following pointers:
172n/a
173n/a p_fpr: bottom of the FPR area (growing upwards)
174n/a p_gpr: bottom of the GPR area (growing upwards)
175n/a p_ov: bottom of the overflow area (growing upwards)
176n/a p_struct: top of the struct copy area (growing downwards)
177n/a
178n/a All areas are kept aligned to twice the word size. */
179n/a
180n/a int gpr_off = ecif->cif->bytes;
181n/a int fpr_off = gpr_off + ROUND_SIZE (MAX_GPRARGS * sizeof (long));
182n/a
183n/a unsigned long long *p_fpr = (unsigned long long *)(stack + fpr_off);
184n/a unsigned long *p_gpr = (unsigned long *)(stack + gpr_off);
185n/a unsigned char *p_struct = (unsigned char *)p_gpr;
186n/a unsigned long *p_ov = (unsigned long *)stack;
187n/a
188n/a int n_fpr = 0;
189n/a int n_gpr = 0;
190n/a int n_ov = 0;
191n/a
192n/a ffi_type **ptr;
193n/a void **p_argv = ecif->avalue;
194n/a int i;
195n/a
196n/a /* If we returning a structure then we set the first parameter register
197n/a to the address of where we are returning this structure. */
198n/a
199n/a if (ecif->cif->flags == FFI390_RET_STRUCT)
200n/a p_gpr[n_gpr++] = (unsigned long) ecif->rvalue;
201n/a
202n/a /* Now for the arguments. */
203n/a
204n/a for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
205n/a i > 0;
206n/a i--, ptr++, p_argv++)
207n/a {
208n/a void *arg = *p_argv;
209n/a int type = (*ptr)->type;
210n/a
211n/a#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
212n/a /* 16-byte long double is passed like a struct. */
213n/a if (type == FFI_TYPE_LONGDOUBLE)
214n/a type = FFI_TYPE_STRUCT;
215n/a#endif
216n/a
217n/a /* Check how a structure type is passed. */
218n/a if (type == FFI_TYPE_STRUCT)
219n/a {
220n/a type = ffi_check_struct_type (*ptr);
221n/a
222n/a /* If we pass the struct via pointer, copy the data. */
223n/a if (type == FFI_TYPE_POINTER)
224n/a {
225n/a p_struct -= ROUND_SIZE ((*ptr)->size);
226n/a memcpy (p_struct, (char *)arg, (*ptr)->size);
227n/a arg = &p_struct;
228n/a }
229n/a }
230n/a
231n/a /* Now handle all primitive int/pointer/float data types. */
232n/a switch (type)
233n/a {
234n/a case FFI_TYPE_DOUBLE:
235n/a if (n_fpr < MAX_FPRARGS)
236n/a p_fpr[n_fpr++] = *(unsigned long long *) arg;
237n/a else
238n/a#ifdef __s390x__
239n/a p_ov[n_ov++] = *(unsigned long *) arg;
240n/a#else
241n/a p_ov[n_ov++] = ((unsigned long *) arg)[0],
242n/a p_ov[n_ov++] = ((unsigned long *) arg)[1];
243n/a#endif
244n/a break;
245n/a
246n/a case FFI_TYPE_FLOAT:
247n/a if (n_fpr < MAX_FPRARGS)
248n/a p_fpr[n_fpr++] = (long long) *(unsigned int *) arg << 32;
249n/a else
250n/a p_ov[n_ov++] = *(unsigned int *) arg;
251n/a break;
252n/a
253n/a case FFI_TYPE_POINTER:
254n/a if (n_gpr < MAX_GPRARGS)
255n/a p_gpr[n_gpr++] = (unsigned long)*(unsigned char **) arg;
256n/a else
257n/a p_ov[n_ov++] = (unsigned long)*(unsigned char **) arg;
258n/a break;
259n/a
260n/a case FFI_TYPE_UINT64:
261n/a case FFI_TYPE_SINT64:
262n/a#ifdef __s390x__
263n/a if (n_gpr < MAX_GPRARGS)
264n/a p_gpr[n_gpr++] = *(unsigned long *) arg;
265n/a else
266n/a p_ov[n_ov++] = *(unsigned long *) arg;
267n/a#else
268n/a if (n_gpr == MAX_GPRARGS-1)
269n/a n_gpr = MAX_GPRARGS;
270n/a if (n_gpr < MAX_GPRARGS)
271n/a p_gpr[n_gpr++] = ((unsigned long *) arg)[0],
272n/a p_gpr[n_gpr++] = ((unsigned long *) arg)[1];
273n/a else
274n/a p_ov[n_ov++] = ((unsigned long *) arg)[0],
275n/a p_ov[n_ov++] = ((unsigned long *) arg)[1];
276n/a#endif
277n/a break;
278n/a
279n/a case FFI_TYPE_UINT32:
280n/a if (n_gpr < MAX_GPRARGS)
281n/a p_gpr[n_gpr++] = *(unsigned int *) arg;
282n/a else
283n/a p_ov[n_ov++] = *(unsigned int *) arg;
284n/a break;
285n/a
286n/a case FFI_TYPE_INT:
287n/a case FFI_TYPE_SINT32:
288n/a if (n_gpr < MAX_GPRARGS)
289n/a p_gpr[n_gpr++] = *(signed int *) arg;
290n/a else
291n/a p_ov[n_ov++] = *(signed int *) arg;
292n/a break;
293n/a
294n/a case FFI_TYPE_UINT16:
295n/a if (n_gpr < MAX_GPRARGS)
296n/a p_gpr[n_gpr++] = *(unsigned short *) arg;
297n/a else
298n/a p_ov[n_ov++] = *(unsigned short *) arg;
299n/a break;
300n/a
301n/a case FFI_TYPE_SINT16:
302n/a if (n_gpr < MAX_GPRARGS)
303n/a p_gpr[n_gpr++] = *(signed short *) arg;
304n/a else
305n/a p_ov[n_ov++] = *(signed short *) arg;
306n/a break;
307n/a
308n/a case FFI_TYPE_UINT8:
309n/a if (n_gpr < MAX_GPRARGS)
310n/a p_gpr[n_gpr++] = *(unsigned char *) arg;
311n/a else
312n/a p_ov[n_ov++] = *(unsigned char *) arg;
313n/a break;
314n/a
315n/a case FFI_TYPE_SINT8:
316n/a if (n_gpr < MAX_GPRARGS)
317n/a p_gpr[n_gpr++] = *(signed char *) arg;
318n/a else
319n/a p_ov[n_ov++] = *(signed char *) arg;
320n/a break;
321n/a
322n/a default:
323n/a FFI_ASSERT (0);
324n/a break;
325n/a }
326n/a }
327n/a}
328n/a
329n/a/*======================== End of Routine ============================*/
330n/a
331n/a/*====================================================================*/
332n/a/* */
333n/a/* Name - ffi_prep_cif_machdep. */
334n/a/* */
335n/a/* Function - Perform machine dependent CIF processing. */
336n/a/* */
337n/a/*====================================================================*/
338n/a
339n/affi_status
340n/affi_prep_cif_machdep(ffi_cif *cif)
341n/a{
342n/a size_t struct_size = 0;
343n/a int n_gpr = 0;
344n/a int n_fpr = 0;
345n/a int n_ov = 0;
346n/a
347n/a ffi_type **ptr;
348n/a int i;
349n/a
350n/a /* Determine return value handling. */
351n/a
352n/a switch (cif->rtype->type)
353n/a {
354n/a /* Void is easy. */
355n/a case FFI_TYPE_VOID:
356n/a cif->flags = FFI390_RET_VOID;
357n/a break;
358n/a
359n/a /* Structures are returned via a hidden pointer. */
360n/a case FFI_TYPE_STRUCT:
361n/a cif->flags = FFI390_RET_STRUCT;
362n/a n_gpr++; /* We need one GPR to pass the pointer. */
363n/a break;
364n/a
365n/a /* Floating point values are returned in fpr 0. */
366n/a case FFI_TYPE_FLOAT:
367n/a cif->flags = FFI390_RET_FLOAT;
368n/a break;
369n/a
370n/a case FFI_TYPE_DOUBLE:
371n/a cif->flags = FFI390_RET_DOUBLE;
372n/a break;
373n/a
374n/a#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
375n/a case FFI_TYPE_LONGDOUBLE:
376n/a cif->flags = FFI390_RET_STRUCT;
377n/a n_gpr++;
378n/a break;
379n/a#endif
380n/a /* Integer values are returned in gpr 2 (and gpr 3
381n/a for 64-bit values on 31-bit machines). */
382n/a case FFI_TYPE_UINT64:
383n/a case FFI_TYPE_SINT64:
384n/a cif->flags = FFI390_RET_INT64;
385n/a break;
386n/a
387n/a case FFI_TYPE_POINTER:
388n/a case FFI_TYPE_INT:
389n/a case FFI_TYPE_UINT32:
390n/a case FFI_TYPE_SINT32:
391n/a case FFI_TYPE_UINT16:
392n/a case FFI_TYPE_SINT16:
393n/a case FFI_TYPE_UINT8:
394n/a case FFI_TYPE_SINT8:
395n/a /* These are to be extended to word size. */
396n/a#ifdef __s390x__
397n/a cif->flags = FFI390_RET_INT64;
398n/a#else
399n/a cif->flags = FFI390_RET_INT32;
400n/a#endif
401n/a break;
402n/a
403n/a default:
404n/a FFI_ASSERT (0);
405n/a break;
406n/a }
407n/a
408n/a /* Now for the arguments. */
409n/a
410n/a for (ptr = cif->arg_types, i = cif->nargs;
411n/a i > 0;
412n/a i--, ptr++)
413n/a {
414n/a int type = (*ptr)->type;
415n/a
416n/a#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
417n/a /* 16-byte long double is passed like a struct. */
418n/a if (type == FFI_TYPE_LONGDOUBLE)
419n/a type = FFI_TYPE_STRUCT;
420n/a#endif
421n/a
422n/a /* Check how a structure type is passed. */
423n/a if (type == FFI_TYPE_STRUCT)
424n/a {
425n/a type = ffi_check_struct_type (*ptr);
426n/a
427n/a /* If we pass the struct via pointer, we must reserve space
428n/a to copy its data for proper call-by-value semantics. */
429n/a if (type == FFI_TYPE_POINTER)
430n/a struct_size += ROUND_SIZE ((*ptr)->size);
431n/a }
432n/a
433n/a /* Now handle all primitive int/float data types. */
434n/a switch (type)
435n/a {
436n/a /* The first MAX_FPRARGS floating point arguments
437n/a go in FPRs, the rest overflow to the stack. */
438n/a
439n/a case FFI_TYPE_DOUBLE:
440n/a if (n_fpr < MAX_FPRARGS)
441n/a n_fpr++;
442n/a else
443n/a n_ov += sizeof (double) / sizeof (long);
444n/a break;
445n/a
446n/a case FFI_TYPE_FLOAT:
447n/a if (n_fpr < MAX_FPRARGS)
448n/a n_fpr++;
449n/a else
450n/a n_ov++;
451n/a break;
452n/a
453n/a /* On 31-bit machines, 64-bit integers are passed in GPR pairs,
454n/a if one is still available, or else on the stack. If only one
455n/a register is free, skip the register (it won't be used for any
456n/a subsequent argument either). */
457n/a
458n/a#ifndef __s390x__
459n/a case FFI_TYPE_UINT64:
460n/a case FFI_TYPE_SINT64:
461n/a if (n_gpr == MAX_GPRARGS-1)
462n/a n_gpr = MAX_GPRARGS;
463n/a if (n_gpr < MAX_GPRARGS)
464n/a n_gpr += 2;
465n/a else
466n/a n_ov += 2;
467n/a break;
468n/a#endif
469n/a
470n/a /* Everything else is passed in GPRs (until MAX_GPRARGS
471n/a have been used) or overflows to the stack. */
472n/a
473n/a default:
474n/a if (n_gpr < MAX_GPRARGS)
475n/a n_gpr++;
476n/a else
477n/a n_ov++;
478n/a break;
479n/a }
480n/a }
481n/a
482n/a /* Total stack space as required for overflow arguments
483n/a and temporary structure copies. */
484n/a
485n/a cif->bytes = ROUND_SIZE (n_ov * sizeof (long)) + struct_size;
486n/a
487n/a return FFI_OK;
488n/a}
489n/a
490n/a/*======================== End of Routine ============================*/
491n/a
492n/a/*====================================================================*/
493n/a/* */
494n/a/* Name - ffi_call. */
495n/a/* */
496n/a/* Function - Call the FFI routine. */
497n/a/* */
498n/a/*====================================================================*/
499n/a
500n/avoid
501n/affi_call(ffi_cif *cif,
502n/a void (*fn)(void),
503n/a void *rvalue,
504n/a void **avalue)
505n/a{
506n/a int ret_type = cif->flags;
507n/a extended_cif ecif;
508n/a
509n/a ecif.cif = cif;
510n/a ecif.avalue = avalue;
511n/a ecif.rvalue = rvalue;
512n/a
513n/a /* If we don't have a return value, we need to fake one. */
514n/a if (rvalue == NULL)
515n/a {
516n/a if (ret_type == FFI390_RET_STRUCT)
517n/a ecif.rvalue = alloca (cif->rtype->size);
518n/a else
519n/a ret_type = FFI390_RET_VOID;
520n/a }
521n/a
522n/a switch (cif->abi)
523n/a {
524n/a case FFI_SYSV:
525n/a ffi_call_SYSV (cif->bytes, &ecif, ffi_prep_args,
526n/a ret_type, ecif.rvalue, fn);
527n/a break;
528n/a
529n/a default:
530n/a FFI_ASSERT (0);
531n/a break;
532n/a }
533n/a}
534n/a
535n/a/*======================== End of Routine ============================*/
536n/a
537n/a/*====================================================================*/
538n/a/* */
539n/a/* Name - ffi_closure_helper_SYSV. */
540n/a/* */
541n/a/* Function - Call a FFI closure target function. */
542n/a/* */
543n/a/*====================================================================*/
544n/a
545n/avoid
546n/affi_closure_helper_SYSV (ffi_closure *closure,
547n/a unsigned long *p_gpr,
548n/a unsigned long long *p_fpr,
549n/a unsigned long *p_ov)
550n/a{
551n/a unsigned long long ret_buffer;
552n/a
553n/a void *rvalue = &ret_buffer;
554n/a void **avalue;
555n/a void **p_arg;
556n/a
557n/a int n_gpr = 0;
558n/a int n_fpr = 0;
559n/a int n_ov = 0;
560n/a
561n/a ffi_type **ptr;
562n/a int i;
563n/a
564n/a /* Allocate buffer for argument list pointers. */
565n/a
566n/a p_arg = avalue = alloca (closure->cif->nargs * sizeof (void *));
567n/a
568n/a /* If we returning a structure, pass the structure address
569n/a directly to the target function. Otherwise, have the target
570n/a function store the return value to the GPR save area. */
571n/a
572n/a if (closure->cif->flags == FFI390_RET_STRUCT)
573n/a rvalue = (void *) p_gpr[n_gpr++];
574n/a
575n/a /* Now for the arguments. */
576n/a
577n/a for (ptr = closure->cif->arg_types, i = closure->cif->nargs;
578n/a i > 0;
579n/a i--, p_arg++, ptr++)
580n/a {
581n/a int deref_struct_pointer = 0;
582n/a int type = (*ptr)->type;
583n/a
584n/a#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
585n/a /* 16-byte long double is passed like a struct. */
586n/a if (type == FFI_TYPE_LONGDOUBLE)
587n/a type = FFI_TYPE_STRUCT;
588n/a#endif
589n/a
590n/a /* Check how a structure type is passed. */
591n/a if (type == FFI_TYPE_STRUCT)
592n/a {
593n/a type = ffi_check_struct_type (*ptr);
594n/a
595n/a /* If we pass the struct via pointer, remember to
596n/a retrieve the pointer later. */
597n/a if (type == FFI_TYPE_POINTER)
598n/a deref_struct_pointer = 1;
599n/a }
600n/a
601n/a /* Pointers are passed like UINTs of the same size. */
602n/a if (type == FFI_TYPE_POINTER)
603n/a#ifdef __s390x__
604n/a type = FFI_TYPE_UINT64;
605n/a#else
606n/a type = FFI_TYPE_UINT32;
607n/a#endif
608n/a
609n/a /* Now handle all primitive int/float data types. */
610n/a switch (type)
611n/a {
612n/a case FFI_TYPE_DOUBLE:
613n/a if (n_fpr < MAX_FPRARGS)
614n/a *p_arg = &p_fpr[n_fpr++];
615n/a else
616n/a *p_arg = &p_ov[n_ov],
617n/a n_ov += sizeof (double) / sizeof (long);
618n/a break;
619n/a
620n/a case FFI_TYPE_FLOAT:
621n/a if (n_fpr < MAX_FPRARGS)
622n/a *p_arg = &p_fpr[n_fpr++];
623n/a else
624n/a *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;
625n/a break;
626n/a
627n/a case FFI_TYPE_UINT64:
628n/a case FFI_TYPE_SINT64:
629n/a#ifdef __s390x__
630n/a if (n_gpr < MAX_GPRARGS)
631n/a *p_arg = &p_gpr[n_gpr++];
632n/a else
633n/a *p_arg = &p_ov[n_ov++];
634n/a#else
635n/a if (n_gpr == MAX_GPRARGS-1)
636n/a n_gpr = MAX_GPRARGS;
637n/a if (n_gpr < MAX_GPRARGS)
638n/a *p_arg = &p_gpr[n_gpr], n_gpr += 2;
639n/a else
640n/a *p_arg = &p_ov[n_ov], n_ov += 2;
641n/a#endif
642n/a break;
643n/a
644n/a case FFI_TYPE_INT:
645n/a case FFI_TYPE_UINT32:
646n/a case FFI_TYPE_SINT32:
647n/a if (n_gpr < MAX_GPRARGS)
648n/a *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 4;
649n/a else
650n/a *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;
651n/a break;
652n/a
653n/a case FFI_TYPE_UINT16:
654n/a case FFI_TYPE_SINT16:
655n/a if (n_gpr < MAX_GPRARGS)
656n/a *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 2;
657n/a else
658n/a *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 2;
659n/a break;
660n/a
661n/a case FFI_TYPE_UINT8:
662n/a case FFI_TYPE_SINT8:
663n/a if (n_gpr < MAX_GPRARGS)
664n/a *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 1;
665n/a else
666n/a *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 1;
667n/a break;
668n/a
669n/a default:
670n/a FFI_ASSERT (0);
671n/a break;
672n/a }
673n/a
674n/a /* If this is a struct passed via pointer, we need to
675n/a actually retrieve that pointer. */
676n/a if (deref_struct_pointer)
677n/a *p_arg = *(void **)*p_arg;
678n/a }
679n/a
680n/a
681n/a /* Call the target function. */
682n/a (closure->fun) (closure->cif, rvalue, avalue, closure->user_data);
683n/a
684n/a /* Convert the return value. */
685n/a switch (closure->cif->rtype->type)
686n/a {
687n/a /* Void is easy, and so is struct. */
688n/a case FFI_TYPE_VOID:
689n/a case FFI_TYPE_STRUCT:
690n/a#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
691n/a case FFI_TYPE_LONGDOUBLE:
692n/a#endif
693n/a break;
694n/a
695n/a /* Floating point values are returned in fpr 0. */
696n/a case FFI_TYPE_FLOAT:
697n/a p_fpr[0] = (long long) *(unsigned int *) rvalue << 32;
698n/a break;
699n/a
700n/a case FFI_TYPE_DOUBLE:
701n/a p_fpr[0] = *(unsigned long long *) rvalue;
702n/a break;
703n/a
704n/a /* Integer values are returned in gpr 2 (and gpr 3
705n/a for 64-bit values on 31-bit machines). */
706n/a case FFI_TYPE_UINT64:
707n/a case FFI_TYPE_SINT64:
708n/a#ifdef __s390x__
709n/a p_gpr[0] = *(unsigned long *) rvalue;
710n/a#else
711n/a p_gpr[0] = ((unsigned long *) rvalue)[0],
712n/a p_gpr[1] = ((unsigned long *) rvalue)[1];
713n/a#endif
714n/a break;
715n/a
716n/a case FFI_TYPE_POINTER:
717n/a case FFI_TYPE_UINT32:
718n/a case FFI_TYPE_UINT16:
719n/a case FFI_TYPE_UINT8:
720n/a p_gpr[0] = *(unsigned long *) rvalue;
721n/a break;
722n/a
723n/a case FFI_TYPE_INT:
724n/a case FFI_TYPE_SINT32:
725n/a case FFI_TYPE_SINT16:
726n/a case FFI_TYPE_SINT8:
727n/a p_gpr[0] = *(signed long *) rvalue;
728n/a break;
729n/a
730n/a default:
731n/a FFI_ASSERT (0);
732n/a break;
733n/a }
734n/a}
735n/a
736n/a/*======================== End of Routine ============================*/
737n/a
738n/a/*====================================================================*/
739n/a/* */
740n/a/* Name - ffi_prep_closure_loc. */
741n/a/* */
742n/a/* Function - Prepare a FFI closure. */
743n/a/* */
744n/a/*====================================================================*/
745n/a
746n/affi_status
747n/affi_prep_closure_loc (ffi_closure *closure,
748n/a ffi_cif *cif,
749n/a void (*fun) (ffi_cif *, void *, void **, void *),
750n/a void *user_data,
751n/a void *codeloc)
752n/a{
753n/a if (cif->abi != FFI_SYSV)
754n/a return FFI_BAD_ABI;
755n/a
756n/a#ifndef __s390x__
757n/a *(short *)&closure->tramp [0] = 0x0d10; /* basr %r1,0 */
758n/a *(short *)&closure->tramp [2] = 0x9801; /* lm %r0,%r1,6(%r1) */
759n/a *(short *)&closure->tramp [4] = 0x1006;
760n/a *(short *)&closure->tramp [6] = 0x07f1; /* br %r1 */
761n/a *(long *)&closure->tramp [8] = (long)codeloc;
762n/a *(long *)&closure->tramp[12] = (long)&ffi_closure_SYSV;
763n/a#else
764n/a *(short *)&closure->tramp [0] = 0x0d10; /* basr %r1,0 */
765n/a *(short *)&closure->tramp [2] = 0xeb01; /* lmg %r0,%r1,14(%r1) */
766n/a *(short *)&closure->tramp [4] = 0x100e;
767n/a *(short *)&closure->tramp [6] = 0x0004;
768n/a *(short *)&closure->tramp [8] = 0x07f1; /* br %r1 */
769n/a *(long *)&closure->tramp[16] = (long)codeloc;
770n/a *(long *)&closure->tramp[24] = (long)&ffi_closure_SYSV;
771n/a#endif
772n/a
773n/a closure->cif = cif;
774n/a closure->user_data = user_data;
775n/a closure->fun = fun;
776n/a
777n/a return FFI_OK;
778n/a}
779n/a
780n/a/*======================== End of Routine ============================*/
781n/a