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

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

#countcontent
1n/a/* -----------------------------------------------------------------------
2n/a ffi.c - Copyright (c) 2012 Alexandre K. I. de Mendonca <alexandre.keunecke@gmail.com>,
3n/a Paulo Pizarro <paulo.pizarro@gmail.com>
4n/a
5n/a Blackfin 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#include <ffi.h>
28n/a#include <ffi_common.h>
29n/a
30n/a#include <stdlib.h>
31n/a#include <stdio.h>
32n/a
33n/a/* Maximum number of GPRs available for argument passing. */
34n/a#define MAX_GPRARGS 3
35n/a
36n/a/*
37n/a * Return types
38n/a */
39n/a#define FFIBFIN_RET_VOID 0
40n/a#define FFIBFIN_RET_BYTE 1
41n/a#define FFIBFIN_RET_HALFWORD 2
42n/a#define FFIBFIN_RET_INT64 3
43n/a#define FFIBFIN_RET_INT32 4
44n/a
45n/a/*====================================================================*/
46n/a/* PROTOTYPE *
47n/a /*====================================================================*/
48n/avoid ffi_prep_args(unsigned char *, extended_cif *);
49n/a
50n/a/*====================================================================*/
51n/a/* Externals */
52n/a/* (Assembly) */
53n/a/*====================================================================*/
54n/a
55n/aextern void ffi_call_SYSV(unsigned, extended_cif *, void(*)(unsigned char *, extended_cif *), unsigned, void *, void(*fn)(void));
56n/a
57n/a/*====================================================================*/
58n/a/* Implementation */
59n/a/* */
60n/a/*====================================================================*/
61n/a
62n/a
63n/a/*
64n/a * This function calculates the return type (size) based on type.
65n/a */
66n/a
67n/affi_status ffi_prep_cif_machdep(ffi_cif *cif)
68n/a{
69n/a /* --------------------------------------*
70n/a * Return handling *
71n/a * --------------------------------------*/
72n/a switch (cif->rtype->type) {
73n/a case FFI_TYPE_VOID:
74n/a cif->flags = FFIBFIN_RET_VOID;
75n/a break;
76n/a case FFI_TYPE_UINT16:
77n/a case FFI_TYPE_SINT16:
78n/a cif->flags = FFIBFIN_RET_HALFWORD;
79n/a break;
80n/a case FFI_TYPE_UINT8:
81n/a cif->flags = FFIBFIN_RET_BYTE;
82n/a break;
83n/a case FFI_TYPE_INT:
84n/a case FFI_TYPE_UINT32:
85n/a case FFI_TYPE_SINT32:
86n/a case FFI_TYPE_FLOAT:
87n/a case FFI_TYPE_POINTER:
88n/a case FFI_TYPE_SINT8:
89n/a cif->flags = FFIBFIN_RET_INT32;
90n/a break;
91n/a case FFI_TYPE_SINT64:
92n/a case FFI_TYPE_UINT64:
93n/a case FFI_TYPE_DOUBLE:
94n/a cif->flags = FFIBFIN_RET_INT64;
95n/a break;
96n/a case FFI_TYPE_STRUCT:
97n/a if (cif->rtype->size <= 4){
98n/a cif->flags = FFIBFIN_RET_INT32;
99n/a }else if (cif->rtype->size == 8){
100n/a cif->flags = FFIBFIN_RET_INT64;
101n/a }else{
102n/a //it will return via a hidden pointer in P0
103n/a cif->flags = FFIBFIN_RET_VOID;
104n/a }
105n/a break;
106n/a default:
107n/a FFI_ASSERT(0);
108n/a break;
109n/a }
110n/a return FFI_OK;
111n/a}
112n/a
113n/a/*
114n/a * This will prepare the arguments and will call the assembly routine
115n/a * cif = the call interface
116n/a * fn = the function to be called
117n/a * rvalue = the return value
118n/a * avalue = the arguments
119n/a */
120n/avoid ffi_call(ffi_cif *cif, void(*fn)(void), void *rvalue, void **avalue)
121n/a{
122n/a int ret_type = cif->flags;
123n/a extended_cif ecif;
124n/a ecif.cif = cif;
125n/a ecif.avalue = avalue;
126n/a ecif.rvalue = rvalue;
127n/a
128n/a switch (cif->abi) {
129n/a case FFI_SYSV:
130n/a ffi_call_SYSV(cif->bytes, &ecif, ffi_prep_args, ret_type, ecif.rvalue, fn);
131n/a break;
132n/a default:
133n/a FFI_ASSERT(0);
134n/a break;
135n/a }
136n/a}
137n/a
138n/a
139n/a/*
140n/a* This function prepares the parameters (copies them from the ecif to the stack)
141n/a* to call the function (ffi_prep_args is called by the assembly routine in file
142n/a* sysv.S, which also calls the actual function)
143n/a*/
144n/avoid ffi_prep_args(unsigned char *stack, extended_cif *ecif)
145n/a{
146n/a register unsigned int i = 0;
147n/a void **p_argv;
148n/a unsigned char *argp;
149n/a ffi_type **p_arg;
150n/a argp = stack;
151n/a p_argv = ecif->avalue;
152n/a for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
153n/a (i != 0);
154n/a i--, p_arg++) {
155n/a size_t z;
156n/a z = (*p_arg)->size;
157n/a if (z < sizeof(int)) {
158n/a z = sizeof(int);
159n/a switch ((*p_arg)->type) {
160n/a case FFI_TYPE_SINT8: {
161n/a signed char v = *(SINT8 *)(* p_argv);
162n/a signed int t = v;
163n/a *(signed int *) argp = t;
164n/a }
165n/a break;
166n/a case FFI_TYPE_UINT8: {
167n/a unsigned char v = *(UINT8 *)(* p_argv);
168n/a unsigned int t = v;
169n/a *(unsigned int *) argp = t;
170n/a }
171n/a break;
172n/a case FFI_TYPE_SINT16:
173n/a *(signed int *) argp = (signed int) * (SINT16 *)(* p_argv);
174n/a break;
175n/a case FFI_TYPE_UINT16:
176n/a *(unsigned int *) argp = (unsigned int) * (UINT16 *)(* p_argv);
177n/a break;
178n/a case FFI_TYPE_STRUCT:
179n/a memcpy(argp, *p_argv, (*p_arg)->size);
180n/a break;
181n/a default:
182n/a FFI_ASSERT(0);
183n/a break;
184n/a }
185n/a } else if (z == sizeof(int)) {
186n/a *(unsigned int *) argp = (unsigned int) * (UINT32 *)(* p_argv);
187n/a } else {
188n/a memcpy(argp, *p_argv, z);
189n/a }
190n/a p_argv++;
191n/a argp += z;
192n/a }
193n/a}
194n/a
195n/a
196n/a