summaryrefslogtreecommitdiffstats
path: root/Modules/_ctypes/libffi_osx
diff options
context:
space:
mode:
authorEzio Melotti <ezio.melotti@gmail.com>2011-03-15 03:18:48 (GMT)
committerEzio Melotti <ezio.melotti@gmail.com>2011-03-15 03:18:48 (GMT)
commit42da663e6fe7ecbb89b17d596c76812a91bb99a4 (patch)
treef660a093d1eb0841656b9b10173589f357ec0484 /Modules/_ctypes/libffi_osx
parentf6db0bbbeefa1bde9fd09c53e7c6bf0e57481590 (diff)
downloadcpython-42da663e6fe7ecbb89b17d596c76812a91bb99a4.zip
cpython-42da663e6fe7ecbb89b17d596c76812a91bb99a4.tar.gz
cpython-42da663e6fe7ecbb89b17d596c76812a91bb99a4.tar.bz2
#11515: fix several typos. Patch by Piotr Kasprzyk.
Diffstat (limited to 'Modules/_ctypes/libffi_osx')
-rw-r--r--Modules/_ctypes/libffi_osx/powerpc/ppc-ffi_darwin.c2782
1 files changed, 1391 insertions, 1391 deletions
diff --git a/Modules/_ctypes/libffi_osx/powerpc/ppc-ffi_darwin.c b/Modules/_ctypes/libffi_osx/powerpc/ppc-ffi_darwin.c
index 8953d5f..e00f153 100644
--- a/Modules/_ctypes/libffi_osx/powerpc/ppc-ffi_darwin.c
+++ b/Modules/_ctypes/libffi_osx/powerpc/ppc-ffi_darwin.c
@@ -39,7 +39,7 @@
#if 0
#if defined(POWERPC_DARWIN)
-#include <libkern/OSCacheControl.h> // for sys_icache_invalidate()
+#include <libkern/OSCacheControl.h> // for sys_icache_invalidate()
#endif
#else
@@ -55,8 +55,8 @@ extern void ffi_closure_ASM(void);
// The layout of a function descriptor. A C function pointer really
// points to one of these.
typedef struct aix_fd_struct {
- void* code_pointer;
- void* toc;
+ void* code_pointer;
+ void* toc;
} aix_fd;
/* ffi_prep_args is called by the assembly routine once stack space
@@ -64,241 +64,241 @@ typedef struct aix_fd_struct {
The stack layout we want looks like this:
- | Return address from ffi_call_DARWIN | higher addresses
+ | Return address from ffi_call_DARWIN | higher addresses
|--------------------------------------------|
- | Previous backchain pointer 4/8 | stack pointer here
+ | Previous backchain pointer 4/8 | stack pointer here
|--------------------------------------------|-\ <<< on entry to
- | Saved r28-r31 (4/8)*4 | | ffi_call_DARWIN
+ | Saved r28-r31 (4/8)*4 | | ffi_call_DARWIN
|--------------------------------------------| |
| Parameters (at least 8*(4/8)=32/64) | | (176) +112 - +288
|--------------------------------------------| |
| Space for GPR2 4/8 | |
- |--------------------------------------------| | stack |
- | Reserved (4/8)*2 | | grows |
- |--------------------------------------------| | down V
+ |--------------------------------------------| | stack |
+ | Reserved (4/8)*2 | | grows |
+ |--------------------------------------------| | down V
| Space for callee's LR 4/8 | |
- |--------------------------------------------| | lower addresses
+ |--------------------------------------------| | lower addresses
| Saved CR 4/8 | |
|--------------------------------------------| | stack pointer here
| Current backchain pointer 4/8 | | during
|--------------------------------------------|-/ <<< ffi_call_DARWIN
- Note: ppc64 CR is saved in the low word of a long on the stack.
+ Note: ppc64 CR is saved in the low word of a long on the stack.
*/
/*@-exportheader@*/
void
ffi_prep_args(
- extended_cif* inEcif,
- unsigned *const stack)
+ extended_cif* inEcif,
+ unsigned *const stack)
/*@=exportheader@*/
{
- /* Copy the ecif to a local var so we can trample the arg.
- BC note: test this with GP later for possible problems... */
- volatile extended_cif* ecif = inEcif;
+ /* Copy the ecif to a local var so we can trample the arg.
+ BC note: test this with GP later for possible problems... */
+ volatile extended_cif* ecif = inEcif;
- const unsigned bytes = ecif->cif->bytes;
- const unsigned flags = ecif->cif->flags;
+ const unsigned bytes = ecif->cif->bytes;
+ const unsigned flags = ecif->cif->flags;
- /* Cast the stack arg from int* to long*. sizeof(long) == 4 in 32-bit mode
- and 8 in 64-bit mode. */
- unsigned long *const longStack = (unsigned long *const)stack;
+ /* Cast the stack arg from int* to long*. sizeof(long) == 4 in 32-bit mode
+ and 8 in 64-bit mode. */
+ unsigned long *const longStack = (unsigned long *const)stack;
- /* 'stacktop' points at the previous backchain pointer. */
+ /* 'stacktop' points at the previous backchain pointer. */
#if defined(__ppc64__)
- // In ppc-darwin.s, an extra 96 bytes is reserved for the linkage area,
- // saved registers, and an extra FPR.
- unsigned long *const stacktop =
- (unsigned long *)(unsigned long)((char*)longStack + bytes + 96);
+ // In ppc-darwin.s, an extra 96 bytes is reserved for the linkage area,
+ // saved registers, and an extra FPR.
+ unsigned long *const stacktop =
+ (unsigned long *)(unsigned long)((char*)longStack + bytes + 96);
#elif defined(__ppc__)
- unsigned long *const stacktop = longStack + (bytes / sizeof(long));
+ unsigned long *const stacktop = longStack + (bytes / sizeof(long));
#else
#error undefined architecture
#endif
- /* 'fpr_base' points at the space for fpr1, and grows upwards as
- we use FPR registers. */
- double* fpr_base = (double*)(stacktop - ASM_NEEDS_REGISTERS) -
- NUM_FPR_ARG_REGISTERS;
+ /* 'fpr_base' points at the space for fpr1, and grows upwards as
+ we use FPR registers. */
+ double* fpr_base = (double*)(stacktop - ASM_NEEDS_REGISTERS) -
+ NUM_FPR_ARG_REGISTERS;
#if defined(__ppc64__)
- // 64-bit saves an extra register, and uses an extra FPR. Knock fpr_base
- // down a couple pegs.
- fpr_base -= 2;
+ // 64-bit saves an extra register, and uses an extra FPR. Knock fpr_base
+ // down a couple pegs.
+ fpr_base -= 2;
#endif
- unsigned int fparg_count = 0;
+ unsigned int fparg_count = 0;
- /* 'next_arg' grows up as we put parameters in it. */
- unsigned long* next_arg = longStack + 6; /* 6 reserved positions. */
+ /* 'next_arg' grows up as we put parameters in it. */
+ unsigned long* next_arg = longStack + 6; /* 6 reserved positions. */
- int i;
- double double_tmp;
- void** p_argv = ecif->avalue;
- unsigned long gprvalue;
- ffi_type** ptr = ecif->cif->arg_types;
+ int i;
+ double double_tmp;
+ void** p_argv = ecif->avalue;
+ unsigned long gprvalue;
+ ffi_type** ptr = ecif->cif->arg_types;
- /* Check that everything starts aligned properly. */
- FFI_ASSERT(stack == SF_ROUND(stack));
- FFI_ASSERT(stacktop == SF_ROUND(stacktop));
- FFI_ASSERT(bytes == SF_ROUND(bytes));
+ /* Check that everything starts aligned properly. */
+ FFI_ASSERT(stack == SF_ROUND(stack));
+ FFI_ASSERT(stacktop == SF_ROUND(stacktop));
+ FFI_ASSERT(bytes == SF_ROUND(bytes));
- /* Deal with return values that are actually pass-by-reference.
- Rule:
- Return values are referenced by r3, so r4 is the first parameter. */
+ /* Deal with return values that are actually pass-by-reference.
+ Rule:
+ Return values are referenced by r3, so r4 is the first parameter. */
- if (flags & FLAG_RETVAL_REFERENCE)
- *next_arg++ = (unsigned long)(char*)ecif->rvalue;
+ if (flags & FLAG_RETVAL_REFERENCE)
+ *next_arg++ = (unsigned long)(char*)ecif->rvalue;
- /* Now for the arguments. */
- for (i = ecif->cif->nargs; i > 0; i--, ptr++, p_argv++)
+ /* Now for the arguments. */
+ for (i = ecif->cif->nargs; i > 0; i--, ptr++, p_argv++)
{
- switch ((*ptr)->type)
- {
- /* If a floating-point parameter appears before all of the general-
- purpose registers are filled, the corresponding GPRs that match
- the size of the floating-point parameter are shadowed for the
- benefit of vararg and pre-ANSI functions. */
- case FFI_TYPE_FLOAT:
- double_tmp = *(float*)*p_argv;
+ switch ((*ptr)->type)
+ {
+ /* If a floating-point parameter appears before all of the general-
+ purpose registers are filled, the corresponding GPRs that match
+ the size of the floating-point parameter are shadowed for the
+ benefit of vararg and pre-ANSI functions. */
+ case FFI_TYPE_FLOAT:
+ double_tmp = *(float*)*p_argv;
- if (fparg_count < NUM_FPR_ARG_REGISTERS)
- *fpr_base++ = double_tmp;
+ if (fparg_count < NUM_FPR_ARG_REGISTERS)
+ *fpr_base++ = double_tmp;
- *(double*)next_arg = double_tmp;
+ *(double*)next_arg = double_tmp;
- next_arg++;
- fparg_count++;
- FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
+ next_arg++;
+ fparg_count++;
+ FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
- break;
+ break;
- case FFI_TYPE_DOUBLE:
- double_tmp = *(double*)*p_argv;
+ case FFI_TYPE_DOUBLE:
+ double_tmp = *(double*)*p_argv;
- if (fparg_count < NUM_FPR_ARG_REGISTERS)
- *fpr_base++ = double_tmp;
+ if (fparg_count < NUM_FPR_ARG_REGISTERS)
+ *fpr_base++ = double_tmp;
- *(double*)next_arg = double_tmp;
+ *(double*)next_arg = double_tmp;
- next_arg += MODE_CHOICE(2,1);
- fparg_count++;
- FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
+ next_arg += MODE_CHOICE(2,1);
+ fparg_count++;
+ FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
- break;
+ break;
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
- case FFI_TYPE_LONGDOUBLE:
+ case FFI_TYPE_LONGDOUBLE:
#if defined(__ppc64__)
- if (fparg_count < NUM_FPR_ARG_REGISTERS)
- *(long double*)fpr_base = *(long double*)*p_argv;
+ if (fparg_count < NUM_FPR_ARG_REGISTERS)
+ *(long double*)fpr_base = *(long double*)*p_argv;
#elif defined(__ppc__)
- if (fparg_count < NUM_FPR_ARG_REGISTERS - 1)
- *(long double*)fpr_base = *(long double*)*p_argv;
- else if (fparg_count == NUM_FPR_ARG_REGISTERS - 1)
- *(double*)fpr_base = *(double*)*p_argv;
+ if (fparg_count < NUM_FPR_ARG_REGISTERS - 1)
+ *(long double*)fpr_base = *(long double*)*p_argv;
+ else if (fparg_count == NUM_FPR_ARG_REGISTERS - 1)
+ *(double*)fpr_base = *(double*)*p_argv;
#else
#error undefined architecture
#endif
- *(long double*)next_arg = *(long double*)*p_argv;
- fparg_count += 2;
- fpr_base += 2;
- next_arg += MODE_CHOICE(4,2);
- FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
+ *(long double*)next_arg = *(long double*)*p_argv;
+ fparg_count += 2;
+ fpr_base += 2;
+ next_arg += MODE_CHOICE(4,2);
+ FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
- break;
-#endif // FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ break;
+#endif // FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
- case FFI_TYPE_UINT64:
- case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
#if defined(__ppc64__)
- gprvalue = *(long long*)*p_argv;
- goto putgpr;
+ gprvalue = *(long long*)*p_argv;
+ goto putgpr;
#elif defined(__ppc__)
- *(long long*)next_arg = *(long long*)*p_argv;
- next_arg += 2;
- break;
+ *(long long*)next_arg = *(long long*)*p_argv;
+ next_arg += 2;
+ break;
#else
#error undefined architecture
#endif
- case FFI_TYPE_POINTER:
- gprvalue = *(unsigned long*)*p_argv;
- goto putgpr;
+ case FFI_TYPE_POINTER:
+ gprvalue = *(unsigned long*)*p_argv;
+ goto putgpr;
- case FFI_TYPE_UINT8:
- gprvalue = *(unsigned char*)*p_argv;
- goto putgpr;
+ case FFI_TYPE_UINT8:
+ gprvalue = *(unsigned char*)*p_argv;
+ goto putgpr;
- case FFI_TYPE_SINT8:
- gprvalue = *(signed char*)*p_argv;
- goto putgpr;
+ case FFI_TYPE_SINT8:
+ gprvalue = *(signed char*)*p_argv;
+ goto putgpr;
- case FFI_TYPE_UINT16:
- gprvalue = *(unsigned short*)*p_argv;
- goto putgpr;
+ case FFI_TYPE_UINT16:
+ gprvalue = *(unsigned short*)*p_argv;
+ goto putgpr;
- case FFI_TYPE_SINT16:
- gprvalue = *(signed short*)*p_argv;
- goto putgpr;
+ case FFI_TYPE_SINT16:
+ gprvalue = *(signed short*)*p_argv;
+ goto putgpr;
- case FFI_TYPE_STRUCT:
- {
+ case FFI_TYPE_STRUCT:
+ {
#if defined(__ppc64__)
- unsigned int gprSize = 0;
- unsigned int fprSize = 0;
+ unsigned int gprSize = 0;
+ unsigned int fprSize = 0;
- ffi64_struct_to_reg_form(*ptr, (char*)*p_argv, NULL, &fparg_count,
- (char*)next_arg, &gprSize, (char*)fpr_base, &fprSize);
- next_arg += gprSize / sizeof(long);
- fpr_base += fprSize / sizeof(double);
+ ffi64_struct_to_reg_form(*ptr, (char*)*p_argv, NULL, &fparg_count,
+ (char*)next_arg, &gprSize, (char*)fpr_base, &fprSize);
+ next_arg += gprSize / sizeof(long);
+ fpr_base += fprSize / sizeof(double);
#elif defined(__ppc__)
- char* dest_cpy = (char*)next_arg;
-
- /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
- SI 4 bytes) are aligned as if they were those modes.
- Structures with 3 byte in size are padded upwards. */
- unsigned size_al = (*ptr)->size;
-
- /* If the first member of the struct is a double, then align
- the struct to double-word. */
- if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE)
- size_al = ALIGN((*ptr)->size, 8);
-
- if (ecif->cif->abi == FFI_DARWIN)
- {
- if (size_al < 3)
- dest_cpy += 4 - size_al;
- }
-
- memcpy((char*)dest_cpy, (char*)*p_argv, size_al);
- next_arg += (size_al + 3) / 4;
+ char* dest_cpy = (char*)next_arg;
+
+ /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
+ SI 4 bytes) are aligned as if they were those modes.
+ Structures with 3 byte in size are padded upwards. */
+ unsigned size_al = (*ptr)->size;
+
+ /* If the first member of the struct is a double, then align
+ the struct to double-word. */
+ if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE)
+ size_al = ALIGN((*ptr)->size, 8);
+
+ if (ecif->cif->abi == FFI_DARWIN)
+ {
+ if (size_al < 3)
+ dest_cpy += 4 - size_al;
+ }
+
+ memcpy((char*)dest_cpy, (char*)*p_argv, size_al);
+ next_arg += (size_al + 3) / 4;
#else
#error undefined architecture
#endif
- break;
- }
+ break;
+ }
- case FFI_TYPE_INT:
- case FFI_TYPE_UINT32:
- case FFI_TYPE_SINT32:
- gprvalue = *(unsigned*)*p_argv;
+ case FFI_TYPE_INT:
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_SINT32:
+ gprvalue = *(unsigned*)*p_argv;
putgpr:
- *next_arg++ = gprvalue;
- break;
+ *next_arg++ = gprvalue;
+ break;
- default:
- break;
- }
- }
+ default:
+ break;
+ }
+ }
/* Check that we didn't overrun the stack... */
//FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS);
//FFI_ASSERT((unsigned *)fpr_base
- // <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
+ // <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
//FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
}
@@ -306,320 +306,320 @@ putgpr:
bool
ffi64_struct_contains_fp(
- const ffi_type* inType)
+ const ffi_type* inType)
{
- bool containsFP = false;
- unsigned int i;
-
- for (i = 0; inType->elements[i] != NULL && !containsFP; i++)
- {
- if (inType->elements[i]->type == FFI_TYPE_FLOAT ||
- inType->elements[i]->type == FFI_TYPE_DOUBLE ||
- inType->elements[i]->type == FFI_TYPE_LONGDOUBLE)
- containsFP = true;
- else if (inType->elements[i]->type == FFI_TYPE_STRUCT)
- containsFP = ffi64_struct_contains_fp(inType->elements[i]);
- }
-
- return containsFP;
+ bool containsFP = false;
+ unsigned int i;
+
+ for (i = 0; inType->elements[i] != NULL && !containsFP; i++)
+ {
+ if (inType->elements[i]->type == FFI_TYPE_FLOAT ||
+ inType->elements[i]->type == FFI_TYPE_DOUBLE ||
+ inType->elements[i]->type == FFI_TYPE_LONGDOUBLE)
+ containsFP = true;
+ else if (inType->elements[i]->type == FFI_TYPE_STRUCT)
+ containsFP = ffi64_struct_contains_fp(inType->elements[i]);
+ }
+
+ return containsFP;
}
-#endif // defined(__ppc64__)
+#endif // defined(__ppc64__)
/* Perform machine dependent cif processing. */
ffi_status
ffi_prep_cif_machdep(
- ffi_cif* cif)
+ ffi_cif* cif)
{
- /* All this is for the DARWIN ABI. */
- int i;
- ffi_type** ptr;
- int intarg_count = 0;
- int fparg_count = 0;
- unsigned int flags = 0;
- unsigned int size_al = 0;
-
- /* All the machine-independent calculation of cif->bytes will be wrong.
- Redo the calculation for DARWIN. */
-
- /* Space for the frame pointer, callee's LR, CR, etc, and for
- the asm's temp regs. */
- unsigned int bytes = (6 + ASM_NEEDS_REGISTERS) * sizeof(long);
-
- /* Return value handling. The rules are as follows:
- - 32-bit (or less) integer values are returned in gpr3;
- - Structures of size <= 4 bytes also returned in gpr3;
- - 64-bit integer values and structures between 5 and 8 bytes are
- returned in gpr3 and gpr4;
- - Single/double FP values are returned in fpr1;
- - Long double FP (if not equivalent to double) values are returned in
- fpr1 and fpr2;
- - Larger structures values are allocated space and a pointer is passed
- as the first argument. */
- switch (cif->rtype->type)
- {
+ /* All this is for the DARWIN ABI. */
+ int i;
+ ffi_type** ptr;
+ int intarg_count = 0;
+ int fparg_count = 0;
+ unsigned int flags = 0;
+ unsigned int size_al = 0;
+
+ /* All the machine-independent calculation of cif->bytes will be wrong.
+ Redo the calculation for DARWIN. */
+
+ /* Space for the frame pointer, callee's LR, CR, etc, and for
+ the asm's temp regs. */
+ unsigned int bytes = (6 + ASM_NEEDS_REGISTERS) * sizeof(long);
+
+ /* Return value handling. The rules are as follows:
+ - 32-bit (or less) integer values are returned in gpr3;
+ - Structures of size <= 4 bytes also returned in gpr3;
+ - 64-bit integer values and structures between 5 and 8 bytes are
+ returned in gpr3 and gpr4;
+ - Single/double FP values are returned in fpr1;
+ - Long double FP (if not equivalent to double) values are returned in
+ fpr1 and fpr2;
+ - Larger structures values are allocated space and a pointer is passed
+ as the first argument. */
+ switch (cif->rtype->type)
+ {
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
- case FFI_TYPE_LONGDOUBLE:
- flags |= FLAG_RETURNS_128BITS;
- flags |= FLAG_RETURNS_FP;
- break;
-#endif // FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
-
- case FFI_TYPE_DOUBLE:
- flags |= FLAG_RETURNS_64BITS;
- /* Fall through. */
- case FFI_TYPE_FLOAT:
- flags |= FLAG_RETURNS_FP;
- break;
+ case FFI_TYPE_LONGDOUBLE:
+ flags |= FLAG_RETURNS_128BITS;
+ flags |= FLAG_RETURNS_FP;
+ break;
+#endif // FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+
+ case FFI_TYPE_DOUBLE:
+ flags |= FLAG_RETURNS_64BITS;
+ /* Fall through. */
+ case FFI_TYPE_FLOAT:
+ flags |= FLAG_RETURNS_FP;
+ break;
#if defined(__ppc64__)
- case FFI_TYPE_POINTER:
+ case FFI_TYPE_POINTER:
#endif
- case FFI_TYPE_UINT64:
- case FFI_TYPE_SINT64:
- flags |= FLAG_RETURNS_64BITS;
- break;
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+ flags |= FLAG_RETURNS_64BITS;
+ break;
- case FFI_TYPE_STRUCT:
- {
+ case FFI_TYPE_STRUCT:
+ {
#if defined(__ppc64__)
- if (ffi64_stret_needs_ptr(cif->rtype, NULL, NULL))
- {
- flags |= FLAG_RETVAL_REFERENCE;
- flags |= FLAG_RETURNS_NOTHING;
- intarg_count++;
- }
- else
- {
- flags |= FLAG_RETURNS_STRUCT;
+ if (ffi64_stret_needs_ptr(cif->rtype, NULL, NULL))
+ {
+ flags |= FLAG_RETVAL_REFERENCE;
+ flags |= FLAG_RETURNS_NOTHING;
+ intarg_count++;
+ }
+ else
+ {
+ flags |= FLAG_RETURNS_STRUCT;
- if (ffi64_struct_contains_fp(cif->rtype))
- flags |= FLAG_STRUCT_CONTAINS_FP;
- }
+ if (ffi64_struct_contains_fp(cif->rtype))
+ flags |= FLAG_STRUCT_CONTAINS_FP;
+ }
#elif defined(__ppc__)
- flags |= FLAG_RETVAL_REFERENCE;
- flags |= FLAG_RETURNS_NOTHING;
- intarg_count++;
+ flags |= FLAG_RETVAL_REFERENCE;
+ flags |= FLAG_RETURNS_NOTHING;
+ intarg_count++;
#else
#error undefined architecture
#endif
- break;
- }
-
- case FFI_TYPE_VOID:
- flags |= FLAG_RETURNS_NOTHING;
- break;
-
- default:
- /* Returns 32-bit integer, or similar. Nothing to do here. */
- break;
- }
-
- /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
- first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
- goes on the stack. Structures are passed as a pointer to a copy of
- the structure. Stuff on the stack needs to keep proper alignment. */
- for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
- {
- switch ((*ptr)->type)
- {
- case FFI_TYPE_FLOAT:
- case FFI_TYPE_DOUBLE:
- fparg_count++;
- /* If this FP arg is going on the stack, it must be
- 8-byte-aligned. */
- if (fparg_count > NUM_FPR_ARG_REGISTERS
- && intarg_count % 2 != 0)
- intarg_count++;
- break;
+ break;
+ }
+
+ case FFI_TYPE_VOID:
+ flags |= FLAG_RETURNS_NOTHING;
+ break;
+
+ default:
+ /* Returns 32-bit integer, or similar. Nothing to do here. */
+ break;
+ }
+
+ /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
+ first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
+ goes on the stack. Structures are passed as a pointer to a copy of
+ the structure. Stuff on the stack needs to keep proper alignment. */
+ for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+ {
+ switch ((*ptr)->type)
+ {
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ fparg_count++;
+ /* If this FP arg is going on the stack, it must be
+ 8-byte-aligned. */
+ if (fparg_count > NUM_FPR_ARG_REGISTERS
+ && intarg_count % 2 != 0)
+ intarg_count++;
+ break;
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
- case FFI_TYPE_LONGDOUBLE:
- fparg_count += 2;
- /* If this FP arg is going on the stack, it must be
- 8-byte-aligned. */
+ case FFI_TYPE_LONGDOUBLE:
+ fparg_count += 2;
+ /* If this FP arg is going on the stack, it must be
+ 8-byte-aligned. */
- if (
+ if (
#if defined(__ppc64__)
- fparg_count > NUM_FPR_ARG_REGISTERS + 1
+ fparg_count > NUM_FPR_ARG_REGISTERS + 1
#elif defined(__ppc__)
- fparg_count > NUM_FPR_ARG_REGISTERS
+ fparg_count > NUM_FPR_ARG_REGISTERS
#else
#error undefined architecture
#endif
- && intarg_count % 2 != 0)
- intarg_count++;
-
- intarg_count += 2;
- break;
-#endif // FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
-
- case FFI_TYPE_UINT64:
- case FFI_TYPE_SINT64:
- /* 'long long' arguments are passed as two words, but
- either both words must fit in registers or both go
- on the stack. If they go on the stack, they must
- be 8-byte-aligned. */
- if (intarg_count == NUM_GPR_ARG_REGISTERS - 1
- || (intarg_count >= NUM_GPR_ARG_REGISTERS
- && intarg_count % 2 != 0))
- intarg_count++;
-
- intarg_count += MODE_CHOICE(2,1);
-
- break;
-
- case FFI_TYPE_STRUCT:
- size_al = (*ptr)->size;
- /* If the first member of the struct is a double, then align
- the struct to double-word. */
- if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE)
- size_al = ALIGN((*ptr)->size, 8);
+ && intarg_count % 2 != 0)
+ intarg_count++;
+
+ intarg_count += 2;
+ break;
+#endif // FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+ /* 'long long' arguments are passed as two words, but
+ either both words must fit in registers or both go
+ on the stack. If they go on the stack, they must
+ be 8-byte-aligned. */
+ if (intarg_count == NUM_GPR_ARG_REGISTERS - 1
+ || (intarg_count >= NUM_GPR_ARG_REGISTERS
+ && intarg_count % 2 != 0))
+ intarg_count++;
+
+ intarg_count += MODE_CHOICE(2,1);
+
+ break;
+
+ case FFI_TYPE_STRUCT:
+ size_al = (*ptr)->size;
+ /* If the first member of the struct is a double, then align
+ the struct to double-word. */
+ if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE)
+ size_al = ALIGN((*ptr)->size, 8);
#if defined(__ppc64__)
- // Look for FP struct members.
- unsigned int j;
-
- for (j = 0; (*ptr)->elements[j] != NULL; j++)
- {
- if ((*ptr)->elements[j]->type == FFI_TYPE_FLOAT ||
- (*ptr)->elements[j]->type == FFI_TYPE_DOUBLE)
- {
- fparg_count++;
-
- if (fparg_count > NUM_FPR_ARG_REGISTERS)
- intarg_count++;
- }
- else if ((*ptr)->elements[j]->type == FFI_TYPE_LONGDOUBLE)
- {
- fparg_count += 2;
-
- if (fparg_count > NUM_FPR_ARG_REGISTERS + 1)
- intarg_count += 2;
- }
- else
- intarg_count++;
- }
+ // Look for FP struct members.
+ unsigned int j;
+
+ for (j = 0; (*ptr)->elements[j] != NULL; j++)
+ {
+ if ((*ptr)->elements[j]->type == FFI_TYPE_FLOAT ||
+ (*ptr)->elements[j]->type == FFI_TYPE_DOUBLE)
+ {
+ fparg_count++;
+
+ if (fparg_count > NUM_FPR_ARG_REGISTERS)
+ intarg_count++;
+ }
+ else if ((*ptr)->elements[j]->type == FFI_TYPE_LONGDOUBLE)
+ {
+ fparg_count += 2;
+
+ if (fparg_count > NUM_FPR_ARG_REGISTERS + 1)
+ intarg_count += 2;
+ }
+ else
+ intarg_count++;
+ }
#elif defined(__ppc__)
- intarg_count += (size_al + 3) / 4;
+ intarg_count += (size_al + 3) / 4;
#else
#error undefined architecture
#endif
- break;
+ break;
- default:
- /* Everything else is passed as a 4/8-byte word in a GPR, either
- the object itself or a pointer to it. */
- intarg_count++;
- break;
- }
- }
+ default:
+ /* Everything else is passed as a 4/8-byte word in a GPR, either
+ the object itself or a pointer to it. */
+ intarg_count++;
+ break;
+ }
+ }
- /* Space for the FPR registers, if needed. */
- if (fparg_count != 0)
- {
- flags |= FLAG_FP_ARGUMENTS;
+ /* Space for the FPR registers, if needed. */
+ if (fparg_count != 0)
+ {
+ flags |= FLAG_FP_ARGUMENTS;
#if defined(__ppc64__)
- bytes += (NUM_FPR_ARG_REGISTERS + 1) * sizeof(double);
+ bytes += (NUM_FPR_ARG_REGISTERS + 1) * sizeof(double);
#elif defined(__ppc__)
- bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
+ bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
#else
#error undefined architecture
#endif
- }
+ }
- /* Stack space. */
+ /* Stack space. */
#if defined(__ppc64__)
- if ((intarg_count + fparg_count) > NUM_GPR_ARG_REGISTERS)
- bytes += (intarg_count + fparg_count) * sizeof(long);
+ if ((intarg_count + fparg_count) > NUM_GPR_ARG_REGISTERS)
+ bytes += (intarg_count + fparg_count) * sizeof(long);
#elif defined(__ppc__)
- if ((intarg_count + 2 * fparg_count) > NUM_GPR_ARG_REGISTERS)
- bytes += (intarg_count + 2 * fparg_count) * sizeof(long);
+ if ((intarg_count + 2 * fparg_count) > NUM_GPR_ARG_REGISTERS)
+ bytes += (intarg_count + 2 * fparg_count) * sizeof(long);
#else
#error undefined architecture
#endif
- else
- bytes += NUM_GPR_ARG_REGISTERS * sizeof(long);
+ else
+ bytes += NUM_GPR_ARG_REGISTERS * sizeof(long);
- /* The stack space allocated needs to be a multiple of 16/32 bytes. */
- bytes = SF_ROUND(bytes);
+ /* The stack space allocated needs to be a multiple of 16/32 bytes. */
+ bytes = SF_ROUND(bytes);
- cif->flags = flags;
- cif->bytes = bytes;
+ cif->flags = flags;
+ cif->bytes = bytes;
- return FFI_OK;
+ return FFI_OK;
}
/*@-declundef@*/
/*@-exportheader@*/
extern void
ffi_call_AIX(
-/*@out@*/ extended_cif*,
- unsigned,
- unsigned,
-/*@out@*/ unsigned*,
- void (*fn)(void),
- void (*fn2)(extended_cif*, unsigned *const));
+/*@out@*/ extended_cif*,
+ unsigned,
+ unsigned,
+/*@out@*/ unsigned*,
+ void (*fn)(void),
+ void (*fn2)(extended_cif*, unsigned *const));
extern void
ffi_call_DARWIN(
-/*@out@*/ extended_cif*,
- unsigned long,
- unsigned,
-/*@out@*/ unsigned*,
- void (*fn)(void),
- void (*fn2)(extended_cif*, unsigned *const));
+/*@out@*/ extended_cif*,
+ unsigned long,
+ unsigned,
+/*@out@*/ unsigned*,
+ void (*fn)(void),
+ void (*fn2)(extended_cif*, unsigned *const));
/*@=declundef@*/
/*@=exportheader@*/
void
ffi_call(
-/*@dependent@*/ ffi_cif* cif,
- void (*fn)(void),
-/*@out@*/ void* rvalue,
-/*@dependent@*/ void** avalue)
+/*@dependent@*/ ffi_cif* cif,
+ void (*fn)(void),
+/*@out@*/ void* rvalue,
+/*@dependent@*/ void** avalue)
{
- extended_cif ecif;
-
- ecif.cif = cif;
- ecif.avalue = avalue;
-
- /* If the return value is a struct and we don't have a return
- value address then we need to make one. */
- if ((rvalue == NULL) &&
- (cif->rtype->type == FFI_TYPE_STRUCT))
- {
- /*@-sysunrecog@*/
- ecif.rvalue = alloca(cif->rtype->size);
- /*@=sysunrecog@*/
- }
- else
- ecif.rvalue = rvalue;
-
- switch (cif->abi)
- {
- case FFI_AIX:
- /*@-usedef@*/
- ffi_call_AIX(&ecif, -cif->bytes,
- cif->flags, ecif.rvalue, fn, ffi_prep_args);
- /*@=usedef@*/
- break;
-
- case FFI_DARWIN:
- /*@-usedef@*/
- ffi_call_DARWIN(&ecif, -(long)cif->bytes,
- cif->flags, ecif.rvalue, fn, ffi_prep_args);
- /*@=usedef@*/
- break;
-
- default:
- FFI_ASSERT(0);
- break;
+ extended_cif ecif;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /* If the return value is a struct and we don't have a return
+ value address then we need to make one. */
+ if ((rvalue == NULL) &&
+ (cif->rtype->type == FFI_TYPE_STRUCT))
+ {
+ /*@-sysunrecog@*/
+ ecif.rvalue = alloca(cif->rtype->size);
+ /*@=sysunrecog@*/
+ }
+ else
+ ecif.rvalue = rvalue;
+
+ switch (cif->abi)
+ {
+ case FFI_AIX:
+ /*@-usedef@*/
+ ffi_call_AIX(&ecif, -cif->bytes,
+ cif->flags, ecif.rvalue, fn, ffi_prep_args);
+ /*@=usedef@*/
+ break;
+
+ case FFI_DARWIN:
+ /*@-usedef@*/
+ ffi_call_DARWIN(&ecif, -(long)cif->bytes,
+ cif->flags, ecif.rvalue, fn, ffi_prep_args);
+ /*@=usedef@*/
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ break;
}
}
@@ -627,53 +627,53 @@ ffi_call(
and aix_clsoure.S
SP previous -> +---------------------------------------+ <--- child frame
- | back chain to caller 4 |
- +---------------------------------------+ 4
- | saved CR 4 |
- +---------------------------------------+ 8
- | saved LR 4 |
- +---------------------------------------+ 12
- | reserved for compilers 4 |
- +---------------------------------------+ 16
- | reserved for binders 4 |
- +---------------------------------------+ 20
- | saved TOC pointer 4 |
- +---------------------------------------+ 24
- | always reserved 8*4=32 (previous GPRs)|
- | according to the linkage convention |
- | from AIX |
- +---------------------------------------+ 56
- | our FPR area 13*8=104 |
- | f1 |
- | . |
- | f13 |
- +---------------------------------------+ 160
- | result area 8 |
- +---------------------------------------+ 168
- | alignement to the next multiple of 16 |
+ | back chain to caller 4 |
+ +---------------------------------------+ 4
+ | saved CR 4 |
+ +---------------------------------------+ 8
+ | saved LR 4 |
+ +---------------------------------------+ 12
+ | reserved for compilers 4 |
+ +---------------------------------------+ 16
+ | reserved for binders 4 |
+ +---------------------------------------+ 20
+ | saved TOC pointer 4 |
+ +---------------------------------------+ 24
+ | always reserved 8*4=32 (previous GPRs)|
+ | according to the linkage convention |
+ | from AIX |
+ +---------------------------------------+ 56
+ | our FPR area 13*8=104 |
+ | f1 |
+ | . |
+ | f13 |
+ +---------------------------------------+ 160
+ | result area 8 |
+ +---------------------------------------+ 168
+ | alignment to the next multiple of 16 |
SP current --> +---------------------------------------+ 176 <- parent frame
- | back chain to caller 4 |
- +---------------------------------------+ 180
- | saved CR 4 |
- +---------------------------------------+ 184
- | saved LR 4 |
- +---------------------------------------+ 188
- | reserved for compilers 4 |
- +---------------------------------------+ 192
- | reserved for binders 4 |
- +---------------------------------------+ 196
- | saved TOC pointer 4 |
- +---------------------------------------+ 200
- | always reserved 8*4=32 we store our |
- | GPRs here |
- | r3 |
- | . |
- | r10 |
- +---------------------------------------+ 232
- | overflow part |
- +---------------------------------------+ xxx
- | ???? |
- +---------------------------------------+ xxx
+ | back chain to caller 4 |
+ +---------------------------------------+ 180
+ | saved CR 4 |
+ +---------------------------------------+ 184
+ | saved LR 4 |
+ +---------------------------------------+ 188
+ | reserved for compilers 4 |
+ +---------------------------------------+ 192
+ | reserved for binders 4 |
+ +---------------------------------------+ 196
+ | saved TOC pointer 4 |
+ +---------------------------------------+ 200
+ | always reserved 8*4=32 we store our |
+ | GPRs here |
+ | r3 |
+ | . |
+ | r10 |
+ +---------------------------------------+ 232
+ | overflow part |
+ +---------------------------------------+ xxx
+ | ???? |
+ +---------------------------------------+ xxx
*/
#if !defined(POWERPC_DARWIN)
@@ -682,1095 +682,1095 @@ SP current --> +---------------------------------------+ 176 <- parent frame
static void
flush_icache(
- char* addr)
+ char* addr)
{
#ifndef _AIX
- __asm__ volatile (
- "dcbf 0,%0\n"
- "sync\n"
- "icbi 0,%0\n"
- "sync\n"
- "isync"
- : : "r" (addr) : "memory");
+ __asm__ volatile (
+ "dcbf 0,%0\n"
+ "sync\n"
+ "icbi 0,%0\n"
+ "sync\n"
+ "isync"
+ : : "r" (addr) : "memory");
#endif
}
static void
flush_range(
- char* addr,
- int size)
+ char* addr,
+ int size)
{
- int i;
+ int i;
- for (i = 0; i < size; i += MIN_LINE_SIZE)
- flush_icache(addr + i);
+ for (i = 0; i < size; i += MIN_LINE_SIZE)
+ flush_icache(addr + i);
- flush_icache(addr + size - 1);
+ flush_icache(addr + size - 1);
}
-#endif // !defined(POWERPC_DARWIN)
+#endif // !defined(POWERPC_DARWIN)
ffi_status
ffi_prep_closure(
- ffi_closure* closure,
- ffi_cif* cif,
- void (*fun)(ffi_cif*, void*, void**, void*),
- void* user_data)
+ ffi_closure* closure,
+ ffi_cif* cif,
+ void (*fun)(ffi_cif*, void*, void**, void*),
+ void* user_data)
{
- switch (cif->abi)
- {
- case FFI_DARWIN:
- {
- FFI_ASSERT (cif->abi == FFI_DARWIN);
+ switch (cif->abi)
+ {
+ case FFI_DARWIN:
+ {
+ FFI_ASSERT (cif->abi == FFI_DARWIN);
- unsigned int* tramp = (unsigned int*)&closure->tramp[0];
+ unsigned int* tramp = (unsigned int*)&closure->tramp[0];
#if defined(__ppc64__)
- tramp[0] = 0x7c0802a6; // mflr r0
- tramp[1] = 0x429f0005; // bcl 20,31,+0x8
- tramp[2] = 0x7d6802a6; // mflr r11
- tramp[3] = 0x7c0803a6; // mtlr r0
- tramp[4] = 0xe98b0018; // ld r12,24(r11)
- tramp[5] = 0x7d8903a6; // mtctr r12
- tramp[6] = 0xe96b0020; // ld r11,32(r11)
- tramp[7] = 0x4e800420; // bctr
- *(unsigned long*)&tramp[8] = (unsigned long)ffi_closure_ASM;
- *(unsigned long*)&tramp[10] = (unsigned long)closure;
+ tramp[0] = 0x7c0802a6; // mflr r0
+ tramp[1] = 0x429f0005; // bcl 20,31,+0x8
+ tramp[2] = 0x7d6802a6; // mflr r11
+ tramp[3] = 0x7c0803a6; // mtlr r0
+ tramp[4] = 0xe98b0018; // ld r12,24(r11)
+ tramp[5] = 0x7d8903a6; // mtctr r12
+ tramp[6] = 0xe96b0020; // ld r11,32(r11)
+ tramp[7] = 0x4e800420; // bctr
+ *(unsigned long*)&tramp[8] = (unsigned long)ffi_closure_ASM;
+ *(unsigned long*)&tramp[10] = (unsigned long)closure;
#elif defined(__ppc__)
- tramp[0] = 0x7c0802a6; // mflr r0
- tramp[1] = 0x429f0005; // bcl 20,31,+0x8
- tramp[2] = 0x7d6802a6; // mflr r11
- tramp[3] = 0x7c0803a6; // mtlr r0
- tramp[4] = 0x818b0018; // lwz r12,24(r11)
- tramp[5] = 0x7d8903a6; // mtctr r12
- tramp[6] = 0x816b001c; // lwz r11,28(r11)
- tramp[7] = 0x4e800420; // bctr
- tramp[8] = (unsigned long)ffi_closure_ASM;
- tramp[9] = (unsigned long)closure;
+ tramp[0] = 0x7c0802a6; // mflr r0
+ tramp[1] = 0x429f0005; // bcl 20,31,+0x8
+ tramp[2] = 0x7d6802a6; // mflr r11
+ tramp[3] = 0x7c0803a6; // mtlr r0
+ tramp[4] = 0x818b0018; // lwz r12,24(r11)
+ tramp[5] = 0x7d8903a6; // mtctr r12
+ tramp[6] = 0x816b001c; // lwz r11,28(r11)
+ tramp[7] = 0x4e800420; // bctr
+ tramp[8] = (unsigned long)ffi_closure_ASM;
+ tramp[9] = (unsigned long)closure;
#else
#error undefined architecture
#endif
- closure->cif = cif;
- closure->fun = fun;
- closure->user_data = user_data;
+ closure->cif = cif;
+ closure->fun = fun;
+ closure->user_data = user_data;
- // Flush the icache. Only necessary on Darwin.
+ // Flush the icache. Only necessary on Darwin.
#if defined(POWERPC_DARWIN)
- sys_icache_invalidate(closure->tramp, FFI_TRAMPOLINE_SIZE);
+ sys_icache_invalidate(closure->tramp, FFI_TRAMPOLINE_SIZE);
#else
- flush_range(closure->tramp, FFI_TRAMPOLINE_SIZE);
+ flush_range(closure->tramp, FFI_TRAMPOLINE_SIZE);
#endif
- break;
- }
+ break;
+ }
- case FFI_AIX:
- {
- FFI_ASSERT (cif->abi == FFI_AIX);
+ case FFI_AIX:
+ {
+ FFI_ASSERT (cif->abi == FFI_AIX);
- ffi_aix_trampoline_struct* tramp_aix =
- (ffi_aix_trampoline_struct*)(closure->tramp);
- aix_fd* fd = (aix_fd*)(void*)ffi_closure_ASM;
+ ffi_aix_trampoline_struct* tramp_aix =
+ (ffi_aix_trampoline_struct*)(closure->tramp);
+ aix_fd* fd = (aix_fd*)(void*)ffi_closure_ASM;
- tramp_aix->code_pointer = fd->code_pointer;
- tramp_aix->toc = fd->toc;
- tramp_aix->static_chain = closure;
- closure->cif = cif;
- closure->fun = fun;
- closure->user_data = user_data;
- break;
- }
+ tramp_aix->code_pointer = fd->code_pointer;
+ tramp_aix->toc = fd->toc;
+ tramp_aix->static_chain = closure;
+ closure->cif = cif;
+ closure->fun = fun;
+ closure->user_data = user_data;
+ break;
+ }
- default:
- return FFI_BAD_ABI;
- }
+ default:
+ return FFI_BAD_ABI;
+ }
- return FFI_OK;
+ return FFI_OK;
}
#if defined(__ppc__)
- typedef double ldbits[2];
+ typedef double ldbits[2];
- typedef union
- {
- ldbits lb;
- long double ld;
- } ldu;
+ typedef union
+ {
+ ldbits lb;
+ long double ld;
+ } ldu;
#endif
typedef union
{
- float f;
- double d;
+ float f;
+ double d;
} ffi_dblfl;
-/* The trampoline invokes ffi_closure_ASM, and on entry, r11 holds the
- address of the closure. After storing the registers that could possibly
- contain parameters to be passed into the stack frame and setting up space
- for a return value, ffi_closure_ASM invokes the following helper function
- to do most of the work. */
+/* The trampoline invokes ffi_closure_ASM, and on entry, r11 holds the
+ address of the closure. After storing the registers that could possibly
+ contain parameters to be passed into the stack frame and setting up space
+ for a return value, ffi_closure_ASM invokes the following helper function
+ to do most of the work. */
int
ffi_closure_helper_DARWIN(
- ffi_closure* closure,
- void* rvalue,
- unsigned long* pgr,
- ffi_dblfl* pfr)
+ ffi_closure* closure,
+ void* rvalue,
+ unsigned long* pgr,
+ ffi_dblfl* pfr)
{
- /* rvalue is the pointer to space for return value in closure assembly
- pgr is the pointer to where r3-r10 are stored in ffi_closure_ASM
- pfr is the pointer to where f1-f13 are stored in ffi_closure_ASM. */
+ /* rvalue is the pointer to space for return value in closure assembly
+ pgr is the pointer to where r3-r10 are stored in ffi_closure_ASM
+ pfr is the pointer to where f1-f13 are stored in ffi_closure_ASM. */
#if defined(__ppc__)
- ldu temp_ld;
+ ldu temp_ld;
#endif
- double temp;
- unsigned int i;
- unsigned int nf = 0; /* number of FPRs already used. */
- unsigned int ng = 0; /* number of GPRs already used. */
- ffi_cif* cif = closure->cif;
- long avn = cif->nargs;
- void** avalue = alloca(cif->nargs * sizeof(void*));
- ffi_type** arg_types = cif->arg_types;
-
- /* Copy the caller's structure return value address so that the closure
- returns the data directly to the caller. */
+ double temp;
+ unsigned int i;
+ unsigned int nf = 0; /* number of FPRs already used. */
+ unsigned int ng = 0; /* number of GPRs already used. */
+ ffi_cif* cif = closure->cif;
+ long avn = cif->nargs;
+ void** avalue = alloca(cif->nargs * sizeof(void*));
+ ffi_type** arg_types = cif->arg_types;
+
+ /* Copy the caller's structure return value address so that the closure
+ returns the data directly to the caller. */
#if defined(__ppc64__)
- if (cif->rtype->type == FFI_TYPE_STRUCT &&
- ffi64_stret_needs_ptr(cif->rtype, NULL, NULL))
+ if (cif->rtype->type == FFI_TYPE_STRUCT &&
+ ffi64_stret_needs_ptr(cif->rtype, NULL, NULL))
#elif defined(__ppc__)
- if (cif->rtype->type == FFI_TYPE_STRUCT)
+ if (cif->rtype->type == FFI_TYPE_STRUCT)
#else
#error undefined architecture
#endif
- {
- rvalue = (void*)*pgr;
- pgr++;
- ng++;
- }
-
- /* Grab the addresses of the arguments from the stack frame. */
- for (i = 0; i < avn; i++)
- {
- switch (arg_types[i]->type)
- {
- case FFI_TYPE_SINT8:
- case FFI_TYPE_UINT8:
- avalue[i] = (char*)pgr + MODE_CHOICE(3,7);
- ng++;
- pgr++;
- break;
-
- case FFI_TYPE_SINT16:
- case FFI_TYPE_UINT16:
- avalue[i] = (char*)pgr + MODE_CHOICE(2,6);
- ng++;
- pgr++;
- break;
+ {
+ rvalue = (void*)*pgr;
+ pgr++;
+ ng++;
+ }
+
+ /* Grab the addresses of the arguments from the stack frame. */
+ for (i = 0; i < avn; i++)
+ {
+ switch (arg_types[i]->type)
+ {
+ case FFI_TYPE_SINT8:
+ case FFI_TYPE_UINT8:
+ avalue[i] = (char*)pgr + MODE_CHOICE(3,7);
+ ng++;
+ pgr++;
+ break;
+
+ case FFI_TYPE_SINT16:
+ case FFI_TYPE_UINT16:
+ avalue[i] = (char*)pgr + MODE_CHOICE(2,6);
+ ng++;
+ pgr++;
+ break;
#if defined(__ppc__)
- case FFI_TYPE_POINTER:
+ case FFI_TYPE_POINTER:
#endif
- case FFI_TYPE_SINT32:
- case FFI_TYPE_UINT32:
- avalue[i] = (char*)pgr + MODE_CHOICE(0,4);
- ng++;
- pgr++;
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_UINT32:
+ avalue[i] = (char*)pgr + MODE_CHOICE(0,4);
+ ng++;
+ pgr++;
- break;
+ break;
- case FFI_TYPE_STRUCT:
- if (cif->abi == FFI_DARWIN)
- {
+ case FFI_TYPE_STRUCT:
+ if (cif->abi == FFI_DARWIN)
+ {
#if defined(__ppc64__)
- unsigned int gprSize = 0;
- unsigned int fprSize = 0;
- unsigned int savedFPRSize = fprSize;
+ unsigned int gprSize = 0;
+ unsigned int fprSize = 0;
+ unsigned int savedFPRSize = fprSize;
- avalue[i] = alloca(arg_types[i]->size);
- ffi64_struct_to_ram_form(arg_types[i], (const char*)pgr,
- &gprSize, (const char*)pfr, &fprSize, &nf, avalue[i], NULL);
+ avalue[i] = alloca(arg_types[i]->size);
+ ffi64_struct_to_ram_form(arg_types[i], (const char*)pgr,
+ &gprSize, (const char*)pfr, &fprSize, &nf, avalue[i], NULL);
- ng += gprSize / sizeof(long);
- pgr += gprSize / sizeof(long);
- pfr += (fprSize - savedFPRSize) / sizeof(double);
+ ng += gprSize / sizeof(long);
+ pgr += gprSize / sizeof(long);
+ pfr += (fprSize - savedFPRSize) / sizeof(double);
#elif defined(__ppc__)
- /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
- SI 4 bytes) are aligned as if they were those modes. */
- unsigned int size_al = size_al = arg_types[i]->size;
-
- /* If the first member of the struct is a double, then align
- the struct to double-word. */
- if (arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE)
- size_al = ALIGN(arg_types[i]->size, 8);
-
- if (size_al < 3)
- avalue[i] = (void*)pgr + MODE_CHOICE(4,8) - size_al;
- else
- avalue[i] = (void*)pgr;
-
- ng += (size_al + 3) / sizeof(long);
- pgr += (size_al + 3) / sizeof(long);
+ /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
+ SI 4 bytes) are aligned as if they were those modes. */
+ unsigned int size_al = size_al = arg_types[i]->size;
+
+ /* If the first member of the struct is a double, then align
+ the struct to double-word. */
+ if (arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE)
+ size_al = ALIGN(arg_types[i]->size, 8);
+
+ if (size_al < 3)
+ avalue[i] = (void*)pgr + MODE_CHOICE(4,8) - size_al;
+ else
+ avalue[i] = (void*)pgr;
+
+ ng += (size_al + 3) / sizeof(long);
+ pgr += (size_al + 3) / sizeof(long);
#else
#error undefined architecture
#endif
- }
+ }
- break;
+ break;
#if defined(__ppc64__)
- case FFI_TYPE_POINTER:
+ case FFI_TYPE_POINTER:
#endif
- case FFI_TYPE_SINT64:
- case FFI_TYPE_UINT64:
- /* Long long ints are passed in 1 or 2 GPRs. */
- avalue[i] = pgr;
- ng += MODE_CHOICE(2,1);
- pgr += MODE_CHOICE(2,1);
-
- break;
-
- case FFI_TYPE_FLOAT:
- /* A float value consumes a GPR.
- There are 13 64-bit floating point registers. */
- if (nf < NUM_FPR_ARG_REGISTERS)
- {
- temp = pfr->d;
- pfr->f = (float)temp;
- avalue[i] = pfr;
- pfr++;
- }
- else
- avalue[i] = pgr;
-
- nf++;
- ng++;
- pgr++;
- break;
-
- case FFI_TYPE_DOUBLE:
- /* A double value consumes one or two GPRs.
- There are 13 64bit floating point registers. */
- if (nf < NUM_FPR_ARG_REGISTERS)
- {
- avalue[i] = pfr;
- pfr++;
- }
- else
- avalue[i] = pgr;
-
- nf++;
- ng += MODE_CHOICE(2,1);
- pgr += MODE_CHOICE(2,1);
-
- break;
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ /* Long long ints are passed in 1 or 2 GPRs. */
+ avalue[i] = pgr;
+ ng += MODE_CHOICE(2,1);
+ pgr += MODE_CHOICE(2,1);
+
+ break;
+
+ case FFI_TYPE_FLOAT:
+ /* A float value consumes a GPR.
+ There are 13 64-bit floating point registers. */
+ if (nf < NUM_FPR_ARG_REGISTERS)
+ {
+ temp = pfr->d;
+ pfr->f = (float)temp;
+ avalue[i] = pfr;
+ pfr++;
+ }
+ else
+ avalue[i] = pgr;
+
+ nf++;
+ ng++;
+ pgr++;
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ /* A double value consumes one or two GPRs.
+ There are 13 64bit floating point registers. */
+ if (nf < NUM_FPR_ARG_REGISTERS)
+ {
+ avalue[i] = pfr;
+ pfr++;
+ }
+ else
+ avalue[i] = pgr;
+
+ nf++;
+ ng += MODE_CHOICE(2,1);
+ pgr += MODE_CHOICE(2,1);
+
+ break;
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
- case FFI_TYPE_LONGDOUBLE:
+ case FFI_TYPE_LONGDOUBLE:
#if defined(__ppc64__)
- if (nf < NUM_FPR_ARG_REGISTERS)
- {
- avalue[i] = pfr;
- pfr += 2;
- }
+ if (nf < NUM_FPR_ARG_REGISTERS)
+ {
+ avalue[i] = pfr;
+ pfr += 2;
+ }
#elif defined(__ppc__)
- /* A long double value consumes 2/4 GPRs and 2 FPRs.
- There are 13 64bit floating point registers. */
- if (nf < NUM_FPR_ARG_REGISTERS - 1)
- {
- avalue[i] = pfr;
- pfr += 2;
- }
- /* Here we have the situation where one part of the long double
- is stored in fpr13 and the other part is already on the stack.
- We use a union to pass the long double to avalue[i]. */
- else if (nf == NUM_FPR_ARG_REGISTERS - 1)
- {
- memcpy (&temp_ld.lb[0], pfr, sizeof(temp_ld.lb[0]));
- memcpy (&temp_ld.lb[1], pgr + 2, sizeof(temp_ld.lb[1]));
- avalue[i] = &temp_ld.ld;
- }
+ /* A long double value consumes 2/4 GPRs and 2 FPRs.
+ There are 13 64bit floating point registers. */
+ if (nf < NUM_FPR_ARG_REGISTERS - 1)
+ {
+ avalue[i] = pfr;
+ pfr += 2;
+ }
+ /* Here we have the situation where one part of the long double
+ is stored in fpr13 and the other part is already on the stack.
+ We use a union to pass the long double to avalue[i]. */
+ else if (nf == NUM_FPR_ARG_REGISTERS - 1)
+ {
+ memcpy (&temp_ld.lb[0], pfr, sizeof(temp_ld.lb[0]));
+ memcpy (&temp_ld.lb[1], pgr + 2, sizeof(temp_ld.lb[1]));
+ avalue[i] = &temp_ld.ld;
+ }
#else
#error undefined architecture
#endif
- else
- avalue[i] = pgr;
+ else
+ avalue[i] = pgr;
- nf += 2;
- ng += MODE_CHOICE(4,2);
- pgr += MODE_CHOICE(4,2);
+ nf += 2;
+ ng += MODE_CHOICE(4,2);
+ pgr += MODE_CHOICE(4,2);
- break;
+ break;
-#endif /* FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE */
+#endif /* FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE */
- default:
- FFI_ASSERT(0);
- break;
- }
- }
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+ }
- (closure->fun)(cif, rvalue, avalue, closure->user_data);
+ (closure->fun)(cif, rvalue, avalue, closure->user_data);
- /* Tell ffi_closure_ASM to perform return type promotions. */
- return cif->rtype->type;
+ /* Tell ffi_closure_ASM to perform return type promotions. */
+ return cif->rtype->type;
}
#if defined(__ppc64__)
-/* ffi64_struct_to_ram_form
+/* ffi64_struct_to_ram_form
- Rebuild a struct's natural layout from buffers of concatenated registers.
- Return the number of registers used.
- inGPRs[0-7] == r3, inFPRs[0-7] == f1 ...
+ Rebuild a struct's natural layout from buffers of concatenated registers.
+ Return the number of registers used.
+ inGPRs[0-7] == r3, inFPRs[0-7] == f1 ...
*/
void
ffi64_struct_to_ram_form(
- const ffi_type* inType,
- const char* inGPRs,
- unsigned int* ioGPRMarker,
- const char* inFPRs,
- unsigned int* ioFPRMarker,
- unsigned int* ioFPRsUsed,
- char* outStruct, // caller-allocated
- unsigned int* ioStructMarker)
+ const ffi_type* inType,
+ const char* inGPRs,
+ unsigned int* ioGPRMarker,
+ const char* inFPRs,
+ unsigned int* ioFPRMarker,
+ unsigned int* ioFPRsUsed,
+ char* outStruct, // caller-allocated
+ unsigned int* ioStructMarker)
{
- unsigned int srcGMarker = 0;
- unsigned int srcFMarker = 0;
- unsigned int savedFMarker = 0;
- unsigned int fprsUsed = 0;
- unsigned int savedFPRsUsed = 0;
- unsigned int destMarker = 0;
-
- static unsigned int recurseCount = 0;
-
- if (ioGPRMarker)
- srcGMarker = *ioGPRMarker;
-
- if (ioFPRMarker)
- {
- srcFMarker = *ioFPRMarker;
- savedFMarker = srcFMarker;
- }
-
- if (ioFPRsUsed)
- {
- fprsUsed = *ioFPRsUsed;
- savedFPRsUsed = fprsUsed;
- }
-
- if (ioStructMarker)
- destMarker = *ioStructMarker;
-
- size_t i;
-
- switch (inType->size)
- {
- case 1: case 2: case 4:
- srcGMarker += 8 - inType->size;
- break;
-
- default:
- break;
- }
-
- for (i = 0; inType->elements[i] != NULL; i++)
- {
- switch (inType->elements[i]->type)
- {
- case FFI_TYPE_FLOAT:
- srcFMarker = ALIGN(srcFMarker, 4);
- srcGMarker = ALIGN(srcGMarker, 4);
- destMarker = ALIGN(destMarker, 4);
-
- if (fprsUsed < NUM_FPR_ARG_REGISTERS)
- {
- *(float*)&outStruct[destMarker] =
- (float)*(double*)&inFPRs[srcFMarker];
- srcFMarker += 8;
- fprsUsed++;
- }
- else
- *(float*)&outStruct[destMarker] =
- (float)*(double*)&inGPRs[srcGMarker];
-
- srcGMarker += 4;
- destMarker += 4;
-
- // Skip to next GPR if next element won't fit and we're
- // not already at a register boundary.
- if (inType->elements[i + 1] != NULL && (destMarker % 8))
- {
- if (!FFI_TYPE_1_BYTE(inType->elements[i + 1]->type) &&
- (!FFI_TYPE_2_BYTE(inType->elements[i + 1]->type) ||
- (ALIGN(srcGMarker, 8) - srcGMarker) < 2) &&
- (!FFI_TYPE_4_BYTE(inType->elements[i + 1]->type) ||
- (ALIGN(srcGMarker, 8) - srcGMarker) < 4))
- srcGMarker = ALIGN(srcGMarker, 8);
- }
-
- break;
-
- case FFI_TYPE_DOUBLE:
- srcFMarker = ALIGN(srcFMarker, 8);
- destMarker = ALIGN(destMarker, 8);
-
- if (fprsUsed < NUM_FPR_ARG_REGISTERS)
- {
- *(double*)&outStruct[destMarker] =
- *(double*)&inFPRs[srcFMarker];
- srcFMarker += 8;
- fprsUsed++;
- }
- else
- *(double*)&outStruct[destMarker] =
- *(double*)&inGPRs[srcGMarker];
-
- destMarker += 8;
-
- // Skip next GPR
- srcGMarker += 8;
- srcGMarker = ALIGN(srcGMarker, 8);
-
- break;
-
- case FFI_TYPE_LONGDOUBLE:
- destMarker = ALIGN(destMarker, 16);
-
- if (fprsUsed < NUM_FPR_ARG_REGISTERS)
- {
- srcFMarker = ALIGN(srcFMarker, 8);
- srcGMarker = ALIGN(srcGMarker, 8);
- *(long double*)&outStruct[destMarker] =
- *(long double*)&inFPRs[srcFMarker];
- srcFMarker += 16;
- fprsUsed += 2;
- }
- else
- {
- srcFMarker = ALIGN(srcFMarker, 16);
- srcGMarker = ALIGN(srcGMarker, 16);
- *(long double*)&outStruct[destMarker] =
- *(long double*)&inGPRs[srcGMarker];
- }
-
- destMarker += 16;
-
- // Skip next 2 GPRs
- srcGMarker += 16;
- srcGMarker = ALIGN(srcGMarker, 8);
-
- break;
-
- case FFI_TYPE_UINT8:
- case FFI_TYPE_SINT8:
- {
- if (inType->alignment == 1) // chars only
- {
- if (inType->size == 1)
- outStruct[destMarker++] = inGPRs[srcGMarker++];
- else if (inType->size == 2)
- {
- outStruct[destMarker++] = inGPRs[srcGMarker++];
- outStruct[destMarker++] = inGPRs[srcGMarker++];
- i++;
- }
- else
- {
- memcpy(&outStruct[destMarker],
- &inGPRs[srcGMarker], inType->size);
- srcGMarker += inType->size;
- destMarker += inType->size;
- i += inType->size - 1;
- }
- }
- else // chars and other stuff
- {
- outStruct[destMarker++] = inGPRs[srcGMarker++];
-
- // Skip to next GPR if next element won't fit and we're
- // not already at a register boundary.
- if (inType->elements[i + 1] != NULL && (srcGMarker % 8))
- {
- if (!FFI_TYPE_1_BYTE(inType->elements[i + 1]->type) &&
- (!FFI_TYPE_2_BYTE(inType->elements[i + 1]->type) ||
- (ALIGN(srcGMarker, 8) - srcGMarker) < 2) &&
- (!FFI_TYPE_4_BYTE(inType->elements[i + 1]->type) ||
- (ALIGN(srcGMarker, 8) - srcGMarker) < 4))
- srcGMarker = ALIGN(srcGMarker, inType->alignment); // was 8
- }
- }
-
- break;
- }
-
- case FFI_TYPE_UINT16:
- case FFI_TYPE_SINT16:
- srcGMarker = ALIGN(srcGMarker, 2);
- destMarker = ALIGN(destMarker, 2);
-
- *(short*)&outStruct[destMarker] =
- *(short*)&inGPRs[srcGMarker];
- srcGMarker += 2;
- destMarker += 2;
-
- break;
-
- case FFI_TYPE_INT:
- case FFI_TYPE_UINT32:
- case FFI_TYPE_SINT32:
- srcGMarker = ALIGN(srcGMarker, 4);
- destMarker = ALIGN(destMarker, 4);
-
- *(int*)&outStruct[destMarker] =
- *(int*)&inGPRs[srcGMarker];
- srcGMarker += 4;
- destMarker += 4;
-
- break;
-
- case FFI_TYPE_POINTER:
- case FFI_TYPE_UINT64:
- case FFI_TYPE_SINT64:
- srcGMarker = ALIGN(srcGMarker, 8);
- destMarker = ALIGN(destMarker, 8);
-
- *(long long*)&outStruct[destMarker] =
- *(long long*)&inGPRs[srcGMarker];
- srcGMarker += 8;
- destMarker += 8;
-
- break;
-
- case FFI_TYPE_STRUCT:
- recurseCount++;
- ffi64_struct_to_ram_form(inType->elements[i], inGPRs,
- &srcGMarker, inFPRs, &srcFMarker, &fprsUsed,
- outStruct, &destMarker);
- recurseCount--;
- break;
-
- default:
- FFI_ASSERT(0); // unknown element type
- break;
- }
- }
-
- srcGMarker = ALIGN(srcGMarker, inType->alignment);
-
- // Take care of the special case for 16-byte structs, but not for
- // nested structs.
- if (recurseCount == 0 && srcGMarker == 16)
- {
- *(long double*)&outStruct[0] = *(long double*)&inGPRs[0];
- srcFMarker = savedFMarker;
- fprsUsed = savedFPRsUsed;
- }
-
- if (ioGPRMarker)
- *ioGPRMarker = ALIGN(srcGMarker, 8);
-
- if (ioFPRMarker)
- *ioFPRMarker = srcFMarker;
-
- if (ioFPRsUsed)
- *ioFPRsUsed = fprsUsed;
-
- if (ioStructMarker)
- *ioStructMarker = ALIGN(destMarker, 8);
+ unsigned int srcGMarker = 0;
+ unsigned int srcFMarker = 0;
+ unsigned int savedFMarker = 0;
+ unsigned int fprsUsed = 0;
+ unsigned int savedFPRsUsed = 0;
+ unsigned int destMarker = 0;
+
+ static unsigned int recurseCount = 0;
+
+ if (ioGPRMarker)
+ srcGMarker = *ioGPRMarker;
+
+ if (ioFPRMarker)
+ {
+ srcFMarker = *ioFPRMarker;
+ savedFMarker = srcFMarker;
+ }
+
+ if (ioFPRsUsed)
+ {
+ fprsUsed = *ioFPRsUsed;
+ savedFPRsUsed = fprsUsed;
+ }
+
+ if (ioStructMarker)
+ destMarker = *ioStructMarker;
+
+ size_t i;
+
+ switch (inType->size)
+ {
+ case 1: case 2: case 4:
+ srcGMarker += 8 - inType->size;
+ break;
+
+ default:
+ break;
+ }
+
+ for (i = 0; inType->elements[i] != NULL; i++)
+ {
+ switch (inType->elements[i]->type)
+ {
+ case FFI_TYPE_FLOAT:
+ srcFMarker = ALIGN(srcFMarker, 4);
+ srcGMarker = ALIGN(srcGMarker, 4);
+ destMarker = ALIGN(destMarker, 4);
+
+ if (fprsUsed < NUM_FPR_ARG_REGISTERS)
+ {
+ *(float*)&outStruct[destMarker] =
+ (float)*(double*)&inFPRs[srcFMarker];
+ srcFMarker += 8;
+ fprsUsed++;
+ }
+ else
+ *(float*)&outStruct[destMarker] =
+ (float)*(double*)&inGPRs[srcGMarker];
+
+ srcGMarker += 4;
+ destMarker += 4;
+
+ // Skip to next GPR if next element won't fit and we're
+ // not already at a register boundary.
+ if (inType->elements[i + 1] != NULL && (destMarker % 8))
+ {
+ if (!FFI_TYPE_1_BYTE(inType->elements[i + 1]->type) &&
+ (!FFI_TYPE_2_BYTE(inType->elements[i + 1]->type) ||
+ (ALIGN(srcGMarker, 8) - srcGMarker) < 2) &&
+ (!FFI_TYPE_4_BYTE(inType->elements[i + 1]->type) ||
+ (ALIGN(srcGMarker, 8) - srcGMarker) < 4))
+ srcGMarker = ALIGN(srcGMarker, 8);
+ }
+
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ srcFMarker = ALIGN(srcFMarker, 8);
+ destMarker = ALIGN(destMarker, 8);
+
+ if (fprsUsed < NUM_FPR_ARG_REGISTERS)
+ {
+ *(double*)&outStruct[destMarker] =
+ *(double*)&inFPRs[srcFMarker];
+ srcFMarker += 8;
+ fprsUsed++;
+ }
+ else
+ *(double*)&outStruct[destMarker] =
+ *(double*)&inGPRs[srcGMarker];
+
+ destMarker += 8;
+
+ // Skip next GPR
+ srcGMarker += 8;
+ srcGMarker = ALIGN(srcGMarker, 8);
+
+ break;
+
+ case FFI_TYPE_LONGDOUBLE:
+ destMarker = ALIGN(destMarker, 16);
+
+ if (fprsUsed < NUM_FPR_ARG_REGISTERS)
+ {
+ srcFMarker = ALIGN(srcFMarker, 8);
+ srcGMarker = ALIGN(srcGMarker, 8);
+ *(long double*)&outStruct[destMarker] =
+ *(long double*)&inFPRs[srcFMarker];
+ srcFMarker += 16;
+ fprsUsed += 2;
+ }
+ else
+ {
+ srcFMarker = ALIGN(srcFMarker, 16);
+ srcGMarker = ALIGN(srcGMarker, 16);
+ *(long double*)&outStruct[destMarker] =
+ *(long double*)&inGPRs[srcGMarker];
+ }
+
+ destMarker += 16;
+
+ // Skip next 2 GPRs
+ srcGMarker += 16;
+ srcGMarker = ALIGN(srcGMarker, 8);
+
+ break;
+
+ case FFI_TYPE_UINT8:
+ case FFI_TYPE_SINT8:
+ {
+ if (inType->alignment == 1) // chars only
+ {
+ if (inType->size == 1)
+ outStruct[destMarker++] = inGPRs[srcGMarker++];
+ else if (inType->size == 2)
+ {
+ outStruct[destMarker++] = inGPRs[srcGMarker++];
+ outStruct[destMarker++] = inGPRs[srcGMarker++];
+ i++;
+ }
+ else
+ {
+ memcpy(&outStruct[destMarker],
+ &inGPRs[srcGMarker], inType->size);
+ srcGMarker += inType->size;
+ destMarker += inType->size;
+ i += inType->size - 1;
+ }
+ }
+ else // chars and other stuff
+ {
+ outStruct[destMarker++] = inGPRs[srcGMarker++];
+
+ // Skip to next GPR if next element won't fit and we're
+ // not already at a register boundary.
+ if (inType->elements[i + 1] != NULL && (srcGMarker % 8))
+ {
+ if (!FFI_TYPE_1_BYTE(inType->elements[i + 1]->type) &&
+ (!FFI_TYPE_2_BYTE(inType->elements[i + 1]->type) ||
+ (ALIGN(srcGMarker, 8) - srcGMarker) < 2) &&
+ (!FFI_TYPE_4_BYTE(inType->elements[i + 1]->type) ||
+ (ALIGN(srcGMarker, 8) - srcGMarker) < 4))
+ srcGMarker = ALIGN(srcGMarker, inType->alignment); // was 8
+ }
+ }
+
+ break;
+ }
+
+ case FFI_TYPE_UINT16:
+ case FFI_TYPE_SINT16:
+ srcGMarker = ALIGN(srcGMarker, 2);
+ destMarker = ALIGN(destMarker, 2);
+
+ *(short*)&outStruct[destMarker] =
+ *(short*)&inGPRs[srcGMarker];
+ srcGMarker += 2;
+ destMarker += 2;
+
+ break;
+
+ case FFI_TYPE_INT:
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_SINT32:
+ srcGMarker = ALIGN(srcGMarker, 4);
+ destMarker = ALIGN(destMarker, 4);
+
+ *(int*)&outStruct[destMarker] =
+ *(int*)&inGPRs[srcGMarker];
+ srcGMarker += 4;
+ destMarker += 4;
+
+ break;
+
+ case FFI_TYPE_POINTER:
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+ srcGMarker = ALIGN(srcGMarker, 8);
+ destMarker = ALIGN(destMarker, 8);
+
+ *(long long*)&outStruct[destMarker] =
+ *(long long*)&inGPRs[srcGMarker];
+ srcGMarker += 8;
+ destMarker += 8;
+
+ break;
+
+ case FFI_TYPE_STRUCT:
+ recurseCount++;
+ ffi64_struct_to_ram_form(inType->elements[i], inGPRs,
+ &srcGMarker, inFPRs, &srcFMarker, &fprsUsed,
+ outStruct, &destMarker);
+ recurseCount--;
+ break;
+
+ default:
+ FFI_ASSERT(0); // unknown element type
+ break;
+ }
+ }
+
+ srcGMarker = ALIGN(srcGMarker, inType->alignment);
+
+ // Take care of the special case for 16-byte structs, but not for
+ // nested structs.
+ if (recurseCount == 0 && srcGMarker == 16)
+ {
+ *(long double*)&outStruct[0] = *(long double*)&inGPRs[0];
+ srcFMarker = savedFMarker;
+ fprsUsed = savedFPRsUsed;
+ }
+
+ if (ioGPRMarker)
+ *ioGPRMarker = ALIGN(srcGMarker, 8);
+
+ if (ioFPRMarker)
+ *ioFPRMarker = srcFMarker;
+
+ if (ioFPRsUsed)
+ *ioFPRsUsed = fprsUsed;
+
+ if (ioStructMarker)
+ *ioStructMarker = ALIGN(destMarker, 8);
}
-/* ffi64_struct_to_reg_form
+/* ffi64_struct_to_reg_form
- Copy a struct's elements into buffers that can be sliced into registers.
- Return the sizes of the output buffers in bytes. Pass NULL buffer pointers
- to calculate size only.
- outGPRs[0-7] == r3, outFPRs[0-7] == f1 ...
+ Copy a struct's elements into buffers that can be sliced into registers.
+ Return the sizes of the output buffers in bytes. Pass NULL buffer pointers
+ to calculate size only.
+ outGPRs[0-7] == r3, outFPRs[0-7] == f1 ...
*/
void
ffi64_struct_to_reg_form(
- const ffi_type* inType,
- const char* inStruct,
- unsigned int* ioStructMarker,
- unsigned int* ioFPRsUsed,
- char* outGPRs, // caller-allocated
- unsigned int* ioGPRSize,
- char* outFPRs, // caller-allocated
- unsigned int* ioFPRSize)
+ const ffi_type* inType,
+ const char* inStruct,
+ unsigned int* ioStructMarker,
+ unsigned int* ioFPRsUsed,
+ char* outGPRs, // caller-allocated
+ unsigned int* ioGPRSize,
+ char* outFPRs, // caller-allocated
+ unsigned int* ioFPRSize)
{
- size_t i;
- unsigned int srcMarker = 0;
- unsigned int destGMarker = 0;
- unsigned int destFMarker = 0;
- unsigned int savedFMarker = 0;
- unsigned int fprsUsed = 0;
- unsigned int savedFPRsUsed = 0;
-
- static unsigned int recurseCount = 0;
-
- if (ioStructMarker)
- srcMarker = *ioStructMarker;
-
- if (ioFPRsUsed)
- {
- fprsUsed = *ioFPRsUsed;
- savedFPRsUsed = fprsUsed;
- }
-
- if (ioGPRSize)
- destGMarker = *ioGPRSize;
-
- if (ioFPRSize)
- {
- destFMarker = *ioFPRSize;
- savedFMarker = destFMarker;
- }
-
- switch (inType->size)
- {
- case 1: case 2: case 4:
- destGMarker += 8 - inType->size;
- break;
-
- default:
- break;
- }
-
- for (i = 0; inType->elements[i] != NULL; i++)
- {
- switch (inType->elements[i]->type)
- {
- // Shadow floating-point types in GPRs for vararg and pre-ANSI
- // functions.
- case FFI_TYPE_FLOAT:
- // Nudge markers to next 4/8-byte boundary
- srcMarker = ALIGN(srcMarker, 4);
- destGMarker = ALIGN(destGMarker, 4);
- destFMarker = ALIGN(destFMarker, 8);
-
- if (fprsUsed < NUM_FPR_ARG_REGISTERS)
- {
- if (outFPRs != NULL && inStruct != NULL)
- *(double*)&outFPRs[destFMarker] =
- (double)*(float*)&inStruct[srcMarker];
-
- destFMarker += 8;
- fprsUsed++;
- }
-
- if (outGPRs != NULL && inStruct != NULL)
- *(double*)&outGPRs[destGMarker] =
- (double)*(float*)&inStruct[srcMarker];
-
- srcMarker += 4;
- destGMarker += 4;
-
- // Skip to next GPR if next element won't fit and we're
- // not already at a register boundary.
- if (inType->elements[i + 1] != NULL && (srcMarker % 8))
- {
- if (!FFI_TYPE_1_BYTE(inType->elements[i + 1]->type) &&
- (!FFI_TYPE_2_BYTE(inType->elements[i + 1]->type) ||
- (ALIGN(destGMarker, 8) - destGMarker) < 2) &&
- (!FFI_TYPE_4_BYTE(inType->elements[i + 1]->type) ||
- (ALIGN(destGMarker, 8) - destGMarker) < 4))
- destGMarker = ALIGN(destGMarker, 8);
- }
-
- break;
-
- case FFI_TYPE_DOUBLE:
- srcMarker = ALIGN(srcMarker, 8);
- destFMarker = ALIGN(destFMarker, 8);
-
- if (fprsUsed < NUM_FPR_ARG_REGISTERS)
- {
- if (outFPRs != NULL && inStruct != NULL)
- *(double*)&outFPRs[destFMarker] =
- *(double*)&inStruct[srcMarker];
-
- destFMarker += 8;
- fprsUsed++;
- }
-
- if (outGPRs != NULL && inStruct != NULL)
- *(double*)&outGPRs[destGMarker] =
- *(double*)&inStruct[srcMarker];
-
- srcMarker += 8;
-
- // Skip next GPR
- destGMarker += 8;
- destGMarker = ALIGN(destGMarker, 8);
-
- break;
-
- case FFI_TYPE_LONGDOUBLE:
- srcMarker = ALIGN(srcMarker, 16);
-
- if (fprsUsed < NUM_FPR_ARG_REGISTERS)
- {
- destFMarker = ALIGN(destFMarker, 8);
- destGMarker = ALIGN(destGMarker, 8);
-
- if (outFPRs != NULL && inStruct != NULL)
- *(long double*)&outFPRs[destFMarker] =
- *(long double*)&inStruct[srcMarker];
-
- if (outGPRs != NULL && inStruct != NULL)
- *(long double*)&outGPRs[destGMarker] =
- *(long double*)&inStruct[srcMarker];
-
- destFMarker += 16;
- fprsUsed += 2;
- }
- else
- {
- destGMarker = ALIGN(destGMarker, 16);
-
- if (outGPRs != NULL && inStruct != NULL)
- *(long double*)&outGPRs[destGMarker] =
- *(long double*)&inStruct[srcMarker];
- }
-
- srcMarker += 16;
- destGMarker += 16; // Skip next 2 GPRs
- destGMarker = ALIGN(destGMarker, 8); // was 16
-
- break;
-
- case FFI_TYPE_UINT8:
- case FFI_TYPE_SINT8:
- if (inType->alignment == 1) // bytes only
- {
- if (inType->size == 1)
- {
- if (outGPRs != NULL && inStruct != NULL)
- outGPRs[destGMarker] = inStruct[srcMarker];
-
- srcMarker++;
- destGMarker++;
- }
- else if (inType->size == 2)
- {
- if (outGPRs != NULL && inStruct != NULL)
- {
- outGPRs[destGMarker] = inStruct[srcMarker];
- outGPRs[destGMarker + 1] = inStruct[srcMarker + 1];
- }
-
- srcMarker += 2;
- destGMarker += 2;
-
- i++;
- }
- else
- {
- if (outGPRs != NULL && inStruct != NULL)
- {
- // Avoid memcpy for small chunks.
- if (inType->size <= sizeof(long))
- *(long*)&outGPRs[destGMarker] =
- *(long*)&inStruct[srcMarker];
- else
- memcpy(&outGPRs[destGMarker],
- &inStruct[srcMarker], inType->size);
- }
-
- srcMarker += inType->size;
- destGMarker += inType->size;
- i += inType->size - 1;
- }
- }
- else // bytes and other stuff
- {
- if (outGPRs != NULL && inStruct != NULL)
- outGPRs[destGMarker] = inStruct[srcMarker];
-
- srcMarker++;
- destGMarker++;
-
- // Skip to next GPR if next element won't fit and we're
- // not already at a register boundary.
- if (inType->elements[i + 1] != NULL && (destGMarker % 8))
- {
- if (!FFI_TYPE_1_BYTE(inType->elements[i + 1]->type) &&
- (!FFI_TYPE_2_BYTE(inType->elements[i + 1]->type) ||
- (ALIGN(destGMarker, 8) - destGMarker) < 2) &&
- (!FFI_TYPE_4_BYTE(inType->elements[i + 1]->type) ||
- (ALIGN(destGMarker, 8) - destGMarker) < 4))
- destGMarker = ALIGN(destGMarker, inType->alignment); // was 8
- }
- }
-
- break;
-
- case FFI_TYPE_UINT16:
- case FFI_TYPE_SINT16:
- srcMarker = ALIGN(srcMarker, 2);
- destGMarker = ALIGN(destGMarker, 2);
-
- if (outGPRs != NULL && inStruct != NULL)
- *(short*)&outGPRs[destGMarker] =
- *(short*)&inStruct[srcMarker];
-
- srcMarker += 2;
- destGMarker += 2;
-
- if (inType->elements[i + 1] == NULL)
- destGMarker = ALIGN(destGMarker, inType->alignment);
-
- break;
-
- case FFI_TYPE_INT:
- case FFI_TYPE_UINT32:
- case FFI_TYPE_SINT32:
- srcMarker = ALIGN(srcMarker, 4);
- destGMarker = ALIGN(destGMarker, 4);
-
- if (outGPRs != NULL && inStruct != NULL)
- *(int*)&outGPRs[destGMarker] =
- *(int*)&inStruct[srcMarker];
-
- srcMarker += 4;
- destGMarker += 4;
-
- break;
-
- case FFI_TYPE_POINTER:
- case FFI_TYPE_UINT64:
- case FFI_TYPE_SINT64:
- srcMarker = ALIGN(srcMarker, 8);
- destGMarker = ALIGN(destGMarker, 8);
-
- if (outGPRs != NULL && inStruct != NULL)
- *(long long*)&outGPRs[destGMarker] =
- *(long long*)&inStruct[srcMarker];
-
- srcMarker += 8;
- destGMarker += 8;
-
- if (inType->elements[i + 1] == NULL)
- destGMarker = ALIGN(destGMarker, inType->alignment);
-
- break;
-
- case FFI_TYPE_STRUCT:
- recurseCount++;
- ffi64_struct_to_reg_form(inType->elements[i],
- inStruct, &srcMarker, &fprsUsed, outGPRs,
- &destGMarker, outFPRs, &destFMarker);
- recurseCount--;
- break;
-
- default:
- FFI_ASSERT(0);
- break;
- }
- }
-
- destGMarker = ALIGN(destGMarker, inType->alignment);
-
- // Take care of the special case for 16-byte structs, but not for
- // nested structs.
- if (recurseCount == 0 && destGMarker == 16)
- {
- if (outGPRs != NULL && inStruct != NULL)
- *(long double*)&outGPRs[0] = *(long double*)&inStruct[0];
-
- destFMarker = savedFMarker;
- fprsUsed = savedFPRsUsed;
- }
-
- if (ioStructMarker)
- *ioStructMarker = ALIGN(srcMarker, 8);
-
- if (ioFPRsUsed)
- *ioFPRsUsed = fprsUsed;
-
- if (ioGPRSize)
- *ioGPRSize = ALIGN(destGMarker, 8);
-
- if (ioFPRSize)
- *ioFPRSize = ALIGN(destFMarker, 8);
+ size_t i;
+ unsigned int srcMarker = 0;
+ unsigned int destGMarker = 0;
+ unsigned int destFMarker = 0;
+ unsigned int savedFMarker = 0;
+ unsigned int fprsUsed = 0;
+ unsigned int savedFPRsUsed = 0;
+
+ static unsigned int recurseCount = 0;
+
+ if (ioStructMarker)
+ srcMarker = *ioStructMarker;
+
+ if (ioFPRsUsed)
+ {
+ fprsUsed = *ioFPRsUsed;
+ savedFPRsUsed = fprsUsed;
+ }
+
+ if (ioGPRSize)
+ destGMarker = *ioGPRSize;
+
+ if (ioFPRSize)
+ {
+ destFMarker = *ioFPRSize;
+ savedFMarker = destFMarker;
+ }
+
+ switch (inType->size)
+ {
+ case 1: case 2: case 4:
+ destGMarker += 8 - inType->size;
+ break;
+
+ default:
+ break;
+ }
+
+ for (i = 0; inType->elements[i] != NULL; i++)
+ {
+ switch (inType->elements[i]->type)
+ {
+ // Shadow floating-point types in GPRs for vararg and pre-ANSI
+ // functions.
+ case FFI_TYPE_FLOAT:
+ // Nudge markers to next 4/8-byte boundary
+ srcMarker = ALIGN(srcMarker, 4);
+ destGMarker = ALIGN(destGMarker, 4);
+ destFMarker = ALIGN(destFMarker, 8);
+
+ if (fprsUsed < NUM_FPR_ARG_REGISTERS)
+ {
+ if (outFPRs != NULL && inStruct != NULL)
+ *(double*)&outFPRs[destFMarker] =
+ (double)*(float*)&inStruct[srcMarker];
+
+ destFMarker += 8;
+ fprsUsed++;
+ }
+
+ if (outGPRs != NULL && inStruct != NULL)
+ *(double*)&outGPRs[destGMarker] =
+ (double)*(float*)&inStruct[srcMarker];
+
+ srcMarker += 4;
+ destGMarker += 4;
+
+ // Skip to next GPR if next element won't fit and we're
+ // not already at a register boundary.
+ if (inType->elements[i + 1] != NULL && (srcMarker % 8))
+ {
+ if (!FFI_TYPE_1_BYTE(inType->elements[i + 1]->type) &&
+ (!FFI_TYPE_2_BYTE(inType->elements[i + 1]->type) ||
+ (ALIGN(destGMarker, 8) - destGMarker) < 2) &&
+ (!FFI_TYPE_4_BYTE(inType->elements[i + 1]->type) ||
+ (ALIGN(destGMarker, 8) - destGMarker) < 4))
+ destGMarker = ALIGN(destGMarker, 8);
+ }
+
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ srcMarker = ALIGN(srcMarker, 8);
+ destFMarker = ALIGN(destFMarker, 8);
+
+ if (fprsUsed < NUM_FPR_ARG_REGISTERS)
+ {
+ if (outFPRs != NULL && inStruct != NULL)
+ *(double*)&outFPRs[destFMarker] =
+ *(double*)&inStruct[srcMarker];
+
+ destFMarker += 8;
+ fprsUsed++;
+ }
+
+ if (outGPRs != NULL && inStruct != NULL)
+ *(double*)&outGPRs[destGMarker] =
+ *(double*)&inStruct[srcMarker];
+
+ srcMarker += 8;
+
+ // Skip next GPR
+ destGMarker += 8;
+ destGMarker = ALIGN(destGMarker, 8);
+
+ break;
+
+ case FFI_TYPE_LONGDOUBLE:
+ srcMarker = ALIGN(srcMarker, 16);
+
+ if (fprsUsed < NUM_FPR_ARG_REGISTERS)
+ {
+ destFMarker = ALIGN(destFMarker, 8);
+ destGMarker = ALIGN(destGMarker, 8);
+
+ if (outFPRs != NULL && inStruct != NULL)
+ *(long double*)&outFPRs[destFMarker] =
+ *(long double*)&inStruct[srcMarker];
+
+ if (outGPRs != NULL && inStruct != NULL)
+ *(long double*)&outGPRs[destGMarker] =
+ *(long double*)&inStruct[srcMarker];
+
+ destFMarker += 16;
+ fprsUsed += 2;
+ }
+ else
+ {
+ destGMarker = ALIGN(destGMarker, 16);
+
+ if (outGPRs != NULL && inStruct != NULL)
+ *(long double*)&outGPRs[destGMarker] =
+ *(long double*)&inStruct[srcMarker];
+ }
+
+ srcMarker += 16;
+ destGMarker += 16; // Skip next 2 GPRs
+ destGMarker = ALIGN(destGMarker, 8); // was 16
+
+ break;
+
+ case FFI_TYPE_UINT8:
+ case FFI_TYPE_SINT8:
+ if (inType->alignment == 1) // bytes only
+ {
+ if (inType->size == 1)
+ {
+ if (outGPRs != NULL && inStruct != NULL)
+ outGPRs[destGMarker] = inStruct[srcMarker];
+
+ srcMarker++;
+ destGMarker++;
+ }
+ else if (inType->size == 2)
+ {
+ if (outGPRs != NULL && inStruct != NULL)
+ {
+ outGPRs[destGMarker] = inStruct[srcMarker];
+ outGPRs[destGMarker + 1] = inStruct[srcMarker + 1];
+ }
+
+ srcMarker += 2;
+ destGMarker += 2;
+
+ i++;
+ }
+ else
+ {
+ if (outGPRs != NULL && inStruct != NULL)
+ {
+ // Avoid memcpy for small chunks.
+ if (inType->size <= sizeof(long))
+ *(long*)&outGPRs[destGMarker] =
+ *(long*)&inStruct[srcMarker];
+ else
+ memcpy(&outGPRs[destGMarker],
+ &inStruct[srcMarker], inType->size);
+ }
+
+ srcMarker += inType->size;
+ destGMarker += inType->size;
+ i += inType->size - 1;
+ }
+ }
+ else // bytes and other stuff
+ {
+ if (outGPRs != NULL && inStruct != NULL)
+ outGPRs[destGMarker] = inStruct[srcMarker];
+
+ srcMarker++;
+ destGMarker++;
+
+ // Skip to next GPR if next element won't fit and we're
+ // not already at a register boundary.
+ if (inType->elements[i + 1] != NULL && (destGMarker % 8))
+ {
+ if (!FFI_TYPE_1_BYTE(inType->elements[i + 1]->type) &&
+ (!FFI_TYPE_2_BYTE(inType->elements[i + 1]->type) ||
+ (ALIGN(destGMarker, 8) - destGMarker) < 2) &&
+ (!FFI_TYPE_4_BYTE(inType->elements[i + 1]->type) ||
+ (ALIGN(destGMarker, 8) - destGMarker) < 4))
+ destGMarker = ALIGN(destGMarker, inType->alignment); // was 8
+ }
+ }
+
+ break;
+
+ case FFI_TYPE_UINT16:
+ case FFI_TYPE_SINT16:
+ srcMarker = ALIGN(srcMarker, 2);
+ destGMarker = ALIGN(destGMarker, 2);
+
+ if (outGPRs != NULL && inStruct != NULL)
+ *(short*)&outGPRs[destGMarker] =
+ *(short*)&inStruct[srcMarker];
+
+ srcMarker += 2;
+ destGMarker += 2;
+
+ if (inType->elements[i + 1] == NULL)
+ destGMarker = ALIGN(destGMarker, inType->alignment);
+
+ break;
+
+ case FFI_TYPE_INT:
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_SINT32:
+ srcMarker = ALIGN(srcMarker, 4);
+ destGMarker = ALIGN(destGMarker, 4);
+
+ if (outGPRs != NULL && inStruct != NULL)
+ *(int*)&outGPRs[destGMarker] =
+ *(int*)&inStruct[srcMarker];
+
+ srcMarker += 4;
+ destGMarker += 4;
+
+ break;
+
+ case FFI_TYPE_POINTER:
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+ srcMarker = ALIGN(srcMarker, 8);
+ destGMarker = ALIGN(destGMarker, 8);
+
+ if (outGPRs != NULL && inStruct != NULL)
+ *(long long*)&outGPRs[destGMarker] =
+ *(long long*)&inStruct[srcMarker];
+
+ srcMarker += 8;
+ destGMarker += 8;
+
+ if (inType->elements[i + 1] == NULL)
+ destGMarker = ALIGN(destGMarker, inType->alignment);
+
+ break;
+
+ case FFI_TYPE_STRUCT:
+ recurseCount++;
+ ffi64_struct_to_reg_form(inType->elements[i],
+ inStruct, &srcMarker, &fprsUsed, outGPRs,
+ &destGMarker, outFPRs, &destFMarker);
+ recurseCount--;
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+ }
+
+ destGMarker = ALIGN(destGMarker, inType->alignment);
+
+ // Take care of the special case for 16-byte structs, but not for
+ // nested structs.
+ if (recurseCount == 0 && destGMarker == 16)
+ {
+ if (outGPRs != NULL && inStruct != NULL)
+ *(long double*)&outGPRs[0] = *(long double*)&inStruct[0];
+
+ destFMarker = savedFMarker;
+ fprsUsed = savedFPRsUsed;
+ }
+
+ if (ioStructMarker)
+ *ioStructMarker = ALIGN(srcMarker, 8);
+
+ if (ioFPRsUsed)
+ *ioFPRsUsed = fprsUsed;
+
+ if (ioGPRSize)
+ *ioGPRSize = ALIGN(destGMarker, 8);
+
+ if (ioFPRSize)
+ *ioFPRSize = ALIGN(destFMarker, 8);
}
-/* ffi64_stret_needs_ptr
+/* ffi64_stret_needs_ptr
- Determine whether a returned struct needs a pointer in r3 or can fit
- in registers.
+ Determine whether a returned struct needs a pointer in r3 or can fit
+ in registers.
*/
bool
ffi64_stret_needs_ptr(
- const ffi_type* inType,
- unsigned short* ioGPRCount,
- unsigned short* ioFPRCount)
+ const ffi_type* inType,
+ unsigned short* ioGPRCount,
+ unsigned short* ioFPRCount)
{
- // Obvious case first- struct is larger than combined FPR size.
- if (inType->size > 14 * 8)
- return true;
+ // Obvious case first- struct is larger than combined FPR size.
+ if (inType->size > 14 * 8)
+ return true;
- // Now the struct can physically fit in registers, determine if it
- // also fits logically.
- bool needsPtr = false;
- unsigned short gprsUsed = 0;
- unsigned short fprsUsed = 0;
- size_t i;
+ // Now the struct can physically fit in registers, determine if it
+ // also fits logically.
+ bool needsPtr = false;
+ unsigned short gprsUsed = 0;
+ unsigned short fprsUsed = 0;
+ size_t i;
- if (ioGPRCount)
- gprsUsed = *ioGPRCount;
+ if (ioGPRCount)
+ gprsUsed = *ioGPRCount;
- if (ioFPRCount)
- fprsUsed = *ioFPRCount;
+ if (ioFPRCount)
+ fprsUsed = *ioFPRCount;
- for (i = 0; inType->elements[i] != NULL && !needsPtr; i++)
- {
- switch (inType->elements[i]->type)
- {
- case FFI_TYPE_FLOAT:
- case FFI_TYPE_DOUBLE:
- gprsUsed++;
- fprsUsed++;
+ for (i = 0; inType->elements[i] != NULL && !needsPtr; i++)
+ {
+ switch (inType->elements[i]->type)
+ {
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ gprsUsed++;
+ fprsUsed++;
- if (fprsUsed > 13)
- needsPtr = true;
+ if (fprsUsed > 13)
+ needsPtr = true;
- break;
+ break;
- case FFI_TYPE_LONGDOUBLE:
- gprsUsed += 2;
- fprsUsed += 2;
+ case FFI_TYPE_LONGDOUBLE:
+ gprsUsed += 2;
+ fprsUsed += 2;
- if (fprsUsed > 14)
- needsPtr = true;
+ if (fprsUsed > 14)
+ needsPtr = true;
- break;
+ break;
- case FFI_TYPE_UINT8:
- case FFI_TYPE_SINT8:
- {
- gprsUsed++;
+ case FFI_TYPE_UINT8:
+ case FFI_TYPE_SINT8:
+ {
+ gprsUsed++;
- if (gprsUsed > 8)
- {
- needsPtr = true;
- break;
- }
+ if (gprsUsed > 8)
+ {
+ needsPtr = true;
+ break;
+ }
- if (inType->elements[i + 1] == NULL) // last byte in the struct
- break;
+ if (inType->elements[i + 1] == NULL) // last byte in the struct
+ break;
- // Count possible contiguous bytes ahead, up to 8.
- unsigned short j;
+ // Count possible contiguous bytes ahead, up to 8.
+ unsigned short j;
- for (j = 1; j < 8; j++)
- {
- if (inType->elements[i + j] == NULL ||
- !FFI_TYPE_1_BYTE(inType->elements[i + j]->type))
- break;
- }
+ for (j = 1; j < 8; j++)
+ {
+ if (inType->elements[i + j] == NULL ||
+ !FFI_TYPE_1_BYTE(inType->elements[i + j]->type))
+ break;
+ }
- i += j - 1; // allow for i++ before the test condition
+ i += j - 1; // allow for i++ before the test condition
- break;
- }
+ break;
+ }
- case FFI_TYPE_UINT16:
- case FFI_TYPE_SINT16:
- case FFI_TYPE_INT:
- case FFI_TYPE_UINT32:
- case FFI_TYPE_SINT32:
- case FFI_TYPE_POINTER:
- case FFI_TYPE_UINT64:
- case FFI_TYPE_SINT64:
- gprsUsed++;
+ case FFI_TYPE_UINT16:
+ case FFI_TYPE_SINT16:
+ case FFI_TYPE_INT:
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_POINTER:
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+ gprsUsed++;
- if (gprsUsed > 8)
- needsPtr = true;
+ if (gprsUsed > 8)
+ needsPtr = true;
- break;
+ break;
- case FFI_TYPE_STRUCT:
- needsPtr = ffi64_stret_needs_ptr(
- inType->elements[i], &gprsUsed, &fprsUsed);
+ case FFI_TYPE_STRUCT:
+ needsPtr = ffi64_stret_needs_ptr(
+ inType->elements[i], &gprsUsed, &fprsUsed);
- break;
+ break;
- default:
- FFI_ASSERT(0);
- break;
- }
- }
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+ }
- if (ioGPRCount)
- *ioGPRCount = gprsUsed;
+ if (ioGPRCount)
+ *ioGPRCount = gprsUsed;
- if (ioFPRCount)
- *ioFPRCount = fprsUsed;
+ if (ioFPRCount)
+ *ioFPRCount = fprsUsed;
- return needsPtr;
+ return needsPtr;
}
-/* ffi64_data_size
+/* ffi64_data_size
- Calculate the size in bytes of an ffi type.
+ Calculate the size in bytes of an ffi type.
*/
unsigned int
ffi64_data_size(
- const ffi_type* inType)
+ const ffi_type* inType)
{
- unsigned int size = 0;
-
- switch (inType->type)
- {
- case FFI_TYPE_UINT8:
- case FFI_TYPE_SINT8:
- size = 1;
- break;
-
- case FFI_TYPE_UINT16:
- case FFI_TYPE_SINT16:
- size = 2;
- break;
-
- case FFI_TYPE_INT:
- case FFI_TYPE_UINT32:
- case FFI_TYPE_SINT32:
- case FFI_TYPE_FLOAT:
- size = 4;
- break;
-
- case FFI_TYPE_POINTER:
- case FFI_TYPE_UINT64:
- case FFI_TYPE_SINT64:
- case FFI_TYPE_DOUBLE:
- size = 8;
- break;
-
- case FFI_TYPE_LONGDOUBLE:
- size = 16;
- break;
-
- case FFI_TYPE_STRUCT:
- ffi64_struct_to_reg_form(
- inType, NULL, NULL, NULL, NULL, &size, NULL, NULL);
- break;
-
- case FFI_TYPE_VOID:
- break;
-
- default:
- FFI_ASSERT(0);
- break;
- }
-
- return size;
+ unsigned int size = 0;
+
+ switch (inType->type)
+ {
+ case FFI_TYPE_UINT8:
+ case FFI_TYPE_SINT8:
+ size = 1;
+ break;
+
+ case FFI_TYPE_UINT16:
+ case FFI_TYPE_SINT16:
+ size = 2;
+ break;
+
+ case FFI_TYPE_INT:
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_FLOAT:
+ size = 4;
+ break;
+
+ case FFI_TYPE_POINTER:
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_DOUBLE:
+ size = 8;
+ break;
+
+ case FFI_TYPE_LONGDOUBLE:
+ size = 16;
+ break;
+
+ case FFI_TYPE_STRUCT:
+ ffi64_struct_to_reg_form(
+ inType, NULL, NULL, NULL, NULL, &size, NULL, NULL);
+ break;
+
+ case FFI_TYPE_VOID:
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+
+ return size;
}
-#endif /* defined(__ppc64__) */
-#endif /* __ppc__ || __ppc64__ */
+#endif /* defined(__ppc64__) */
+#endif /* __ppc__ || __ppc64__ */