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

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

#countcontent
1n/a/* -----------------------------------------------------------------------
2n/a ffi.c - Copyright (c) 2012 Anthony Green
3n/a Copyright (c) 1998, 2001, 2007, 2008 Red Hat, Inc.
4n/a
5n/a Alpha 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,
19n/a EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20n/a MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21n/a NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22n/a HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23n/a WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24n/a OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25n/a DEALINGS IN THE SOFTWARE.
26n/a ----------------------------------------------------------------------- */
27n/a
28n/a#include <ffi.h>
29n/a#include <ffi_common.h>
30n/a#include <stdlib.h>
31n/a
32n/a/* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE;
33n/a all further uses in this file will refer to the 128-bit type. */
34n/a#if defined(__LONG_DOUBLE_128__)
35n/a# if FFI_TYPE_LONGDOUBLE != 4
36n/a# error FFI_TYPE_LONGDOUBLE out of date
37n/a# endif
38n/a#else
39n/a# undef FFI_TYPE_LONGDOUBLE
40n/a# define FFI_TYPE_LONGDOUBLE 4
41n/a#endif
42n/a
43n/aextern void ffi_call_osf(void *, unsigned long, unsigned, void *, void (*)(void))
44n/a FFI_HIDDEN;
45n/aextern void ffi_closure_osf(void) FFI_HIDDEN;
46n/a
47n/a
48n/affi_status
49n/affi_prep_cif_machdep(ffi_cif *cif)
50n/a{
51n/a /* Adjust cif->bytes to represent a minimum 6 words for the temporary
52n/a register argument loading area. */
53n/a if (cif->bytes < 6*FFI_SIZEOF_ARG)
54n/a cif->bytes = 6*FFI_SIZEOF_ARG;
55n/a
56n/a /* Set the return type flag */
57n/a switch (cif->rtype->type)
58n/a {
59n/a case FFI_TYPE_STRUCT:
60n/a case FFI_TYPE_FLOAT:
61n/a case FFI_TYPE_DOUBLE:
62n/a cif->flags = cif->rtype->type;
63n/a break;
64n/a
65n/a case FFI_TYPE_LONGDOUBLE:
66n/a /* 128-bit long double is returned in memory, like a struct. */
67n/a cif->flags = FFI_TYPE_STRUCT;
68n/a break;
69n/a
70n/a default:
71n/a cif->flags = FFI_TYPE_INT;
72n/a break;
73n/a }
74n/a
75n/a return FFI_OK;
76n/a}
77n/a
78n/a
79n/avoid
80n/affi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
81n/a{
82n/a unsigned long *stack, *argp;
83n/a long i, avn;
84n/a ffi_type **arg_types;
85n/a
86n/a /* If the return value is a struct and we don't have a return
87n/a value address then we need to make one. */
88n/a if (rvalue == NULL && cif->flags == FFI_TYPE_STRUCT)
89n/a rvalue = alloca(cif->rtype->size);
90n/a
91n/a /* Allocate the space for the arguments, plus 4 words of temp
92n/a space for ffi_call_osf. */
93n/a argp = stack = alloca(cif->bytes + 4*FFI_SIZEOF_ARG);
94n/a
95n/a if (cif->flags == FFI_TYPE_STRUCT)
96n/a *(void **) argp++ = rvalue;
97n/a
98n/a i = 0;
99n/a avn = cif->nargs;
100n/a arg_types = cif->arg_types;
101n/a
102n/a while (i < avn)
103n/a {
104n/a size_t size = (*arg_types)->size;
105n/a
106n/a switch ((*arg_types)->type)
107n/a {
108n/a case FFI_TYPE_SINT8:
109n/a *(SINT64 *) argp = *(SINT8 *)(* avalue);
110n/a break;
111n/a
112n/a case FFI_TYPE_UINT8:
113n/a *(SINT64 *) argp = *(UINT8 *)(* avalue);
114n/a break;
115n/a
116n/a case FFI_TYPE_SINT16:
117n/a *(SINT64 *) argp = *(SINT16 *)(* avalue);
118n/a break;
119n/a
120n/a case FFI_TYPE_UINT16:
121n/a *(SINT64 *) argp = *(UINT16 *)(* avalue);
122n/a break;
123n/a
124n/a case FFI_TYPE_SINT32:
125n/a case FFI_TYPE_UINT32:
126n/a /* Note that unsigned 32-bit quantities are sign extended. */
127n/a *(SINT64 *) argp = *(SINT32 *)(* avalue);
128n/a break;
129n/a
130n/a case FFI_TYPE_SINT64:
131n/a case FFI_TYPE_UINT64:
132n/a case FFI_TYPE_POINTER:
133n/a *(UINT64 *) argp = *(UINT64 *)(* avalue);
134n/a break;
135n/a
136n/a case FFI_TYPE_FLOAT:
137n/a if (argp - stack < 6)
138n/a {
139n/a /* Note the conversion -- all the fp regs are loaded as
140n/a doubles. The in-register format is the same. */
141n/a *(double *) argp = *(float *)(* avalue);
142n/a }
143n/a else
144n/a *(float *) argp = *(float *)(* avalue);
145n/a break;
146n/a
147n/a case FFI_TYPE_DOUBLE:
148n/a *(double *) argp = *(double *)(* avalue);
149n/a break;
150n/a
151n/a case FFI_TYPE_LONGDOUBLE:
152n/a /* 128-bit long double is passed by reference. */
153n/a *(long double **) argp = (long double *)(* avalue);
154n/a size = sizeof (long double *);
155n/a break;
156n/a
157n/a case FFI_TYPE_STRUCT:
158n/a memcpy(argp, *avalue, (*arg_types)->size);
159n/a break;
160n/a
161n/a default:
162n/a FFI_ASSERT(0);
163n/a }
164n/a
165n/a argp += ALIGN(size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
166n/a i++, arg_types++, avalue++;
167n/a }
168n/a
169n/a ffi_call_osf(stack, cif->bytes, cif->flags, rvalue, fn);
170n/a}
171n/a
172n/a
173n/affi_status
174n/affi_prep_closure_loc (ffi_closure* closure,
175n/a ffi_cif* cif,
176n/a void (*fun)(ffi_cif*, void*, void**, void*),
177n/a void *user_data,
178n/a void *codeloc)
179n/a{
180n/a unsigned int *tramp;
181n/a
182n/a if (cif->abi != FFI_OSF)
183n/a return FFI_BAD_ABI;
184n/a
185n/a tramp = (unsigned int *) &closure->tramp[0];
186n/a tramp[0] = 0x47fb0401; /* mov $27,$1 */
187n/a tramp[1] = 0xa77b0010; /* ldq $27,16($27) */
188n/a tramp[2] = 0x6bfb0000; /* jmp $31,($27),0 */
189n/a tramp[3] = 0x47ff041f; /* nop */
190n/a *(void **) &tramp[4] = ffi_closure_osf;
191n/a
192n/a closure->cif = cif;
193n/a closure->fun = fun;
194n/a closure->user_data = user_data;
195n/a
196n/a /* Flush the Icache.
197n/a
198n/a Tru64 UNIX as doesn't understand the imb mnemonic, so use call_pal
199n/a instead, since both Compaq as and gas can handle it.
200n/a
201n/a 0x86 is PAL_imb in Tru64 UNIX <alpha/pal.h>. */
202n/a asm volatile ("call_pal 0x86" : : : "memory");
203n/a
204n/a return FFI_OK;
205n/a}
206n/a
207n/a
208n/along FFI_HIDDEN
209n/affi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp)
210n/a{
211n/a ffi_cif *cif;
212n/a void **avalue;
213n/a ffi_type **arg_types;
214n/a long i, avn, argn;
215n/a
216n/a cif = closure->cif;
217n/a avalue = alloca(cif->nargs * sizeof(void *));
218n/a
219n/a argn = 0;
220n/a
221n/a /* Copy the caller's structure return address to that the closure
222n/a returns the data directly to the caller. */
223n/a if (cif->flags == FFI_TYPE_STRUCT)
224n/a {
225n/a rvalue = (void *) argp[0];
226n/a argn = 1;
227n/a }
228n/a
229n/a i = 0;
230n/a avn = cif->nargs;
231n/a arg_types = cif->arg_types;
232n/a
233n/a /* Grab the addresses of the arguments from the stack frame. */
234n/a while (i < avn)
235n/a {
236n/a size_t size = arg_types[i]->size;
237n/a
238n/a switch (arg_types[i]->type)
239n/a {
240n/a case FFI_TYPE_SINT8:
241n/a case FFI_TYPE_UINT8:
242n/a case FFI_TYPE_SINT16:
243n/a case FFI_TYPE_UINT16:
244n/a case FFI_TYPE_SINT32:
245n/a case FFI_TYPE_UINT32:
246n/a case FFI_TYPE_SINT64:
247n/a case FFI_TYPE_UINT64:
248n/a case FFI_TYPE_POINTER:
249n/a case FFI_TYPE_STRUCT:
250n/a avalue[i] = &argp[argn];
251n/a break;
252n/a
253n/a case FFI_TYPE_FLOAT:
254n/a if (argn < 6)
255n/a {
256n/a /* Floats coming from registers need conversion from double
257n/a back to float format. */
258n/a *(float *)&argp[argn - 6] = *(double *)&argp[argn - 6];
259n/a avalue[i] = &argp[argn - 6];
260n/a }
261n/a else
262n/a avalue[i] = &argp[argn];
263n/a break;
264n/a
265n/a case FFI_TYPE_DOUBLE:
266n/a avalue[i] = &argp[argn - (argn < 6 ? 6 : 0)];
267n/a break;
268n/a
269n/a case FFI_TYPE_LONGDOUBLE:
270n/a /* 128-bit long double is passed by reference. */
271n/a avalue[i] = (long double *) argp[argn];
272n/a size = sizeof (long double *);
273n/a break;
274n/a
275n/a default:
276n/a abort ();
277n/a }
278n/a
279n/a argn += ALIGN(size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
280n/a i++;
281n/a }
282n/a
283n/a /* Invoke the closure. */
284n/a closure->fun (cif, rvalue, avalue, closure->user_data);
285n/a
286n/a /* Tell ffi_closure_osf how to perform return type promotions. */
287n/a return cif->rtype->type;
288n/a}