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

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

#countcontent
1n/a/* -----------------------------------------------------------------------
2n/a ffi.c - Copyright (c) 2013 Synopsys, Inc. (www.synopsys.com)
3n/a
4n/a ARC Foreign Function Interface
5n/a
6n/a Permission is hereby granted, free of charge, to any person obtaining
7n/a a copy of this software and associated documentation files (the
8n/a ``Software''), to deal in the Software without restriction, including
9n/a without limitation the rights to use, copy, modify, merge, publish,
10n/a distribute, sublicense, and/or sell copies of the Software, and to
11n/a permit persons to whom the Software is furnished to do so, subject to
12n/a the following conditions:
13n/a
14n/a The above copyright notice and this permission notice shall be included
15n/a in all copies or substantial portions of the Software.
16n/a
17n/a THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
18n/a OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19n/a MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20n/a IN NO EVENT SHALL RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR
21n/a OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22n/a ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23n/a OTHER DEALINGS IN THE SOFTWARE.
24n/a ----------------------------------------------------------------------- */
25n/a
26n/a#include <ffi.h>
27n/a#include <ffi_common.h>
28n/a
29n/a#include <stdlib.h>
30n/a#include <stdint.h>
31n/a
32n/a#include <sys/cachectl.h>
33n/a
34n/a/* for little endian ARC, the code is in fact stored as mixed endian for
35n/a performance reasons */
36n/a#if __BIG_ENDIAN__
37n/a#define CODE_ENDIAN(x) (x)
38n/a#else
39n/a#define CODE_ENDIAN(x) ( (((uint32_t) (x)) << 16) | (((uint32_t) (x)) >> 16))
40n/a#endif
41n/a
42n/a/* ffi_prep_args is called by the assembly routine once stack
43n/a space has been allocated for the function's arguments. */
44n/a
45n/avoid
46n/affi_prep_args (char *stack, extended_cif * ecif)
47n/a{
48n/a unsigned int i;
49n/a int tmp;
50n/a void **p_argv;
51n/a char *argp;
52n/a ffi_type **p_arg;
53n/a
54n/a tmp = 0;
55n/a argp = stack;
56n/a
57n/a if (ecif->cif->rtype->type == FFI_TYPE_STRUCT)
58n/a {
59n/a *(void **) argp = ecif->rvalue;
60n/a argp += 4;
61n/a }
62n/a
63n/a p_argv = ecif->avalue;
64n/a
65n/a for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
66n/a (i != 0); i--, p_arg++)
67n/a {
68n/a size_t z;
69n/a int alignment;
70n/a
71n/a /* align alignment to 4 */
72n/a alignment = (((*p_arg)->alignment - 1) | 3) + 1;
73n/a
74n/a /* Align if necessary. */
75n/a if ((alignment - 1) & (unsigned) argp)
76n/a argp = (char *) ALIGN (argp, alignment);
77n/a
78n/a z = (*p_arg)->size;
79n/a if (z < sizeof (int))
80n/a {
81n/a z = sizeof (int);
82n/a
83n/a switch ((*p_arg)->type)
84n/a {
85n/a case FFI_TYPE_SINT8:
86n/a *(signed int *) argp = (signed int) *(SINT8 *) (*p_argv);
87n/a break;
88n/a
89n/a case FFI_TYPE_UINT8:
90n/a *(unsigned int *) argp = (unsigned int) *(UINT8 *) (*p_argv);
91n/a break;
92n/a
93n/a case FFI_TYPE_SINT16:
94n/a *(signed int *) argp = (signed int) *(SINT16 *) (*p_argv);
95n/a break;
96n/a
97n/a case FFI_TYPE_UINT16:
98n/a *(unsigned int *) argp = (unsigned int) *(UINT16 *) (*p_argv);
99n/a break;
100n/a
101n/a case FFI_TYPE_STRUCT:
102n/a memcpy (argp, *p_argv, (*p_arg)->size);
103n/a break;
104n/a
105n/a default:
106n/a FFI_ASSERT (0);
107n/a }
108n/a }
109n/a else if (z == sizeof (int))
110n/a {
111n/a *(unsigned int *) argp = (unsigned int) *(UINT32 *) (*p_argv);
112n/a }
113n/a else
114n/a {
115n/a if ((*p_arg)->type == FFI_TYPE_STRUCT)
116n/a {
117n/a memcpy (argp, *p_argv, z);
118n/a }
119n/a else
120n/a {
121n/a /* Double or long long 64bit. */
122n/a memcpy (argp, *p_argv, z);
123n/a }
124n/a }
125n/a p_argv++;
126n/a argp += z;
127n/a }
128n/a
129n/a return;
130n/a}
131n/a
132n/a/* Perform machine dependent cif processing. */
133n/affi_status
134n/affi_prep_cif_machdep (ffi_cif * cif)
135n/a{
136n/a /* Set the return type flag. */
137n/a switch (cif->rtype->type)
138n/a {
139n/a case FFI_TYPE_VOID:
140n/a cif->flags = (unsigned) cif->rtype->type;
141n/a break;
142n/a
143n/a case FFI_TYPE_STRUCT:
144n/a cif->flags = (unsigned) cif->rtype->type;
145n/a break;
146n/a
147n/a case FFI_TYPE_SINT64:
148n/a case FFI_TYPE_UINT64:
149n/a case FFI_TYPE_DOUBLE:
150n/a cif->flags = FFI_TYPE_DOUBLE;
151n/a break;
152n/a
153n/a case FFI_TYPE_FLOAT:
154n/a default:
155n/a cif->flags = FFI_TYPE_INT;
156n/a break;
157n/a }
158n/a
159n/a return FFI_OK;
160n/a}
161n/a
162n/aextern void ffi_call_ARCompact (void (*)(char *, extended_cif *),
163n/a extended_cif *, unsigned, unsigned,
164n/a unsigned *, void (*fn) (void));
165n/a
166n/avoid
167n/affi_call (ffi_cif * cif, void (*fn) (void), void *rvalue, void **avalue)
168n/a{
169n/a extended_cif ecif;
170n/a
171n/a ecif.cif = cif;
172n/a ecif.avalue = avalue;
173n/a
174n/a /* If the return value is a struct and we don't have
175n/a a return value address then we need to make one. */
176n/a if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT))
177n/a {
178n/a ecif.rvalue = alloca (cif->rtype->size);
179n/a }
180n/a else
181n/a ecif.rvalue = rvalue;
182n/a
183n/a switch (cif->abi)
184n/a {
185n/a case FFI_ARCOMPACT:
186n/a ffi_call_ARCompact (ffi_prep_args, &ecif, cif->bytes,
187n/a cif->flags, ecif.rvalue, fn);
188n/a break;
189n/a
190n/a default:
191n/a FFI_ASSERT (0);
192n/a break;
193n/a }
194n/a}
195n/a
196n/aint
197n/affi_closure_inner_ARCompact (ffi_closure * closure, void *rvalue,
198n/a ffi_arg * args)
199n/a{
200n/a void **arg_area, **p_argv;
201n/a ffi_cif *cif = closure->cif;
202n/a char *argp = (char *) args;
203n/a ffi_type **p_argt;
204n/a int i;
205n/a
206n/a arg_area = (void **) alloca (cif->nargs * sizeof (void *));
207n/a
208n/a /* handle hidden argument */
209n/a if (cif->flags == FFI_TYPE_STRUCT)
210n/a {
211n/a rvalue = *(void **) argp;
212n/a argp += 4;
213n/a }
214n/a
215n/a p_argv = arg_area;
216n/a
217n/a for (i = 0, p_argt = cif->arg_types; i < cif->nargs;
218n/a i++, p_argt++, p_argv++)
219n/a {
220n/a size_t z;
221n/a int alignment;
222n/a
223n/a /* align alignment to 4 */
224n/a alignment = (((*p_argt)->alignment - 1) | 3) + 1;
225n/a
226n/a /* Align if necessary. */
227n/a if ((alignment - 1) & (unsigned) argp)
228n/a argp = (char *) ALIGN (argp, alignment);
229n/a
230n/a z = (*p_argt)->size;
231n/a *p_argv = (void *) argp;
232n/a argp += z;
233n/a }
234n/a
235n/a (closure->fun) (cif, rvalue, arg_area, closure->user_data);
236n/a
237n/a return cif->flags;
238n/a}
239n/a
240n/aextern void ffi_closure_ARCompact (void);
241n/a
242n/affi_status
243n/affi_prep_closure_loc (ffi_closure * closure, ffi_cif * cif,
244n/a void (*fun) (ffi_cif *, void *, void **, void *),
245n/a void *user_data, void *codeloc)
246n/a{
247n/a uint32_t *tramp = (uint32_t *) & (closure->tramp[0]);
248n/a
249n/a switch (cif->abi)
250n/a {
251n/a case FFI_ARCOMPACT:
252n/a FFI_ASSERT (tramp == codeloc);
253n/a tramp[0] = CODE_ENDIAN (0x200a1fc0); /* mov r8, pcl */
254n/a tramp[1] = CODE_ENDIAN (0x20200f80); /* j [long imm] */
255n/a tramp[2] = CODE_ENDIAN (ffi_closure_ARCompact);
256n/a break;
257n/a
258n/a default:
259n/a return FFI_BAD_ABI;
260n/a }
261n/a
262n/a closure->cif = cif;
263n/a closure->fun = fun;
264n/a closure->user_data = user_data;
265n/a cacheflush (codeloc, FFI_TRAMPOLINE_SIZE, BCACHE);
266n/a
267n/a return FFI_OK;
268n/a}