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

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

#countcontent
1n/a/* -----------------------------------------------------------------------
2n/a ffi.c - Copyright (c) 2011 Anthony Green
3n/a Copyright (c) 2008 David Daney
4n/a Copyright (c) 1996, 2007, 2008, 2011 Red Hat, Inc.
5n/a
6n/a MIPS 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#ifdef __GNUC__
35n/a# if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3))
36n/a# define USE__BUILTIN___CLEAR_CACHE 1
37n/a# endif
38n/a#endif
39n/a
40n/a#ifndef USE__BUILTIN___CLEAR_CACHE
41n/a# if defined(__OpenBSD__)
42n/a# include <mips64/sysarch.h>
43n/a# else
44n/a# include <sys/cachectl.h>
45n/a# endif
46n/a#endif
47n/a
48n/a#ifdef FFI_DEBUG
49n/a# define FFI_MIPS_STOP_HERE() ffi_stop_here()
50n/a#else
51n/a# define FFI_MIPS_STOP_HERE() do {} while(0)
52n/a#endif
53n/a
54n/a#ifdef FFI_MIPS_N32
55n/a#define FIX_ARGP \
56n/aFFI_ASSERT(argp <= &stack[bytes]); \
57n/aif (argp == &stack[bytes]) \
58n/a{ \
59n/a argp = stack; \
60n/a FFI_MIPS_STOP_HERE(); \
61n/a}
62n/a#else
63n/a#define FIX_ARGP
64n/a#endif
65n/a
66n/a
67n/a/* ffi_prep_args is called by the assembly routine once stack space
68n/a has been allocated for the function's arguments */
69n/a
70n/astatic void ffi_prep_args(char *stack,
71n/a extended_cif *ecif,
72n/a int bytes,
73n/a int flags)
74n/a{
75n/a int i;
76n/a void **p_argv;
77n/a char *argp;
78n/a ffi_type **p_arg;
79n/a
80n/a#ifdef FFI_MIPS_N32
81n/a /* If more than 8 double words are used, the remainder go
82n/a on the stack. We reorder stuff on the stack here to
83n/a support this easily. */
84n/a if (bytes > 8 * sizeof(ffi_arg))
85n/a argp = &stack[bytes - (8 * sizeof(ffi_arg))];
86n/a else
87n/a argp = stack;
88n/a#else
89n/a argp = stack;
90n/a#endif
91n/a
92n/a memset(stack, 0, bytes);
93n/a
94n/a#ifdef FFI_MIPS_N32
95n/a if ( ecif->cif->rstruct_flag != 0 )
96n/a#else
97n/a if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT )
98n/a#endif
99n/a {
100n/a *(ffi_arg *) argp = (ffi_arg) ecif->rvalue;
101n/a argp += sizeof(ffi_arg);
102n/a FIX_ARGP;
103n/a }
104n/a
105n/a p_argv = ecif->avalue;
106n/a
107n/a for (i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs; i++, p_arg++)
108n/a {
109n/a size_t z;
110n/a unsigned int a;
111n/a
112n/a /* Align if necessary. */
113n/a a = (*p_arg)->alignment;
114n/a if (a < sizeof(ffi_arg))
115n/a a = sizeof(ffi_arg);
116n/a
117n/a if ((a - 1) & (unsigned long) argp)
118n/a {
119n/a argp = (char *) ALIGN(argp, a);
120n/a FIX_ARGP;
121n/a }
122n/a
123n/a z = (*p_arg)->size;
124n/a if (z <= sizeof(ffi_arg))
125n/a {
126n/a int type = (*p_arg)->type;
127n/a z = sizeof(ffi_arg);
128n/a
129n/a /* The size of a pointer depends on the ABI */
130n/a if (type == FFI_TYPE_POINTER)
131n/a type = (ecif->cif->abi == FFI_N64
132n/a || ecif->cif->abi == FFI_N64_SOFT_FLOAT)
133n/a ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
134n/a
135n/a if (i < 8 && (ecif->cif->abi == FFI_N32_SOFT_FLOAT
136n/a || ecif->cif->abi == FFI_N64_SOFT_FLOAT))
137n/a {
138n/a switch (type)
139n/a {
140n/a case FFI_TYPE_FLOAT:
141n/a type = FFI_TYPE_UINT32;
142n/a break;
143n/a case FFI_TYPE_DOUBLE:
144n/a type = FFI_TYPE_UINT64;
145n/a break;
146n/a default:
147n/a break;
148n/a }
149n/a }
150n/a switch (type)
151n/a {
152n/a case FFI_TYPE_SINT8:
153n/a *(ffi_arg *)argp = *(SINT8 *)(* p_argv);
154n/a break;
155n/a
156n/a case FFI_TYPE_UINT8:
157n/a *(ffi_arg *)argp = *(UINT8 *)(* p_argv);
158n/a break;
159n/a
160n/a case FFI_TYPE_SINT16:
161n/a *(ffi_arg *)argp = *(SINT16 *)(* p_argv);
162n/a break;
163n/a
164n/a case FFI_TYPE_UINT16:
165n/a *(ffi_arg *)argp = *(UINT16 *)(* p_argv);
166n/a break;
167n/a
168n/a case FFI_TYPE_SINT32:
169n/a *(ffi_arg *)argp = *(SINT32 *)(* p_argv);
170n/a break;
171n/a
172n/a case FFI_TYPE_UINT32:
173n/a#ifdef FFI_MIPS_N32
174n/a /* The N32 ABI requires that 32-bit integers
175n/a be sign-extended to 64-bits, regardless of
176n/a whether they are signed or unsigned. */
177n/a *(ffi_arg *)argp = *(SINT32 *)(* p_argv);
178n/a#else
179n/a *(ffi_arg *)argp = *(UINT32 *)(* p_argv);
180n/a#endif
181n/a break;
182n/a
183n/a /* This can only happen with 64bit slots. */
184n/a case FFI_TYPE_FLOAT:
185n/a *(float *) argp = *(float *)(* p_argv);
186n/a break;
187n/a
188n/a /* Handle structures. */
189n/a default:
190n/a memcpy(argp, *p_argv, (*p_arg)->size);
191n/a break;
192n/a }
193n/a }
194n/a else
195n/a {
196n/a#ifdef FFI_MIPS_O32
197n/a memcpy(argp, *p_argv, z);
198n/a#else
199n/a {
200n/a unsigned long end = (unsigned long) argp + z;
201n/a unsigned long cap = (unsigned long) stack + bytes;
202n/a
203n/a /* Check if the data will fit within the register space.
204n/a Handle it if it doesn't. */
205n/a
206n/a if (end <= cap)
207n/a memcpy(argp, *p_argv, z);
208n/a else
209n/a {
210n/a unsigned long portion = cap - (unsigned long)argp;
211n/a
212n/a memcpy(argp, *p_argv, portion);
213n/a argp = stack;
214n/a z -= portion;
215n/a memcpy(argp, (void*)((unsigned long)(*p_argv) + portion),
216n/a z);
217n/a }
218n/a }
219n/a#endif
220n/a }
221n/a p_argv++;
222n/a argp += z;
223n/a FIX_ARGP;
224n/a }
225n/a}
226n/a
227n/a#ifdef FFI_MIPS_N32
228n/a
229n/a/* The n32 spec says that if "a chunk consists solely of a double
230n/a float field (but not a double, which is part of a union), it
231n/a is passed in a floating point register. Any other chunk is
232n/a passed in an integer register". This code traverses structure
233n/a definitions and generates the appropriate flags. */
234n/a
235n/astatic unsigned
236n/acalc_n32_struct_flags(int soft_float, ffi_type *arg,
237n/a unsigned *loc, unsigned *arg_reg)
238n/a{
239n/a unsigned flags = 0;
240n/a unsigned index = 0;
241n/a
242n/a ffi_type *e;
243n/a
244n/a if (soft_float)
245n/a return 0;
246n/a
247n/a while ((e = arg->elements[index]))
248n/a {
249n/a /* Align this object. */
250n/a *loc = ALIGN(*loc, e->alignment);
251n/a if (e->type == FFI_TYPE_DOUBLE)
252n/a {
253n/a /* Already aligned to FFI_SIZEOF_ARG. */
254n/a *arg_reg = *loc / FFI_SIZEOF_ARG;
255n/a if (*arg_reg > 7)
256n/a break;
257n/a flags += (FFI_TYPE_DOUBLE << (*arg_reg * FFI_FLAG_BITS));
258n/a *loc += e->size;
259n/a }
260n/a else
261n/a *loc += e->size;
262n/a index++;
263n/a }
264n/a /* Next Argument register at alignment of FFI_SIZEOF_ARG. */
265n/a *arg_reg = ALIGN(*loc, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
266n/a
267n/a return flags;
268n/a}
269n/a
270n/astatic unsigned
271n/acalc_n32_return_struct_flags(int soft_float, ffi_type *arg)
272n/a{
273n/a unsigned flags = 0;
274n/a unsigned small = FFI_TYPE_SMALLSTRUCT;
275n/a ffi_type *e;
276n/a
277n/a /* Returning structures under n32 is a tricky thing.
278n/a A struct with only one or two floating point fields
279n/a is returned in $f0 (and $f2 if necessary). Any other
280n/a struct results at most 128 bits are returned in $2
281n/a (the first 64 bits) and $3 (remainder, if necessary).
282n/a Larger structs are handled normally. */
283n/a
284n/a if (arg->size > 16)
285n/a return 0;
286n/a
287n/a if (arg->size > 8)
288n/a small = FFI_TYPE_SMALLSTRUCT2;
289n/a
290n/a e = arg->elements[0];
291n/a
292n/a if (e->type == FFI_TYPE_DOUBLE)
293n/a flags = FFI_TYPE_DOUBLE;
294n/a else if (e->type == FFI_TYPE_FLOAT)
295n/a flags = FFI_TYPE_FLOAT;
296n/a
297n/a if (flags && (e = arg->elements[1]))
298n/a {
299n/a if (e->type == FFI_TYPE_DOUBLE)
300n/a flags += FFI_TYPE_DOUBLE << FFI_FLAG_BITS;
301n/a else if (e->type == FFI_TYPE_FLOAT)
302n/a flags += FFI_TYPE_FLOAT << FFI_FLAG_BITS;
303n/a else
304n/a return small;
305n/a
306n/a if (flags && (arg->elements[2]))
307n/a {
308n/a /* There are three arguments and the first two are
309n/a floats! This must be passed the old way. */
310n/a return small;
311n/a }
312n/a if (soft_float)
313n/a flags += FFI_TYPE_STRUCT_SOFT;
314n/a }
315n/a else
316n/a if (!flags)
317n/a return small;
318n/a
319n/a return flags;
320n/a}
321n/a
322n/a#endif
323n/a
324n/a/* Perform machine dependent cif processing */
325n/affi_status ffi_prep_cif_machdep(ffi_cif *cif)
326n/a{
327n/a cif->flags = 0;
328n/a
329n/a#ifdef FFI_MIPS_O32
330n/a /* Set the flags necessary for O32 processing. FFI_O32_SOFT_FLOAT
331n/a * does not have special handling for floating point args.
332n/a */
333n/a
334n/a if (cif->rtype->type != FFI_TYPE_STRUCT && cif->abi == FFI_O32)
335n/a {
336n/a if (cif->nargs > 0)
337n/a {
338n/a switch ((cif->arg_types)[0]->type)
339n/a {
340n/a case FFI_TYPE_FLOAT:
341n/a case FFI_TYPE_DOUBLE:
342n/a cif->flags += (cif->arg_types)[0]->type;
343n/a break;
344n/a
345n/a default:
346n/a break;
347n/a }
348n/a
349n/a if (cif->nargs > 1)
350n/a {
351n/a /* Only handle the second argument if the first
352n/a is a float or double. */
353n/a if (cif->flags)
354n/a {
355n/a switch ((cif->arg_types)[1]->type)
356n/a {
357n/a case FFI_TYPE_FLOAT:
358n/a case FFI_TYPE_DOUBLE:
359n/a cif->flags += (cif->arg_types)[1]->type << FFI_FLAG_BITS;
360n/a break;
361n/a
362n/a default:
363n/a break;
364n/a }
365n/a }
366n/a }
367n/a }
368n/a }
369n/a
370n/a /* Set the return type flag */
371n/a
372n/a if (cif->abi == FFI_O32_SOFT_FLOAT)
373n/a {
374n/a switch (cif->rtype->type)
375n/a {
376n/a case FFI_TYPE_VOID:
377n/a case FFI_TYPE_STRUCT:
378n/a cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
379n/a break;
380n/a
381n/a case FFI_TYPE_SINT64:
382n/a case FFI_TYPE_UINT64:
383n/a case FFI_TYPE_DOUBLE:
384n/a cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);
385n/a break;
386n/a
387n/a case FFI_TYPE_FLOAT:
388n/a default:
389n/a cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
390n/a break;
391n/a }
392n/a }
393n/a else
394n/a {
395n/a /* FFI_O32 */
396n/a switch (cif->rtype->type)
397n/a {
398n/a case FFI_TYPE_VOID:
399n/a case FFI_TYPE_STRUCT:
400n/a case FFI_TYPE_FLOAT:
401n/a case FFI_TYPE_DOUBLE:
402n/a cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
403n/a break;
404n/a
405n/a case FFI_TYPE_SINT64:
406n/a case FFI_TYPE_UINT64:
407n/a cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);
408n/a break;
409n/a
410n/a default:
411n/a cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
412n/a break;
413n/a }
414n/a }
415n/a#endif
416n/a
417n/a#ifdef FFI_MIPS_N32
418n/a /* Set the flags necessary for N32 processing */
419n/a {
420n/a int type;
421n/a unsigned arg_reg = 0;
422n/a unsigned loc = 0;
423n/a unsigned count = (cif->nargs < 8) ? cif->nargs : 8;
424n/a unsigned index = 0;
425n/a
426n/a unsigned struct_flags = 0;
427n/a int soft_float = (cif->abi == FFI_N32_SOFT_FLOAT
428n/a || cif->abi == FFI_N64_SOFT_FLOAT);
429n/a
430n/a if (cif->rtype->type == FFI_TYPE_STRUCT)
431n/a {
432n/a struct_flags = calc_n32_return_struct_flags(soft_float, cif->rtype);
433n/a
434n/a if (struct_flags == 0)
435n/a {
436n/a /* This means that the structure is being passed as
437n/a a hidden argument */
438n/a
439n/a arg_reg = 1;
440n/a count = (cif->nargs < 7) ? cif->nargs : 7;
441n/a
442n/a cif->rstruct_flag = !0;
443n/a }
444n/a else
445n/a cif->rstruct_flag = 0;
446n/a }
447n/a else
448n/a cif->rstruct_flag = 0;
449n/a
450n/a while (count-- > 0 && arg_reg < 8)
451n/a {
452n/a type = (cif->arg_types)[index]->type;
453n/a if (soft_float)
454n/a {
455n/a switch (type)
456n/a {
457n/a case FFI_TYPE_FLOAT:
458n/a type = FFI_TYPE_UINT32;
459n/a break;
460n/a case FFI_TYPE_DOUBLE:
461n/a type = FFI_TYPE_UINT64;
462n/a break;
463n/a default:
464n/a break;
465n/a }
466n/a }
467n/a switch (type)
468n/a {
469n/a case FFI_TYPE_FLOAT:
470n/a case FFI_TYPE_DOUBLE:
471n/a cif->flags +=
472n/a ((cif->arg_types)[index]->type << (arg_reg * FFI_FLAG_BITS));
473n/a arg_reg++;
474n/a break;
475n/a case FFI_TYPE_LONGDOUBLE:
476n/a /* Align it. */
477n/a arg_reg = ALIGN(arg_reg, 2);
478n/a /* Treat it as two adjacent doubles. */
479n/a if (soft_float)
480n/a {
481n/a arg_reg += 2;
482n/a }
483n/a else
484n/a {
485n/a cif->flags +=
486n/a (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
487n/a arg_reg++;
488n/a cif->flags +=
489n/a (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
490n/a arg_reg++;
491n/a }
492n/a break;
493n/a
494n/a case FFI_TYPE_STRUCT:
495n/a loc = arg_reg * FFI_SIZEOF_ARG;
496n/a cif->flags += calc_n32_struct_flags(soft_float,
497n/a (cif->arg_types)[index],
498n/a &loc, &arg_reg);
499n/a break;
500n/a
501n/a default:
502n/a arg_reg++;
503n/a break;
504n/a }
505n/a
506n/a index++;
507n/a }
508n/a
509n/a /* Set the return type flag */
510n/a switch (cif->rtype->type)
511n/a {
512n/a case FFI_TYPE_STRUCT:
513n/a {
514n/a if (struct_flags == 0)
515n/a {
516n/a /* The structure is returned through a hidden
517n/a first argument. Do nothing, 'cause FFI_TYPE_VOID
518n/a is 0 */
519n/a }
520n/a else
521n/a {
522n/a /* The structure is returned via some tricky
523n/a mechanism */
524n/a cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
525n/a cif->flags += struct_flags << (4 + (FFI_FLAG_BITS * 8));
526n/a }
527n/a break;
528n/a }
529n/a
530n/a case FFI_TYPE_VOID:
531n/a /* Do nothing, 'cause FFI_TYPE_VOID is 0 */
532n/a break;
533n/a
534n/a case FFI_TYPE_POINTER:
535n/a if (cif->abi == FFI_N32_SOFT_FLOAT || cif->abi == FFI_N32)
536n/a cif->flags += FFI_TYPE_SINT32 << (FFI_FLAG_BITS * 8);
537n/a else
538n/a cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
539n/a break;
540n/a
541n/a case FFI_TYPE_FLOAT:
542n/a if (soft_float)
543n/a {
544n/a cif->flags += FFI_TYPE_SINT32 << (FFI_FLAG_BITS * 8);
545n/a break;
546n/a }
547n/a /* else fall through */
548n/a case FFI_TYPE_DOUBLE:
549n/a if (soft_float)
550n/a cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
551n/a else
552n/a cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8);
553n/a break;
554n/a
555n/a case FFI_TYPE_LONGDOUBLE:
556n/a /* Long double is returned as if it were a struct containing
557n/a two doubles. */
558n/a if (soft_float)
559n/a {
560n/a cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
561n/a cif->flags += FFI_TYPE_SMALLSTRUCT2 << (4 + (FFI_FLAG_BITS * 8));
562n/a }
563n/a else
564n/a {
565n/a cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
566n/a cif->flags += (FFI_TYPE_DOUBLE
567n/a + (FFI_TYPE_DOUBLE << FFI_FLAG_BITS))
568n/a << (4 + (FFI_FLAG_BITS * 8));
569n/a }
570n/a break;
571n/a default:
572n/a cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
573n/a break;
574n/a }
575n/a }
576n/a#endif
577n/a
578n/a return FFI_OK;
579n/a}
580n/a
581n/a/* Low level routine for calling O32 functions */
582n/aextern int ffi_call_O32(void (*)(char *, extended_cif *, int, int),
583n/a extended_cif *, unsigned,
584n/a unsigned, unsigned *, void (*)(void));
585n/a
586n/a/* Low level routine for calling N32 functions */
587n/aextern int ffi_call_N32(void (*)(char *, extended_cif *, int, int),
588n/a extended_cif *, unsigned,
589n/a unsigned, void *, void (*)(void));
590n/a
591n/avoid ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
592n/a{
593n/a extended_cif ecif;
594n/a
595n/a ecif.cif = cif;
596n/a ecif.avalue = avalue;
597n/a
598n/a /* If the return value is a struct and we don't have a return */
599n/a /* value address then we need to make one */
600n/a
601n/a if ((rvalue == NULL) &&
602n/a (cif->rtype->type == FFI_TYPE_STRUCT))
603n/a ecif.rvalue = alloca(cif->rtype->size);
604n/a else
605n/a ecif.rvalue = rvalue;
606n/a
607n/a switch (cif->abi)
608n/a {
609n/a#ifdef FFI_MIPS_O32
610n/a case FFI_O32:
611n/a case FFI_O32_SOFT_FLOAT:
612n/a ffi_call_O32(ffi_prep_args, &ecif, cif->bytes,
613n/a cif->flags, ecif.rvalue, fn);
614n/a break;
615n/a#endif
616n/a
617n/a#ifdef FFI_MIPS_N32
618n/a case FFI_N32:
619n/a case FFI_N32_SOFT_FLOAT:
620n/a case FFI_N64:
621n/a case FFI_N64_SOFT_FLOAT:
622n/a {
623n/a int copy_rvalue = 0;
624n/a int copy_offset = 0;
625n/a char *rvalue_copy = ecif.rvalue;
626n/a if (cif->rtype->type == FFI_TYPE_STRUCT && cif->rtype->size < 16)
627n/a {
628n/a /* For structures smaller than 16 bytes we clobber memory
629n/a in 8 byte increments. Make a copy so we don't clobber
630n/a the callers memory outside of the struct bounds. */
631n/a rvalue_copy = alloca(16);
632n/a copy_rvalue = 1;
633n/a }
634n/a else if (cif->rtype->type == FFI_TYPE_FLOAT
635n/a && (cif->abi == FFI_N64_SOFT_FLOAT
636n/a || cif->abi == FFI_N32_SOFT_FLOAT))
637n/a {
638n/a rvalue_copy = alloca (8);
639n/a copy_rvalue = 1;
640n/a#if defined(__MIPSEB__) || defined(_MIPSEB)
641n/a copy_offset = 4;
642n/a#endif
643n/a }
644n/a ffi_call_N32(ffi_prep_args, &ecif, cif->bytes,
645n/a cif->flags, rvalue_copy, fn);
646n/a if (copy_rvalue)
647n/a memcpy(ecif.rvalue, rvalue_copy + copy_offset, cif->rtype->size);
648n/a }
649n/a break;
650n/a#endif
651n/a
652n/a default:
653n/a FFI_ASSERT(0);
654n/a break;
655n/a }
656n/a}
657n/a
658n/a#if FFI_CLOSURES
659n/a#if defined(FFI_MIPS_O32)
660n/aextern void ffi_closure_O32(void);
661n/a#else
662n/aextern void ffi_closure_N32(void);
663n/a#endif /* FFI_MIPS_O32 */
664n/a
665n/affi_status
666n/affi_prep_closure_loc (ffi_closure *closure,
667n/a ffi_cif *cif,
668n/a void (*fun)(ffi_cif*,void*,void**,void*),
669n/a void *user_data,
670n/a void *codeloc)
671n/a{
672n/a unsigned int *tramp = (unsigned int *) &closure->tramp[0];
673n/a void * fn;
674n/a char *clear_location = (char *) codeloc;
675n/a
676n/a#if defined(FFI_MIPS_O32)
677n/a if (cif->abi != FFI_O32 && cif->abi != FFI_O32_SOFT_FLOAT)
678n/a return FFI_BAD_ABI;
679n/a fn = ffi_closure_O32;
680n/a#else
681n/a#if _MIPS_SIM ==_ABIN32
682n/a if (cif->abi != FFI_N32
683n/a && cif->abi != FFI_N32_SOFT_FLOAT)
684n/a return FFI_BAD_ABI;
685n/a#else
686n/a if (cif->abi != FFI_N64
687n/a && cif->abi != FFI_N64_SOFT_FLOAT)
688n/a return FFI_BAD_ABI;
689n/a#endif
690n/a fn = ffi_closure_N32;
691n/a#endif /* FFI_MIPS_O32 */
692n/a
693n/a#if defined(FFI_MIPS_O32) || (_MIPS_SIM ==_ABIN32)
694n/a /* lui $25,high(fn) */
695n/a tramp[0] = 0x3c190000 | ((unsigned)fn >> 16);
696n/a /* ori $25,low(fn) */
697n/a tramp[1] = 0x37390000 | ((unsigned)fn & 0xffff);
698n/a /* lui $12,high(codeloc) */
699n/a tramp[2] = 0x3c0c0000 | ((unsigned)codeloc >> 16);
700n/a /* jr $25 */
701n/a tramp[3] = 0x03200008;
702n/a /* ori $12,low(codeloc) */
703n/a tramp[4] = 0x358c0000 | ((unsigned)codeloc & 0xffff);
704n/a#else
705n/a /* N64 has a somewhat larger trampoline. */
706n/a /* lui $25,high(fn) */
707n/a tramp[0] = 0x3c190000 | ((unsigned long)fn >> 48);
708n/a /* lui $12,high(codeloc) */
709n/a tramp[1] = 0x3c0c0000 | ((unsigned long)codeloc >> 48);
710n/a /* ori $25,mid-high(fn) */
711n/a tramp[2] = 0x37390000 | (((unsigned long)fn >> 32 ) & 0xffff);
712n/a /* ori $12,mid-high(codeloc) */
713n/a tramp[3] = 0x358c0000 | (((unsigned long)codeloc >> 32) & 0xffff);
714n/a /* dsll $25,$25,16 */
715n/a tramp[4] = 0x0019cc38;
716n/a /* dsll $12,$12,16 */
717n/a tramp[5] = 0x000c6438;
718n/a /* ori $25,mid-low(fn) */
719n/a tramp[6] = 0x37390000 | (((unsigned long)fn >> 16 ) & 0xffff);
720n/a /* ori $12,mid-low(codeloc) */
721n/a tramp[7] = 0x358c0000 | (((unsigned long)codeloc >> 16) & 0xffff);
722n/a /* dsll $25,$25,16 */
723n/a tramp[8] = 0x0019cc38;
724n/a /* dsll $12,$12,16 */
725n/a tramp[9] = 0x000c6438;
726n/a /* ori $25,low(fn) */
727n/a tramp[10] = 0x37390000 | ((unsigned long)fn & 0xffff);
728n/a /* jr $25 */
729n/a tramp[11] = 0x03200008;
730n/a /* ori $12,low(codeloc) */
731n/a tramp[12] = 0x358c0000 | ((unsigned long)codeloc & 0xffff);
732n/a
733n/a#endif
734n/a
735n/a closure->cif = cif;
736n/a closure->fun = fun;
737n/a closure->user_data = user_data;
738n/a
739n/a#ifdef USE__BUILTIN___CLEAR_CACHE
740n/a __builtin___clear_cache(clear_location, clear_location + FFI_TRAMPOLINE_SIZE);
741n/a#else
742n/a cacheflush (clear_location, FFI_TRAMPOLINE_SIZE, ICACHE);
743n/a#endif
744n/a return FFI_OK;
745n/a}
746n/a
747n/a/*
748n/a * Decodes the arguments to a function, which will be stored on the
749n/a * stack. AR is the pointer to the beginning of the integer arguments
750n/a * (and, depending upon the arguments, some floating-point arguments
751n/a * as well). FPR is a pointer to the area where floating point
752n/a * registers have been saved, if any.
753n/a *
754n/a * RVALUE is the location where the function return value will be
755n/a * stored. CLOSURE is the prepared closure to invoke.
756n/a *
757n/a * This function should only be called from assembly, which is in
758n/a * turn called from a trampoline.
759n/a *
760n/a * Returns the function return type.
761n/a *
762n/a * Based on the similar routine for sparc.
763n/a */
764n/aint
765n/affi_closure_mips_inner_O32 (ffi_closure *closure,
766n/a void *rvalue, ffi_arg *ar,
767n/a double *fpr)
768n/a{
769n/a ffi_cif *cif;
770n/a void **avaluep;
771n/a ffi_arg *avalue;
772n/a ffi_type **arg_types;
773n/a int i, avn, argn, seen_int;
774n/a
775n/a cif = closure->cif;
776n/a avalue = alloca (cif->nargs * sizeof (ffi_arg));
777n/a avaluep = alloca (cif->nargs * sizeof (ffi_arg));
778n/a
779n/a seen_int = (cif->abi == FFI_O32_SOFT_FLOAT);
780n/a argn = 0;
781n/a
782n/a if ((cif->flags >> (FFI_FLAG_BITS * 2)) == FFI_TYPE_STRUCT)
783n/a {
784n/a rvalue = (void *)(UINT32)ar[0];
785n/a argn = 1;
786n/a }
787n/a
788n/a i = 0;
789n/a avn = cif->nargs;
790n/a arg_types = cif->arg_types;
791n/a
792n/a while (i < avn)
793n/a {
794n/a if (i < 2 && !seen_int &&
795n/a (arg_types[i]->type == FFI_TYPE_FLOAT ||
796n/a arg_types[i]->type == FFI_TYPE_DOUBLE ||
797n/a arg_types[i]->type == FFI_TYPE_LONGDOUBLE))
798n/a {
799n/a#if defined(__MIPSEB__) || defined(_MIPSEB)
800n/a if (arg_types[i]->type == FFI_TYPE_FLOAT)
801n/a avaluep[i] = ((char *) &fpr[i]) + sizeof (float);
802n/a else
803n/a#endif
804n/a avaluep[i] = (char *) &fpr[i];
805n/a }
806n/a else
807n/a {
808n/a if (arg_types[i]->alignment == 8 && (argn & 0x1))
809n/a argn++;
810n/a switch (arg_types[i]->type)
811n/a {
812n/a case FFI_TYPE_SINT8:
813n/a avaluep[i] = &avalue[i];
814n/a *(SINT8 *) &avalue[i] = (SINT8) ar[argn];
815n/a break;
816n/a
817n/a case FFI_TYPE_UINT8:
818n/a avaluep[i] = &avalue[i];
819n/a *(UINT8 *) &avalue[i] = (UINT8) ar[argn];
820n/a break;
821n/a
822n/a case FFI_TYPE_SINT16:
823n/a avaluep[i] = &avalue[i];
824n/a *(SINT16 *) &avalue[i] = (SINT16) ar[argn];
825n/a break;
826n/a
827n/a case FFI_TYPE_UINT16:
828n/a avaluep[i] = &avalue[i];
829n/a *(UINT16 *) &avalue[i] = (UINT16) ar[argn];
830n/a break;
831n/a
832n/a default:
833n/a avaluep[i] = (char *) &ar[argn];
834n/a break;
835n/a }
836n/a seen_int = 1;
837n/a }
838n/a argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
839n/a i++;
840n/a }
841n/a
842n/a /* Invoke the closure. */
843n/a (closure->fun) (cif, rvalue, avaluep, closure->user_data);
844n/a
845n/a if (cif->abi == FFI_O32_SOFT_FLOAT)
846n/a {
847n/a switch (cif->rtype->type)
848n/a {
849n/a case FFI_TYPE_FLOAT:
850n/a return FFI_TYPE_INT;
851n/a case FFI_TYPE_DOUBLE:
852n/a return FFI_TYPE_UINT64;
853n/a default:
854n/a return cif->rtype->type;
855n/a }
856n/a }
857n/a else
858n/a {
859n/a return cif->rtype->type;
860n/a }
861n/a}
862n/a
863n/a#if defined(FFI_MIPS_N32)
864n/a
865n/astatic void
866n/acopy_struct_N32(char *target, unsigned offset, ffi_abi abi, ffi_type *type,
867n/a int argn, unsigned arg_offset, ffi_arg *ar,
868n/a ffi_arg *fpr, int soft_float)
869n/a{
870n/a ffi_type **elt_typep = type->elements;
871n/a while(*elt_typep)
872n/a {
873n/a ffi_type *elt_type = *elt_typep;
874n/a unsigned o;
875n/a char *tp;
876n/a char *argp;
877n/a char *fpp;
878n/a
879n/a o = ALIGN(offset, elt_type->alignment);
880n/a arg_offset += o - offset;
881n/a offset = o;
882n/a argn += arg_offset / sizeof(ffi_arg);
883n/a arg_offset = arg_offset % sizeof(ffi_arg);
884n/a
885n/a argp = (char *)(ar + argn);
886n/a fpp = (char *)(argn >= 8 ? ar + argn : fpr + argn);
887n/a
888n/a tp = target + offset;
889n/a
890n/a if (elt_type->type == FFI_TYPE_DOUBLE && !soft_float)
891n/a *(double *)tp = *(double *)fpp;
892n/a else
893n/a memcpy(tp, argp + arg_offset, elt_type->size);
894n/a
895n/a offset += elt_type->size;
896n/a arg_offset += elt_type->size;
897n/a elt_typep++;
898n/a argn += arg_offset / sizeof(ffi_arg);
899n/a arg_offset = arg_offset % sizeof(ffi_arg);
900n/a }
901n/a}
902n/a
903n/a/*
904n/a * Decodes the arguments to a function, which will be stored on the
905n/a * stack. AR is the pointer to the beginning of the integer
906n/a * arguments. FPR is a pointer to the area where floating point
907n/a * registers have been saved.
908n/a *
909n/a * RVALUE is the location where the function return value will be
910n/a * stored. CLOSURE is the prepared closure to invoke.
911n/a *
912n/a * This function should only be called from assembly, which is in
913n/a * turn called from a trampoline.
914n/a *
915n/a * Returns the function return flags.
916n/a *
917n/a */
918n/aint
919n/affi_closure_mips_inner_N32 (ffi_closure *closure,
920n/a void *rvalue, ffi_arg *ar,
921n/a ffi_arg *fpr)
922n/a{
923n/a ffi_cif *cif;
924n/a void **avaluep;
925n/a ffi_arg *avalue;
926n/a ffi_type **arg_types;
927n/a int i, avn, argn;
928n/a int soft_float;
929n/a ffi_arg *argp;
930n/a
931n/a cif = closure->cif;
932n/a soft_float = cif->abi == FFI_N64_SOFT_FLOAT
933n/a || cif->abi == FFI_N32_SOFT_FLOAT;
934n/a avalue = alloca (cif->nargs * sizeof (ffi_arg));
935n/a avaluep = alloca (cif->nargs * sizeof (ffi_arg));
936n/a
937n/a argn = 0;
938n/a
939n/a if (cif->rstruct_flag)
940n/a {
941n/a#if _MIPS_SIM==_ABIN32
942n/a rvalue = (void *)(UINT32)ar[0];
943n/a#else /* N64 */
944n/a rvalue = (void *)ar[0];
945n/a#endif
946n/a argn = 1;
947n/a }
948n/a
949n/a i = 0;
950n/a avn = cif->nargs;
951n/a arg_types = cif->arg_types;
952n/a
953n/a while (i < avn)
954n/a {
955n/a if (arg_types[i]->type == FFI_TYPE_FLOAT
956n/a || arg_types[i]->type == FFI_TYPE_DOUBLE
957n/a || arg_types[i]->type == FFI_TYPE_LONGDOUBLE)
958n/a {
959n/a argp = (argn >= 8 || soft_float) ? ar + argn : fpr + argn;
960n/a if ((arg_types[i]->type == FFI_TYPE_LONGDOUBLE) && ((unsigned)argp & (arg_types[i]->alignment-1)))
961n/a {
962n/a argp=(ffi_arg*)ALIGN(argp,arg_types[i]->alignment);
963n/a argn++;
964n/a }
965n/a#if defined(__MIPSEB__) || defined(_MIPSEB)
966n/a if (arg_types[i]->type == FFI_TYPE_FLOAT && argn < 8)
967n/a avaluep[i] = ((char *) argp) + sizeof (float);
968n/a else
969n/a#endif
970n/a avaluep[i] = (char *) argp;
971n/a }
972n/a else
973n/a {
974n/a unsigned type = arg_types[i]->type;
975n/a
976n/a if (arg_types[i]->alignment > sizeof(ffi_arg))
977n/a argn = ALIGN(argn, arg_types[i]->alignment / sizeof(ffi_arg));
978n/a
979n/a argp = ar + argn;
980n/a
981n/a /* The size of a pointer depends on the ABI */
982n/a if (type == FFI_TYPE_POINTER)
983n/a type = (cif->abi == FFI_N64 || cif->abi == FFI_N64_SOFT_FLOAT)
984n/a ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
985n/a
986n/a if (soft_float && type == FFI_TYPE_FLOAT)
987n/a type = FFI_TYPE_UINT32;
988n/a
989n/a switch (type)
990n/a {
991n/a case FFI_TYPE_SINT8:
992n/a avaluep[i] = &avalue[i];
993n/a *(SINT8 *) &avalue[i] = (SINT8) *argp;
994n/a break;
995n/a
996n/a case FFI_TYPE_UINT8:
997n/a avaluep[i] = &avalue[i];
998n/a *(UINT8 *) &avalue[i] = (UINT8) *argp;
999n/a break;
1000n/a
1001n/a case FFI_TYPE_SINT16:
1002n/a avaluep[i] = &avalue[i];
1003n/a *(SINT16 *) &avalue[i] = (SINT16) *argp;
1004n/a break;
1005n/a
1006n/a case FFI_TYPE_UINT16:
1007n/a avaluep[i] = &avalue[i];
1008n/a *(UINT16 *) &avalue[i] = (UINT16) *argp;
1009n/a break;
1010n/a
1011n/a case FFI_TYPE_SINT32:
1012n/a avaluep[i] = &avalue[i];
1013n/a *(SINT32 *) &avalue[i] = (SINT32) *argp;
1014n/a break;
1015n/a
1016n/a case FFI_TYPE_UINT32:
1017n/a avaluep[i] = &avalue[i];
1018n/a *(UINT32 *) &avalue[i] = (UINT32) *argp;
1019n/a break;
1020n/a
1021n/a case FFI_TYPE_STRUCT:
1022n/a if (argn < 8)
1023n/a {
1024n/a /* Allocate space for the struct as at least part of
1025n/a it was passed in registers. */
1026n/a avaluep[i] = alloca(arg_types[i]->size);
1027n/a copy_struct_N32(avaluep[i], 0, cif->abi, arg_types[i],
1028n/a argn, 0, ar, fpr, soft_float);
1029n/a
1030n/a break;
1031n/a }
1032n/a /* Else fall through. */
1033n/a default:
1034n/a avaluep[i] = (char *) argp;
1035n/a break;
1036n/a }
1037n/a }
1038n/a argn += ALIGN(arg_types[i]->size, sizeof(ffi_arg)) / sizeof(ffi_arg);
1039n/a i++;
1040n/a }
1041n/a
1042n/a /* Invoke the closure. */
1043n/a (closure->fun) (cif, rvalue, avaluep, closure->user_data);
1044n/a
1045n/a return cif->flags >> (FFI_FLAG_BITS * 8);
1046n/a}
1047n/a
1048n/a#endif /* FFI_MIPS_N32 */
1049n/a
1050n/a#endif /* FFI_CLOSURES */