aix.S (ffi_call_AIX): Convert to more standard register usage.
* src/powerpc/aix.S (ffi_call_AIX): Convert to more standard register usage. Call ffi_prep_args directly. Add long double return value support. * src/powerpc/ffi_darwin.c (ffi_prep_args): Double arg increment applies to FFI_TYPE_DOUBLE. Correct fpr_base increment typo. Separate FFI_TYPE_SINT32 and FFI_TYPE_UINT32 cases. (ffi_prep_cif_machdep): Only 16 byte stack alignment in 64 bit mode. (ffi_closure_helper_DARWIN): Remove nf and ng counters. Move temp into case. * src/powerpc/aix_closure.S: Maintain 16 byte stack alignment. Allocate result area between params and FPRs. From-SVN: r154892
This commit is contained in:
parent
5e87bf4a14
commit
6d518d3b72
|
@ -1,3 +1,18 @@
|
||||||
|
2009-11-30 David Edelsohn <edelsohn@gnu.org>
|
||||||
|
|
||||||
|
* src/powerpc/aix.S (ffi_call_AIX): Convert to more standard
|
||||||
|
register usage. Call ffi_prep_args directly. Add long double
|
||||||
|
return value support.
|
||||||
|
* src/powerpc/ffi_darwin.c (ffi_prep_args): Double arg increment
|
||||||
|
applies to FFI_TYPE_DOUBLE. Correct fpr_base increment typo.
|
||||||
|
Separate FFI_TYPE_SINT32 and FFI_TYPE_UINT32 cases.
|
||||||
|
(ffi_prep_cif_machdep): Only 16 byte stack alignment in 64 bit
|
||||||
|
mode.
|
||||||
|
(ffi_closure_helper_DARWIN): Remove nf and ng counters. Move temp
|
||||||
|
into case.
|
||||||
|
* src/powerpc/aix_closure.S: Maintain 16 byte stack alignment.
|
||||||
|
Allocate result area between params and FPRs.
|
||||||
|
|
||||||
2009-11-30 David Edelsohn <edelsohn@gnu.org>
|
2009-11-30 David Edelsohn <edelsohn@gnu.org>
|
||||||
|
|
||||||
PR target/35484
|
PR target/35484
|
||||||
|
|
|
@ -104,47 +104,34 @@ ffi_call_AIX:
|
||||||
.llong .ffi_call_AIX, TOC[tc0], 0
|
.llong .ffi_call_AIX, TOC[tc0], 0
|
||||||
.csect .text[PR]
|
.csect .text[PR]
|
||||||
.ffi_call_AIX:
|
.ffi_call_AIX:
|
||||||
mr r12,r8 // We only need r12 until the call, so it doesn't have to be saved...
|
|
||||||
/* Save the old stack pointer as AP. */
|
|
||||||
mr r8,r1
|
|
||||||
|
|
||||||
/* Allocate the stack space we need. */
|
|
||||||
stdux r1,r1,r4
|
|
||||||
|
|
||||||
/* Save registers we use. */
|
/* Save registers we use. */
|
||||||
mflr r9
|
mflr r0
|
||||||
|
|
||||||
std r28,-32(r8)
|
std r28,-32(r1)
|
||||||
std r29,-24(r8)
|
std r29,-24(r1)
|
||||||
std r30,-16(r8)
|
std r30,-16(r1)
|
||||||
std r31, -8(r8)
|
std r31, -8(r1)
|
||||||
|
|
||||||
std r9, 16(r8)
|
std r0, 16(r1)
|
||||||
std r2, 40(r1)
|
mr r28, r1 /* our AP. */
|
||||||
|
stdux r1, r1, r4
|
||||||
|
|
||||||
/* Save arguments over call... */
|
/* Save arguments over call... */
|
||||||
mr r31, r5 /* flags, */
|
mr r31, r5 /* flags, */
|
||||||
mr r30, r6 /* rvalue, */
|
mr r30, r6 /* rvalue, */
|
||||||
mr r29,r7 /* function address, */
|
mr r29, r7 /* function address. */
|
||||||
mr r28,r8 /* our AP. */
|
std r2, 40(r1)
|
||||||
|
|
||||||
/* Call ffi_prep_args. */
|
/* Call ffi_prep_args. */
|
||||||
mr r4, r1
|
mr r4, r1
|
||||||
li r9,0
|
bl .ffi_prep_args
|
||||||
|
|
||||||
ld r2,8(r12)
|
|
||||||
ld r12,0(r12)
|
|
||||||
mtctr r12 // r12 holds address of _ffi_prep_args
|
|
||||||
bctrl
|
|
||||||
ld r2,40(r1)
|
|
||||||
|
|
||||||
/* Now do the call. */
|
/* Now do the call. */
|
||||||
ld r12,0(r29)
|
ld r0, 0(r29)
|
||||||
|
ld r2, 8(r29)
|
||||||
/* Set up cr1 with bits 4-7 of the flags. */
|
/* Set up cr1 with bits 4-7 of the flags. */
|
||||||
mtcrf 0x40, r31
|
mtcrf 0x40, r31
|
||||||
std r2,40(r1)
|
mtctr r0
|
||||||
mtctr r12
|
|
||||||
ld r2,8(r29)
|
|
||||||
/* Load all those argument registers. */
|
/* Load all those argument registers. */
|
||||||
// We have set up a nice stack frame, just load it into registers.
|
// We have set up a nice stack frame, just load it into registers.
|
||||||
ld r3, 40+(1*8)(r1)
|
ld r3, 40+(1*8)(r1)
|
||||||
|
@ -188,25 +175,25 @@ L2:
|
||||||
bt 30, L(done_return_value)
|
bt 30, L(done_return_value)
|
||||||
bt 29, L(fp_return_value)
|
bt 29, L(fp_return_value)
|
||||||
std r3, 0(r30)
|
std r3, 0(r30)
|
||||||
bf 28,L(done_return_value)
|
|
||||||
std r4,4(r30)
|
|
||||||
|
|
||||||
/* Fall through... */
|
/* Fall through... */
|
||||||
|
|
||||||
L(done_return_value):
|
L(done_return_value):
|
||||||
/* Restore the registers we used and return. */
|
/* Restore the registers we used and return. */
|
||||||
ld r9,16(r28)
|
mr r1, r28
|
||||||
ld r31,-8(r28)
|
ld r0, 16(r28)
|
||||||
mtlr r9
|
ld r28,-32(r1)
|
||||||
ld r30,-16(r28)
|
mtlr r0
|
||||||
ld r29,-24(r28)
|
ld r29,-24(r1)
|
||||||
ld r28,-32(r28)
|
ld r30,-16(r1)
|
||||||
ld r1,0(r1)
|
ld r31,-8(r1)
|
||||||
blr
|
blr
|
||||||
|
|
||||||
L(fp_return_value):
|
L(fp_return_value):
|
||||||
bf 28,L(float_return_value)
|
bf 28,L(float_return_value)
|
||||||
stfd f1,0(r30)
|
stfd f1,0(r30)
|
||||||
|
bf 31,L(done_return_value)
|
||||||
|
stfd f2,8(r30)
|
||||||
b L(done_return_value)
|
b L(done_return_value)
|
||||||
L(float_return_value):
|
L(float_return_value):
|
||||||
stfs f1,0(r30)
|
stfs f1,0(r30)
|
||||||
|
|
|
@ -105,11 +105,12 @@ ffi_closure_ASM:
|
||||||
|
|
||||||
/* 48 Bytes (Linkage Area) */
|
/* 48 Bytes (Linkage Area) */
|
||||||
/* 64 Bytes (params) */
|
/* 64 Bytes (params) */
|
||||||
|
/* 16 Bytes (result) */
|
||||||
/* 104 Bytes (13*8 from FPR) */
|
/* 104 Bytes (13*8 from FPR) */
|
||||||
/* 32 Bytes (result) */
|
/* 8 Bytes (alignment) */
|
||||||
/* 248 Bytes */
|
/* 240 Bytes */
|
||||||
|
|
||||||
stdu r1,-248(r1) /* skip over caller save area
|
stdu r1,-240(r1) /* skip over caller save area
|
||||||
keep stack aligned to 16 */
|
keep stack aligned to 16 */
|
||||||
|
|
||||||
/* we want to build up an area for the parameters passed */
|
/* we want to build up an area for the parameters passed */
|
||||||
|
@ -117,42 +118,42 @@ ffi_closure_ASM:
|
||||||
|
|
||||||
/* we store gpr 3 to gpr 10 (aligned to 4)
|
/* we store gpr 3 to gpr 10 (aligned to 4)
|
||||||
in the parents outgoing area */
|
in the parents outgoing area */
|
||||||
std r3, (304+0*8)(r1)
|
std r3, 288+(0*8)(r1)
|
||||||
std r4, (304+1*8)(r1)
|
std r4, 288+(1*8)(r1)
|
||||||
std r5, (304+2*8)(r1)
|
std r5, 288+(2*8)(r1)
|
||||||
std r6, (304+3*8)(r1)
|
std r6, 288+(3*8)(r1)
|
||||||
std r7, (304+4*8)(r1)
|
std r7, 288+(4*8)(r1)
|
||||||
std r8, (304+5*8)(r1)
|
std r8, 288+(5*8)(r1)
|
||||||
std r9, (304+6*8)(r1)
|
std r9, 288+(6*8)(r1)
|
||||||
std r10, (304+7*8)(r1)
|
std r10, 288+(7*8)(r1)
|
||||||
|
|
||||||
/* next save fpr 1 to fpr 13 (aligned to 8) */
|
/* next save fpr 1 to fpr 13 (aligned to 8) */
|
||||||
stfd f1, (112+0*8)(r1)
|
stfd f1, 128+(0*8)(r1)
|
||||||
stfd f2, (112+1*8)(r1)
|
stfd f2, 128+(1*8)(r1)
|
||||||
stfd f3, (112+2*8)(r1)
|
stfd f3, 128+(2*8)(r1)
|
||||||
stfd f4, (112+3*8)(r1)
|
stfd f4, 128+(3*8)(r1)
|
||||||
stfd f5, (112+4*8)(r1)
|
stfd f5, 128+(4*8)(r1)
|
||||||
stfd f6, (112+5*8)(r1)
|
stfd f6, 128+(5*8)(r1)
|
||||||
stfd f7, (112+6*8)(r1)
|
stfd f7, 128+(6*8)(r1)
|
||||||
stfd f8, (112+7*8)(r1)
|
stfd f8, 128+(7*8)(r1)
|
||||||
stfd f9, (112+8*8)(r1)
|
stfd f9, 128+(8*8)(r1)
|
||||||
stfd f10, (112+9*8)(r1)
|
stfd f10, 128+(9*8)(r1)
|
||||||
stfd f11, (112+10*8)(r1)
|
stfd f11, 128+(10*8)(r1)
|
||||||
stfd f12, (112+11*8)(r1)
|
stfd f12, 128+(11*8)(r1)
|
||||||
stfd f13, (112+12*8)(r1)
|
stfd f13, 128+(12*8)(r1)
|
||||||
|
|
||||||
/* set up registers for the routine that actually does the work */
|
/* set up registers for the routine that actually does the work */
|
||||||
/* get the context pointer from the trampoline */
|
/* get the context pointer from the trampoline */
|
||||||
mr r3,r11
|
mr r3,r11
|
||||||
|
|
||||||
/* now load up the pointer to the result storage */
|
/* now load up the pointer to the result storage */
|
||||||
addi r4,r1,216
|
addi r4,r1,112
|
||||||
|
|
||||||
/* now load up the pointer to the saved gpr registers */
|
/* now load up the pointer to the saved gpr registers */
|
||||||
addi r5,r1,304
|
addi r5,r1,288
|
||||||
|
|
||||||
/* now load up the pointer to the saved fpr registers */
|
/* now load up the pointer to the saved fpr registers */
|
||||||
addi r6,r1,112
|
addi r6,r1,128
|
||||||
|
|
||||||
/* make the call */
|
/* make the call */
|
||||||
bl .ffi_closure_helper_DARWIN
|
bl .ffi_closure_helper_DARWIN
|
||||||
|
@ -164,7 +165,7 @@ ffi_closure_ASM:
|
||||||
|
|
||||||
/* look up the proper starting point in table */
|
/* look up the proper starting point in table */
|
||||||
/* by using return type as offset */
|
/* by using return type as offset */
|
||||||
addi r5,r1,216 /* get pointer to results area */
|
addi r5,r1,112 /* get pointer to results area */
|
||||||
ld r4,LC..60(2) /* get address of jump table */
|
ld r4,LC..60(2) /* get address of jump table */
|
||||||
sldi r3,r3,2 /* now multiply return type by 4 */
|
sldi r3,r3,2 /* now multiply return type by 4 */
|
||||||
lwzx r3,r4,r3 /* get the contents of that table value */
|
lwzx r3,r4,r3 /* get the contents of that table value */
|
||||||
|
@ -243,7 +244,7 @@ L..58:
|
||||||
|
|
||||||
/* case void / done */
|
/* case void / done */
|
||||||
L..44:
|
L..44:
|
||||||
addi r1,r1,248 /* restore stack pointer */
|
addi r1,r1,240 /* restore stack pointer */
|
||||||
ld r0,16(r1) /* get return address */
|
ld r0,16(r1) /* get return address */
|
||||||
mtlr r0 /* reset link register */
|
mtlr r0 /* reset link register */
|
||||||
blr
|
blr
|
||||||
|
|
|
@ -132,11 +132,7 @@ void ffi_prep_args(extended_cif *ecif, unsigned long *const stack)
|
||||||
*(double *)next_arg = double_tmp;
|
*(double *)next_arg = double_tmp;
|
||||||
else
|
else
|
||||||
*fpr_base++ = double_tmp;
|
*fpr_base++ = double_tmp;
|
||||||
#ifdef POWERPC64
|
|
||||||
next_arg++;
|
next_arg++;
|
||||||
#else
|
|
||||||
next_arg += 2;
|
|
||||||
#endif
|
|
||||||
fparg_count++;
|
fparg_count++;
|
||||||
FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
|
FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
|
||||||
break;
|
break;
|
||||||
|
@ -147,7 +143,11 @@ void ffi_prep_args(extended_cif *ecif, unsigned long *const stack)
|
||||||
*(double *)next_arg = double_tmp;
|
*(double *)next_arg = double_tmp;
|
||||||
else
|
else
|
||||||
*fpr_base++ = double_tmp;
|
*fpr_base++ = double_tmp;
|
||||||
|
#ifdef POWERPC64
|
||||||
|
next_arg++;
|
||||||
|
#else
|
||||||
next_arg += 2;
|
next_arg += 2;
|
||||||
|
#endif
|
||||||
fparg_count++;
|
fparg_count++;
|
||||||
FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
|
FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
|
||||||
break;
|
break;
|
||||||
|
@ -157,7 +157,7 @@ void ffi_prep_args(extended_cif *ecif, unsigned long *const stack)
|
||||||
case FFI_TYPE_LONGDOUBLE:
|
case FFI_TYPE_LONGDOUBLE:
|
||||||
#ifdef POWERPC64
|
#ifdef POWERPC64
|
||||||
if (fparg_count < NUM_FPR_ARG_REGISTERS)
|
if (fparg_count < NUM_FPR_ARG_REGISTERS)
|
||||||
*((long double *) fpr_base)++ = *(long double *) *p_argv;
|
*(long double *) fpr_base++ = *(long double *) *p_argv;
|
||||||
else
|
else
|
||||||
*(long double *) next_arg = *(long double *) *p_argv;
|
*(long double *) next_arg = *(long double *) *p_argv;
|
||||||
next_arg += 2;
|
next_arg += 2;
|
||||||
|
@ -238,9 +238,12 @@ void ffi_prep_args(extended_cif *ecif, unsigned long *const stack)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FFI_TYPE_INT:
|
case FFI_TYPE_INT:
|
||||||
case FFI_TYPE_UINT32:
|
|
||||||
case FFI_TYPE_SINT32:
|
case FFI_TYPE_SINT32:
|
||||||
gprvalue = *(unsigned *)*p_argv;
|
gprvalue = *(signed int *) *p_argv;
|
||||||
|
goto putgpr;
|
||||||
|
|
||||||
|
case FFI_TYPE_UINT32:
|
||||||
|
gprvalue = *(unsigned int *) *p_argv;
|
||||||
putgpr:
|
putgpr:
|
||||||
*next_arg++ = gprvalue;
|
*next_arg++ = gprvalue;
|
||||||
break;
|
break;
|
||||||
|
@ -457,11 +460,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
|
||||||
bytes += NUM_GPR_ARG_REGISTERS * sizeof(long);
|
bytes += NUM_GPR_ARG_REGISTERS * 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. */
|
||||||
#ifdef POWERPC64
|
|
||||||
bytes = (bytes + 31) & -0x1F;
|
|
||||||
#else
|
|
||||||
bytes = (bytes + 15) & ~0xF;
|
bytes = (bytes + 15) & ~0xF;
|
||||||
#endif
|
|
||||||
|
|
||||||
cif->flags = flags;
|
cif->flags = flags;
|
||||||
cif->bytes = bytes;
|
cif->bytes = bytes;
|
||||||
|
@ -690,25 +689,19 @@ int ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,
|
||||||
void ** avalue;
|
void ** avalue;
|
||||||
ffi_type ** arg_types;
|
ffi_type ** arg_types;
|
||||||
long i, avn;
|
long i, avn;
|
||||||
long nf; /* number of floating registers already used. */
|
|
||||||
long ng; /* number of general registers already used. */
|
|
||||||
ffi_cif * cif;
|
ffi_cif * cif;
|
||||||
double temp;
|
ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS;
|
||||||
unsigned size_al;
|
unsigned size_al;
|
||||||
|
|
||||||
cif = closure->cif;
|
cif = closure->cif;
|
||||||
avalue = alloca(cif->nargs * sizeof(void *));
|
avalue = alloca(cif->nargs * sizeof(void *));
|
||||||
|
|
||||||
nf = 0;
|
|
||||||
ng = 0;
|
|
||||||
|
|
||||||
/* Copy the caller's structure return value address so that the closure
|
/* Copy the caller's structure return value address so that the closure
|
||||||
returns the data directly to the caller. */
|
returns the data directly to the caller. */
|
||||||
if (cif->rtype->type == FFI_TYPE_STRUCT)
|
if (cif->rtype->type == FFI_TYPE_STRUCT)
|
||||||
{
|
{
|
||||||
rvalue = (void *) *pgr;
|
rvalue = (void *) *pgr;
|
||||||
pgr++;
|
pgr++;
|
||||||
ng++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
|
@ -727,7 +720,6 @@ int ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,
|
||||||
#else
|
#else
|
||||||
avalue[i] = (char *) pgr + 3;
|
avalue[i] = (char *) pgr + 3;
|
||||||
#endif
|
#endif
|
||||||
ng++;
|
|
||||||
pgr++;
|
pgr++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -738,7 +730,6 @@ int ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,
|
||||||
#else
|
#else
|
||||||
avalue[i] = (char *) pgr + 2;
|
avalue[i] = (char *) pgr + 2;
|
||||||
#endif
|
#endif
|
||||||
ng++;
|
|
||||||
pgr++;
|
pgr++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -750,7 +741,6 @@ int ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,
|
||||||
case FFI_TYPE_POINTER:
|
case FFI_TYPE_POINTER:
|
||||||
avalue[i] = pgr;
|
avalue[i] = pgr;
|
||||||
#endif
|
#endif
|
||||||
ng++;
|
|
||||||
pgr++;
|
pgr++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -763,7 +753,6 @@ int ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,
|
||||||
avalue[i] = (void *) pgr + 8 - size_al;
|
avalue[i] = (void *) pgr + 8 - size_al;
|
||||||
else
|
else
|
||||||
avalue[i] = (void *) pgr;
|
avalue[i] = (void *) pgr;
|
||||||
ng += (size_al + 7) / 8;
|
|
||||||
pgr += (size_al + 7) / 8;
|
pgr += (size_al + 7) / 8;
|
||||||
#else
|
#else
|
||||||
/* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
|
/* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
|
||||||
|
@ -777,7 +766,6 @@ int ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,
|
||||||
avalue[i] = (void*) pgr + 4 - size_al;
|
avalue[i] = (void*) pgr + 4 - size_al;
|
||||||
else
|
else
|
||||||
avalue[i] = (void*) pgr;
|
avalue[i] = (void*) pgr;
|
||||||
ng += (size_al + 3) / 4;
|
|
||||||
pgr += (size_al + 3) / 4;
|
pgr += (size_al + 3) / 4;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
@ -787,13 +775,11 @@ int ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,
|
||||||
#ifdef POWERPC64
|
#ifdef POWERPC64
|
||||||
case FFI_TYPE_POINTER:
|
case FFI_TYPE_POINTER:
|
||||||
avalue[i] = pgr;
|
avalue[i] = pgr;
|
||||||
ng++;
|
|
||||||
pgr++;
|
pgr++;
|
||||||
break;
|
break;
|
||||||
#else
|
#else
|
||||||
/* Long long ints are passed in two gpr's. */
|
/* Long long ints are passed in two gpr's. */
|
||||||
avalue[i] = pgr;
|
avalue[i] = pgr;
|
||||||
ng += 2;
|
|
||||||
pgr += 2;
|
pgr += 2;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
@ -801,9 +787,9 @@ int ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,
|
||||||
case FFI_TYPE_FLOAT:
|
case FFI_TYPE_FLOAT:
|
||||||
/* A float value consumes a GPR.
|
/* A float value consumes a GPR.
|
||||||
There are 13 64bit floating point registers. */
|
There are 13 64bit floating point registers. */
|
||||||
if (nf < NUM_FPR_ARG_REGISTERS)
|
if (pfr < end_pfr)
|
||||||
{
|
{
|
||||||
temp = pfr->d;
|
double temp = pfr->d;
|
||||||
pfr->f = (float) temp;
|
pfr->f = (float) temp;
|
||||||
avalue[i] = pfr;
|
avalue[i] = pfr;
|
||||||
pfr++;
|
pfr++;
|
||||||
|
@ -812,15 +798,13 @@ int ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,
|
||||||
{
|
{
|
||||||
avalue[i] = pgr;
|
avalue[i] = pgr;
|
||||||
}
|
}
|
||||||
nf++;
|
|
||||||
ng++;
|
|
||||||
pgr++;
|
pgr++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FFI_TYPE_DOUBLE:
|
case FFI_TYPE_DOUBLE:
|
||||||
/* A double value consumes two GPRs.
|
/* A double value consumes two GPRs.
|
||||||
There are 13 64bit floating point registers. */
|
There are 13 64bit floating point registers. */
|
||||||
if (nf < NUM_FPR_ARG_REGISTERS)
|
if (pfr < end_pfr)
|
||||||
{
|
{
|
||||||
avalue[i] = pfr;
|
avalue[i] = pfr;
|
||||||
pfr++;
|
pfr++;
|
||||||
|
@ -829,12 +813,9 @@ int ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,
|
||||||
{
|
{
|
||||||
avalue[i] = pgr;
|
avalue[i] = pgr;
|
||||||
}
|
}
|
||||||
nf++;
|
|
||||||
#ifdef POWERPC64
|
#ifdef POWERPC64
|
||||||
ng++;
|
|
||||||
pgr++;
|
pgr++;
|
||||||
#else
|
#else
|
||||||
ng += 2;
|
|
||||||
pgr += 2;
|
pgr += 2;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
@ -843,22 +824,25 @@ int ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,
|
||||||
|
|
||||||
case FFI_TYPE_LONGDOUBLE:
|
case FFI_TYPE_LONGDOUBLE:
|
||||||
#ifdef POWERPC64
|
#ifdef POWERPC64
|
||||||
if (nf < NUM_FPR_ARG_REGISTERS)
|
if (pfr + 1 < end_pfr)
|
||||||
{
|
{
|
||||||
avalue[i] = pfr;
|
avalue[i] = pfr;
|
||||||
pfr += 2;
|
pfr += 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (pfr < end_pfr)
|
||||||
|
{
|
||||||
|
*pgr = *(unsigned long *) pfr;
|
||||||
|
pfr++;
|
||||||
|
}
|
||||||
avalue[i] = pgr;
|
avalue[i] = pgr;
|
||||||
}
|
}
|
||||||
nf += 2;
|
|
||||||
ng += 2;
|
|
||||||
pgr += 2;
|
pgr += 2;
|
||||||
#else /* POWERPC64 */
|
#else /* POWERPC64 */
|
||||||
/* A long double value consumes four GPRs and two FPRs.
|
/* A long double value consumes four GPRs and two FPRs.
|
||||||
There are 13 64bit floating point registers. */
|
There are 13 64bit floating point registers. */
|
||||||
if (nf < NUM_FPR_ARG_REGISTERS - 1)
|
if (pfr + 1 < end_pfr)
|
||||||
{
|
{
|
||||||
avalue[i] = pfr;
|
avalue[i] = pfr;
|
||||||
pfr += 2;
|
pfr += 2;
|
||||||
|
@ -866,7 +850,7 @@ int ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,
|
||||||
/* Here we have the situation where one part of the long double
|
/* 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.
|
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]. */
|
We use a union to pass the long double to avalue[i]. */
|
||||||
else if (nf == NUM_FPR_ARG_REGISTERS - 1)
|
else if (pfr + 1 == end_pfr)
|
||||||
{
|
{
|
||||||
union ldu temp_ld;
|
union ldu temp_ld;
|
||||||
memcpy (&temp_ld.lb[0], pfr, sizeof(ldbits));
|
memcpy (&temp_ld.lb[0], pfr, sizeof(ldbits));
|
||||||
|
@ -877,8 +861,6 @@ int ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,
|
||||||
{
|
{
|
||||||
avalue[i] = pgr;
|
avalue[i] = pgr;
|
||||||
}
|
}
|
||||||
nf += 2;
|
|
||||||
ng += 4;
|
|
||||||
pgr += 4;
|
pgr += 4;
|
||||||
#endif /* POWERPC64 */
|
#endif /* POWERPC64 */
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue