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

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

#countcontent
1n/a/* -----------------------------------------------------------------------
2n/a ffi.c - Copyright (c) 2011 Anthony Green
3n/a Copyright (c) 2009 Bradley Smith <brad@brad-smith.co.uk>
4n/a
5n/a AVR32 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
31n/a#include <stdlib.h>
32n/a#include <stdio.h>
33n/a#include <unistd.h>
34n/a#include <asm/unistd.h>
35n/a
36n/a/* #define DEBUG */
37n/a
38n/aextern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
39n/a unsigned int, unsigned int, unsigned int*, unsigned int,
40n/a void (*fn)(void));
41n/aextern void ffi_closure_SYSV (ffi_closure *);
42n/a
43n/aunsigned int pass_struct_on_stack(ffi_type *type)
44n/a{
45n/a if(type->type != FFI_TYPE_STRUCT)
46n/a return 0;
47n/a
48n/a if(type->alignment < type->size &&
49n/a !(type->size == 4 || type->size == 8) &&
50n/a !(type->size == 8 && type->alignment >= 4))
51n/a return 1;
52n/a
53n/a if(type->size == 3 || type->size == 5 || type->size == 6 ||
54n/a type->size == 7)
55n/a return 1;
56n/a
57n/a return 0;
58n/a}
59n/a
60n/a/* ffi_prep_args is called by the assembly routine once stack space
61n/a * has been allocated for the function's arguments
62n/a *
63n/a * This is annoyingly complex since we need to keep track of used
64n/a * registers.
65n/a */
66n/a
67n/avoid ffi_prep_args(char *stack, extended_cif *ecif)
68n/a{
69n/a unsigned int i;
70n/a void **p_argv;
71n/a ffi_type **p_arg;
72n/a char *reg_base = stack;
73n/a char *stack_base = stack + 20;
74n/a unsigned int stack_offset = 0;
75n/a unsigned int reg_mask = 0;
76n/a
77n/a p_argv = ecif->avalue;
78n/a
79n/a /* If cif->flags is struct then we know it's not passed in registers */
80n/a if(ecif->cif->flags == FFI_TYPE_STRUCT)
81n/a {
82n/a *(void**)reg_base = ecif->rvalue;
83n/a reg_mask |= 1;
84n/a }
85n/a
86n/a for(i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs;
87n/a i++, p_arg++)
88n/a {
89n/a size_t z = (*p_arg)->size;
90n/a int alignment = (*p_arg)->alignment;
91n/a int type = (*p_arg)->type;
92n/a char *addr = 0;
93n/a
94n/a if(z % 4 != 0)
95n/a z += (4 - z % 4);
96n/a
97n/a if(reg_mask != 0x1f)
98n/a {
99n/a if(pass_struct_on_stack(*p_arg))
100n/a {
101n/a addr = stack_base + stack_offset;
102n/a stack_offset += z;
103n/a }
104n/a else if(z == sizeof(int))
105n/a {
106n/a char index = 0;
107n/a
108n/a while((reg_mask >> index) & 1)
109n/a index++;
110n/a
111n/a addr = reg_base + (index * 4);
112n/a reg_mask |= (1 << index);
113n/a }
114n/a else if(z == 2 * sizeof(int))
115n/a {
116n/a if(!((reg_mask >> 1) & 1))
117n/a {
118n/a addr = reg_base + 4;
119n/a reg_mask |= (3 << 1);
120n/a }
121n/a else if(!((reg_mask >> 3) & 1))
122n/a {
123n/a addr = reg_base + 12;
124n/a reg_mask |= (3 << 3);
125n/a }
126n/a }
127n/a }
128n/a
129n/a if(!addr)
130n/a {
131n/a addr = stack_base + stack_offset;
132n/a stack_offset += z;
133n/a }
134n/a
135n/a if(type == FFI_TYPE_STRUCT && (*p_arg)->elements[1] == NULL)
136n/a type = (*p_arg)->elements[0]->type;
137n/a
138n/a switch(type)
139n/a {
140n/a case FFI_TYPE_UINT8:
141n/a *(unsigned int *)addr = (unsigned int)*(UINT8 *)(*p_argv);
142n/a break;
143n/a case FFI_TYPE_SINT8:
144n/a *(signed int *)addr = (signed int)*(SINT8 *)(*p_argv);
145n/a break;
146n/a case FFI_TYPE_UINT16:
147n/a *(unsigned int *)addr = (unsigned int)*(UINT16 *)(*p_argv);
148n/a break;
149n/a case FFI_TYPE_SINT16:
150n/a *(signed int *)addr = (signed int)*(SINT16 *)(*p_argv);
151n/a break;
152n/a default:
153n/a memcpy(addr, *p_argv, z);
154n/a }
155n/a
156n/a p_argv++;
157n/a }
158n/a
159n/a#ifdef DEBUG
160n/a /* Debugging */
161n/a for(i = 0; i < 5; i++)
162n/a {
163n/a if((reg_mask & (1 << i)) == 0)
164n/a printf("r%d: (unused)\n", 12 - i);
165n/a else
166n/a printf("r%d: 0x%08x\n", 12 - i, ((unsigned int*)reg_base)[i]);
167n/a }
168n/a
169n/a for(i = 0; i < stack_offset / 4; i++)
170n/a {
171n/a printf("sp+%d: 0x%08x\n", i*4, ((unsigned int*)stack_base)[i]);
172n/a }
173n/a#endif
174n/a}
175n/a
176n/a/* Perform machine dependent cif processing */
177n/affi_status ffi_prep_cif_machdep(ffi_cif *cif)
178n/a{
179n/a /* Round the stack up to a multiple of 8 bytes. This isn't needed
180n/a * everywhere, but it is on some platforms, and it doesn't harm
181n/a * anything when it isn't needed. */
182n/a cif->bytes = (cif->bytes + 7) & ~7;
183n/a
184n/a /* Flag to indicate that he return value is in fact a struct */
185n/a cif->rstruct_flag = 0;
186n/a
187n/a /* Set the return type flag */
188n/a switch(cif->rtype->type)
189n/a {
190n/a case FFI_TYPE_SINT8:
191n/a case FFI_TYPE_UINT8:
192n/a cif->flags = (unsigned)FFI_TYPE_UINT8;
193n/a break;
194n/a case FFI_TYPE_SINT16:
195n/a case FFI_TYPE_UINT16:
196n/a cif->flags = (unsigned)FFI_TYPE_UINT16;
197n/a break;
198n/a case FFI_TYPE_FLOAT:
199n/a case FFI_TYPE_SINT32:
200n/a case FFI_TYPE_UINT32:
201n/a case FFI_TYPE_POINTER:
202n/a cif->flags = (unsigned)FFI_TYPE_UINT32;
203n/a break;
204n/a case FFI_TYPE_DOUBLE:
205n/a case FFI_TYPE_SINT64:
206n/a case FFI_TYPE_UINT64:
207n/a cif->flags = (unsigned)FFI_TYPE_UINT64;
208n/a break;
209n/a case FFI_TYPE_STRUCT:
210n/a cif->rstruct_flag = 1;
211n/a if(!pass_struct_on_stack(cif->rtype))
212n/a {
213n/a if(cif->rtype->size <= 1)
214n/a cif->flags = (unsigned)FFI_TYPE_UINT8;
215n/a else if(cif->rtype->size <= 2)
216n/a cif->flags = (unsigned)FFI_TYPE_UINT16;
217n/a else if(cif->rtype->size <= 4)
218n/a cif->flags = (unsigned)FFI_TYPE_UINT32;
219n/a else if(cif->rtype->size <= 8)
220n/a cif->flags = (unsigned)FFI_TYPE_UINT64;
221n/a else
222n/a cif->flags = (unsigned)cif->rtype->type;
223n/a }
224n/a else
225n/a cif->flags = (unsigned)cif->rtype->type;
226n/a break;
227n/a default:
228n/a cif->flags = (unsigned)cif->rtype->type;
229n/a break;
230n/a }
231n/a
232n/a return FFI_OK;
233n/a}
234n/a
235n/avoid ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
236n/a{
237n/a extended_cif ecif;
238n/a
239n/a unsigned int size = 0, i = 0;
240n/a ffi_type **p_arg;
241n/a
242n/a ecif.cif = cif;
243n/a ecif.avalue = avalue;
244n/a
245n/a for(i = 0, p_arg = cif->arg_types; i < cif->nargs; i++, p_arg++)
246n/a size += (*p_arg)->size + (4 - (*p_arg)->size % 4);
247n/a
248n/a /* If the return value is a struct and we don't have a return value
249n/a * address then we need to make one */
250n/a
251n/a /* If cif->flags is struct then it's not suitable for registers */
252n/a if((rvalue == NULL) && (cif->flags == FFI_TYPE_STRUCT))
253n/a ecif.rvalue = alloca(cif->rtype->size);
254n/a else
255n/a ecif.rvalue = rvalue;
256n/a
257n/a switch(cif->abi)
258n/a {
259n/a case FFI_SYSV:
260n/a ffi_call_SYSV(ffi_prep_args, &ecif, size, cif->flags,
261n/a ecif.rvalue, cif->rstruct_flag, fn);
262n/a break;
263n/a default:
264n/a FFI_ASSERT(0);
265n/a break;
266n/a }
267n/a}
268n/a
269n/astatic void ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
270n/a void **avalue, ffi_cif *cif)
271n/a{
272n/a register unsigned int i, reg_mask = 0;
273n/a register void **p_argv;
274n/a register ffi_type **p_arg;
275n/a register char *reg_base = stack;
276n/a register char *stack_base = stack + 20;
277n/a register unsigned int stack_offset = 0;
278n/a
279n/a#ifdef DEBUG
280n/a /* Debugging */
281n/a for(i = 0; i < cif->nargs + 7; i++)
282n/a {
283n/a printf("sp+%d: 0x%08x\n", i*4, ((unsigned int*)stack)[i]);
284n/a }
285n/a#endif
286n/a
287n/a /* If cif->flags is struct then we know it's not passed in registers */
288n/a if(cif->flags == FFI_TYPE_STRUCT)
289n/a {
290n/a *rvalue = *(void **)reg_base;
291n/a reg_mask |= 1;
292n/a }
293n/a
294n/a p_argv = avalue;
295n/a
296n/a for(i = 0, p_arg = cif->arg_types; i < cif->nargs; i++, p_arg++)
297n/a {
298n/a size_t z = (*p_arg)->size;
299n/a int alignment = (*p_arg)->alignment;
300n/a
301n/a *p_argv = 0;
302n/a
303n/a if(z % 4 != 0)
304n/a z += (4 - z % 4);
305n/a
306n/a if(reg_mask != 0x1f)
307n/a {
308n/a if(pass_struct_on_stack(*p_arg))
309n/a {
310n/a *p_argv = (void*)stack_base + stack_offset;
311n/a stack_offset += z;
312n/a }
313n/a else if(z <= sizeof(int))
314n/a {
315n/a char index = 0;
316n/a
317n/a while((reg_mask >> index) & 1)
318n/a index++;
319n/a
320n/a *p_argv = (void*)reg_base + (index * 4);
321n/a reg_mask |= (1 << index);
322n/a }
323n/a else if(z == 2 * sizeof(int))
324n/a {
325n/a if(!((reg_mask >> 1) & 1))
326n/a {
327n/a *p_argv = (void*)reg_base + 4;
328n/a reg_mask |= (3 << 1);
329n/a }
330n/a else if(!((reg_mask >> 3) & 1))
331n/a {
332n/a *p_argv = (void*)reg_base + 12;
333n/a reg_mask |= (3 << 3);
334n/a }
335n/a }
336n/a }
337n/a
338n/a if(!*p_argv)
339n/a {
340n/a *p_argv = (void*)stack_base + stack_offset;
341n/a stack_offset += z;
342n/a }
343n/a
344n/a if((*p_arg)->type != FFI_TYPE_STRUCT ||
345n/a (*p_arg)->elements[1] == NULL)
346n/a {
347n/a if(alignment == 1)
348n/a **(unsigned int**)p_argv <<= 24;
349n/a else if(alignment == 2)
350n/a **(unsigned int**)p_argv <<= 16;
351n/a }
352n/a
353n/a p_argv++;
354n/a }
355n/a
356n/a#ifdef DEBUG
357n/a /* Debugging */
358n/a for(i = 0; i < cif->nargs; i++)
359n/a {
360n/a printf("sp+%d: 0x%08x\n", i*4, *(((unsigned int**)avalue)[i]));
361n/a }
362n/a#endif
363n/a}
364n/a
365n/a/* This function is jumped to by the trampoline */
366n/a
367n/aunsigned int ffi_closure_SYSV_inner(ffi_closure *closure, void **respp,
368n/a void *args)
369n/a{
370n/a ffi_cif *cif;
371n/a void **arg_area;
372n/a unsigned int i, size = 0;
373n/a ffi_type **p_arg;
374n/a
375n/a cif = closure->cif;
376n/a
377n/a for(i = 0, p_arg = cif->arg_types; i < cif->nargs; i++, p_arg++)
378n/a size += (*p_arg)->size + (4 - (*p_arg)->size % 4);
379n/a
380n/a arg_area = (void **)alloca(size);
381n/a
382n/a /* this call will initialize ARG_AREA, such that each element in that
383n/a * array points to the corresponding value on the stack; and if the
384n/a * function returns a structure, it will re-set RESP to point to the
385n/a * structure return address. */
386n/a
387n/a ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif);
388n/a
389n/a (closure->fun)(cif, *respp, arg_area, closure->user_data);
390n/a
391n/a return cif->flags;
392n/a}
393n/a
394n/affi_status ffi_prep_closure_loc(ffi_closure* closure, ffi_cif* cif,
395n/a void (*fun)(ffi_cif*, void*, void**, void*), void *user_data,
396n/a void *codeloc)
397n/a{
398n/a if (cif->abi != FFI_SYSV)
399n/a return FFI_BAD_ABI;
400n/a
401n/a unsigned char *__tramp = (unsigned char*)(&closure->tramp[0]);
402n/a unsigned int __fun = (unsigned int)(&ffi_closure_SYSV);
403n/a unsigned int __ctx = (unsigned int)(codeloc);
404n/a unsigned int __rstruct_flag = (unsigned int)(cif->rstruct_flag);
405n/a unsigned int __inner = (unsigned int)(&ffi_closure_SYSV_inner);
406n/a *(unsigned int*) &__tramp[0] = 0xebcd1f00; /* pushm r8-r12 */
407n/a *(unsigned int*) &__tramp[4] = 0xfefc0010; /* ld.w r12, pc[16] */
408n/a *(unsigned int*) &__tramp[8] = 0xfefb0010; /* ld.w r11, pc[16] */
409n/a *(unsigned int*) &__tramp[12] = 0xfefa0010; /* ld.w r10, pc[16] */
410n/a *(unsigned int*) &__tramp[16] = 0xfeff0010; /* ld.w pc, pc[16] */
411n/a *(unsigned int*) &__tramp[20] = __ctx;
412n/a *(unsigned int*) &__tramp[24] = __rstruct_flag;
413n/a *(unsigned int*) &__tramp[28] = __inner;
414n/a *(unsigned int*) &__tramp[32] = __fun;
415n/a syscall(__NR_cacheflush, 0, (&__tramp[0]), 36);
416n/a
417n/a closure->cif = cif;
418n/a closure->user_data = user_data;
419n/a closure->fun = fun;
420n/a
421n/a return FFI_OK;
422n/a}
423n/a