Commit cd4241aa by Alan Modra Committed by Alan Modra

ffi.c: Formatting.

	* src/powerpc/ffi.c: Formatting.
	(ffi_prep_args_SYSV): Avoid possible aliasing problems by using unions.
	(ffi_prep_args64): Likewise.

From-SVN: r107963
parent 022123e6
2005-12-03 Alan Modra <amodra@bigpond.net.au>
* src/powerpc/ffi.c: Formatting.
(ffi_prep_args_SYSV): Avoid possible aliasing problems by using unions.
(ffi_prep_args64): Likewise.
2005-09-30 Geoffrey Keating <geoffk@apple.com> 2005-09-30 Geoffrey Keating <geoffk@apple.com>
* testsuite/lib/libffi-dg.exp (libffi_target_compile): For * testsuite/lib/libffi-dg.exp (libffi_target_compile): For
......
...@@ -30,8 +30,8 @@ ...@@ -30,8 +30,8 @@
#include <stdio.h> #include <stdio.h>
extern void ffi_closure_SYSV(void); extern void ffi_closure_SYSV (void);
extern void FFI_HIDDEN ffi_closure_LINUX64(void); extern void FFI_HIDDEN ffi_closure_LINUX64 (void);
enum { enum {
/* The assembly depends on these exact flags. */ /* The assembly depends on these exact flags. */
...@@ -81,78 +81,104 @@ enum { ASM_NEEDS_REGISTERS = 4 }; ...@@ -81,78 +81,104 @@ enum { ASM_NEEDS_REGISTERS = 4 };
*/ */
/*@-exportheader@*/ /*@-exportheader@*/
void ffi_prep_args_SYSV(extended_cif *ecif, unsigned *const stack) void
ffi_prep_args_SYSV (extended_cif *ecif, unsigned *const stack)
/*@=exportheader@*/ /*@=exportheader@*/
{ {
const unsigned bytes = ecif->cif->bytes; const unsigned bytes = ecif->cif->bytes;
const unsigned flags = ecif->cif->flags; const unsigned flags = ecif->cif->flags;
typedef union {
char *c;
unsigned *u;
long long *ll;
float *f;
double *d;
} valp;
/* 'stacktop' points at the previous backchain pointer. */ /* 'stacktop' points at the previous backchain pointer. */
unsigned *const stacktop = stack + (bytes / sizeof(unsigned)); valp stacktop;
/* 'gpr_base' points at the space for gpr3, and grows upwards as /* 'gpr_base' points at the space for gpr3, and grows upwards as
we use GPR registers. */ we use GPR registers. */
unsigned *gpr_base = stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS; valp gpr_base;
int intarg_count = 0; int intarg_count;
/* 'fpr_base' points at the space for fpr1, and grows upwards as /* 'fpr_base' points at the space for fpr1, and grows upwards as
we use FPR registers. */ we use FPR registers. */
double *fpr_base = (double *)gpr_base - NUM_FPR_ARG_REGISTERS; valp fpr_base;
int fparg_count = 0; int fparg_count;
/* 'copy_space' grows down as we put structures in it. It should /* 'copy_space' grows down as we put structures in it. It should
stay 16-byte aligned. */ stay 16-byte aligned. */
char *copy_space = ((flags & FLAG_FP_ARGUMENTS) valp copy_space;
? (char *)fpr_base
: (char *)gpr_base);
/* 'next_arg' grows up as we put parameters in it. */ /* 'next_arg' grows up as we put parameters in it. */
unsigned *next_arg = stack + 2; valp next_arg;
int i; int i;
ffi_type **ptr; ffi_type **ptr;
double double_tmp; double double_tmp;
void **p_argv; union {
void **v;
char **c;
signed char **sc;
unsigned char **uc;
signed short **ss;
unsigned short **us;
unsigned int **ui;
long long **ll;
float **f;
double **d;
} p_argv;
size_t struct_copy_size; size_t struct_copy_size;
unsigned gprvalue; unsigned gprvalue;
stacktop.c = (char *) stack + bytes;
gpr_base.u = stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS;
intarg_count = 0;
fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS;
fparg_count = 0;
copy_space.c = ((flags & FLAG_FP_ARGUMENTS) ? fpr_base.c : gpr_base.c);
next_arg.u = stack + 2;
/* Check that everything starts aligned properly. */ /* Check that everything starts aligned properly. */
FFI_ASSERT(((unsigned)(char *)stack & 0xF) == 0); FFI_ASSERT (((unsigned) (char *) stack & 0xF) == 0);
FFI_ASSERT(((unsigned)(char *)copy_space & 0xF) == 0); FFI_ASSERT (((unsigned) copy_space.c & 0xF) == 0);
FFI_ASSERT(((unsigned)(char *)stacktop & 0xF) == 0); FFI_ASSERT (((unsigned) stacktop.c & 0xF) == 0);
FFI_ASSERT((bytes & 0xF) == 0); FFI_ASSERT ((bytes & 0xF) == 0);
FFI_ASSERT(copy_space >= (char *)next_arg); FFI_ASSERT (copy_space.c >= next_arg.c);
/* Deal with return values that are actually pass-by-reference. */ /* Deal with return values that are actually pass-by-reference. */
if (flags & FLAG_RETVAL_REFERENCE) if (flags & FLAG_RETVAL_REFERENCE)
{ {
*gpr_base++ = (unsigned long)(char *)ecif->rvalue; *gpr_base.u++ = (unsigned long) (char *) ecif->rvalue;
intarg_count++; intarg_count++;
} }
/* Now for the arguments. */ /* Now for the arguments. */
p_argv = ecif->avalue; p_argv.v = ecif->avalue;
for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs; for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
i > 0; i > 0;
i--, ptr++, p_argv++) i--, ptr++, p_argv.v++)
{ {
switch ((*ptr)->type) switch ((*ptr)->type)
{ {
case FFI_TYPE_FLOAT: case FFI_TYPE_FLOAT:
double_tmp = *(float *)*p_argv; double_tmp = **p_argv.f;
if (fparg_count >= NUM_FPR_ARG_REGISTERS) if (fparg_count >= NUM_FPR_ARG_REGISTERS)
{ {
*(float *)next_arg = (float)double_tmp; *next_arg.f = (float) double_tmp;
next_arg += 1; next_arg.u += 1;
} }
else else
*fpr_base++ = double_tmp; *fpr_base.d++ = double_tmp;
fparg_count++; fparg_count++;
FFI_ASSERT(flags & FLAG_FP_ARGUMENTS); FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
break; break;
case FFI_TYPE_DOUBLE: case FFI_TYPE_DOUBLE:
double_tmp = *(double *)*p_argv; double_tmp = **p_argv.d;
if (fparg_count >= NUM_FPR_ARG_REGISTERS) if (fparg_count >= NUM_FPR_ARG_REGISTERS)
{ {
...@@ -160,15 +186,15 @@ void ffi_prep_args_SYSV(extended_cif *ecif, unsigned *const stack) ...@@ -160,15 +186,15 @@ void ffi_prep_args_SYSV(extended_cif *ecif, unsigned *const stack)
&& intarg_count % 2 != 0) && intarg_count % 2 != 0)
{ {
intarg_count++; intarg_count++;
next_arg++; next_arg.u++;
} }
*(double *)next_arg = double_tmp; *next_arg.d = double_tmp;
next_arg += 2; next_arg.u += 2;
} }
else else
*fpr_base++ = double_tmp; *fpr_base.d++ = double_tmp;
fparg_count++; fparg_count++;
FFI_ASSERT(flags & FLAG_FP_ARGUMENTS); FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
break; break;
case FFI_TYPE_UINT64: case FFI_TYPE_UINT64:
...@@ -177,13 +203,13 @@ void ffi_prep_args_SYSV(extended_cif *ecif, unsigned *const stack) ...@@ -177,13 +203,13 @@ void ffi_prep_args_SYSV(extended_cif *ecif, unsigned *const stack)
intarg_count++; intarg_count++;
if (intarg_count >= NUM_GPR_ARG_REGISTERS) if (intarg_count >= NUM_GPR_ARG_REGISTERS)
{ {
if (intarg_count%2 != 0) if (intarg_count % 2 != 0)
{ {
intarg_count++; intarg_count++;
next_arg++; next_arg.u++;
} }
*(long long *)next_arg = *(long long *)*p_argv; *next_arg.ll = **p_argv.ll;
next_arg += 2; next_arg.u += 2;
} }
else else
{ {
...@@ -194,13 +220,12 @@ void ffi_prep_args_SYSV(extended_cif *ecif, unsigned *const stack) ...@@ -194,13 +220,12 @@ void ffi_prep_args_SYSV(extended_cif *ecif, unsigned *const stack)
* not correct starting register of pair then skip * not correct starting register of pair then skip
* until the proper starting register * until the proper starting register
*/ */
if (intarg_count%2 != 0) if (intarg_count % 2 != 0)
{ {
intarg_count ++; intarg_count ++;
gpr_base++; gpr_base.u++;
} }
*(long long *)gpr_base = *(long long *)*p_argv; *gpr_base.ll++ = **p_argv.ll;
gpr_base += 2;
} }
intarg_count += 2; intarg_count += 2;
break; break;
...@@ -210,49 +235,50 @@ void ffi_prep_args_SYSV(extended_cif *ecif, unsigned *const stack) ...@@ -210,49 +235,50 @@ void ffi_prep_args_SYSV(extended_cif *ecif, unsigned *const stack)
case FFI_TYPE_LONGDOUBLE: case FFI_TYPE_LONGDOUBLE:
#endif #endif
struct_copy_size = ((*ptr)->size + 15) & ~0xF; struct_copy_size = ((*ptr)->size + 15) & ~0xF;
copy_space -= struct_copy_size; copy_space.c -= struct_copy_size;
memcpy(copy_space, (char *)*p_argv, (*ptr)->size); memcpy (copy_space.c, *p_argv.c, (*ptr)->size);
gprvalue = (unsigned long)copy_space; gprvalue = (unsigned long) copy_space.c;
FFI_ASSERT(copy_space > (char *)next_arg); FFI_ASSERT (copy_space.c > next_arg.c);
FFI_ASSERT(flags & FLAG_ARG_NEEDS_COPY); FFI_ASSERT (flags & FLAG_ARG_NEEDS_COPY);
goto putgpr; goto putgpr;
case FFI_TYPE_UINT8: case FFI_TYPE_UINT8:
gprvalue = *(unsigned char *)*p_argv; gprvalue = **p_argv.uc;
goto putgpr; goto putgpr;
case FFI_TYPE_SINT8: case FFI_TYPE_SINT8:
gprvalue = *(signed char *)*p_argv; gprvalue = **p_argv.sc;
goto putgpr; goto putgpr;
case FFI_TYPE_UINT16: case FFI_TYPE_UINT16:
gprvalue = *(unsigned short *)*p_argv; gprvalue = **p_argv.us;
goto putgpr; goto putgpr;
case FFI_TYPE_SINT16: case FFI_TYPE_SINT16:
gprvalue = *(signed short *)*p_argv; gprvalue = **p_argv.ss;
goto putgpr; goto putgpr;
case FFI_TYPE_INT: case FFI_TYPE_INT:
case FFI_TYPE_UINT32: case FFI_TYPE_UINT32:
case FFI_TYPE_SINT32: case FFI_TYPE_SINT32:
case FFI_TYPE_POINTER: case FFI_TYPE_POINTER:
gprvalue = *(unsigned *)*p_argv; gprvalue = **p_argv.ui;
putgpr: putgpr:
if (intarg_count >= NUM_GPR_ARG_REGISTERS) if (intarg_count >= NUM_GPR_ARG_REGISTERS)
*next_arg++ = gprvalue; *next_arg.u++ = gprvalue;
else else
*gpr_base++ = gprvalue; *gpr_base.u++ = gprvalue;
intarg_count++; intarg_count++;
break; break;
} }
} }
/* Check that we didn't overrun the stack... */ /* Check that we didn't overrun the stack... */
FFI_ASSERT(copy_space >= (char *)next_arg); FFI_ASSERT (copy_space.c >= next_arg.c);
FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS); FFI_ASSERT (gpr_base.u <= stacktop.u - ASM_NEEDS_REGISTERS);
FFI_ASSERT((unsigned *)fpr_base FFI_ASSERT (fpr_base.u
<= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS); <= stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4); FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
} }
/* About the LINUX64 ABI. */ /* About the LINUX64 ABI. */
...@@ -297,159 +323,187 @@ enum { ASM_NEEDS_REGISTERS64 = 4 }; ...@@ -297,159 +323,187 @@ enum { ASM_NEEDS_REGISTERS64 = 4 };
*/ */
/*@-exportheader@*/ /*@-exportheader@*/
void FFI_HIDDEN ffi_prep_args64(extended_cif *ecif, unsigned long *const stack) void FFI_HIDDEN
ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack)
/*@=exportheader@*/ /*@=exportheader@*/
{ {
const unsigned long bytes = ecif->cif->bytes; const unsigned long bytes = ecif->cif->bytes;
const unsigned long flags = ecif->cif->flags; const unsigned long flags = ecif->cif->flags;
typedef union {
char *c;
unsigned long *ul;
float *f;
double *d;
} valp;
/* 'stacktop' points at the previous backchain pointer. */ /* 'stacktop' points at the previous backchain pointer. */
unsigned long *const stacktop = stack + (bytes / sizeof(unsigned long)); valp stacktop;
/* 'next_arg' points at the space for gpr3, and grows upwards as /* 'next_arg' points at the space for gpr3, and grows upwards as
we use GPR registers, then continues at rest. */ we use GPR registers, then continues at rest. */
unsigned long *const gpr_base = stacktop - ASM_NEEDS_REGISTERS64 valp gpr_base;
- NUM_GPR_ARG_REGISTERS64; valp gpr_end;
unsigned long *const gpr_end = gpr_base + NUM_GPR_ARG_REGISTERS64; valp rest;
unsigned long *const rest = stack + 6 + NUM_GPR_ARG_REGISTERS64; valp next_arg;
unsigned long *next_arg = gpr_base;
/* 'fpr_base' points at the space for fpr3, and grows upwards as /* 'fpr_base' points at the space for fpr3, and grows upwards as
we use FPR registers. */ we use FPR registers. */
double *fpr_base = (double *)gpr_base - NUM_FPR_ARG_REGISTERS64; valp fpr_base;
int fparg_count = 0; int fparg_count;
int i, words; int i, words;
ffi_type **ptr; ffi_type **ptr;
double double_tmp; double double_tmp;
void **p_argv; union {
void **v;
char **c;
signed char **sc;
unsigned char **uc;
signed short **ss;
unsigned short **us;
signed int **si;
unsigned int **ui;
unsigned long **ul;
float **f;
double **d;
} p_argv;
unsigned long gprvalue; unsigned long gprvalue;
stacktop.c = (char *) stack + bytes;
gpr_base.ul = stacktop.ul - ASM_NEEDS_REGISTERS64 - NUM_GPR_ARG_REGISTERS64;
gpr_end.ul = gpr_base.ul + NUM_GPR_ARG_REGISTERS64;
rest.ul = stack + 6 + NUM_GPR_ARG_REGISTERS64;
fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS64;
fparg_count = 0;
next_arg.ul = gpr_base.ul;
/* Check that everything starts aligned properly. */ /* Check that everything starts aligned properly. */
FFI_ASSERT(((unsigned long)(char *)stack & 0xF) == 0); FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0);
FFI_ASSERT(((unsigned long)(char *)stacktop & 0xF) == 0); FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0);
FFI_ASSERT((bytes & 0xF) == 0); FFI_ASSERT ((bytes & 0xF) == 0);
/* Deal with return values that are actually pass-by-reference. */ /* Deal with return values that are actually pass-by-reference. */
if (flags & FLAG_RETVAL_REFERENCE) if (flags & FLAG_RETVAL_REFERENCE)
*next_arg++ = (unsigned long)(char *)ecif->rvalue; *next_arg.ul++ = (unsigned long) (char *) ecif->rvalue;
/* Now for the arguments. */ /* Now for the arguments. */
p_argv = ecif->avalue; p_argv.v = ecif->avalue;
for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs; for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
i > 0; i > 0;
i--, ptr++, p_argv++) i--, ptr++, p_argv.v++)
{ {
switch ((*ptr)->type) switch ((*ptr)->type)
{ {
case FFI_TYPE_FLOAT: case FFI_TYPE_FLOAT:
double_tmp = *(float *)*p_argv; double_tmp = **p_argv.f;
*(float *)next_arg = (float)double_tmp; *next_arg.f = (float) double_tmp;
if (++next_arg == gpr_end) if (++next_arg.ul == gpr_end.ul)
next_arg = rest; next_arg.ul = rest.ul;
if (fparg_count < NUM_FPR_ARG_REGISTERS64) if (fparg_count < NUM_FPR_ARG_REGISTERS64)
*fpr_base++ = double_tmp; *fpr_base.d++ = double_tmp;
fparg_count++; fparg_count++;
FFI_ASSERT(flags & FLAG_FP_ARGUMENTS); FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
break; break;
case FFI_TYPE_DOUBLE: case FFI_TYPE_DOUBLE:
double_tmp = *(double *)*p_argv; double_tmp = **p_argv.d;
*(double *)next_arg = double_tmp; *next_arg.d = double_tmp;
if (++next_arg == gpr_end) if (++next_arg.ul == gpr_end.ul)
next_arg = rest; next_arg.ul = rest.ul;
if (fparg_count < NUM_FPR_ARG_REGISTERS64) if (fparg_count < NUM_FPR_ARG_REGISTERS64)
*fpr_base++ = double_tmp; *fpr_base.d++ = double_tmp;
fparg_count++; fparg_count++;
FFI_ASSERT(flags & FLAG_FP_ARGUMENTS); FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
break; break;
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
case FFI_TYPE_LONGDOUBLE: case FFI_TYPE_LONGDOUBLE:
double_tmp = ((double *) *p_argv)[0]; double_tmp = (*p_argv.d)[0];
*(double *) next_arg = double_tmp; *next_arg.d = double_tmp;
if (++next_arg == gpr_end) if (++next_arg.ul == gpr_end.ul)
next_arg = rest; next_arg.ul = rest.ul;
if (fparg_count < NUM_FPR_ARG_REGISTERS64) if (fparg_count < NUM_FPR_ARG_REGISTERS64)
*fpr_base++ = double_tmp; *fpr_base.d++ = double_tmp;
fparg_count++; fparg_count++;
double_tmp = ((double *) *p_argv)[1]; double_tmp = (*p_argv.d)[1];
*(double *) next_arg = double_tmp; *next_arg.d = double_tmp;
if (++next_arg == gpr_end) if (++next_arg.ul == gpr_end.ul)
next_arg = rest; next_arg.ul = rest.ul;
if (fparg_count < NUM_FPR_ARG_REGISTERS64) if (fparg_count < NUM_FPR_ARG_REGISTERS64)
*fpr_base++ = double_tmp; *fpr_base.d++ = double_tmp;
fparg_count++; fparg_count++;
FFI_ASSERT(flags & FLAG_FP_ARGUMENTS); FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
break; break;
#endif #endif
case FFI_TYPE_STRUCT: case FFI_TYPE_STRUCT:
words = ((*ptr)->size + 7) / 8; words = ((*ptr)->size + 7) / 8;
if (next_arg >= gpr_base && next_arg + words > gpr_end) if (next_arg.ul >= gpr_base.ul && next_arg.ul + words > gpr_end.ul)
{ {
size_t first = (char *) gpr_end - (char *) next_arg; size_t first = gpr_end.c - next_arg.c;
memcpy((char *) next_arg, (char *) *p_argv, first); memcpy (next_arg.c, *p_argv.c, first);
memcpy((char *) rest, (char *) *p_argv + first, memcpy (rest.c, *p_argv.c + first, (*ptr)->size - first);
(*ptr)->size - first); next_arg.c = rest.c + words * 8 - first;
next_arg = (unsigned long *) ((char *) rest + words * 8 - first);
} }
else else
{ {
char *where = (char *) next_arg; char *where = next_arg.c;
/* Structures with size less than eight bytes are passed /* Structures with size less than eight bytes are passed
left-padded. */ left-padded. */
if ((*ptr)->size < 8) if ((*ptr)->size < 8)
where += 8 - (*ptr)->size; where += 8 - (*ptr)->size;
memcpy (where, (char *) *p_argv, (*ptr)->size); memcpy (where, *p_argv.c, (*ptr)->size);
next_arg += words; next_arg.ul += words;
if (next_arg == gpr_end) if (next_arg.ul == gpr_end.ul)
next_arg = rest; next_arg.ul = rest.ul;
} }
break; break;
case FFI_TYPE_UINT8: case FFI_TYPE_UINT8:
gprvalue = *(unsigned char *)*p_argv; gprvalue = **p_argv.uc;
goto putgpr; goto putgpr;
case FFI_TYPE_SINT8: case FFI_TYPE_SINT8:
gprvalue = *(signed char *)*p_argv; gprvalue = **p_argv.sc;
goto putgpr; goto putgpr;
case FFI_TYPE_UINT16: case FFI_TYPE_UINT16:
gprvalue = *(unsigned short *)*p_argv; gprvalue = **p_argv.us;
goto putgpr; goto putgpr;
case FFI_TYPE_SINT16: case FFI_TYPE_SINT16:
gprvalue = *(signed short *)*p_argv; gprvalue = **p_argv.ss;
goto putgpr; goto putgpr;
case FFI_TYPE_UINT32: case FFI_TYPE_UINT32:
gprvalue = *(unsigned int *)*p_argv; gprvalue = **p_argv.ui;
goto putgpr; goto putgpr;
case FFI_TYPE_INT: case FFI_TYPE_INT:
case FFI_TYPE_SINT32: case FFI_TYPE_SINT32:
gprvalue = *(signed int *)*p_argv; gprvalue = **p_argv.si;
goto putgpr; goto putgpr;
case FFI_TYPE_UINT64: case FFI_TYPE_UINT64:
case FFI_TYPE_SINT64: case FFI_TYPE_SINT64:
case FFI_TYPE_POINTER: case FFI_TYPE_POINTER:
gprvalue = *(unsigned long *)*p_argv; gprvalue = **p_argv.ul;
putgpr: putgpr:
*next_arg++ = gprvalue; *next_arg.ul++ = gprvalue;
if (next_arg == gpr_end) if (next_arg.ul == gpr_end.ul)
next_arg = rest; next_arg.ul = rest.ul;
break; break;
} }
} }
FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS
|| (next_arg >= gpr_base && next_arg <= gpr_base + 4)); || (next_arg.ul >= gpr_base.ul
&& next_arg.ul <= gpr_base.ul + 4));
} }
/* Perform machine dependent cif processing */ /* Perform machine dependent cif processing */
ffi_status ffi_prep_cif_machdep(ffi_cif *cif) ffi_status
ffi_prep_cif_machdep (ffi_cif *cif)
{ {
/* All this is for the SYSV and LINUX64 ABI. */ /* All this is for the SYSV and LINUX64 ABI. */
int i; int i;
...@@ -467,10 +521,10 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) ...@@ -467,10 +521,10 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
Redo the calculation for SYSV. */ Redo the calculation for SYSV. */
/* Space for the frame pointer, callee's LR, and the asm's temp regs. */ /* Space for the frame pointer, callee's LR, and the asm's temp regs. */
bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof(int); bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof (int);
/* Space for the GPR registers. */ /* Space for the GPR registers. */
bytes += NUM_GPR_ARG_REGISTERS * sizeof(int); bytes += NUM_GPR_ARG_REGISTERS * sizeof (int);
} }
else else
{ {
...@@ -478,10 +532,10 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) ...@@ -478,10 +532,10 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
/* Space for backchain, CR, LR, cc/ld doubleword, TOC and the asm's temp /* Space for backchain, CR, LR, cc/ld doubleword, TOC and the asm's temp
regs. */ regs. */
bytes = (6 + ASM_NEEDS_REGISTERS64) * sizeof(long); bytes = (6 + ASM_NEEDS_REGISTERS64) * sizeof (long);
/* Space for the mandatory parm save area and general registers. */ /* Space for the mandatory parm save area and general registers. */
bytes += 2 * NUM_GPR_ARG_REGISTERS64 * sizeof(long); bytes += 2 * NUM_GPR_ARG_REGISTERS64 * sizeof (long);
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
if (type == FFI_TYPE_LONGDOUBLE) if (type == FFI_TYPE_LONGDOUBLE)
...@@ -523,20 +577,23 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) ...@@ -523,20 +577,23 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
in memory. */ in memory. */
/* Treat structs with size <= 8 bytes. */ /* Treat structs with size <= 8 bytes. */
if (size <= 8) { if (size <= 8)
{
flags |= FLAG_RETURNS_SMST; flags |= FLAG_RETURNS_SMST;
/* These structs are returned in r3. We pack the type and the /* These structs are returned in r3. We pack the type and the
precalculated shift value (needed in the sysv.S) into flags. precalculated shift value (needed in the sysv.S) into flags.
The same applies for the structs returned in r3/r4. */ The same applies for the structs returned in r3/r4. */
if (size <= 4) { if (size <= 4)
flags |= 1 << (31 - FFI_SYSV_TYPE_SMALL_STRUCT - 1 ) {
| (8 * (4 - size) << 4); flags |= 1 << (31 - FFI_SYSV_TYPE_SMALL_STRUCT - 1);
flags |= 8 * (4 - size) << 4;
break; break;
} }
/* These structs are returned in r3 and r4. See above. */ /* These structs are returned in r3 and r4. See above. */
if (size <= 8) { if (size <= 8)
flags |= 1 << (31 - FFI_SYSV_TYPE_SMALL_STRUCT - 2 ) {
| (8 * (8 - size) << 4); flags |= 1 << (31 - FFI_SYSV_TYPE_SMALL_STRUCT - 2);
flags |= 8 * (8 - size) << 4;
break; break;
} }
} }
...@@ -600,7 +657,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) ...@@ -600,7 +657,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
(r7,r8), (r9,r10). (r7,r8), (r9,r10).
*/ */
if (intarg_count == NUM_GPR_ARG_REGISTERS-1 if (intarg_count == NUM_GPR_ARG_REGISTERS-1
|| intarg_count%2 != 0) || intarg_count % 2 != 0)
intarg_count++; intarg_count++;
intarg_count += 2; intarg_count += 2;
break; break;
...@@ -663,23 +720,23 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) ...@@ -663,23 +720,23 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
{ {
/* Space for the FPR registers, if needed. */ /* Space for the FPR registers, if needed. */
if (fparg_count != 0) if (fparg_count != 0)
bytes += NUM_FPR_ARG_REGISTERS * sizeof(double); bytes += NUM_FPR_ARG_REGISTERS * sizeof (double);
/* Stack space. */ /* Stack space. */
if (intarg_count > NUM_GPR_ARG_REGISTERS) if (intarg_count > NUM_GPR_ARG_REGISTERS)
bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof(int); bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof (int);
if (fparg_count > NUM_FPR_ARG_REGISTERS) if (fparg_count > NUM_FPR_ARG_REGISTERS)
bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof(double); bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof (double);
} }
else else
{ {
/* Space for the FPR registers, if needed. */ /* Space for the FPR registers, if needed. */
if (fparg_count != 0) if (fparg_count != 0)
bytes += NUM_FPR_ARG_REGISTERS64 * sizeof(double); bytes += NUM_FPR_ARG_REGISTERS64 * sizeof (double);
/* Stack space. */ /* Stack space. */
if (intarg_count > NUM_GPR_ARG_REGISTERS64) if (intarg_count > NUM_GPR_ARG_REGISTERS64)
bytes += (intarg_count - NUM_GPR_ARG_REGISTERS64) * sizeof(long); bytes += (intarg_count - NUM_GPR_ARG_REGISTERS64) * sizeof (long);
} }
/* The stack space allocated needs to be a multiple of 16 bytes. */ /* The stack space allocated needs to be a multiple of 16 bytes. */
...@@ -707,7 +764,8 @@ extern void FFI_HIDDEN ffi_call_LINUX64(/*@out@*/ extended_cif *, ...@@ -707,7 +764,8 @@ extern void FFI_HIDDEN ffi_call_LINUX64(/*@out@*/ extended_cif *,
/*@=declundef@*/ /*@=declundef@*/
/*@=exportheader@*/ /*@=exportheader@*/
void ffi_call(/*@dependent@*/ ffi_cif *cif, void
ffi_call(/*@dependent@*/ ffi_cif *cif,
void (*fn)(), void (*fn)(),
/*@out@*/ void *rvalue, /*@out@*/ void *rvalue,
/*@dependent@*/ void **avalue) /*@dependent@*/ void **avalue)
...@@ -720,8 +778,7 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif, ...@@ -720,8 +778,7 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
/* If the return value is a struct and we don't have a return */ /* If the return value is a struct and we don't have a return */
/* value address then we need to make one */ /* value address then we need to make one */
if ((rvalue == NULL) && if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT))
(cif->rtype->type == FFI_TYPE_STRUCT))
{ {
/*@-sysunrecog@*/ /*@-sysunrecog@*/
ecif.rvalue = alloca(cif->rtype->size); ecif.rvalue = alloca(cif->rtype->size);
...@@ -737,47 +794,47 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif, ...@@ -737,47 +794,47 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
case FFI_SYSV: case FFI_SYSV:
case FFI_GCC_SYSV: case FFI_GCC_SYSV:
/*@-usedef@*/ /*@-usedef@*/
ffi_call_SYSV(&ecif, -cif->bytes, ffi_call_SYSV (&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn);
cif->flags, ecif.rvalue, fn);
/*@=usedef@*/ /*@=usedef@*/
break; break;
#else #else
case FFI_LINUX64: case FFI_LINUX64:
/*@-usedef@*/ /*@-usedef@*/
ffi_call_LINUX64(&ecif, -(long) cif->bytes, ffi_call_LINUX64 (&ecif, -(long) cif->bytes, cif->flags, ecif.rvalue, fn);
cif->flags, ecif.rvalue, fn);
/*@=usedef@*/ /*@=usedef@*/
break; break;
#endif #endif
default: default:
FFI_ASSERT(0); FFI_ASSERT (0);
break; break;
} }
} }
#ifndef POWERPC64 #ifndef POWERPC64
static void flush_icache(char *, int);
#define MIN_CACHE_LINE_SIZE 8 #define MIN_CACHE_LINE_SIZE 8
static void flush_icache(char * addr1, int size) static void
flush_icache (char *addr1, int size)
{ {
int i; int i;
char * addr; char * addr;
for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE) { for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE)
{
addr = addr1 + i; addr = addr1 + i;
__asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;" : : "r"(addr) : "memory"); __asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;"
: : "r" (addr) : "memory");
} }
addr = addr1 + size - 1; addr = addr1 + size - 1;
__asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;" "sync;" "isync;" : : "r"(addr) : "memory"); __asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;" "sync;" "isync;"
: : "r"(addr) : "memory");
} }
#endif #endif
ffi_status ffi_status
ffi_prep_closure (ffi_closure* closure, ffi_prep_closure (ffi_closure *closure,
ffi_cif* cif, ffi_cif *cif,
void (*fun)(ffi_cif*, void*, void**, void*), void (*fun) (ffi_cif *, void *, void **, void *),
void *user_data) void *user_data)
{ {
#ifdef POWERPC64 #ifdef POWERPC64
...@@ -801,11 +858,11 @@ ffi_prep_closure (ffi_closure* closure, ...@@ -801,11 +858,11 @@ ffi_prep_closure (ffi_closure* closure,
tramp[7] = 0x816b0004; /* lwz r11,4(r11) */ tramp[7] = 0x816b0004; /* lwz r11,4(r11) */
tramp[8] = 0x7c0903a6; /* mtctr r0 */ tramp[8] = 0x7c0903a6; /* mtctr r0 */
tramp[9] = 0x4e800420; /* bctr */ tramp[9] = 0x4e800420; /* bctr */
*(void **) &tramp[2] = (void *)ffi_closure_SYSV; /* function */ *(void **) &tramp[2] = (void *) ffi_closure_SYSV; /* function */
*(void **) &tramp[3] = (void *)closure; /* context */ *(void **) &tramp[3] = (void *) closure; /* context */
/* Flush the icache. */ /* Flush the icache. */
flush_icache(&closure->tramp[0],FFI_TRAMPOLINE_SIZE); flush_icache (&closure->tramp[0],FFI_TRAMPOLINE_SIZE);
#endif #endif
closure->cif = cif; closure->cif = cif;
...@@ -821,8 +878,8 @@ typedef union ...@@ -821,8 +878,8 @@ typedef union
double d; double d;
} ffi_dblfl; } ffi_dblfl;
int ffi_closure_helper_SYSV (ffi_closure*, void*, unsigned long*, int ffi_closure_helper_SYSV (ffi_closure *, void *, unsigned long *,
ffi_dblfl*, unsigned long*); ffi_dblfl *, unsigned long *);
/* Basically the trampoline invokes ffi_closure_SYSV, and on /* Basically the trampoline invokes ffi_closure_SYSV, and on
* entry, r11 holds the address of the closure. * entry, r11 holds the address of the closure.
...@@ -833,9 +890,9 @@ int ffi_closure_helper_SYSV (ffi_closure*, void*, unsigned long*, ...@@ -833,9 +890,9 @@ int ffi_closure_helper_SYSV (ffi_closure*, void*, unsigned long*,
*/ */
int int
ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue, ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue,
unsigned long * pgr, ffi_dblfl * pfr, unsigned long *pgr, ffi_dblfl *pfr,
unsigned long * pst) unsigned long *pst)
{ {
/* rvalue is the pointer to space for return value in closure assembly */ /* 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_SYSV */ /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */
...@@ -852,7 +909,7 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue, ...@@ -852,7 +909,7 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
unsigned size; unsigned size;
cif = closure->cif; cif = closure->cif;
avalue = alloca(cif->nargs * sizeof(void *)); avalue = alloca (cif->nargs * sizeof (void *));
size = cif->rtype->size; size = cif->rtype->size;
nf = 0; nf = 0;
...@@ -865,7 +922,8 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue, ...@@ -865,7 +922,8 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
if (cif->rtype->type == FFI_TYPE_STRUCT) if (cif->rtype->type == FFI_TYPE_STRUCT)
{ {
if (!((cif->abi == FFI_SYSV) && (size <= 8))) { if (!((cif->abi == FFI_SYSV) && (size <= 8)))
{
rvalue = (void *) *pgr; rvalue = (void *) *pgr;
ng++; ng++;
pgr++; pgr++;
...@@ -884,12 +942,15 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue, ...@@ -884,12 +942,15 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
case FFI_TYPE_SINT8: case FFI_TYPE_SINT8:
case FFI_TYPE_UINT8: case FFI_TYPE_UINT8:
/* there are 8 gpr registers used to pass values */ /* there are 8 gpr registers used to pass values */
if (ng < 8) { if (ng < 8)
avalue[i] = (((char *)pgr)+3); {
avalue[i] = (char *) pgr + 3;
ng++; ng++;
pgr++; pgr++;
} else { }
avalue[i] = (((char *)pst)+3); else
{
avalue[i] = (char *) pst + 3;
pst++; pst++;
} }
break; break;
...@@ -897,12 +958,15 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue, ...@@ -897,12 +958,15 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
case FFI_TYPE_SINT16: case FFI_TYPE_SINT16:
case FFI_TYPE_UINT16: case FFI_TYPE_UINT16:
/* there are 8 gpr registers used to pass values */ /* there are 8 gpr registers used to pass values */
if (ng < 8) { if (ng < 8)
avalue[i] = (((char *)pgr)+2); {
avalue[i] = (char *) pgr + 2;
ng++; ng++;
pgr++; pgr++;
} else { }
avalue[i] = (((char *)pst)+2); else
{
avalue[i] = (char *) pst + 2;
pst++; pst++;
} }
break; break;
...@@ -911,11 +975,14 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue, ...@@ -911,11 +975,14 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
case FFI_TYPE_UINT32: case FFI_TYPE_UINT32:
case FFI_TYPE_POINTER: case FFI_TYPE_POINTER:
/* there are 8 gpr registers used to pass values */ /* there are 8 gpr registers used to pass values */
if (ng < 8) { if (ng < 8)
{
avalue[i] = pgr; avalue[i] = pgr;
ng++; ng++;
pgr++; pgr++;
} else { }
else
{
avalue[i] = pst; avalue[i] = pst;
pst++; pst++;
} }
...@@ -924,11 +991,14 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue, ...@@ -924,11 +991,14 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
case FFI_TYPE_STRUCT: case FFI_TYPE_STRUCT:
/* Structs are passed by reference. The address will appear in a /* Structs are passed by reference. The address will appear in a
gpr if it is one of the first 8 arguments. */ gpr if it is one of the first 8 arguments. */
if (ng < 8) { if (ng < 8)
{
avalue[i] = (void *) *pgr; avalue[i] = (void *) *pgr;
ng++; ng++;
pgr++; pgr++;
} else { }
else
{
avalue[i] = (void *) *pst; avalue[i] = (void *) *pst;
pst++; pst++;
} }
...@@ -945,19 +1015,24 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue, ...@@ -945,19 +1015,24 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
* or pst to find the correct address for this type * or pst to find the correct address for this type
* of parameter. * of parameter.
*/ */
if (ng < 7) { if (ng < 7)
if (ng & 0x01) { {
if (ng & 0x01)
{
/* skip r4, r6, r8 as starting points */ /* skip r4, r6, r8 as starting points */
ng++; ng++;
pgr++; pgr++;
} }
avalue[i] = pgr; avalue[i] = pgr;
ng+=2; ng += 2;
pgr+=2; pgr += 2;
} else { }
if (((long)pst) & 4) pst++; else
{
if (((long) pst) & 4)
pst++;
avalue[i] = pst; avalue[i] = pst;
pst+=2; pst += 2;
} }
break; break;
...@@ -969,13 +1044,16 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue, ...@@ -969,13 +1044,16 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
/* there are 8 64bit floating point registers */ /* there are 8 64bit floating point registers */
if (nf < 8) { if (nf < 8)
{
temp = pfr->d; temp = pfr->d;
pfr->f = (float)temp; pfr->f = (float) temp;
avalue[i] = pfr; avalue[i] = pfr;
nf++; nf++;
pfr++; pfr++;
} else { }
else
{
/* FIXME? here we are really changing the values /* FIXME? here we are really changing the values
* stored in the original calling routines outgoing * stored in the original calling routines outgoing
* parameter stack. This is probably a really * parameter stack. This is probably a really
...@@ -983,7 +1061,7 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue, ...@@ -983,7 +1061,7 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
*/ */
avalue[i] = pst; avalue[i] = pst;
nf++; nf++;
pst+=1; pst += 1;
} }
break; break;
...@@ -991,20 +1069,24 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue, ...@@ -991,20 +1069,24 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
/* On the outgoing stack all values are aligned to 8 */ /* On the outgoing stack all values are aligned to 8 */
/* there are 8 64bit floating point registers */ /* there are 8 64bit floating point registers */
if (nf < 8) { if (nf < 8)
{
avalue[i] = pfr; avalue[i] = pfr;
nf++; nf++;
pfr++; pfr++;
} else { }
if (((long)pst) & 4) pst++; else
{
if (((long) pst) & 4)
pst++;
avalue[i] = pst; avalue[i] = pst;
nf++; nf++;
pst+=2; pst += 2;
} }
break; break;
default: default:
FFI_ASSERT(0); FFI_ASSERT (0);
} }
i++; i++;
...@@ -1023,8 +1105,8 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue, ...@@ -1023,8 +1105,8 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
} }
int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure*, void*, unsigned long*, int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure *, void *,
ffi_dblfl*); unsigned long *, ffi_dblfl *);
int FFI_HIDDEN int FFI_HIDDEN
ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue, ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
...@@ -1153,7 +1235,7 @@ ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue, ...@@ -1153,7 +1235,7 @@ ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
#endif #endif
default: default:
FFI_ASSERT(0); FFI_ASSERT (0);
} }
i++; i++;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment