mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-27 05:44:15 +08:00
[multiple changes]
2003-01-13 Andreas Tobler <a.tobler@schweiz.ch> * libffi/src/ffitest.c add closure testcases 2003-01-13 Kevin B. Hendricks <khendricks@ivey.uwo.ca> * libffi/src/powerpc/ffi.c fix alignment bug for float (4 byte aligned iso 8 byte) From-SVN: r61263
This commit is contained in:
parent
8d59b23018
commit
7b5102af84
@ -1,3 +1,13 @@
|
||||
2003-01-13 Andreas Tobler <a.tobler@schweiz.ch>
|
||||
|
||||
* libffi/src/ffitest.c
|
||||
add closure testcases
|
||||
|
||||
2003-01-13 Kevin B. Hendricks <khendricks@ivey.uwo.ca>
|
||||
|
||||
* libffi/src/powerpc/ffi.c
|
||||
fix alignment bug for float (4 byte aligned iso 8 byte)
|
||||
|
||||
2003-01-09 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* src/powerpc/ffi_darwin.c: Remove RCS version string.
|
||||
|
@ -288,10 +288,121 @@ static test_structure_9 struct9 (test_structure_9 ts)
|
||||
static void
|
||||
closure_test_fn(ffi_cif* cif,void* resp,void** args, void* userdata)
|
||||
{
|
||||
*(ffi_arg*)resp = *(int*)args[0] + (int)(*(float*)args[1]) + (int)(long)userdata;
|
||||
*(ffi_arg*)resp =
|
||||
(int)*(unsigned long long *)args[0] + (int)(*(int *)args[1]) +
|
||||
(int)(*(unsigned long long *)args[2]) + (int)*(int *)args[3] +
|
||||
(int)(*(signed short *)args[4]) +
|
||||
(int)(*(unsigned long long *)args[5]) +
|
||||
(int)*(int *)args[6] + (int)(*(int *)args[7]) +
|
||||
(int)(*(double *)args[8]) + (int)*(int *)args[9] +
|
||||
(int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
|
||||
(int)*(int *)args[12] + (int)(*(int *)args[13]) +
|
||||
(int)(*(int *)args[14]) + *(int *)args[15] + (int)(long)userdata;
|
||||
|
||||
printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
|
||||
(int)*(unsigned long long *)args[0], (int)(*(int *)args[1]),
|
||||
(int)(*(unsigned long long *)args[2]),
|
||||
(int)*(int *)args[3], (int)(*(signed short *)args[4]),
|
||||
(int)(*(unsigned long long *)args[5]),
|
||||
(int)*(int *)args[6], (int)(*(int *)args[7]),
|
||||
(int)(*(double *)args[8]), (int)*(int *)args[9],
|
||||
(int)(*(int *)args[10]), (int)(*(float *)args[11]),
|
||||
(int)*(int *)args[12], (int)(*(int *)args[13]),
|
||||
(int)(*(int *)args[14]),*(int *)args[15],
|
||||
(int)(long)userdata, *(int*)resp);
|
||||
}
|
||||
|
||||
typedef int (*closure_test_type)(int, float);
|
||||
typedef int (*closure_test_type)(unsigned long long, int, unsigned long long,
|
||||
int, signed short, unsigned long long, int,
|
||||
int, double, int, int, float, int, int,
|
||||
int, int);
|
||||
|
||||
static void closure_test_fn1(ffi_cif* cif,void* resp,void** args,
|
||||
void* userdata)
|
||||
{
|
||||
*(ffi_arg*)resp =
|
||||
(int)*(float *)args[0] +(int)(*(float *)args[1]) +
|
||||
(int)(*(float *)args[2]) + (int)*(float *)args[3] +
|
||||
(int)(*(signed short *)args[4]) + (int)(*(float *)args[5]) +
|
||||
(int)*(float *)args[6] + (int)(*(int *)args[7]) +
|
||||
(int)(*(double*)args[8]) + (int)*(int *)args[9] +
|
||||
(int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
|
||||
(int)*(int *)args[12] + (int)(*(int *)args[13]) +
|
||||
(int)(*(int *)args[14]) + *(int *)args[15] + (int)(long)userdata;
|
||||
|
||||
printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
|
||||
(int)*(float *)args[0], (int)(*(float *)args[1]),
|
||||
(int)(*(float *)args[2]), (int)*(float *)args[3],
|
||||
(int)(*(signed short *)args[4]), (int)(*(float *)args[5]),
|
||||
(int)*(float *)args[6], (int)(*(int *)args[7]),
|
||||
(int)(*(double *)args[8]), (int)*(int *)args[9],
|
||||
(int)(*(int *)args[10]), (int)(*(float *)args[11]),
|
||||
(int)*(int *)args[12], (int)(*(int *)args[13]),
|
||||
(int)(*(int *)args[14]), *(int *)args[15],
|
||||
(int)(long)userdata, *(int*)resp);
|
||||
}
|
||||
|
||||
typedef int (*closure_test_type1)(float, float, float, float, signed short,
|
||||
float, float, int, double, int, int, float,
|
||||
int, int, int, int);
|
||||
|
||||
static void closure_test_fn2(ffi_cif* cif,void* resp,void** args,
|
||||
void* userdata)
|
||||
{
|
||||
*(ffi_arg*)resp =
|
||||
(int)*(double *)args[0] +(int)(*(double *)args[1]) +
|
||||
(int)(*(double *)args[2]) + (int)*(double *)args[3] +
|
||||
(int)(*(signed short *)args[4]) + (int)(*(double *)args[5]) +
|
||||
(int)*(double *)args[6] + (int)(*(int *)args[7]) +
|
||||
(int)(*(double *)args[8]) + (int)*(int *)args[9] +
|
||||
(int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
|
||||
(int)*(int *)args[12] + (int)(*(float *)args[13]) +
|
||||
(int)(*(int *)args[14]) + *(int *)args[15] + (int)(long)userdata;
|
||||
|
||||
printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
|
||||
(int)*(double *)args[0], (int)(*(double *)args[1]),
|
||||
(int)(*(double *)args[2]), (int)*(double *)args[3],
|
||||
(int)(*(signed short *)args[4]), (int)(*(double *)args[5]),
|
||||
(int)*(double *)args[6], (int)(*(int *)args[7]),
|
||||
(int)(*(double*)args[8]), (int)*(int *)args[9],
|
||||
(int)(*(int *)args[10]), (int)(*(float *)args[11]),
|
||||
(int)*(int *)args[12], (int)(*(float *)args[13]),
|
||||
(int)(*(int *)args[14]), *(int *)args[15], (int)(long)userdata,
|
||||
*(int*)resp);
|
||||
}
|
||||
|
||||
typedef int (*closure_test_type2)(double, double, double, double, signed short,
|
||||
double, double, int, double, int, int, float,
|
||||
int, float, int, int);
|
||||
|
||||
static void closure_test_fn3(ffi_cif* cif,void* resp,void** args,
|
||||
void* userdata)
|
||||
{
|
||||
*(ffi_arg*)resp =
|
||||
(int)*(float *)args[0] +(int)(*(float *)args[1]) +
|
||||
(int)(*(float *)args[2]) + (int)*(float *)args[3] +
|
||||
(int)(*(float *)args[4]) + (int)(*(float *)args[5]) +
|
||||
(int)*(float *)args[6] + (int)(*(float *)args[7]) +
|
||||
(int)(*(double *)args[8]) + (int)*(int *)args[9] +
|
||||
(int)(*(float *)args[10]) + (int)(*(float *)args[11]) +
|
||||
(int)*(int *)args[12] + (int)(*(float *)args[13]) +
|
||||
(int)(*(float *)args[14]) + *(int *)args[15] + (int)(long)userdata;
|
||||
|
||||
printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
|
||||
(int)*(float *)args[0], (int)(*(float *)args[1]),
|
||||
(int)(*(float *)args[2]), (int)*(float *)args[3],
|
||||
(int)(*(float *)args[4]), (int)(*(float *)args[5]),
|
||||
(int)*(float *)args[6], (int)(*(float *)args[7]),
|
||||
(int)(*(double *)args[8]), (int)*(int *)args[9],
|
||||
(int)(*(float *)args[10]), (int)(*(float *)args[11]),
|
||||
(int)*(int *)args[12], (int)(*(float *)args[13]),
|
||||
(int)(*(float *)args[14]), *(int *)args[15], (int)(long)userdata,
|
||||
*(int*)resp);
|
||||
}
|
||||
|
||||
typedef int (*closure_test_type3)(float, float, float, float, float, float,
|
||||
float, float, double, int, float, float, int,
|
||||
float, float, int);
|
||||
#endif
|
||||
|
||||
int main(/*@unused@*/ int argc, /*@unused@*/ char *argv[])
|
||||
@ -315,6 +426,12 @@ int main(/*@unused@*/ int argc, /*@unused@*/ char *argv[])
|
||||
ffi_arg rint;
|
||||
long long rlonglong;
|
||||
|
||||
/* The closure must not be an automatic variable on
|
||||
platforms (Solaris) that forbid stack execution by default. */
|
||||
static ffi_closure cl;
|
||||
|
||||
ffi_type * cl_arg_types[17];
|
||||
|
||||
ffi_type ts1_type;
|
||||
ffi_type ts2_type;
|
||||
ffi_type ts3_type;
|
||||
@ -1044,24 +1161,137 @@ int main(/*@unused@*/ int argc, /*@unused@*/ char *argv[])
|
||||
# if FFI_CLOSURES
|
||||
/* A simple closure test */
|
||||
{
|
||||
/* The closure must not be an automatic variable on
|
||||
platforms (Solaris) that forbid stack execution by default. */
|
||||
static ffi_closure cl;
|
||||
ffi_type * cl_arg_types[3];
|
||||
(void) puts("\nEnter FFI_CLOSURES\n");
|
||||
|
||||
cl_arg_types[0] = &ffi_type_uint64;
|
||||
cl_arg_types[1] = &ffi_type_uint;
|
||||
cl_arg_types[2] = &ffi_type_uint64;
|
||||
cl_arg_types[3] = &ffi_type_uint;
|
||||
cl_arg_types[4] = &ffi_type_sshort;
|
||||
cl_arg_types[5] = &ffi_type_uint64;
|
||||
cl_arg_types[6] = &ffi_type_uint;
|
||||
cl_arg_types[7] = &ffi_type_uint;
|
||||
cl_arg_types[8] = &ffi_type_double;
|
||||
cl_arg_types[9] = &ffi_type_uint;
|
||||
cl_arg_types[10] = &ffi_type_uint;
|
||||
cl_arg_types[11] = &ffi_type_float;
|
||||
cl_arg_types[12] = &ffi_type_uint;
|
||||
cl_arg_types[13] = &ffi_type_uint;
|
||||
cl_arg_types[14] = &ffi_type_uint;
|
||||
cl_arg_types[15] = &ffi_type_uint;
|
||||
cl_arg_types[16] = NULL;
|
||||
|
||||
cl_arg_types[0] = &ffi_type_sint;
|
||||
cl_arg_types[1] = &ffi_type_float;
|
||||
cl_arg_types[2] = NULL;
|
||||
|
||||
/* Initialize the cif */
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
|
||||
&ffi_type_sint, cl_arg_types) == FFI_OK);
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
|
||||
&ffi_type_sint, cl_arg_types) == FFI_OK);
|
||||
|
||||
CHECK(ffi_prep_closure(&cl, &cif, closure_test_fn,
|
||||
(void *) 3 /* userdata */)
|
||||
== FFI_OK);
|
||||
CHECK((*((closure_test_type)(&cl)))(1, 2.0) == 6);
|
||||
(void *) 3 /* userdata */) == FFI_OK);
|
||||
|
||||
CHECK((*((closure_test_type)(&cl)))
|
||||
(1LL, 2, 3LL, 4, 127, 429LL, 7, 8, 9.5, 10, 11, 12, 13,
|
||||
19, 21, 1) == 680);
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
cl_arg_types[0] = &ffi_type_float;
|
||||
cl_arg_types[1] = &ffi_type_float;
|
||||
cl_arg_types[2] = &ffi_type_float;
|
||||
cl_arg_types[3] = &ffi_type_float;
|
||||
cl_arg_types[4] = &ffi_type_sshort;
|
||||
cl_arg_types[5] = &ffi_type_float;
|
||||
cl_arg_types[6] = &ffi_type_float;
|
||||
cl_arg_types[7] = &ffi_type_uint;
|
||||
cl_arg_types[8] = &ffi_type_double;
|
||||
cl_arg_types[9] = &ffi_type_uint;
|
||||
cl_arg_types[10] = &ffi_type_uint;
|
||||
cl_arg_types[11] = &ffi_type_float;
|
||||
cl_arg_types[12] = &ffi_type_uint;
|
||||
cl_arg_types[13] = &ffi_type_uint;
|
||||
cl_arg_types[14] = &ffi_type_uint;
|
||||
cl_arg_types[15] = &ffi_type_uint;
|
||||
cl_arg_types[16] = NULL;
|
||||
|
||||
/* Initialize the cif */
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
|
||||
&ffi_type_sint, cl_arg_types) == FFI_OK);
|
||||
|
||||
CHECK(ffi_prep_closure(&cl, &cif, closure_test_fn1,
|
||||
(void *) 3 /* userdata */) == FFI_OK);
|
||||
|
||||
CHECK((*((closure_test_type1)(&cl)))
|
||||
(1.1, 2.2, 3.3, 4.4, 127, 5.5, 6.6, 8, 9, 10, 11, 12.0, 13,
|
||||
19, 21, 1) == 255);
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
cl_arg_types[0] = &ffi_type_double;
|
||||
cl_arg_types[1] = &ffi_type_double;
|
||||
cl_arg_types[2] = &ffi_type_double;
|
||||
cl_arg_types[3] = &ffi_type_double;
|
||||
cl_arg_types[4] = &ffi_type_sshort;
|
||||
cl_arg_types[5] = &ffi_type_double;
|
||||
cl_arg_types[6] = &ffi_type_double;
|
||||
cl_arg_types[7] = &ffi_type_uint;
|
||||
cl_arg_types[8] = &ffi_type_double;
|
||||
cl_arg_types[9] = &ffi_type_uint;
|
||||
cl_arg_types[10] = &ffi_type_uint;
|
||||
cl_arg_types[11] = &ffi_type_float;
|
||||
cl_arg_types[12] = &ffi_type_uint;
|
||||
cl_arg_types[13] = &ffi_type_float;
|
||||
cl_arg_types[14] = &ffi_type_uint;
|
||||
cl_arg_types[15] = &ffi_type_uint;
|
||||
cl_arg_types[16] = NULL;
|
||||
|
||||
/* Initialize the cif */
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
|
||||
&ffi_type_sint, cl_arg_types) == FFI_OK);
|
||||
|
||||
CHECK(ffi_prep_closure(&cl, &cif, closure_test_fn2,
|
||||
(void *) 3 /* userdata */) == FFI_OK);
|
||||
|
||||
CHECK((*((closure_test_type2)(&cl)))
|
||||
(1, 2, 3, 4, 127, 5, 6, 8, 9, 10, 11, 12.0, 13,
|
||||
19.0, 21, 1) == 255);
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
cl_arg_types[0] = &ffi_type_float;
|
||||
cl_arg_types[1] = &ffi_type_float;
|
||||
cl_arg_types[2] = &ffi_type_float;
|
||||
cl_arg_types[3] = &ffi_type_float;
|
||||
cl_arg_types[4] = &ffi_type_float;
|
||||
cl_arg_types[5] = &ffi_type_float;
|
||||
cl_arg_types[6] = &ffi_type_float;
|
||||
cl_arg_types[7] = &ffi_type_float;
|
||||
cl_arg_types[8] = &ffi_type_double;
|
||||
cl_arg_types[9] = &ffi_type_uint;
|
||||
cl_arg_types[10] = &ffi_type_float;
|
||||
cl_arg_types[11] = &ffi_type_float;
|
||||
cl_arg_types[12] = &ffi_type_uint;
|
||||
cl_arg_types[13] = &ffi_type_float;
|
||||
cl_arg_types[14] = &ffi_type_float;
|
||||
cl_arg_types[15] = &ffi_type_uint;
|
||||
cl_arg_types[16] = NULL;
|
||||
|
||||
/* Initialize the cif */
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
|
||||
&ffi_type_sint, cl_arg_types) == FFI_OK);
|
||||
|
||||
CHECK(ffi_prep_closure(&cl, &cif, closure_test_fn3,
|
||||
(void *) 3 /* userdata */) == FFI_OK);
|
||||
|
||||
CHECK((*((closure_test_type3)(&cl)))
|
||||
(1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9, 10, 11.11, 12.0, 13,
|
||||
19.19, 21.21, 1) == 135);
|
||||
}
|
||||
|
||||
(void) puts("\nFinished FFI_CLOSURES\n");
|
||||
|
||||
# endif
|
||||
|
||||
/* If we arrived here, all is good */
|
||||
|
@ -137,11 +137,20 @@ void ffi_prep_args(extended_cif *ecif, unsigned *const stack)
|
||||
switch ((*ptr)->type)
|
||||
{
|
||||
case FFI_TYPE_FLOAT:
|
||||
case FFI_TYPE_DOUBLE:
|
||||
if ((*ptr)->type == FFI_TYPE_FLOAT)
|
||||
double_tmp = *(float *)*p_argv;
|
||||
double_tmp = *(float *)*p_argv;
|
||||
if (fparg_count >= NUM_FPR_ARG_REGISTERS)
|
||||
{
|
||||
*(float *)next_arg = (float)double_tmp;
|
||||
next_arg += 1;
|
||||
}
|
||||
else
|
||||
double_tmp = *(double *)*p_argv;
|
||||
*fpr_base++ = double_tmp;
|
||||
fparg_count++;
|
||||
FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_DOUBLE:
|
||||
double_tmp = *(double *)*p_argv;
|
||||
|
||||
if (fparg_count >= NUM_FPR_ARG_REGISTERS)
|
||||
{
|
||||
@ -320,6 +329,10 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
|
||||
switch ((*ptr)->type)
|
||||
{
|
||||
case FFI_TYPE_FLOAT:
|
||||
fparg_count++;
|
||||
/* floating singles are not 8-aligned on stack */
|
||||
break;
|
||||
|
||||
case FFI_TYPE_DOUBLE:
|
||||
fparg_count++;
|
||||
/* If this FP arg is going on the stack, it must be
|
||||
@ -612,20 +625,15 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
|
||||
case FFI_TYPE_FLOAT:
|
||||
/* unfortunately float values are stored as doubles
|
||||
* in the ffi_closure_SYSV code (since we don't check
|
||||
* the type in that routine). This is also true
|
||||
* of floats passed on the outgoing parameter stack.
|
||||
* Also, on the outgoing stack all values are aligned
|
||||
* to 8
|
||||
*
|
||||
* Don't you just love the simplicity of this ABI!
|
||||
* the type in that routine).
|
||||
*/
|
||||
|
||||
/* there are 8 64bit floating point registers */
|
||||
|
||||
if (nf < 8) {
|
||||
temp = *(double*)pfr;
|
||||
temp = *(double*)pfr;
|
||||
*(float*)pfr = (float)temp;
|
||||
avalue[i] = pfr;
|
||||
avalue[i] = pfr;
|
||||
nf++;
|
||||
pfr+=2;
|
||||
} else {
|
||||
@ -634,12 +642,9 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
|
||||
* parameter stack. This is probably a really
|
||||
* naughty thing to do but...
|
||||
*/
|
||||
if (((long)pst) & 4) pst++;
|
||||
temp = *(double*)pst;
|
||||
*(float*)pst = (float)temp;
|
||||
avalue[i] = pst;
|
||||
nf++;
|
||||
pst+=2;
|
||||
pst+=1;
|
||||
}
|
||||
break;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user