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

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

#countcontent
1n/a/* -----------------------------------------------------------------------
2n/a ffi.c - Copyright (C) 2004 Anthony Green
3n/a Copyright (C) 2007 Free Software Foundation, Inc.
4n/a Copyright (C) 2008 Red Hat, Inc.
5n/a
6n/a FR-V Foreign Function Interface
7n/a
8n/a Permission is hereby granted, free of charge, to any person obtaining
9n/a a copy of this software and associated documentation files (the
10n/a ``Software''), to deal in the Software without restriction, including
11n/a without limitation the rights to use, copy, modify, merge, publish,
12n/a distribute, sublicense, and/or sell copies of the Software, and to
13n/a permit persons to whom the Software is furnished to do so, subject to
14n/a the following conditions:
15n/a
16n/a The above copyright notice and this permission notice shall be included
17n/a in all copies or substantial portions of the Software.
18n/a
19n/a THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
20n/a EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21n/a MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22n/a NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23n/a HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24n/a WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25n/a OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26n/a DEALINGS IN THE SOFTWARE.
27n/a ----------------------------------------------------------------------- */
28n/a
29n/a#include <ffi.h>
30n/a#include <ffi_common.h>
31n/a
32n/a#include <stdlib.h>
33n/a
34n/a/* ffi_prep_args is called by the assembly routine once stack space
35n/a has been allocated for the function's arguments */
36n/a
37n/avoid *ffi_prep_args(char *stack, extended_cif *ecif)
38n/a{
39n/a register unsigned int i;
40n/a register void **p_argv;
41n/a register char *argp;
42n/a register ffi_type **p_arg;
43n/a register int count = 0;
44n/a
45n/a p_argv = ecif->avalue;
46n/a argp = stack;
47n/a
48n/a for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
49n/a (i != 0);
50n/a i--, p_arg++)
51n/a {
52n/a size_t z;
53n/a
54n/a z = (*p_arg)->size;
55n/a
56n/a if ((*p_arg)->type == FFI_TYPE_STRUCT)
57n/a {
58n/a z = sizeof(void*);
59n/a *(void **) argp = *p_argv;
60n/a }
61n/a /* if ((*p_arg)->type == FFI_TYPE_FLOAT)
62n/a {
63n/a if (count > 24)
64n/a {
65n/a // This is going on the stack. Turn it into a double.
66n/a *(double *) argp = (double) *(float*)(* p_argv);
67n/a z = sizeof(double);
68n/a }
69n/a else
70n/a *(void **) argp = *(void **)(* p_argv);
71n/a } */
72n/a else if (z < sizeof(int))
73n/a {
74n/a z = sizeof(int);
75n/a switch ((*p_arg)->type)
76n/a {
77n/a case FFI_TYPE_SINT8:
78n/a *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
79n/a break;
80n/a
81n/a case FFI_TYPE_UINT8:
82n/a *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
83n/a break;
84n/a
85n/a case FFI_TYPE_SINT16:
86n/a *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
87n/a break;
88n/a
89n/a case FFI_TYPE_UINT16:
90n/a *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
91n/a break;
92n/a
93n/a default:
94n/a FFI_ASSERT(0);
95n/a }
96n/a }
97n/a else if (z == sizeof(int))
98n/a {
99n/a *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
100n/a }
101n/a else
102n/a {
103n/a memcpy(argp, *p_argv, z);
104n/a }
105n/a p_argv++;
106n/a argp += z;
107n/a count += z;
108n/a }
109n/a
110n/a return (stack + ((count > 24) ? 24 : ALIGN_DOWN(count, 8)));
111n/a}
112n/a
113n/a/* Perform machine dependent cif processing */
114n/affi_status ffi_prep_cif_machdep(ffi_cif *cif)
115n/a{
116n/a if (cif->rtype->type == FFI_TYPE_STRUCT)
117n/a cif->flags = -1;
118n/a else
119n/a cif->flags = cif->rtype->size;
120n/a
121n/a cif->bytes = ALIGN (cif->bytes, 8);
122n/a
123n/a return FFI_OK;
124n/a}
125n/a
126n/aextern void ffi_call_EABI(void *(*)(char *, extended_cif *),
127n/a extended_cif *,
128n/a unsigned, unsigned,
129n/a unsigned *,
130n/a void (*fn)(void));
131n/a
132n/avoid ffi_call(ffi_cif *cif,
133n/a void (*fn)(void),
134n/a void *rvalue,
135n/a void **avalue)
136n/a{
137n/a extended_cif ecif;
138n/a
139n/a ecif.cif = cif;
140n/a ecif.avalue = avalue;
141n/a
142n/a /* If the return value is a struct and we don't have a return */
143n/a /* value address then we need to make one */
144n/a
145n/a if ((rvalue == NULL) &&
146n/a (cif->rtype->type == FFI_TYPE_STRUCT))
147n/a {
148n/a ecif.rvalue = alloca(cif->rtype->size);
149n/a }
150n/a else
151n/a ecif.rvalue = rvalue;
152n/a
153n/a
154n/a switch (cif->abi)
155n/a {
156n/a case FFI_EABI:
157n/a ffi_call_EABI(ffi_prep_args, &ecif, cif->bytes,
158n/a cif->flags, ecif.rvalue, fn);
159n/a break;
160n/a default:
161n/a FFI_ASSERT(0);
162n/a break;
163n/a }
164n/a}
165n/a
166n/avoid ffi_closure_eabi (unsigned arg1, unsigned arg2, unsigned arg3,
167n/a unsigned arg4, unsigned arg5, unsigned arg6)
168n/a{
169n/a /* This function is called by a trampoline. The trampoline stows a
170n/a pointer to the ffi_closure object in gr7. We must save this
171n/a pointer in a place that will persist while we do our work. */
172n/a register ffi_closure *creg __asm__ ("gr7");
173n/a ffi_closure *closure = creg;
174n/a
175n/a /* Arguments that don't fit in registers are found on the stack
176n/a at a fixed offset above the current frame pointer. */
177n/a register char *frame_pointer __asm__ ("fp");
178n/a char *stack_args = frame_pointer + 16;
179n/a
180n/a /* Lay the register arguments down in a continuous chunk of memory. */
181n/a unsigned register_args[6] =
182n/a { arg1, arg2, arg3, arg4, arg5, arg6 };
183n/a
184n/a ffi_cif *cif = closure->cif;
185n/a ffi_type **arg_types = cif->arg_types;
186n/a void **avalue = alloca (cif->nargs * sizeof(void *));
187n/a char *ptr = (char *) register_args;
188n/a int i;
189n/a
190n/a /* Find the address of each argument. */
191n/a for (i = 0; i < cif->nargs; i++)
192n/a {
193n/a switch (arg_types[i]->type)
194n/a {
195n/a case FFI_TYPE_SINT8:
196n/a case FFI_TYPE_UINT8:
197n/a avalue[i] = ptr + 3;
198n/a break;
199n/a case FFI_TYPE_SINT16:
200n/a case FFI_TYPE_UINT16:
201n/a avalue[i] = ptr + 2;
202n/a break;
203n/a case FFI_TYPE_SINT32:
204n/a case FFI_TYPE_UINT32:
205n/a case FFI_TYPE_FLOAT:
206n/a avalue[i] = ptr;
207n/a break;
208n/a case FFI_TYPE_STRUCT:
209n/a avalue[i] = *(void**)ptr;
210n/a break;
211n/a default:
212n/a /* This is an 8-byte value. */
213n/a avalue[i] = ptr;
214n/a ptr += 4;
215n/a break;
216n/a }
217n/a ptr += 4;
218n/a
219n/a /* If we've handled more arguments than fit in registers,
220n/a start looking at the those passed on the stack. */
221n/a if (ptr == ((char *)register_args + (6*4)))
222n/a ptr = stack_args;
223n/a }
224n/a
225n/a /* Invoke the closure. */
226n/a if (cif->rtype->type == FFI_TYPE_STRUCT)
227n/a {
228n/a /* The caller allocates space for the return structure, and
229n/a passes a pointer to this space in gr3. Use this value directly
230n/a as the return value. */
231n/a register void *return_struct_ptr __asm__("gr3");
232n/a (closure->fun) (cif, return_struct_ptr, avalue, closure->user_data);
233n/a }
234n/a else
235n/a {
236n/a /* Allocate space for the return value and call the function. */
237n/a long long rvalue;
238n/a (closure->fun) (cif, &rvalue, avalue, closure->user_data);
239n/a
240n/a /* Functions return 4-byte or smaller results in gr8. 8-byte
241n/a values also use gr9. We fill the both, even for small return
242n/a values, just to avoid a branch. */
243n/a asm ("ldi @(%0, #0), gr8" : : "r" (&rvalue));
244n/a asm ("ldi @(%0, #0), gr9" : : "r" (&((int *) &rvalue)[1]));
245n/a }
246n/a}
247n/a
248n/affi_status
249n/affi_prep_closure_loc (ffi_closure* closure,
250n/a ffi_cif* cif,
251n/a void (*fun)(ffi_cif*, void*, void**, void*),
252n/a void *user_data,
253n/a void *codeloc)
254n/a{
255n/a unsigned int *tramp = (unsigned int *) &closure->tramp[0];
256n/a unsigned long fn = (long) ffi_closure_eabi;
257n/a unsigned long cls = (long) codeloc;
258n/a#ifdef __FRV_FDPIC__
259n/a register void *got __asm__("gr15");
260n/a#endif
261n/a int i;
262n/a
263n/a fn = (unsigned long) ffi_closure_eabi;
264n/a
265n/a#ifdef __FRV_FDPIC__
266n/a tramp[0] = &((unsigned int *)codeloc)[2];
267n/a tramp[1] = got;
268n/a tramp[2] = 0x8cfc0000 + (fn & 0xffff); /* setlos lo(fn), gr6 */
269n/a tramp[3] = 0x8efc0000 + (cls & 0xffff); /* setlos lo(cls), gr7 */
270n/a tramp[4] = 0x8cf80000 + (fn >> 16); /* sethi hi(fn), gr6 */
271n/a tramp[5] = 0x8ef80000 + (cls >> 16); /* sethi hi(cls), gr7 */
272n/a tramp[6] = 0x9cc86000; /* ldi @(gr6, #0), gr14 */
273n/a tramp[7] = 0x8030e000; /* jmpl @(gr14, gr0) */
274n/a#else
275n/a tramp[0] = 0x8cfc0000 + (fn & 0xffff); /* setlos lo(fn), gr6 */
276n/a tramp[1] = 0x8efc0000 + (cls & 0xffff); /* setlos lo(cls), gr7 */
277n/a tramp[2] = 0x8cf80000 + (fn >> 16); /* sethi hi(fn), gr6 */
278n/a tramp[3] = 0x8ef80000 + (cls >> 16); /* sethi hi(cls), gr7 */
279n/a tramp[4] = 0x80300006; /* jmpl @(gr0, gr6) */
280n/a#endif
281n/a
282n/a closure->cif = cif;
283n/a closure->fun = fun;
284n/a closure->user_data = user_data;
285n/a
286n/a /* Cache flushing. */
287n/a for (i = 0; i < FFI_TRAMPOLINE_SIZE; i++)
288n/a __asm__ volatile ("dcf @(%0,%1)\n\tici @(%2,%1)" :: "r" (tramp), "r" (i),
289n/a "r" (codeloc));
290n/a
291n/a return FFI_OK;
292n/a}