Various MSVC-related changes.
This commit is contained in:
committed by
Anthony Green
parent
e1539266e6
commit
0a1ab12a8d
64
.pc/msvc-changes/testsuite/libffi.call/closure_stdcall.c
Normal file
64
.pc/msvc-changes/testsuite/libffi.call/closure_stdcall.c
Normal file
@@ -0,0 +1,64 @@
|
||||
/* Area: closure_call (stdcall convention)
|
||||
Purpose: Check handling when caller expects stdcall callee
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <twalljava@dev.java.net> */
|
||||
|
||||
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
|
||||
#include "ffitest.h"
|
||||
|
||||
static void
|
||||
closure_test_stdcall(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata)
|
||||
{
|
||||
*(ffi_arg*)resp =
|
||||
(int)*(int *)args[0] + (int)(*(int *)args[1])
|
||||
+ (int)(*(int *)args[2]) + (int)(*(int *)args[3])
|
||||
+ (int)(intptr_t)userdata;
|
||||
|
||||
printf("%d %d %d %d: %d\n",
|
||||
(int)*(int *)args[0], (int)(*(int *)args[1]),
|
||||
(int)(*(int *)args[2]), (int)(*(int *)args[3]),
|
||||
(int)*(ffi_arg *)resp);
|
||||
|
||||
}
|
||||
|
||||
typedef int (__stdcall *closure_test_type0)(int, int, int, int);
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
ffi_type * cl_arg_types[17];
|
||||
int res;
|
||||
void* sp_pre;
|
||||
void* sp_post;
|
||||
char buf[1024];
|
||||
|
||||
cl_arg_types[0] = &ffi_type_uint;
|
||||
cl_arg_types[1] = &ffi_type_uint;
|
||||
cl_arg_types[2] = &ffi_type_uint;
|
||||
cl_arg_types[3] = &ffi_type_uint;
|
||||
cl_arg_types[4] = NULL;
|
||||
|
||||
/* Initialize the cif */
|
||||
CHECK(ffi_prep_cif(&cif, FFI_STDCALL, 4,
|
||||
&ffi_type_sint, cl_arg_types) == FFI_OK);
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_stdcall,
|
||||
(void *) 3 /* userdata */, code) == FFI_OK);
|
||||
|
||||
asm volatile (" movl %%esp,%0" : "=g" (sp_pre));
|
||||
res = (*(closure_test_type0)code)(0, 1, 2, 3);
|
||||
asm volatile (" movl %%esp,%0" : "=g" (sp_post));
|
||||
/* { dg-output "0 1 2 3: 9" } */
|
||||
|
||||
printf("res: %d\n",res);
|
||||
/* { dg-output "\nres: 9" } */
|
||||
|
||||
sprintf(buf, "mismatch: pre=%p vs post=%p", sp_pre, sp_post);
|
||||
printf("stack pointer %s\n", (sp_pre == sp_post ? "match" : buf));
|
||||
/* { dg-output "\nstack pointer match" } */
|
||||
exit(0);
|
||||
}
|
||||
64
.pc/msvc-changes/testsuite/libffi.call/closure_thiscall.c
Normal file
64
.pc/msvc-changes/testsuite/libffi.call/closure_thiscall.c
Normal file
@@ -0,0 +1,64 @@
|
||||
/* Area: closure_call (thiscall convention)
|
||||
Purpose: Check handling when caller expects thiscall callee
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <ktietz@redhat.com> */
|
||||
|
||||
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
|
||||
#include "ffitest.h"
|
||||
|
||||
static void
|
||||
closure_test_thiscall(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata)
|
||||
{
|
||||
*(ffi_arg*)resp =
|
||||
(int)*(int *)args[0] + (int)(*(int *)args[1])
|
||||
+ (int)(*(int *)args[2]) + (int)(*(int *)args[3])
|
||||
+ (int)(intptr_t)userdata;
|
||||
|
||||
printf("%d %d %d %d: %d\n",
|
||||
(int)*(int *)args[0], (int)(*(int *)args[1]),
|
||||
(int)(*(int *)args[2]), (int)(*(int *)args[3]),
|
||||
(int)*(ffi_arg *)resp);
|
||||
|
||||
}
|
||||
|
||||
typedef int (__thiscall *closure_test_type0)(int, int, int, int);
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
ffi_type * cl_arg_types[17];
|
||||
int res;
|
||||
void* sp_pre;
|
||||
void* sp_post;
|
||||
char buf[1024];
|
||||
|
||||
cl_arg_types[0] = &ffi_type_uint;
|
||||
cl_arg_types[1] = &ffi_type_uint;
|
||||
cl_arg_types[2] = &ffi_type_uint;
|
||||
cl_arg_types[3] = &ffi_type_uint;
|
||||
cl_arg_types[4] = NULL;
|
||||
|
||||
/* Initialize the cif */
|
||||
CHECK(ffi_prep_cif(&cif, FFI_THISCALL, 4,
|
||||
&ffi_type_sint, cl_arg_types) == FFI_OK);
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_thiscall,
|
||||
(void *) 3 /* userdata */, code) == FFI_OK);
|
||||
|
||||
asm volatile (" movl %%esp,%0" : "=g" (sp_pre));
|
||||
res = (*(closure_test_type0)code)(0, 1, 2, 3);
|
||||
asm volatile (" movl %%esp,%0" : "=g" (sp_post));
|
||||
/* { dg-output "0 1 2 3: 9" } */
|
||||
|
||||
printf("res: %d\n",res);
|
||||
/* { dg-output "\nres: 9" } */
|
||||
|
||||
sprintf(buf, "mismatch: pre=%p vs post=%p", sp_pre, sp_post);
|
||||
printf("stack pointer %s\n", (sp_pre == sp_post ? "match" : buf));
|
||||
/* { dg-output "\nstack pointer match" } */
|
||||
exit(0);
|
||||
}
|
||||
94
.pc/msvc-changes/testsuite/libffi.call/cls_12byte.c
Normal file
94
.pc/msvc-changes/testsuite/libffi.call/cls_12byte.c
Normal file
@@ -0,0 +1,94 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20030828 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_12byte {
|
||||
int a;
|
||||
int b;
|
||||
int c;
|
||||
} cls_struct_12byte;
|
||||
|
||||
cls_struct_12byte cls_struct_12byte_fn(struct cls_struct_12byte b1,
|
||||
struct cls_struct_12byte b2)
|
||||
{
|
||||
struct cls_struct_12byte result;
|
||||
|
||||
result.a = b1.a + b2.a;
|
||||
result.b = b1.b + b2.b;
|
||||
result.c = b1.c + b2.c;
|
||||
|
||||
printf("%d %d %d %d %d %d: %d %d %d\n", b1.a, b1.b, b1.c, b2.a, b2.b, b2.c,
|
||||
result.a, result.b, result.c);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void cls_struct_12byte_gn(ffi_cif* cif __UNUSED__, void* resp,
|
||||
void** args , void* userdata __UNUSED__)
|
||||
{
|
||||
struct cls_struct_12byte b1, b2;
|
||||
|
||||
b1 = *(struct cls_struct_12byte*)(args[0]);
|
||||
b2 = *(struct cls_struct_12byte*)(args[1]);
|
||||
|
||||
*(cls_struct_12byte*)resp = cls_struct_12byte_fn(b1, b2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[4];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_12byte h_dbl = { 7, 4, 9 };
|
||||
struct cls_struct_12byte j_dbl = { 1, 5, 3 };
|
||||
struct cls_struct_12byte res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_sint;
|
||||
cls_struct_fields[1] = &ffi_type_sint;
|
||||
cls_struct_fields[2] = &ffi_type_sint;
|
||||
cls_struct_fields[3] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &h_dbl;
|
||||
args_dbl[1] = &j_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_12byte_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "7 4 9 1 5 3: 8 9 12" } */
|
||||
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 8 9 12" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_12byte_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl.a = 0;
|
||||
res_dbl.b = 0;
|
||||
res_dbl.c = 0;
|
||||
|
||||
res_dbl = ((cls_struct_12byte(*)(cls_struct_12byte, cls_struct_12byte))(code))(h_dbl, j_dbl);
|
||||
/* { dg-output "\n7 4 9 1 5 3: 8 9 12" } */
|
||||
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 8 9 12" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
95
.pc/msvc-changes/testsuite/libffi.call/cls_16byte.c
Normal file
95
.pc/msvc-changes/testsuite/libffi.call/cls_16byte.c
Normal file
@@ -0,0 +1,95 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Depending on the ABI. Check overlapping.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20030828 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_16byte {
|
||||
int a;
|
||||
double b;
|
||||
int c;
|
||||
} cls_struct_16byte;
|
||||
|
||||
cls_struct_16byte cls_struct_16byte_fn(struct cls_struct_16byte b1,
|
||||
struct cls_struct_16byte b2)
|
||||
{
|
||||
struct cls_struct_16byte result;
|
||||
|
||||
result.a = b1.a + b2.a;
|
||||
result.b = b1.b + b2.b;
|
||||
result.c = b1.c + b2.c;
|
||||
|
||||
printf("%d %g %d %d %g %d: %d %g %d\n", b1.a, b1.b, b1.c, b2.a, b2.b, b2.c,
|
||||
result.a, result.b, result.c);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void cls_struct_16byte_gn(ffi_cif* cif __UNUSED__, void* resp,
|
||||
void** args, void* userdata __UNUSED__)
|
||||
{
|
||||
struct cls_struct_16byte b1, b2;
|
||||
|
||||
b1 = *(struct cls_struct_16byte*)(args[0]);
|
||||
b2 = *(struct cls_struct_16byte*)(args[1]);
|
||||
|
||||
*(cls_struct_16byte*)resp = cls_struct_16byte_fn(b1, b2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[4];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_16byte h_dbl = { 7, 8.0, 9 };
|
||||
struct cls_struct_16byte j_dbl = { 1, 9.0, 3 };
|
||||
struct cls_struct_16byte res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_sint;
|
||||
cls_struct_fields[1] = &ffi_type_double;
|
||||
cls_struct_fields[2] = &ffi_type_sint;
|
||||
cls_struct_fields[3] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &h_dbl;
|
||||
args_dbl[1] = &j_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_16byte_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "7 8 9 1 9 3: 8 17 12" } */
|
||||
printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 8 17 12" } */
|
||||
|
||||
res_dbl.a = 0;
|
||||
res_dbl.b = 0.0;
|
||||
res_dbl.c = 0;
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_16byte_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_16byte(*)(cls_struct_16byte, cls_struct_16byte))(code))(h_dbl, j_dbl);
|
||||
/* { dg-output "\n7 8 9 1 9 3: 8 17 12" } */
|
||||
printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 8 17 12" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
96
.pc/msvc-changes/testsuite/libffi.call/cls_18byte.c
Normal file
96
.pc/msvc-changes/testsuite/libffi.call/cls_18byte.c
Normal file
@@ -0,0 +1,96 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Depending on the ABI. Double alignment check on darwin.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20030915 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_18byte {
|
||||
double a;
|
||||
unsigned char b;
|
||||
unsigned char c;
|
||||
double d;
|
||||
} cls_struct_18byte;
|
||||
|
||||
cls_struct_18byte cls_struct_18byte_fn(struct cls_struct_18byte a1,
|
||||
struct cls_struct_18byte a2)
|
||||
{
|
||||
struct cls_struct_18byte result;
|
||||
|
||||
result.a = a1.a + a2.a;
|
||||
result.b = a1.b + a2.b;
|
||||
result.c = a1.c + a2.c;
|
||||
result.d = a1.d + a2.d;
|
||||
|
||||
|
||||
printf("%g %d %d %g %g %d %d %g: %g %d %d %g\n", a1.a, a1.b, a1.c, a1.d,
|
||||
a2.a, a2.b, a2.c, a2.d,
|
||||
result.a, result.b, result.c, result.d);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_18byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
struct cls_struct_18byte a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_18byte*)(args[0]);
|
||||
a2 = *(struct cls_struct_18byte*)(args[1]);
|
||||
|
||||
*(cls_struct_18byte*)resp = cls_struct_18byte_fn(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[3];
|
||||
ffi_type* cls_struct_fields[5];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[3];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_18byte g_dbl = { 1.0, 127, 126, 3.0 };
|
||||
struct cls_struct_18byte f_dbl = { 4.0, 125, 124, 5.0 };
|
||||
struct cls_struct_18byte res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_double;
|
||||
cls_struct_fields[1] = &ffi_type_uchar;
|
||||
cls_struct_fields[2] = &ffi_type_uchar;
|
||||
cls_struct_fields[3] = &ffi_type_double;
|
||||
cls_struct_fields[4] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &g_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_18byte_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "1 127 126 3 4 125 124 5: 5 252 250 8" } */
|
||||
printf("res: %g %d %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
|
||||
/* { dg-output "\nres: 5 252 250 8" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_18byte_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_18byte(*)(cls_struct_18byte, cls_struct_18byte))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n1 127 126 3 4 125 124 5: 5 252 250 8" } */
|
||||
printf("res: %g %d %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
|
||||
/* { dg-output "\nres: 5 252 250 8" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
102
.pc/msvc-changes/testsuite/libffi.call/cls_19byte.c
Normal file
102
.pc/msvc-changes/testsuite/libffi.call/cls_19byte.c
Normal file
@@ -0,0 +1,102 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Depending on the ABI. Double alignment check on darwin.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20030915 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_19byte {
|
||||
double a;
|
||||
unsigned char b;
|
||||
unsigned char c;
|
||||
double d;
|
||||
unsigned char e;
|
||||
} cls_struct_19byte;
|
||||
|
||||
cls_struct_19byte cls_struct_19byte_fn(struct cls_struct_19byte a1,
|
||||
struct cls_struct_19byte a2)
|
||||
{
|
||||
struct cls_struct_19byte result;
|
||||
|
||||
result.a = a1.a + a2.a;
|
||||
result.b = a1.b + a2.b;
|
||||
result.c = a1.c + a2.c;
|
||||
result.d = a1.d + a2.d;
|
||||
result.e = a1.e + a2.e;
|
||||
|
||||
|
||||
printf("%g %d %d %g %d %g %d %d %g %d: %g %d %d %g %d\n",
|
||||
a1.a, a1.b, a1.c, a1.d, a1.e,
|
||||
a2.a, a2.b, a2.c, a2.d, a2.e,
|
||||
result.a, result.b, result.c, result.d, result.e);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_19byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
struct cls_struct_19byte a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_19byte*)(args[0]);
|
||||
a2 = *(struct cls_struct_19byte*)(args[1]);
|
||||
|
||||
*(cls_struct_19byte*)resp = cls_struct_19byte_fn(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[3];
|
||||
ffi_type* cls_struct_fields[6];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[3];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_19byte g_dbl = { 1.0, 127, 126, 3.0, 120 };
|
||||
struct cls_struct_19byte f_dbl = { 4.0, 125, 124, 5.0, 119 };
|
||||
struct cls_struct_19byte res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_double;
|
||||
cls_struct_fields[1] = &ffi_type_uchar;
|
||||
cls_struct_fields[2] = &ffi_type_uchar;
|
||||
cls_struct_fields[3] = &ffi_type_double;
|
||||
cls_struct_fields[4] = &ffi_type_uchar;
|
||||
cls_struct_fields[5] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &g_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_19byte_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "1 127 126 3 120 4 125 124 5 119: 5 252 250 8 239" } */
|
||||
printf("res: %g %d %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
|
||||
res_dbl.d, res_dbl.e);
|
||||
/* { dg-output "\nres: 5 252 250 8 239" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_19byte_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_19byte(*)(cls_struct_19byte, cls_struct_19byte))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n1 127 126 3 120 4 125 124 5 119: 5 252 250 8 239" } */
|
||||
printf("res: %g %d %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
|
||||
res_dbl.d, res_dbl.e);
|
||||
/* { dg-output "\nres: 5 252 250 8 239" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
89
.pc/msvc-changes/testsuite/libffi.call/cls_1_1byte.c
Normal file
89
.pc/msvc-changes/testsuite/libffi.call/cls_1_1byte.c
Normal file
@@ -0,0 +1,89 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Especially with small structures which may fit in one
|
||||
register. Depending on the ABI.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20030902 */
|
||||
|
||||
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_1_1byte {
|
||||
unsigned char a;
|
||||
} cls_struct_1_1byte;
|
||||
|
||||
cls_struct_1_1byte cls_struct_1_1byte_fn(struct cls_struct_1_1byte a1,
|
||||
struct cls_struct_1_1byte a2)
|
||||
{
|
||||
struct cls_struct_1_1byte result;
|
||||
|
||||
result.a = a1.a + a2.a;
|
||||
|
||||
printf("%d %d: %d\n", a1.a, a2.a, result.a);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_1_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
|
||||
struct cls_struct_1_1byte a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_1_1byte*)(args[0]);
|
||||
a2 = *(struct cls_struct_1_1byte*)(args[1]);
|
||||
|
||||
*(cls_struct_1_1byte*)resp = cls_struct_1_1byte_fn(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[2];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_1_1byte g_dbl = { 12 };
|
||||
struct cls_struct_1_1byte f_dbl = { 178 };
|
||||
struct cls_struct_1_1byte res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_uchar;
|
||||
cls_struct_fields[1] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &g_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_1_1byte_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "12 178: 190" } */
|
||||
printf("res: %d\n", res_dbl.a);
|
||||
/* { dg-output "\nres: 190" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_1_1byte_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_1_1byte(*)(cls_struct_1_1byte, cls_struct_1_1byte))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n12 178: 190" } */
|
||||
printf("res: %d\n", res_dbl.a);
|
||||
/* { dg-output "\nres: 190" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
91
.pc/msvc-changes/testsuite/libffi.call/cls_20byte.c
Normal file
91
.pc/msvc-changes/testsuite/libffi.call/cls_20byte.c
Normal file
@@ -0,0 +1,91 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Depending on the ABI. Check overlapping.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20030828 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_20byte {
|
||||
double a;
|
||||
double b;
|
||||
int c;
|
||||
} cls_struct_20byte;
|
||||
|
||||
cls_struct_20byte cls_struct_20byte_fn(struct cls_struct_20byte a1,
|
||||
struct cls_struct_20byte a2)
|
||||
{
|
||||
struct cls_struct_20byte result;
|
||||
|
||||
result.a = a1.a + a2.a;
|
||||
result.b = a1.b + a2.b;
|
||||
result.c = a1.c + a2.c;
|
||||
|
||||
printf("%g %g %d %g %g %d: %g %g %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c,
|
||||
result.a, result.b, result.c);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_20byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
struct cls_struct_20byte a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_20byte*)(args[0]);
|
||||
a2 = *(struct cls_struct_20byte*)(args[1]);
|
||||
|
||||
*(cls_struct_20byte*)resp = cls_struct_20byte_fn(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[4];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_20byte g_dbl = { 1.0, 2.0, 3 };
|
||||
struct cls_struct_20byte f_dbl = { 4.0, 5.0, 7 };
|
||||
struct cls_struct_20byte res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_double;
|
||||
cls_struct_fields[1] = &ffi_type_double;
|
||||
cls_struct_fields[2] = &ffi_type_sint;
|
||||
cls_struct_fields[3] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &g_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_20byte_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "1 2 3 4 5 7: 5 7 10" } */
|
||||
printf("res: %g %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 5 7 10" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_20byte_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_20byte(*)(cls_struct_20byte, cls_struct_20byte))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n1 2 3 4 5 7: 5 7 10" } */
|
||||
printf("res: %g %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 5 7 10" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
93
.pc/msvc-changes/testsuite/libffi.call/cls_20byte1.c
Normal file
93
.pc/msvc-changes/testsuite/libffi.call/cls_20byte1.c
Normal file
@@ -0,0 +1,93 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Depending on the ABI. Check overlapping.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20030828 */
|
||||
|
||||
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_20byte {
|
||||
int a;
|
||||
double b;
|
||||
double c;
|
||||
} cls_struct_20byte;
|
||||
|
||||
cls_struct_20byte cls_struct_20byte_fn(struct cls_struct_20byte a1,
|
||||
struct cls_struct_20byte a2)
|
||||
{
|
||||
struct cls_struct_20byte result;
|
||||
|
||||
result.a = a1.a + a2.a;
|
||||
result.b = a1.b + a2.b;
|
||||
result.c = a1.c + a2.c;
|
||||
|
||||
printf("%d %g %g %d %g %g: %d %g %g\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c,
|
||||
result.a, result.b, result.c);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_20byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
struct cls_struct_20byte a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_20byte*)(args[0]);
|
||||
a2 = *(struct cls_struct_20byte*)(args[1]);
|
||||
|
||||
*(cls_struct_20byte*)resp = cls_struct_20byte_fn(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[3];
|
||||
ffi_type* cls_struct_fields[4];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[3];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_20byte g_dbl = { 1, 2.0, 3.0 };
|
||||
struct cls_struct_20byte f_dbl = { 4, 5.0, 7.0 };
|
||||
struct cls_struct_20byte res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_sint;
|
||||
cls_struct_fields[1] = &ffi_type_double;
|
||||
cls_struct_fields[2] = &ffi_type_double;
|
||||
cls_struct_fields[3] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &g_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_20byte_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "1 2 3 4 5 7: 5 7 10" } */
|
||||
printf("res: %d %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 5 7 10" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_20byte_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_20byte(*)(cls_struct_20byte, cls_struct_20byte))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n1 2 3 4 5 7: 5 7 10" } */
|
||||
printf("res: %d %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 5 7 10" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
113
.pc/msvc-changes/testsuite/libffi.call/cls_24byte.c
Normal file
113
.pc/msvc-changes/testsuite/libffi.call/cls_24byte.c
Normal file
@@ -0,0 +1,113 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Depending on the ABI. Check overlapping.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20030828 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_24byte {
|
||||
double a;
|
||||
double b;
|
||||
int c;
|
||||
float d;
|
||||
} cls_struct_24byte;
|
||||
|
||||
cls_struct_24byte cls_struct_24byte_fn(struct cls_struct_24byte b0,
|
||||
struct cls_struct_24byte b1,
|
||||
struct cls_struct_24byte b2,
|
||||
struct cls_struct_24byte b3)
|
||||
{
|
||||
struct cls_struct_24byte result;
|
||||
|
||||
result.a = b0.a + b1.a + b2.a + b3.a;
|
||||
result.b = b0.b + b1.b + b2.b + b3.b;
|
||||
result.c = b0.c + b1.c + b2.c + b3.c;
|
||||
result.d = b0.d + b1.d + b2.d + b3.d;
|
||||
|
||||
printf("%g %g %d %g %g %g %d %g %g %g %d %g %g %g %d %g: %g %g %d %g\n",
|
||||
b0.a, b0.b, b0.c, b0.d,
|
||||
b1.a, b1.b, b1.c, b1.d,
|
||||
b2.a, b2.b, b2.c, b2.d,
|
||||
b3.a, b3.b, b3.c, b2.d,
|
||||
result.a, result.b, result.c, result.d);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_24byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
struct cls_struct_24byte b0, b1, b2, b3;
|
||||
|
||||
b0 = *(struct cls_struct_24byte*)(args[0]);
|
||||
b1 = *(struct cls_struct_24byte*)(args[1]);
|
||||
b2 = *(struct cls_struct_24byte*)(args[2]);
|
||||
b3 = *(struct cls_struct_24byte*)(args[3]);
|
||||
|
||||
*(cls_struct_24byte*)resp = cls_struct_24byte_fn(b0, b1, b2, b3);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[5];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_24byte e_dbl = { 9.0, 2.0, 6, 5.0 };
|
||||
struct cls_struct_24byte f_dbl = { 1.0, 2.0, 3, 7.0 };
|
||||
struct cls_struct_24byte g_dbl = { 4.0, 5.0, 7, 9.0 };
|
||||
struct cls_struct_24byte h_dbl = { 8.0, 6.0, 1, 4.0 };
|
||||
struct cls_struct_24byte res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_double;
|
||||
cls_struct_fields[1] = &ffi_type_double;
|
||||
cls_struct_fields[2] = &ffi_type_sint;
|
||||
cls_struct_fields[3] = &ffi_type_float;
|
||||
cls_struct_fields[4] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = &cls_struct_type;
|
||||
dbl_arg_types[3] = &cls_struct_type;
|
||||
dbl_arg_types[4] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &e_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = &g_dbl;
|
||||
args_dbl[3] = &h_dbl;
|
||||
args_dbl[4] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_24byte_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "9 2 6 5 1 2 3 7 4 5 7 9 8 6 1 9: 22 15 17 25" } */
|
||||
printf("res: %g %g %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
|
||||
/* { dg-output "\nres: 22 15 17 25" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_24byte_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_24byte(*)(cls_struct_24byte,
|
||||
cls_struct_24byte,
|
||||
cls_struct_24byte,
|
||||
cls_struct_24byte))
|
||||
(code))(e_dbl, f_dbl, g_dbl, h_dbl);
|
||||
/* { dg-output "\n9 2 6 5 1 2 3 7 4 5 7 9 8 6 1 9: 22 15 17 25" } */
|
||||
printf("res: %g %g %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
|
||||
/* { dg-output "\nres: 22 15 17 25" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
90
.pc/msvc-changes/testsuite/libffi.call/cls_2byte.c
Normal file
90
.pc/msvc-changes/testsuite/libffi.call/cls_2byte.c
Normal file
@@ -0,0 +1,90 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Especially with small structures which may fit in one
|
||||
register. Depending on the ABI.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20030828 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_2byte {
|
||||
unsigned char a;
|
||||
unsigned char b;
|
||||
} cls_struct_2byte;
|
||||
|
||||
cls_struct_2byte cls_struct_2byte_fn(struct cls_struct_2byte a1,
|
||||
struct cls_struct_2byte a2)
|
||||
{
|
||||
struct cls_struct_2byte result;
|
||||
|
||||
result.a = a1.a + a2.a;
|
||||
result.b = a1.b + a2.b;
|
||||
|
||||
printf("%d %d %d %d: %d %d\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_2byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
|
||||
struct cls_struct_2byte a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_2byte*)(args[0]);
|
||||
a2 = *(struct cls_struct_2byte*)(args[1]);
|
||||
|
||||
*(cls_struct_2byte*)resp = cls_struct_2byte_fn(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[4];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_2byte g_dbl = { 12, 127 };
|
||||
struct cls_struct_2byte f_dbl = { 1, 13 };
|
||||
struct cls_struct_2byte res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_uchar;
|
||||
cls_struct_fields[1] = &ffi_type_uchar;
|
||||
cls_struct_fields[2] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &g_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_2byte_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "12 127 1 13: 13 140" } */
|
||||
printf("res: %d %d\n", res_dbl.a, res_dbl.b);
|
||||
/* { dg-output "\nres: 13 140" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_2byte_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_2byte(*)(cls_struct_2byte, cls_struct_2byte))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n12 127 1 13: 13 140" } */
|
||||
printf("res: %d %d\n", res_dbl.a, res_dbl.b);
|
||||
/* { dg-output "\nres: 13 140" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
95
.pc/msvc-changes/testsuite/libffi.call/cls_3_1byte.c
Normal file
95
.pc/msvc-changes/testsuite/libffi.call/cls_3_1byte.c
Normal file
@@ -0,0 +1,95 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Especially with small structures which may fit in one
|
||||
register. Depending on the ABI.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20030902 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_3_1byte {
|
||||
unsigned char a;
|
||||
unsigned char b;
|
||||
unsigned char c;
|
||||
} cls_struct_3_1byte;
|
||||
|
||||
cls_struct_3_1byte cls_struct_3_1byte_fn(struct cls_struct_3_1byte a1,
|
||||
struct cls_struct_3_1byte a2)
|
||||
{
|
||||
struct cls_struct_3_1byte result;
|
||||
|
||||
result.a = a1.a + a2.a;
|
||||
result.b = a1.b + a2.b;
|
||||
result.c = a1.c + a2.c;
|
||||
|
||||
printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c,
|
||||
a2.a, a2.b, a2.c,
|
||||
result.a, result.b, result.c);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_3_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
|
||||
struct cls_struct_3_1byte a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_3_1byte*)(args[0]);
|
||||
a2 = *(struct cls_struct_3_1byte*)(args[1]);
|
||||
|
||||
*(cls_struct_3_1byte*)resp = cls_struct_3_1byte_fn(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[4];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_3_1byte g_dbl = { 12, 13, 14 };
|
||||
struct cls_struct_3_1byte f_dbl = { 178, 179, 180 };
|
||||
struct cls_struct_3_1byte res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_uchar;
|
||||
cls_struct_fields[1] = &ffi_type_uchar;
|
||||
cls_struct_fields[2] = &ffi_type_uchar;
|
||||
cls_struct_fields[3] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &g_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_3_1byte_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "12 13 14 178 179 180: 190 192 194" } */
|
||||
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 190 192 194" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_3_1byte_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_3_1byte(*)(cls_struct_3_1byte, cls_struct_3_1byte))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n12 13 14 178 179 180: 190 192 194" } */
|
||||
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 190 192 194" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
90
.pc/msvc-changes/testsuite/libffi.call/cls_3byte1.c
Normal file
90
.pc/msvc-changes/testsuite/libffi.call/cls_3byte1.c
Normal file
@@ -0,0 +1,90 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Especially with small structures which may fit in one
|
||||
register. Depending on the ABI. Check overlapping.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20030828 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_3byte {
|
||||
unsigned short a;
|
||||
unsigned char b;
|
||||
} cls_struct_3byte;
|
||||
|
||||
cls_struct_3byte cls_struct_3byte_fn(struct cls_struct_3byte a1,
|
||||
struct cls_struct_3byte a2)
|
||||
{
|
||||
struct cls_struct_3byte result;
|
||||
|
||||
result.a = a1.a + a2.a;
|
||||
result.b = a1.b + a2.b;
|
||||
|
||||
printf("%d %d %d %d: %d %d\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_3byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
|
||||
struct cls_struct_3byte a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_3byte*)(args[0]);
|
||||
a2 = *(struct cls_struct_3byte*)(args[1]);
|
||||
|
||||
*(cls_struct_3byte*)resp = cls_struct_3byte_fn(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[4];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_3byte g_dbl = { 12, 119 };
|
||||
struct cls_struct_3byte f_dbl = { 1, 15 };
|
||||
struct cls_struct_3byte res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_ushort;
|
||||
cls_struct_fields[1] = &ffi_type_uchar;
|
||||
cls_struct_fields[2] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &g_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_3byte_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "12 119 1 15: 13 134" } */
|
||||
printf("res: %d %d\n", res_dbl.a, res_dbl.b);
|
||||
/* { dg-output "\nres: 13 134" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_3byte_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_3byte(*)(cls_struct_3byte, cls_struct_3byte))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n12 119 1 15: 13 134" } */
|
||||
printf("res: %d %d\n", res_dbl.a, res_dbl.b);
|
||||
/* { dg-output "\nres: 13 134" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
90
.pc/msvc-changes/testsuite/libffi.call/cls_3byte2.c
Normal file
90
.pc/msvc-changes/testsuite/libffi.call/cls_3byte2.c
Normal file
@@ -0,0 +1,90 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Especially with small structures which may fit in one
|
||||
register. Depending on the ABI. Check overlapping.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20030828 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_3byte_1 {
|
||||
unsigned char a;
|
||||
unsigned short b;
|
||||
} cls_struct_3byte_1;
|
||||
|
||||
cls_struct_3byte_1 cls_struct_3byte_fn1(struct cls_struct_3byte_1 a1,
|
||||
struct cls_struct_3byte_1 a2)
|
||||
{
|
||||
struct cls_struct_3byte_1 result;
|
||||
|
||||
result.a = a1.a + a2.a;
|
||||
result.b = a1.b + a2.b;
|
||||
|
||||
printf("%d %d %d %d: %d %d\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_3byte_gn1(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
|
||||
struct cls_struct_3byte_1 a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_3byte_1*)(args[0]);
|
||||
a2 = *(struct cls_struct_3byte_1*)(args[1]);
|
||||
|
||||
*(cls_struct_3byte_1*)resp = cls_struct_3byte_fn1(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[4];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_3byte_1 g_dbl = { 15, 125 };
|
||||
struct cls_struct_3byte_1 f_dbl = { 9, 19 };
|
||||
struct cls_struct_3byte_1 res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_uchar;
|
||||
cls_struct_fields[1] = &ffi_type_ushort;
|
||||
cls_struct_fields[2] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &g_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_3byte_fn1), &res_dbl, args_dbl);
|
||||
/* { dg-output "15 125 9 19: 24 144" } */
|
||||
printf("res: %d %d\n", res_dbl.a, res_dbl.b);
|
||||
/* { dg-output "\nres: 24 144" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_3byte_gn1, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_3byte_1(*)(cls_struct_3byte_1, cls_struct_3byte_1))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n15 125 9 19: 24 144" } */
|
||||
printf("res: %d %d\n", res_dbl.a, res_dbl.b);
|
||||
/* { dg-output "\nres: 24 144" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
98
.pc/msvc-changes/testsuite/libffi.call/cls_4_1byte.c
Normal file
98
.pc/msvc-changes/testsuite/libffi.call/cls_4_1byte.c
Normal file
@@ -0,0 +1,98 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Especially with small structures which may fit in one
|
||||
register. Depending on the ABI.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20030902 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_4_1byte {
|
||||
unsigned char a;
|
||||
unsigned char b;
|
||||
unsigned char c;
|
||||
unsigned char d;
|
||||
} cls_struct_4_1byte;
|
||||
|
||||
cls_struct_4_1byte cls_struct_4_1byte_fn(struct cls_struct_4_1byte a1,
|
||||
struct cls_struct_4_1byte a2)
|
||||
{
|
||||
struct cls_struct_4_1byte result;
|
||||
|
||||
result.a = a1.a + a2.a;
|
||||
result.b = a1.b + a2.b;
|
||||
result.c = a1.c + a2.c;
|
||||
result.d = a1.d + a2.d;
|
||||
|
||||
printf("%d %d %d %d %d %d %d %d: %d %d %d %d\n", a1.a, a1.b, a1.c, a1.d,
|
||||
a2.a, a2.b, a2.c, a2.d,
|
||||
result.a, result.b, result.c, result.d);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_4_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
|
||||
struct cls_struct_4_1byte a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_4_1byte*)(args[0]);
|
||||
a2 = *(struct cls_struct_4_1byte*)(args[1]);
|
||||
|
||||
*(cls_struct_4_1byte*)resp = cls_struct_4_1byte_fn(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[5];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_4_1byte g_dbl = { 12, 13, 14, 15 };
|
||||
struct cls_struct_4_1byte f_dbl = { 178, 179, 180, 181 };
|
||||
struct cls_struct_4_1byte res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_uchar;
|
||||
cls_struct_fields[1] = &ffi_type_uchar;
|
||||
cls_struct_fields[2] = &ffi_type_uchar;
|
||||
cls_struct_fields[3] = &ffi_type_uchar;
|
||||
cls_struct_fields[4] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &g_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_4_1byte_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "12 13 14 15 178 179 180 181: 190 192 194 196" } */
|
||||
printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
|
||||
/* { dg-output "\nres: 190 192 194 196" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_4_1byte_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_4_1byte(*)(cls_struct_4_1byte, cls_struct_4_1byte))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n12 13 14 15 178 179 180 181: 190 192 194 196" } */
|
||||
printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
|
||||
/* { dg-output "\nres: 190 192 194 196" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
90
.pc/msvc-changes/testsuite/libffi.call/cls_4byte.c
Normal file
90
.pc/msvc-changes/testsuite/libffi.call/cls_4byte.c
Normal file
@@ -0,0 +1,90 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Depending on the ABI. Check overlapping.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20030828 */
|
||||
|
||||
/* { dg-do run } */
|
||||
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_4byte {
|
||||
unsigned short a;
|
||||
unsigned short b;
|
||||
} cls_struct_4byte;
|
||||
|
||||
cls_struct_4byte cls_struct_4byte_fn(struct cls_struct_4byte a1,
|
||||
struct cls_struct_4byte a2)
|
||||
{
|
||||
struct cls_struct_4byte result;
|
||||
|
||||
result.a = a1.a + a2.a;
|
||||
result.b = a1.b + a2.b;
|
||||
|
||||
printf("%d %d %d %d: %d %d\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_4byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
|
||||
struct cls_struct_4byte a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_4byte*)(args[0]);
|
||||
a2 = *(struct cls_struct_4byte*)(args[1]);
|
||||
|
||||
*(cls_struct_4byte*)resp = cls_struct_4byte_fn(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[4];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_4byte g_dbl = { 127, 120 };
|
||||
struct cls_struct_4byte f_dbl = { 12, 128 };
|
||||
struct cls_struct_4byte res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_ushort;
|
||||
cls_struct_fields[1] = &ffi_type_ushort;
|
||||
cls_struct_fields[2] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &g_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_4byte_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "127 120 12 128: 139 248" } */
|
||||
printf("res: %d %d\n", res_dbl.a, res_dbl.b);
|
||||
/* { dg-output "\nres: 139 248" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_4byte_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_4byte(*)(cls_struct_4byte, cls_struct_4byte))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n127 120 12 128: 139 248" } */
|
||||
printf("res: %d %d\n", res_dbl.a, res_dbl.b);
|
||||
/* { dg-output "\nres: 139 248" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
109
.pc/msvc-changes/testsuite/libffi.call/cls_5_1_byte.c
Normal file
109
.pc/msvc-changes/testsuite/libffi.call/cls_5_1_byte.c
Normal file
@@ -0,0 +1,109 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Depending on the ABI. Check overlapping.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20050708 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_5byte {
|
||||
unsigned char a;
|
||||
unsigned char b;
|
||||
unsigned char c;
|
||||
unsigned char d;
|
||||
unsigned char e;
|
||||
} cls_struct_5byte;
|
||||
|
||||
cls_struct_5byte cls_struct_5byte_fn(struct cls_struct_5byte a1,
|
||||
struct cls_struct_5byte a2)
|
||||
{
|
||||
struct cls_struct_5byte result;
|
||||
|
||||
result.a = a1.a + a2.a;
|
||||
result.b = a1.b + a2.b;
|
||||
result.c = a1.c + a2.c;
|
||||
result.d = a1.d + a2.d;
|
||||
result.e = a1.e + a2.e;
|
||||
|
||||
printf("%d %d %d %d %d %d %d %d %d %d: %d %d %d %d %d\n",
|
||||
a1.a, a1.b, a1.c, a1.d, a1.e,
|
||||
a2.a, a2.b, a2.c, a2.d, a2.e,
|
||||
result.a, result.b, result.c, result.d, result.e);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_5byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
|
||||
struct cls_struct_5byte a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_5byte*)(args[0]);
|
||||
a2 = *(struct cls_struct_5byte*)(args[1]);
|
||||
|
||||
*(cls_struct_5byte*)resp = cls_struct_5byte_fn(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[6];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_5byte g_dbl = { 127, 120, 1, 3, 4 };
|
||||
struct cls_struct_5byte f_dbl = { 12, 128, 9, 3, 4 };
|
||||
struct cls_struct_5byte res_dbl = { 0, 0, 0, 0, 0 };
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_uchar;
|
||||
cls_struct_fields[1] = &ffi_type_uchar;
|
||||
cls_struct_fields[2] = &ffi_type_uchar;
|
||||
cls_struct_fields[3] = &ffi_type_uchar;
|
||||
cls_struct_fields[4] = &ffi_type_uchar;
|
||||
cls_struct_fields[5] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &g_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_5byte_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "127 120 1 3 4 12 128 9 3 4: 139 248 10 6 8" } */
|
||||
printf("res: %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
|
||||
res_dbl.d, res_dbl.e);
|
||||
/* { dg-output "\nres: 139 248 10 6 8" } */
|
||||
|
||||
res_dbl.a = 0;
|
||||
res_dbl.b = 0;
|
||||
res_dbl.c = 0;
|
||||
res_dbl.d = 0;
|
||||
res_dbl.e = 0;
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_5byte_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_5byte(*)(cls_struct_5byte, cls_struct_5byte))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n127 120 1 3 4 12 128 9 3 4: 139 248 10 6 8" } */
|
||||
printf("res: %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
|
||||
res_dbl.d, res_dbl.e);
|
||||
/* { dg-output "\nres: 139 248 10 6 8" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
98
.pc/msvc-changes/testsuite/libffi.call/cls_5byte.c
Normal file
98
.pc/msvc-changes/testsuite/libffi.call/cls_5byte.c
Normal file
@@ -0,0 +1,98 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Depending on the ABI. Check overlapping.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20030828 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_5byte {
|
||||
unsigned short a;
|
||||
unsigned short b;
|
||||
unsigned char c;
|
||||
} cls_struct_5byte;
|
||||
|
||||
cls_struct_5byte cls_struct_5byte_fn(struct cls_struct_5byte a1,
|
||||
struct cls_struct_5byte a2)
|
||||
{
|
||||
struct cls_struct_5byte result;
|
||||
|
||||
result.a = a1.a + a2.a;
|
||||
result.b = a1.b + a2.b;
|
||||
result.c = a1.c + a2.c;
|
||||
|
||||
printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c,
|
||||
a2.a, a2.b, a2.c,
|
||||
result.a, result.b, result.c);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_5byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
|
||||
struct cls_struct_5byte a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_5byte*)(args[0]);
|
||||
a2 = *(struct cls_struct_5byte*)(args[1]);
|
||||
|
||||
*(cls_struct_5byte*)resp = cls_struct_5byte_fn(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[4];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_5byte g_dbl = { 127, 120, 1 };
|
||||
struct cls_struct_5byte f_dbl = { 12, 128, 9 };
|
||||
struct cls_struct_5byte res_dbl = { 0, 0, 0 };
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_ushort;
|
||||
cls_struct_fields[1] = &ffi_type_ushort;
|
||||
cls_struct_fields[2] = &ffi_type_uchar;
|
||||
cls_struct_fields[3] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &g_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_5byte_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "127 120 1 12 128 9: 139 248 10" } */
|
||||
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 139 248 10" } */
|
||||
|
||||
res_dbl.a = 0;
|
||||
res_dbl.b = 0;
|
||||
res_dbl.c = 0;
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_5byte_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_5byte(*)(cls_struct_5byte, cls_struct_5byte))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n127 120 1 12 128 9: 139 248 10" } */
|
||||
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 139 248 10" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
124
.pc/msvc-changes/testsuite/libffi.call/cls_64byte.c
Normal file
124
.pc/msvc-changes/testsuite/libffi.call/cls_64byte.c
Normal file
@@ -0,0 +1,124 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Depending on the ABI. Check bigger struct which overlaps
|
||||
the gp and fp register count on Darwin/AIX/ppc64.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20030828 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_64byte {
|
||||
double a;
|
||||
double b;
|
||||
double c;
|
||||
double d;
|
||||
double e;
|
||||
double f;
|
||||
double g;
|
||||
double h;
|
||||
} cls_struct_64byte;
|
||||
|
||||
cls_struct_64byte cls_struct_64byte_fn(struct cls_struct_64byte b0,
|
||||
struct cls_struct_64byte b1,
|
||||
struct cls_struct_64byte b2,
|
||||
struct cls_struct_64byte b3)
|
||||
{
|
||||
struct cls_struct_64byte result;
|
||||
|
||||
result.a = b0.a + b1.a + b2.a + b3.a;
|
||||
result.b = b0.b + b1.b + b2.b + b3.b;
|
||||
result.c = b0.c + b1.c + b2.c + b3.c;
|
||||
result.d = b0.d + b1.d + b2.d + b3.d;
|
||||
result.e = b0.e + b1.e + b2.e + b3.e;
|
||||
result.f = b0.f + b1.f + b2.f + b3.f;
|
||||
result.g = b0.g + b1.g + b2.g + b3.g;
|
||||
result.h = b0.h + b1.h + b2.h + b3.h;
|
||||
|
||||
printf("%g %g %g %g %g %g %g %g\n", result.a, result.b, result.c,
|
||||
result.d, result.e, result.f, result.g, result.h);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_64byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
struct cls_struct_64byte b0, b1, b2, b3;
|
||||
|
||||
b0 = *(struct cls_struct_64byte*)(args[0]);
|
||||
b1 = *(struct cls_struct_64byte*)(args[1]);
|
||||
b2 = *(struct cls_struct_64byte*)(args[2]);
|
||||
b3 = *(struct cls_struct_64byte*)(args[3]);
|
||||
|
||||
*(cls_struct_64byte*)resp = cls_struct_64byte_fn(b0, b1, b2, b3);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[9];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_64byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0 };
|
||||
struct cls_struct_64byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0 };
|
||||
struct cls_struct_64byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0 };
|
||||
struct cls_struct_64byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0 };
|
||||
struct cls_struct_64byte res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_double;
|
||||
cls_struct_fields[1] = &ffi_type_double;
|
||||
cls_struct_fields[2] = &ffi_type_double;
|
||||
cls_struct_fields[3] = &ffi_type_double;
|
||||
cls_struct_fields[4] = &ffi_type_double;
|
||||
cls_struct_fields[5] = &ffi_type_double;
|
||||
cls_struct_fields[6] = &ffi_type_double;
|
||||
cls_struct_fields[7] = &ffi_type_double;
|
||||
cls_struct_fields[8] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = &cls_struct_type;
|
||||
dbl_arg_types[3] = &cls_struct_type;
|
||||
dbl_arg_types[4] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &e_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = &g_dbl;
|
||||
args_dbl[3] = &h_dbl;
|
||||
args_dbl[4] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_64byte_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "22 15 17 25 6 13 19 18" } */
|
||||
printf("res: %g %g %g %g %g %g %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c,
|
||||
res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h);
|
||||
/* { dg-output "\nres: 22 15 17 25 6 13 19 18" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_64byte_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_64byte(*)(cls_struct_64byte,
|
||||
cls_struct_64byte,
|
||||
cls_struct_64byte,
|
||||
cls_struct_64byte))
|
||||
(code))(e_dbl, f_dbl, g_dbl, h_dbl);
|
||||
/* { dg-output "\n22 15 17 25 6 13 19 18" } */
|
||||
printf("res: %g %g %g %g %g %g %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c,
|
||||
res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h);
|
||||
/* { dg-output "\nres: 22 15 17 25 6 13 19 18" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
113
.pc/msvc-changes/testsuite/libffi.call/cls_6_1_byte.c
Normal file
113
.pc/msvc-changes/testsuite/libffi.call/cls_6_1_byte.c
Normal file
@@ -0,0 +1,113 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Depending on the ABI. Check overlapping.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20050708 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_6byte {
|
||||
unsigned char a;
|
||||
unsigned char b;
|
||||
unsigned char c;
|
||||
unsigned char d;
|
||||
unsigned char e;
|
||||
unsigned char f;
|
||||
} cls_struct_6byte;
|
||||
|
||||
cls_struct_6byte cls_struct_6byte_fn(struct cls_struct_6byte a1,
|
||||
struct cls_struct_6byte a2)
|
||||
{
|
||||
struct cls_struct_6byte result;
|
||||
|
||||
result.a = a1.a + a2.a;
|
||||
result.b = a1.b + a2.b;
|
||||
result.c = a1.c + a2.c;
|
||||
result.d = a1.d + a2.d;
|
||||
result.e = a1.e + a2.e;
|
||||
result.f = a1.f + a2.f;
|
||||
|
||||
printf("%d %d %d %d %d %d %d %d %d %d %d %d: %d %d %d %d %d %d\n",
|
||||
a1.a, a1.b, a1.c, a1.d, a1.e, a1.f,
|
||||
a2.a, a2.b, a2.c, a2.d, a2.e, a2.f,
|
||||
result.a, result.b, result.c, result.d, result.e, result.f);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_6byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
|
||||
struct cls_struct_6byte a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_6byte*)(args[0]);
|
||||
a2 = *(struct cls_struct_6byte*)(args[1]);
|
||||
|
||||
*(cls_struct_6byte*)resp = cls_struct_6byte_fn(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[7];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_6byte g_dbl = { 127, 120, 1, 3, 4, 5 };
|
||||
struct cls_struct_6byte f_dbl = { 12, 128, 9, 3, 4, 5 };
|
||||
struct cls_struct_6byte res_dbl = { 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_uchar;
|
||||
cls_struct_fields[1] = &ffi_type_uchar;
|
||||
cls_struct_fields[2] = &ffi_type_uchar;
|
||||
cls_struct_fields[3] = &ffi_type_uchar;
|
||||
cls_struct_fields[4] = &ffi_type_uchar;
|
||||
cls_struct_fields[5] = &ffi_type_uchar;
|
||||
cls_struct_fields[6] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &g_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_6byte_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "127 120 1 3 4 5 12 128 9 3 4 5: 139 248 10 6 8 10" } */
|
||||
printf("res: %d %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
|
||||
res_dbl.d, res_dbl.e, res_dbl.f);
|
||||
/* { dg-output "\nres: 139 248 10 6 8 10" } */
|
||||
|
||||
res_dbl.a = 0;
|
||||
res_dbl.b = 0;
|
||||
res_dbl.c = 0;
|
||||
res_dbl.d = 0;
|
||||
res_dbl.e = 0;
|
||||
res_dbl.f = 0;
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_6byte_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_6byte(*)(cls_struct_6byte, cls_struct_6byte))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n127 120 1 3 4 5 12 128 9 3 4 5: 139 248 10 6 8 10" } */
|
||||
printf("res: %d %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
|
||||
res_dbl.d, res_dbl.e, res_dbl.f);
|
||||
/* { dg-output "\nres: 139 248 10 6 8 10" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
99
.pc/msvc-changes/testsuite/libffi.call/cls_6byte.c
Normal file
99
.pc/msvc-changes/testsuite/libffi.call/cls_6byte.c
Normal file
@@ -0,0 +1,99 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Depending on the ABI. Check overlapping.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20030828 */
|
||||
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_6byte {
|
||||
unsigned short a;
|
||||
unsigned short b;
|
||||
unsigned char c;
|
||||
unsigned char d;
|
||||
} cls_struct_6byte;
|
||||
|
||||
cls_struct_6byte cls_struct_6byte_fn(struct cls_struct_6byte a1,
|
||||
struct cls_struct_6byte a2)
|
||||
{
|
||||
struct cls_struct_6byte result;
|
||||
|
||||
result.a = a1.a + a2.a;
|
||||
result.b = a1.b + a2.b;
|
||||
result.c = a1.c + a2.c;
|
||||
result.d = a1.d + a2.d;
|
||||
|
||||
printf("%d %d %d %d %d %d %d %d: %d %d %d %d\n", a1.a, a1.b, a1.c, a1.d,
|
||||
a2.a, a2.b, a2.c, a2.d,
|
||||
result.a, result.b, result.c, result.d);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_6byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
|
||||
struct cls_struct_6byte a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_6byte*)(args[0]);
|
||||
a2 = *(struct cls_struct_6byte*)(args[1]);
|
||||
|
||||
*(cls_struct_6byte*)resp = cls_struct_6byte_fn(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[5];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_6byte g_dbl = { 127, 120, 1, 128 };
|
||||
struct cls_struct_6byte f_dbl = { 12, 128, 9, 127 };
|
||||
struct cls_struct_6byte res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_ushort;
|
||||
cls_struct_fields[1] = &ffi_type_ushort;
|
||||
cls_struct_fields[2] = &ffi_type_uchar;
|
||||
cls_struct_fields[3] = &ffi_type_uchar;
|
||||
cls_struct_fields[4] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &g_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_6byte_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "127 120 1 128 12 128 9 127: 139 248 10 255" } */
|
||||
printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
|
||||
/* { dg-output "\nres: 139 248 10 255" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_6byte_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_6byte(*)(cls_struct_6byte, cls_struct_6byte))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n127 120 1 128 12 128 9 127: 139 248 10 255" } */
|
||||
printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
|
||||
/* { dg-output "\nres: 139 248 10 255" } */
|
||||
|
||||
|
||||
exit(0);
|
||||
}
|
||||
117
.pc/msvc-changes/testsuite/libffi.call/cls_7_1_byte.c
Normal file
117
.pc/msvc-changes/testsuite/libffi.call/cls_7_1_byte.c
Normal file
@@ -0,0 +1,117 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Depending on the ABI. Check overlapping.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20050708 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_7byte {
|
||||
unsigned char a;
|
||||
unsigned char b;
|
||||
unsigned char c;
|
||||
unsigned char d;
|
||||
unsigned char e;
|
||||
unsigned char f;
|
||||
unsigned char g;
|
||||
} cls_struct_7byte;
|
||||
|
||||
cls_struct_7byte cls_struct_7byte_fn(struct cls_struct_7byte a1,
|
||||
struct cls_struct_7byte a2)
|
||||
{
|
||||
struct cls_struct_7byte result;
|
||||
|
||||
result.a = a1.a + a2.a;
|
||||
result.b = a1.b + a2.b;
|
||||
result.c = a1.c + a2.c;
|
||||
result.d = a1.d + a2.d;
|
||||
result.e = a1.e + a2.e;
|
||||
result.f = a1.f + a2.f;
|
||||
result.g = a1.g + a2.g;
|
||||
|
||||
printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d %d %d %d %d %d %d\n",
|
||||
a1.a, a1.b, a1.c, a1.d, a1.e, a1.f, a1.g,
|
||||
a2.a, a2.b, a2.c, a2.d, a2.e, a2.f, a2.g,
|
||||
result.a, result.b, result.c, result.d, result.e, result.f, result.g);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_7byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
|
||||
struct cls_struct_7byte a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_7byte*)(args[0]);
|
||||
a2 = *(struct cls_struct_7byte*)(args[1]);
|
||||
|
||||
*(cls_struct_7byte*)resp = cls_struct_7byte_fn(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[8];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_7byte g_dbl = { 127, 120, 1, 3, 4, 5, 6 };
|
||||
struct cls_struct_7byte f_dbl = { 12, 128, 9, 3, 4, 5, 6 };
|
||||
struct cls_struct_7byte res_dbl = { 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_uchar;
|
||||
cls_struct_fields[1] = &ffi_type_uchar;
|
||||
cls_struct_fields[2] = &ffi_type_uchar;
|
||||
cls_struct_fields[3] = &ffi_type_uchar;
|
||||
cls_struct_fields[4] = &ffi_type_uchar;
|
||||
cls_struct_fields[5] = &ffi_type_uchar;
|
||||
cls_struct_fields[6] = &ffi_type_uchar;
|
||||
cls_struct_fields[7] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &g_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_7byte_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "127 120 1 3 4 5 6 12 128 9 3 4 5 6: 139 248 10 6 8 10 12" } */
|
||||
printf("res: %d %d %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
|
||||
res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
|
||||
/* { dg-output "\nres: 139 248 10 6 8 10 12" } */
|
||||
|
||||
res_dbl.a = 0;
|
||||
res_dbl.b = 0;
|
||||
res_dbl.c = 0;
|
||||
res_dbl.d = 0;
|
||||
res_dbl.e = 0;
|
||||
res_dbl.f = 0;
|
||||
res_dbl.g = 0;
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_7byte_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_7byte(*)(cls_struct_7byte, cls_struct_7byte))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n127 120 1 3 4 5 6 12 128 9 3 4 5 6: 139 248 10 6 8 10 12" } */
|
||||
printf("res: %d %d %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
|
||||
res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
|
||||
/* { dg-output "\nres: 139 248 10 6 8 10 12" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
97
.pc/msvc-changes/testsuite/libffi.call/cls_7byte.c
Normal file
97
.pc/msvc-changes/testsuite/libffi.call/cls_7byte.c
Normal file
@@ -0,0 +1,97 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Depending on the ABI. Check overlapping.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20030828 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_7byte {
|
||||
unsigned short a;
|
||||
unsigned short b;
|
||||
unsigned char c;
|
||||
unsigned short d;
|
||||
} cls_struct_7byte;
|
||||
|
||||
cls_struct_7byte cls_struct_7byte_fn(struct cls_struct_7byte a1,
|
||||
struct cls_struct_7byte a2)
|
||||
{
|
||||
struct cls_struct_7byte result;
|
||||
|
||||
result.a = a1.a + a2.a;
|
||||
result.b = a1.b + a2.b;
|
||||
result.c = a1.c + a2.c;
|
||||
result.d = a1.d + a2.d;
|
||||
|
||||
printf("%d %d %d %d %d %d %d %d: %d %d %d %d\n", a1.a, a1.b, a1.c, a1.d,
|
||||
a2.a, a2.b, a2.c, a2.d,
|
||||
result.a, result.b, result.c, result.d);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_7byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
|
||||
struct cls_struct_7byte a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_7byte*)(args[0]);
|
||||
a2 = *(struct cls_struct_7byte*)(args[1]);
|
||||
|
||||
*(cls_struct_7byte*)resp = cls_struct_7byte_fn(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[5];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_7byte g_dbl = { 127, 120, 1, 254 };
|
||||
struct cls_struct_7byte f_dbl = { 12, 128, 9, 255 };
|
||||
struct cls_struct_7byte res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_ushort;
|
||||
cls_struct_fields[1] = &ffi_type_ushort;
|
||||
cls_struct_fields[2] = &ffi_type_uchar;
|
||||
cls_struct_fields[3] = &ffi_type_ushort;
|
||||
cls_struct_fields[4] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &g_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_7byte_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "127 120 1 254 12 128 9 255: 139 248 10 509" } */
|
||||
printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
|
||||
/* { dg-output "\nres: 139 248 10 509" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_7byte_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_7byte(*)(cls_struct_7byte, cls_struct_7byte))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n127 120 1 254 12 128 9 255: 139 248 10 509" } */
|
||||
printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
|
||||
/* { dg-output "\nres: 139 248 10 509" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
88
.pc/msvc-changes/testsuite/libffi.call/cls_8byte.c
Normal file
88
.pc/msvc-changes/testsuite/libffi.call/cls_8byte.c
Normal file
@@ -0,0 +1,88 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Depending on the ABI. Check overlapping.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20030828 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_8byte {
|
||||
int a;
|
||||
float b;
|
||||
} cls_struct_8byte;
|
||||
|
||||
cls_struct_8byte cls_struct_8byte_fn(struct cls_struct_8byte a1,
|
||||
struct cls_struct_8byte a2)
|
||||
{
|
||||
struct cls_struct_8byte result;
|
||||
|
||||
result.a = a1.a + a2.a;
|
||||
result.b = a1.b + a2.b;
|
||||
|
||||
printf("%d %g %d %g: %d %g\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_8byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
|
||||
struct cls_struct_8byte a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_8byte*)(args[0]);
|
||||
a2 = *(struct cls_struct_8byte*)(args[1]);
|
||||
|
||||
*(cls_struct_8byte*)resp = cls_struct_8byte_fn(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[4];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_8byte g_dbl = { 1, 2.0 };
|
||||
struct cls_struct_8byte f_dbl = { 4, 5.0 };
|
||||
struct cls_struct_8byte res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_sint;
|
||||
cls_struct_fields[1] = &ffi_type_float;
|
||||
cls_struct_fields[2] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &g_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_8byte_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "1 2 4 5: 5 7" } */
|
||||
printf("res: %d %g\n", res_dbl.a, res_dbl.b);
|
||||
/* { dg-output "\nres: 5 7" } */
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_8byte_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_8byte(*)(cls_struct_8byte, cls_struct_8byte))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n1 2 4 5: 5 7" } */
|
||||
printf("res: %d %g\n", res_dbl.a, res_dbl.b);
|
||||
/* { dg-output "\nres: 5 7" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
90
.pc/msvc-changes/testsuite/libffi.call/cls_9byte1.c
Normal file
90
.pc/msvc-changes/testsuite/libffi.call/cls_9byte1.c
Normal file
@@ -0,0 +1,90 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Depending on the ABI. Darwin/AIX do double-word
|
||||
alignment of the struct if the first element is a double.
|
||||
Check that it does not here.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20030914 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_9byte {
|
||||
int a;
|
||||
double b;
|
||||
} cls_struct_9byte;
|
||||
|
||||
cls_struct_9byte cls_struct_9byte_fn(struct cls_struct_9byte b1,
|
||||
struct cls_struct_9byte b2)
|
||||
{
|
||||
struct cls_struct_9byte result;
|
||||
|
||||
result.a = b1.a + b2.a;
|
||||
result.b = b1.b + b2.b;
|
||||
|
||||
printf("%d %g %d %g: %d %g\n", b1.a, b1.b, b2.a, b2.b,
|
||||
result.a, result.b);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void cls_struct_9byte_gn(ffi_cif* cif __UNUSED__, void* resp,
|
||||
void** args, void* userdata __UNUSED__)
|
||||
{
|
||||
struct cls_struct_9byte b1, b2;
|
||||
|
||||
b1 = *(struct cls_struct_9byte*)(args[0]);
|
||||
b2 = *(struct cls_struct_9byte*)(args[1]);
|
||||
|
||||
*(cls_struct_9byte*)resp = cls_struct_9byte_fn(b1, b2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[3];
|
||||
ffi_type* cls_struct_fields[3];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[3];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_9byte h_dbl = { 7, 8.0};
|
||||
struct cls_struct_9byte j_dbl = { 1, 9.0};
|
||||
struct cls_struct_9byte res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_sint;
|
||||
cls_struct_fields[1] = &ffi_type_double;
|
||||
cls_struct_fields[2] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &h_dbl;
|
||||
args_dbl[1] = &j_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_9byte_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "7 8 1 9: 8 17" } */
|
||||
printf("res: %d %g\n", res_dbl.a, res_dbl.b);
|
||||
/* { dg-output "\nres: 8 17" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_9byte_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_9byte(*)(cls_struct_9byte, cls_struct_9byte))(code))(h_dbl, j_dbl);
|
||||
/* { dg-output "\n7 8 1 9: 8 17" } */
|
||||
printf("res: %d %g\n", res_dbl.a, res_dbl.b);
|
||||
/* { dg-output "\nres: 8 17" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
91
.pc/msvc-changes/testsuite/libffi.call/cls_9byte2.c
Normal file
91
.pc/msvc-changes/testsuite/libffi.call/cls_9byte2.c
Normal file
@@ -0,0 +1,91 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Depending on the ABI. Darwin/AIX do double-word
|
||||
alignment of the struct if the first element is a double.
|
||||
Check that it does here.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20030914 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_9byte {
|
||||
double a;
|
||||
int b;
|
||||
} cls_struct_9byte;
|
||||
|
||||
cls_struct_9byte cls_struct_9byte_fn(struct cls_struct_9byte b1,
|
||||
struct cls_struct_9byte b2)
|
||||
{
|
||||
struct cls_struct_9byte result;
|
||||
|
||||
result.a = b1.a + b2.a;
|
||||
result.b = b1.b + b2.b;
|
||||
|
||||
printf("%g %d %g %d: %g %d\n", b1.a, b1.b, b2.a, b2.b,
|
||||
result.a, result.b);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void cls_struct_9byte_gn(ffi_cif* cif __UNUSED__, void* resp,
|
||||
void** args, void* userdata __UNUSED__)
|
||||
{
|
||||
struct cls_struct_9byte b1, b2;
|
||||
|
||||
b1 = *(struct cls_struct_9byte*)(args[0]);
|
||||
b2 = *(struct cls_struct_9byte*)(args[1]);
|
||||
|
||||
*(cls_struct_9byte*)resp = cls_struct_9byte_fn(b1, b2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[3];
|
||||
ffi_type* cls_struct_fields[3];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[3];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_9byte h_dbl = { 7.0, 8};
|
||||
struct cls_struct_9byte j_dbl = { 1.0, 9};
|
||||
struct cls_struct_9byte res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_double;
|
||||
cls_struct_fields[1] = &ffi_type_sint;
|
||||
cls_struct_fields[2] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &h_dbl;
|
||||
args_dbl[1] = &j_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_9byte_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "7 8 1 9: 8 17" } */
|
||||
printf("res: %g %d\n", res_dbl.a, res_dbl.b);
|
||||
/* { dg-output "\nres: 8 17" } */
|
||||
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_9byte_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_9byte(*)(cls_struct_9byte, cls_struct_9byte))(code))(h_dbl, j_dbl);
|
||||
/* { dg-output "\n7 8 1 9: 8 17" } */
|
||||
printf("res: %g %d\n", res_dbl.a, res_dbl.b);
|
||||
/* { dg-output "\nres: 8 17" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
93
.pc/msvc-changes/testsuite/libffi.call/cls_align_double.c
Normal file
93
.pc/msvc-changes/testsuite/libffi.call/cls_align_double.c
Normal file
@@ -0,0 +1,93 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure alignment of double.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <hos@tamanegi.org> 20031203 */
|
||||
|
||||
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_align {
|
||||
unsigned char a;
|
||||
double b;
|
||||
unsigned char c;
|
||||
} cls_struct_align;
|
||||
|
||||
cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
|
||||
struct cls_struct_align a2)
|
||||
{
|
||||
struct cls_struct_align result;
|
||||
|
||||
result.a = a1.a + a2.a;
|
||||
result.b = a1.b + a2.b;
|
||||
result.c = a1.c + a2.c;
|
||||
|
||||
printf("%d %g %d %d %g %d: %d %g %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
|
||||
struct cls_struct_align a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_align*)(args[0]);
|
||||
a2 = *(struct cls_struct_align*)(args[1]);
|
||||
|
||||
*(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[4];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_align g_dbl = { 12, 4951, 127 };
|
||||
struct cls_struct_align f_dbl = { 1, 9320, 13 };
|
||||
struct cls_struct_align res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_uchar;
|
||||
cls_struct_fields[1] = &ffi_type_double;
|
||||
cls_struct_fields[2] = &ffi_type_uchar;
|
||||
cls_struct_fields[3] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &g_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
|
||||
printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 13 14271 140" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
|
||||
printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 13 14271 140" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
91
.pc/msvc-changes/testsuite/libffi.call/cls_align_float.c
Normal file
91
.pc/msvc-changes/testsuite/libffi.call/cls_align_float.c
Normal file
@@ -0,0 +1,91 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure alignment of float.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <hos@tamanegi.org> 20031203 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_align {
|
||||
unsigned char a;
|
||||
float b;
|
||||
unsigned char c;
|
||||
} cls_struct_align;
|
||||
|
||||
cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
|
||||
struct cls_struct_align a2)
|
||||
{
|
||||
struct cls_struct_align result;
|
||||
|
||||
result.a = a1.a + a2.a;
|
||||
result.b = a1.b + a2.b;
|
||||
result.c = a1.c + a2.c;
|
||||
|
||||
printf("%d %g %d %d %g %d: %d %g %d\n", a1.a, (double)a1.b, a1.c, a2.a, (double)a2.b, a2.c, result.a, (double)result.b, result.c);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
|
||||
struct cls_struct_align a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_align*)(args[0]);
|
||||
a2 = *(struct cls_struct_align*)(args[1]);
|
||||
|
||||
*(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[4];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_align g_dbl = { 12, 4951, 127 };
|
||||
struct cls_struct_align f_dbl = { 1, 9320, 13 };
|
||||
struct cls_struct_align res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_uchar;
|
||||
cls_struct_fields[1] = &ffi_type_float;
|
||||
cls_struct_fields[2] = &ffi_type_uchar;
|
||||
cls_struct_fields[3] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &g_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
|
||||
printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 13 14271 140" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
|
||||
printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 13 14271 140" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure alignment of long double.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <hos@tamanegi.org> 20031203 */
|
||||
|
||||
/* { dg-do run } */
|
||||
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_align {
|
||||
unsigned char a;
|
||||
long double b;
|
||||
unsigned char c;
|
||||
} cls_struct_align;
|
||||
|
||||
cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
|
||||
struct cls_struct_align a2)
|
||||
{
|
||||
struct cls_struct_align result;
|
||||
|
||||
result.a = a1.a + a2.a;
|
||||
result.b = a1.b + a2.b;
|
||||
result.c = a1.c + a2.c;
|
||||
|
||||
printf("%d %g %d %d %g %d: %d %g %d\n", a1.a, (double)a1.b, a1.c, a2.a, (double)a2.b, a2.c, result.a, (double)result.b, result.c);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
|
||||
struct cls_struct_align a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_align*)(args[0]);
|
||||
a2 = *(struct cls_struct_align*)(args[1]);
|
||||
|
||||
*(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[4];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_align g_dbl = { 12, 4951, 127 };
|
||||
struct cls_struct_align f_dbl = { 1, 9320, 13 };
|
||||
struct cls_struct_align res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_uchar;
|
||||
cls_struct_fields[1] = &ffi_type_longdouble;
|
||||
cls_struct_fields[2] = &ffi_type_uchar;
|
||||
cls_struct_fields[3] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &g_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
|
||||
printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 13 14271 140" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
|
||||
printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 13 14271 140" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure alignment of long double.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <hos@tamanegi.org> 20031203 */
|
||||
|
||||
/* { dg-excess-errors "no long double format" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
|
||||
/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
|
||||
/* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */
|
||||
/* { dg-output "" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
|
||||
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_align {
|
||||
long double a;
|
||||
long double b;
|
||||
long double c;
|
||||
long double d;
|
||||
long double e;
|
||||
long double f;
|
||||
long double g;
|
||||
} cls_struct_align;
|
||||
|
||||
cls_struct_align cls_struct_align_fn(
|
||||
cls_struct_align a1,
|
||||
cls_struct_align a2)
|
||||
{
|
||||
struct cls_struct_align r;
|
||||
|
||||
r.a = a1.a + a2.a;
|
||||
r.b = a1.b + a2.b;
|
||||
r.c = a1.c + a2.c;
|
||||
r.d = a1.d + a2.d;
|
||||
r.e = a1.e + a2.e;
|
||||
r.f = a1.f + a2.f;
|
||||
r.g = a1.g + a2.g;
|
||||
|
||||
printf("%Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg: "
|
||||
"%Lg %Lg %Lg %Lg %Lg %Lg %Lg\n",
|
||||
a1.a, a1.b, a1.c, a1.d, a1.e, a1.f, a1.g,
|
||||
a2.a, a2.b, a2.c, a2.d, a2.e, a2.f, a2.g,
|
||||
r.a, r.b, r.c, r.d, r.e, r.f, r.g);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
cls_struct_align cls_struct_align_fn2(
|
||||
cls_struct_align a1)
|
||||
{
|
||||
struct cls_struct_align r;
|
||||
|
||||
r.a = a1.a + 1;
|
||||
r.b = a1.b + 1;
|
||||
r.c = a1.c + 1;
|
||||
r.d = a1.d + 1;
|
||||
r.e = a1.e + 1;
|
||||
r.f = a1.f + 1;
|
||||
r.g = a1.g + 1;
|
||||
|
||||
printf("%Lg %Lg %Lg %Lg %Lg %Lg %Lg: "
|
||||
"%Lg %Lg %Lg %Lg %Lg %Lg %Lg\n",
|
||||
a1.a, a1.b, a1.c, a1.d, a1.e, a1.f, a1.g,
|
||||
r.a, r.b, r.c, r.d, r.e, r.f, r.g);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
struct cls_struct_align a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_align*)(args[0]);
|
||||
a2 = *(struct cls_struct_align*)(args[1]);
|
||||
|
||||
*(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[3];
|
||||
ffi_type* cls_struct_fields[8];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[3];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_align g_dbl = { 1, 2, 3, 4, 5, 6, 7 };
|
||||
struct cls_struct_align f_dbl = { 8, 9, 10, 11, 12, 13, 14 };
|
||||
struct cls_struct_align res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_longdouble;
|
||||
cls_struct_fields[1] = &ffi_type_longdouble;
|
||||
cls_struct_fields[2] = &ffi_type_longdouble;
|
||||
cls_struct_fields[3] = &ffi_type_longdouble;
|
||||
cls_struct_fields[4] = &ffi_type_longdouble;
|
||||
cls_struct_fields[5] = &ffi_type_longdouble;
|
||||
cls_struct_fields[6] = &ffi_type_longdouble;
|
||||
cls_struct_fields[7] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &g_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "1 2 3 4 5 6 7 8 9 10 11 12 13 14: 9 11 13 15 17 19 21" } */
|
||||
printf("res: %Lg %Lg %Lg %Lg %Lg %Lg %Lg\n", res_dbl.a, res_dbl.b,
|
||||
res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
|
||||
/* { dg-output "\nres: 9 11 13 15 17 19 21" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n1 2 3 4 5 6 7 8 9 10 11 12 13 14: 9 11 13 15 17 19 21" } */
|
||||
printf("res: %Lg %Lg %Lg %Lg %Lg %Lg %Lg\n", res_dbl.a, res_dbl.b,
|
||||
res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
|
||||
/* { dg-output "\nres: 9 11 13 15 17 19 21" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure alignment of long double.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: Blake Chaffin 6/18/2007
|
||||
*/
|
||||
|
||||
/* { dg-excess-errors "no long double format" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
|
||||
/* { dg-do run { xfail strongarm*-*-* } } */
|
||||
/* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */
|
||||
/* { dg-output "" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
|
||||
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_align {
|
||||
long double a;
|
||||
long double b;
|
||||
long double c;
|
||||
long double d;
|
||||
long double e;
|
||||
double f;
|
||||
long double g;
|
||||
} cls_struct_align;
|
||||
|
||||
cls_struct_align cls_struct_align_fn(
|
||||
cls_struct_align a1,
|
||||
cls_struct_align a2)
|
||||
{
|
||||
struct cls_struct_align r;
|
||||
|
||||
r.a = a1.a + a2.a;
|
||||
r.b = a1.b + a2.b;
|
||||
r.c = a1.c + a2.c;
|
||||
r.d = a1.d + a2.d;
|
||||
r.e = a1.e + a2.e;
|
||||
r.f = a1.f + a2.f;
|
||||
r.g = a1.g + a2.g;
|
||||
|
||||
printf("%Lg %Lg %Lg %Lg %Lg %g %Lg %Lg %Lg %Lg %Lg %Lg %g %Lg: "
|
||||
"%Lg %Lg %Lg %Lg %Lg %g %Lg\n",
|
||||
a1.a, a1.b, a1.c, a1.d, a1.e, a1.f, a1.g,
|
||||
a2.a, a2.b, a2.c, a2.d, a2.e, a2.f, a2.g,
|
||||
r.a, r.b, r.c, r.d, r.e, r.f, r.g);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
struct cls_struct_align a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_align*)(args[0]);
|
||||
a2 = *(struct cls_struct_align*)(args[1]);
|
||||
|
||||
*(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[3];
|
||||
ffi_type* cls_struct_fields[8];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[3];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_align g_dbl = { 1, 2, 3, 4, 5, 6, 7 };
|
||||
struct cls_struct_align f_dbl = { 8, 9, 10, 11, 12, 13, 14 };
|
||||
struct cls_struct_align res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_longdouble;
|
||||
cls_struct_fields[1] = &ffi_type_longdouble;
|
||||
cls_struct_fields[2] = &ffi_type_longdouble;
|
||||
cls_struct_fields[3] = &ffi_type_longdouble;
|
||||
cls_struct_fields[4] = &ffi_type_longdouble;
|
||||
cls_struct_fields[5] = &ffi_type_double;
|
||||
cls_struct_fields[6] = &ffi_type_longdouble;
|
||||
cls_struct_fields[7] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &g_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "1 2 3 4 5 6 7 8 9 10 11 12 13 14: 9 11 13 15 17 19 21" } */
|
||||
printf("res: %Lg %Lg %Lg %Lg %Lg %g %Lg\n", res_dbl.a, res_dbl.b,
|
||||
res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
|
||||
/* { dg-output "\nres: 9 11 13 15 17 19 21" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n1 2 3 4 5 6 7 8 9 10 11 12 13 14: 9 11 13 15 17 19 21" } */
|
||||
printf("res: %Lg %Lg %Lg %Lg %Lg %g %Lg\n", res_dbl.a, res_dbl.b,
|
||||
res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
|
||||
/* { dg-output "\nres: 9 11 13 15 17 19 21" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
95
.pc/msvc-changes/testsuite/libffi.call/cls_align_pointer.c
Normal file
95
.pc/msvc-changes/testsuite/libffi.call/cls_align_pointer.c
Normal file
@@ -0,0 +1,95 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure alignment of pointer.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <hos@tamanegi.org> 20031203 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_align {
|
||||
unsigned char a;
|
||||
void *b;
|
||||
unsigned char c;
|
||||
} cls_struct_align;
|
||||
|
||||
cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
|
||||
struct cls_struct_align a2)
|
||||
{
|
||||
struct cls_struct_align result;
|
||||
|
||||
result.a = a1.a + a2.a;
|
||||
result.b = (void *)((uintptr_t)a1.b + (uintptr_t)a2.b);
|
||||
result.c = a1.c + a2.c;
|
||||
|
||||
printf("%d %" PRIuPTR " %d %d %" PRIuPTR " %d: %d %" PRIuPTR " %d\n",
|
||||
a1.a, (uintptr_t)a1.b, a1.c,
|
||||
a2.a, (uintptr_t)a2.b, a2.c,
|
||||
result.a, (uintptr_t)result.b,
|
||||
result.c);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
|
||||
struct cls_struct_align a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_align*)(args[0]);
|
||||
a2 = *(struct cls_struct_align*)(args[1]);
|
||||
|
||||
*(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[4];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_align g_dbl = { 12, (void *)4951, 127 };
|
||||
struct cls_struct_align f_dbl = { 1, (void *)9320, 13 };
|
||||
struct cls_struct_align res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_uchar;
|
||||
cls_struct_fields[1] = &ffi_type_pointer;
|
||||
cls_struct_fields[2] = &ffi_type_uchar;
|
||||
cls_struct_fields[3] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &g_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
|
||||
printf("res: %d %" PRIuPTR " %d\n", res_dbl.a, (uintptr_t)res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 13 14271 140" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
|
||||
printf("res: %d %" PRIuPTR " %d\n", res_dbl.a, (uintptr_t)res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 13 14271 140" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
91
.pc/msvc-changes/testsuite/libffi.call/cls_align_sint16.c
Normal file
91
.pc/msvc-changes/testsuite/libffi.call/cls_align_sint16.c
Normal file
@@ -0,0 +1,91 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure alignment of sint16.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <hos@tamanegi.org> 20031203 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_align {
|
||||
unsigned char a;
|
||||
signed short b;
|
||||
unsigned char c;
|
||||
} cls_struct_align;
|
||||
|
||||
cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
|
||||
struct cls_struct_align a2)
|
||||
{
|
||||
struct cls_struct_align result;
|
||||
|
||||
result.a = a1.a + a2.a;
|
||||
result.b = a1.b + a2.b;
|
||||
result.c = a1.c + a2.c;
|
||||
|
||||
printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
|
||||
struct cls_struct_align a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_align*)(args[0]);
|
||||
a2 = *(struct cls_struct_align*)(args[1]);
|
||||
|
||||
*(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[4];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_align g_dbl = { 12, 4951, 127 };
|
||||
struct cls_struct_align f_dbl = { 1, 9320, 13 };
|
||||
struct cls_struct_align res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_uchar;
|
||||
cls_struct_fields[1] = &ffi_type_sshort;
|
||||
cls_struct_fields[2] = &ffi_type_uchar;
|
||||
cls_struct_fields[3] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &g_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
|
||||
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 13 14271 140" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
|
||||
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 13 14271 140" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
91
.pc/msvc-changes/testsuite/libffi.call/cls_align_sint32.c
Normal file
91
.pc/msvc-changes/testsuite/libffi.call/cls_align_sint32.c
Normal file
@@ -0,0 +1,91 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure alignment of sint32.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <hos@tamanegi.org> 20031203 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_align {
|
||||
unsigned char a;
|
||||
signed int b;
|
||||
unsigned char c;
|
||||
} cls_struct_align;
|
||||
|
||||
cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
|
||||
struct cls_struct_align a2)
|
||||
{
|
||||
struct cls_struct_align result;
|
||||
|
||||
result.a = a1.a + a2.a;
|
||||
result.b = a1.b + a2.b;
|
||||
result.c = a1.c + a2.c;
|
||||
|
||||
printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
|
||||
struct cls_struct_align a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_align*)(args[0]);
|
||||
a2 = *(struct cls_struct_align*)(args[1]);
|
||||
|
||||
*(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[4];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_align g_dbl = { 12, 4951, 127 };
|
||||
struct cls_struct_align f_dbl = { 1, 9320, 13 };
|
||||
struct cls_struct_align res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_uchar;
|
||||
cls_struct_fields[1] = &ffi_type_sint;
|
||||
cls_struct_fields[2] = &ffi_type_uchar;
|
||||
cls_struct_fields[3] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &g_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
|
||||
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 13 14271 140" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
|
||||
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 13 14271 140" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
92
.pc/msvc-changes/testsuite/libffi.call/cls_align_sint64.c
Normal file
92
.pc/msvc-changes/testsuite/libffi.call/cls_align_sint64.c
Normal file
@@ -0,0 +1,92 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure alignment of sint64.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <hos@tamanegi.org> 20031203 */
|
||||
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_align {
|
||||
unsigned char a;
|
||||
signed long long b;
|
||||
unsigned char c;
|
||||
} cls_struct_align;
|
||||
|
||||
cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
|
||||
struct cls_struct_align a2)
|
||||
{
|
||||
struct cls_struct_align result;
|
||||
|
||||
result.a = a1.a + a2.a;
|
||||
result.b = a1.b + a2.b;
|
||||
result.c = a1.c + a2.c;
|
||||
|
||||
printf("%d %" PRIdLL " %d %d %" PRIdLL " %d: %d %" PRIdLL " %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
|
||||
struct cls_struct_align a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_align*)(args[0]);
|
||||
a2 = *(struct cls_struct_align*)(args[1]);
|
||||
|
||||
*(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[4];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_align g_dbl = { 12, 4951, 127 };
|
||||
struct cls_struct_align f_dbl = { 1, 9320, 13 };
|
||||
struct cls_struct_align res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_uchar;
|
||||
cls_struct_fields[1] = &ffi_type_sint64;
|
||||
cls_struct_fields[2] = &ffi_type_uchar;
|
||||
cls_struct_fields[3] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &g_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
|
||||
printf("res: %d %" PRIdLL " %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 13 14271 140" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
|
||||
printf("res: %d %" PRIdLL " %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 13 14271 140" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
91
.pc/msvc-changes/testsuite/libffi.call/cls_align_uint16.c
Normal file
91
.pc/msvc-changes/testsuite/libffi.call/cls_align_uint16.c
Normal file
@@ -0,0 +1,91 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure alignment of uint16.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <hos@tamanegi.org> 20031203 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_align {
|
||||
unsigned char a;
|
||||
unsigned short b;
|
||||
unsigned char c;
|
||||
} cls_struct_align;
|
||||
|
||||
cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
|
||||
struct cls_struct_align a2)
|
||||
{
|
||||
struct cls_struct_align result;
|
||||
|
||||
result.a = a1.a + a2.a;
|
||||
result.b = a1.b + a2.b;
|
||||
result.c = a1.c + a2.c;
|
||||
|
||||
printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
|
||||
struct cls_struct_align a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_align*)(args[0]);
|
||||
a2 = *(struct cls_struct_align*)(args[1]);
|
||||
|
||||
*(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[4];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_align g_dbl = { 12, 4951, 127 };
|
||||
struct cls_struct_align f_dbl = { 1, 9320, 13 };
|
||||
struct cls_struct_align res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_uchar;
|
||||
cls_struct_fields[1] = &ffi_type_ushort;
|
||||
cls_struct_fields[2] = &ffi_type_uchar;
|
||||
cls_struct_fields[3] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &g_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
|
||||
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 13 14271 140" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
|
||||
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 13 14271 140" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
91
.pc/msvc-changes/testsuite/libffi.call/cls_align_uint32.c
Normal file
91
.pc/msvc-changes/testsuite/libffi.call/cls_align_uint32.c
Normal file
@@ -0,0 +1,91 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure alignment of uint32.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <hos@tamanegi.org> 20031203 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_align {
|
||||
unsigned char a;
|
||||
unsigned int b;
|
||||
unsigned char c;
|
||||
} cls_struct_align;
|
||||
|
||||
cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
|
||||
struct cls_struct_align a2)
|
||||
{
|
||||
struct cls_struct_align result;
|
||||
|
||||
result.a = a1.a + a2.a;
|
||||
result.b = a1.b + a2.b;
|
||||
result.c = a1.c + a2.c;
|
||||
|
||||
printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
|
||||
struct cls_struct_align a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_align*)(args[0]);
|
||||
a2 = *(struct cls_struct_align*)(args[1]);
|
||||
|
||||
*(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[4];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_align g_dbl = { 12, 4951, 127 };
|
||||
struct cls_struct_align f_dbl = { 1, 9320, 13 };
|
||||
struct cls_struct_align res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_uchar;
|
||||
cls_struct_fields[1] = &ffi_type_uint;
|
||||
cls_struct_fields[2] = &ffi_type_uchar;
|
||||
cls_struct_fields[3] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &g_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
|
||||
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 13 14271 140" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
|
||||
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 13 14271 140" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
93
.pc/msvc-changes/testsuite/libffi.call/cls_align_uint64.c
Normal file
93
.pc/msvc-changes/testsuite/libffi.call/cls_align_uint64.c
Normal file
@@ -0,0 +1,93 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure alignment of uint64.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <hos@tamanegi.org> 20031203 */
|
||||
|
||||
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_align {
|
||||
unsigned char a;
|
||||
unsigned long long b;
|
||||
unsigned char c;
|
||||
} cls_struct_align;
|
||||
|
||||
cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
|
||||
struct cls_struct_align a2)
|
||||
{
|
||||
struct cls_struct_align result;
|
||||
|
||||
result.a = a1.a + a2.a;
|
||||
result.b = a1.b + a2.b;
|
||||
result.c = a1.c + a2.c;
|
||||
|
||||
printf("%d %" PRIdLL " %d %d %" PRIdLL " %d: %d %" PRIdLL " %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
|
||||
struct cls_struct_align a1, a2;
|
||||
|
||||
a1 = *(struct cls_struct_align*)(args[0]);
|
||||
a2 = *(struct cls_struct_align*)(args[1]);
|
||||
|
||||
*(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[4];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct cls_struct_align g_dbl = { 12, 4951, 127 };
|
||||
struct cls_struct_align f_dbl = { 1, 9320, 13 };
|
||||
struct cls_struct_align res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_uchar;
|
||||
cls_struct_fields[1] = &ffi_type_uint64;
|
||||
cls_struct_fields[2] = &ffi_type_uchar;
|
||||
cls_struct_fields[3] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &g_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
|
||||
printf("res: %d %" PRIdLL " %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 13 14271 140" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
|
||||
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
|
||||
printf("res: %d %" PRIdLL " %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
|
||||
/* { dg-output "\nres: 13 14271 140" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
66
.pc/msvc-changes/testsuite/libffi.call/cls_dbls_struct.c
Normal file
66
.pc/msvc-changes/testsuite/libffi.call/cls_dbls_struct.c
Normal file
@@ -0,0 +1,66 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check double arguments in structs.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: Blake Chaffin 6/23/2007 */
|
||||
|
||||
/* { dg-do run } */
|
||||
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct Dbls {
|
||||
double x;
|
||||
double y;
|
||||
} Dbls;
|
||||
|
||||
void
|
||||
closure_test_fn(Dbls p)
|
||||
{
|
||||
printf("%.1f %.1f\n", p.x, p.y);
|
||||
}
|
||||
|
||||
void
|
||||
closure_test_gn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__,
|
||||
void** args, void* userdata __UNUSED__)
|
||||
{
|
||||
closure_test_fn(*(Dbls*)args[0]);
|
||||
}
|
||||
|
||||
int main(int argc __UNUSED__, char** argv __UNUSED__)
|
||||
{
|
||||
ffi_cif cif;
|
||||
|
||||
void *code;
|
||||
ffi_closure* pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
ffi_type* cl_arg_types[1];
|
||||
|
||||
ffi_type ts1_type;
|
||||
ffi_type* ts1_type_elements[4];
|
||||
|
||||
ts1_type.size = 0;
|
||||
ts1_type.alignment = 0;
|
||||
ts1_type.type = FFI_TYPE_STRUCT;
|
||||
ts1_type.elements = ts1_type_elements;
|
||||
|
||||
ts1_type_elements[0] = &ffi_type_double;
|
||||
ts1_type_elements[1] = &ffi_type_double;
|
||||
ts1_type_elements[2] = NULL;
|
||||
|
||||
cl_arg_types[0] = &ts1_type;
|
||||
|
||||
Dbls arg = { 1.0, 2.0 };
|
||||
|
||||
/* Initialize the cif */
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
|
||||
&ffi_type_void, cl_arg_types) == FFI_OK);
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_gn, NULL, code) == FFI_OK);
|
||||
|
||||
((void*(*)(Dbls))(code))(arg);
|
||||
/* { dg-output "1.0 2.0\n" } */
|
||||
|
||||
closure_test_fn(arg);
|
||||
/* { dg-output "1.0 2.0\n" } */
|
||||
|
||||
return 0;
|
||||
}
|
||||
140
.pc/msvc-changes/testsuite/libffi.call/cls_pointer_stack.c
Normal file
140
.pc/msvc-changes/testsuite/libffi.call/cls_pointer_stack.c
Normal file
@@ -0,0 +1,140 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check pointer arguments across multiple hideous stack frames.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: Blake Chaffin 6/7/2007 */
|
||||
|
||||
/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
|
||||
#include "ffitest.h"
|
||||
|
||||
static long dummyVar;
|
||||
|
||||
long dummy_func(
|
||||
long double a1, char b1,
|
||||
long double a2, char b2,
|
||||
long double a3, char b3,
|
||||
long double a4, char b4)
|
||||
{
|
||||
return a1 + b1 + a2 + b2 + a3 + b3 + a4 + b4;
|
||||
}
|
||||
|
||||
void* cls_pointer_fn2(void* a1, void* a2)
|
||||
{
|
||||
long double trample1 = (intptr_t)a1 + (intptr_t)a2;
|
||||
char trample2 = ((char*)&a1)[0] + ((char*)&a2)[0];
|
||||
long double trample3 = (intptr_t)trample1 + (intptr_t)a1;
|
||||
char trample4 = trample2 + ((char*)&a1)[1];
|
||||
long double trample5 = (intptr_t)trample3 + (intptr_t)a2;
|
||||
char trample6 = trample4 + ((char*)&a2)[1];
|
||||
long double trample7 = (intptr_t)trample5 + (intptr_t)trample1;
|
||||
char trample8 = trample6 + trample2;
|
||||
|
||||
dummyVar = dummy_func(trample1, trample2, trample3, trample4,
|
||||
trample5, trample6, trample7, trample8);
|
||||
|
||||
void* result = (void*)((intptr_t)a1 + (intptr_t)a2);
|
||||
|
||||
printf("0x%08x 0x%08x: 0x%08x\n",
|
||||
(unsigned int)(uintptr_t) a1,
|
||||
(unsigned int)(uintptr_t) a2,
|
||||
(unsigned int)(uintptr_t) result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void* cls_pointer_fn1(void* a1, void* a2)
|
||||
{
|
||||
long double trample1 = (intptr_t)a1 + (intptr_t)a2;
|
||||
char trample2 = ((char*)&a1)[0] + ((char*)&a2)[0];
|
||||
long double trample3 = (intptr_t)trample1 + (intptr_t)a1;
|
||||
char trample4 = trample2 + ((char*)&a1)[1];
|
||||
long double trample5 = (intptr_t)trample3 + (intptr_t)a2;
|
||||
char trample6 = trample4 + ((char*)&a2)[1];
|
||||
long double trample7 = (intptr_t)trample5 + (intptr_t)trample1;
|
||||
char trample8 = trample6 + trample2;
|
||||
|
||||
dummyVar = dummy_func(trample1, trample2, trample3, trample4,
|
||||
trample5, trample6, trample7, trample8);
|
||||
|
||||
void* result = (void*)((intptr_t)a1 + (intptr_t)a2);
|
||||
|
||||
printf("0x%08x 0x%08x: 0x%08x\n",
|
||||
(unsigned int)(intptr_t) a1,
|
||||
(unsigned int)(intptr_t) a2,
|
||||
(unsigned int)(intptr_t) result);
|
||||
|
||||
result = cls_pointer_fn2(result, a1);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_pointer_gn(ffi_cif* cif __UNUSED__, void* resp,
|
||||
void** args, void* userdata __UNUSED__)
|
||||
{
|
||||
void* a1 = *(void**)(args[0]);
|
||||
void* a2 = *(void**)(args[1]);
|
||||
|
||||
long double trample1 = (intptr_t)a1 + (intptr_t)a2;
|
||||
char trample2 = ((char*)&a1)[0] + ((char*)&a2)[0];
|
||||
long double trample3 = (intptr_t)trample1 + (intptr_t)a1;
|
||||
char trample4 = trample2 + ((char*)&a1)[1];
|
||||
long double trample5 = (intptr_t)trample3 + (intptr_t)a2;
|
||||
char trample6 = trample4 + ((char*)&a2)[1];
|
||||
long double trample7 = (intptr_t)trample5 + (intptr_t)trample1;
|
||||
char trample8 = trample6 + trample2;
|
||||
|
||||
dummyVar = dummy_func(trample1, trample2, trample3, trample4,
|
||||
trample5, trample6, trample7, trample8);
|
||||
|
||||
*(void**)resp = cls_pointer_fn1(a1, a2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure* pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args[3];
|
||||
// ffi_type cls_pointer_type;
|
||||
ffi_type* arg_types[3];
|
||||
|
||||
/* cls_pointer_type.size = sizeof(void*);
|
||||
cls_pointer_type.alignment = 0;
|
||||
cls_pointer_type.type = FFI_TYPE_POINTER;
|
||||
cls_pointer_type.elements = NULL;*/
|
||||
|
||||
void* arg1 = (void*)0x01234567;
|
||||
void* arg2 = (void*)0x89abcdef;
|
||||
ffi_arg res = 0;
|
||||
|
||||
arg_types[0] = &ffi_type_pointer;
|
||||
arg_types[1] = &ffi_type_pointer;
|
||||
arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_pointer,
|
||||
arg_types) == FFI_OK);
|
||||
|
||||
args[0] = &arg1;
|
||||
args[1] = &arg2;
|
||||
args[2] = NULL;
|
||||
|
||||
printf("\n");
|
||||
ffi_call(&cif, FFI_FN(cls_pointer_fn1), &res, args);
|
||||
|
||||
printf("res: 0x%08x\n", (unsigned int) res);
|
||||
// { dg-output "\n0x01234567 0x89abcdef: 0x8acf1356" }
|
||||
// { dg-output "\n0x8acf1356 0x01234567: 0x8bf258bd" }
|
||||
// { dg-output "\nres: 0x8bf258bd" }
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_pointer_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res = (ffi_arg)(uintptr_t)((void*(*)(void*, void*))(code))(arg1, arg2);
|
||||
|
||||
printf("res: 0x%08x\n", (unsigned int) res);
|
||||
// { dg-output "\n0x01234567 0x89abcdef: 0x8acf1356" }
|
||||
// { dg-output "\n0x8acf1356 0x01234567: 0x8bf258bd" }
|
||||
// { dg-output "\nres: 0x8bf258bd" }
|
||||
|
||||
exit(0);
|
||||
}
|
||||
26
.pc/msvc-changes/testsuite/libffi.call/err_bad_typedef.c
Normal file
26
.pc/msvc-changes/testsuite/libffi.call/err_bad_typedef.c
Normal file
@@ -0,0 +1,26 @@
|
||||
/* Area: ffi_prep_cif
|
||||
Purpose: Test error return for bad typedefs.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: Blake Chaffin 6/6/2007 */
|
||||
|
||||
/* { dg-do run } */
|
||||
|
||||
#include "ffitest.h"
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
ffi_type* arg_types[1];
|
||||
|
||||
arg_types[0] = NULL;
|
||||
|
||||
ffi_type badType = ffi_type_void;
|
||||
|
||||
badType.size = 0;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &badType,
|
||||
arg_types) == FFI_BAD_TYPEDEF);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
50
.pc/msvc-changes/testsuite/libffi.call/fastthis1_win32.c
Normal file
50
.pc/msvc-changes/testsuite/libffi.call/fastthis1_win32.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/* Area: ffi_call
|
||||
Purpose: Check fastcall fct call on X86_WIN32 systems.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: From the original ffitest.c */
|
||||
|
||||
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
|
||||
|
||||
#include "ffitest.h"
|
||||
|
||||
static size_t __attribute__((fastcall)) my_fastcall_f(char *s, float a)
|
||||
{
|
||||
return (size_t) ((int) strlen(s) + (int) a);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
ffi_type *args[MAX_ARGS];
|
||||
void *values[MAX_ARGS];
|
||||
ffi_arg rint;
|
||||
char *s;
|
||||
float v2;
|
||||
args[0] = &ffi_type_pointer;
|
||||
args[1] = &ffi_type_float;
|
||||
values[0] = (void*) &s;
|
||||
values[1] = (void*) &v2;
|
||||
|
||||
/* Initialize the cif */
|
||||
CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 2,
|
||||
&ffi_type_sint, args) == FFI_OK);
|
||||
|
||||
s = "a";
|
||||
v2 = 0.0;
|
||||
ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values);
|
||||
CHECK(rint == 1);
|
||||
|
||||
s = "1234567";
|
||||
v2 = -1.0;
|
||||
ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values);
|
||||
CHECK(rint == 6);
|
||||
|
||||
s = "1234567890123456789012345";
|
||||
v2 = 1.0;
|
||||
ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values);
|
||||
CHECK(rint == 26);
|
||||
|
||||
printf("fastcall fct1 tests passed\n");
|
||||
exit(0);
|
||||
}
|
||||
50
.pc/msvc-changes/testsuite/libffi.call/fastthis2_win32.c
Normal file
50
.pc/msvc-changes/testsuite/libffi.call/fastthis2_win32.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/* Area: ffi_call
|
||||
Purpose: Check fastcall fct call on X86_WIN32 systems.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: From the original ffitest.c */
|
||||
|
||||
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
|
||||
|
||||
#include "ffitest.h"
|
||||
|
||||
static size_t __attribute__((fastcall)) my_fastcall_f(float a, char *s)
|
||||
{
|
||||
return (size_t) ((int) strlen(s) + (int) a);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
ffi_type *args[MAX_ARGS];
|
||||
void *values[MAX_ARGS];
|
||||
ffi_arg rint;
|
||||
char *s;
|
||||
float v2;
|
||||
args[1] = &ffi_type_pointer;
|
||||
args[0] = &ffi_type_float;
|
||||
values[1] = (void*) &s;
|
||||
values[0] = (void*) &v2;
|
||||
|
||||
/* Initialize the cif */
|
||||
CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 2,
|
||||
&ffi_type_sint, args) == FFI_OK);
|
||||
|
||||
s = "a";
|
||||
v2 = 0.0;
|
||||
ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values);
|
||||
CHECK(rint == 1);
|
||||
|
||||
s = "1234567";
|
||||
v2 = -1.0;
|
||||
ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values);
|
||||
CHECK(rint == 6);
|
||||
|
||||
s = "1234567890123456789012345";
|
||||
v2 = 1.0;
|
||||
ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values);
|
||||
CHECK(rint == 26);
|
||||
|
||||
printf("fastcall fct2 tests passed\n");
|
||||
exit(0);
|
||||
}
|
||||
56
.pc/msvc-changes/testsuite/libffi.call/fastthis3_win32.c
Normal file
56
.pc/msvc-changes/testsuite/libffi.call/fastthis3_win32.c
Normal file
@@ -0,0 +1,56 @@
|
||||
/* Area: ffi_call
|
||||
Purpose: Check fastcall f call on X86_WIN32 systems.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: From the original ffitest.c */
|
||||
|
||||
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
|
||||
|
||||
#include "ffitest.h"
|
||||
|
||||
static size_t __attribute__((fastcall)) my_fastcall_f(float a, char *s, int i)
|
||||
{
|
||||
return (size_t) ((int) strlen(s) + (int) a + i);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
ffi_type *args[MAX_ARGS];
|
||||
void *values[MAX_ARGS];
|
||||
ffi_arg rint;
|
||||
char *s;
|
||||
int v1;
|
||||
float v2;
|
||||
args[2] = &ffi_type_sint;
|
||||
args[1] = &ffi_type_pointer;
|
||||
args[0] = &ffi_type_float;
|
||||
values[2] = (void*) &v1;
|
||||
values[1] = (void*) &s;
|
||||
values[0] = (void*) &v2;
|
||||
|
||||
/* Initialize the cif */
|
||||
CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 3,
|
||||
&ffi_type_sint, args) == FFI_OK);
|
||||
|
||||
s = "a";
|
||||
v1 = 1;
|
||||
v2 = 0.0;
|
||||
ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values);
|
||||
CHECK(rint == 2);
|
||||
|
||||
s = "1234567";
|
||||
v2 = -1.0;
|
||||
v1 = -2;
|
||||
ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values);
|
||||
CHECK(rint == 4);
|
||||
|
||||
s = "1234567890123456789012345";
|
||||
v2 = 1.0;
|
||||
v1 = 2;
|
||||
ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values);
|
||||
CHECK(rint == 28);
|
||||
|
||||
printf("fastcall fct3 tests passed\n");
|
||||
exit(0);
|
||||
}
|
||||
153
.pc/msvc-changes/testsuite/libffi.call/ffitest.h
Normal file
153
.pc/msvc-changes/testsuite/libffi.call/ffitest.h
Normal file
@@ -0,0 +1,153 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <ffi.h>
|
||||
#include "fficonfig.h"
|
||||
|
||||
#if defined HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#if defined HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#define MAX_ARGS 256
|
||||
|
||||
#define CHECK(x) !(x) ? abort() : 0
|
||||
|
||||
/* Define __UNUSED__ that also other compilers than gcc can run the tests. */
|
||||
#undef __UNUSED__
|
||||
#if defined(__GNUC__)
|
||||
#define __UNUSED__ __attribute__((__unused__))
|
||||
#else
|
||||
#define __UNUSED__
|
||||
#endif
|
||||
|
||||
/* Prefer MAP_ANON(YMOUS) to /dev/zero, since we don't need to keep a
|
||||
file open. */
|
||||
#ifdef HAVE_MMAP_ANON
|
||||
# undef HAVE_MMAP_DEV_ZERO
|
||||
|
||||
# include <sys/mman.h>
|
||||
# ifndef MAP_FAILED
|
||||
# define MAP_FAILED -1
|
||||
# endif
|
||||
# if !defined (MAP_ANONYMOUS) && defined (MAP_ANON)
|
||||
# define MAP_ANONYMOUS MAP_ANON
|
||||
# endif
|
||||
# define USING_MMAP
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MMAP_DEV_ZERO
|
||||
|
||||
# include <sys/mman.h>
|
||||
# ifndef MAP_FAILED
|
||||
# define MAP_FAILED -1
|
||||
# endif
|
||||
# define USING_MMAP
|
||||
|
||||
#endif
|
||||
|
||||
/* MinGW kludge. */
|
||||
#ifdef _WIN64
|
||||
#define PRIdLL "I64d"
|
||||
#define PRIuLL "I64u"
|
||||
#else
|
||||
#define PRIdLL "lld"
|
||||
#define PRIuLL "llu"
|
||||
#endif
|
||||
|
||||
/* Tru64 UNIX kludge. */
|
||||
#if defined(__alpha__) && defined(__osf__)
|
||||
/* Tru64 UNIX V4.0 doesn't support %lld/%lld, but long is 64-bit. */
|
||||
#undef PRIdLL
|
||||
#define PRIdLL "ld"
|
||||
#undef PRIuLL
|
||||
#define PRIuLL "lu"
|
||||
#define PRId8 "hd"
|
||||
#define PRIu8 "hu"
|
||||
#define PRId64 "ld"
|
||||
#define PRIu64 "lu"
|
||||
#define PRIuPTR "lu"
|
||||
#endif
|
||||
|
||||
/* PA HP-UX kludge. */
|
||||
#if defined(__hppa__) && defined(__hpux__) && !defined(PRIuPTR)
|
||||
#define PRIuPTR "lu"
|
||||
#endif
|
||||
|
||||
/* IRIX kludge. */
|
||||
#if defined(__sgi)
|
||||
/* IRIX 6.5 <inttypes.h> provides all definitions, but only for C99
|
||||
compilations. */
|
||||
#define PRId8 "hhd"
|
||||
#define PRIu8 "hhu"
|
||||
#if (_MIPS_SZLONG == 32)
|
||||
#define PRId64 "lld"
|
||||
#define PRIu64 "llu"
|
||||
#endif
|
||||
/* This doesn't match <inttypes.h>, which always has "lld" here, but the
|
||||
arguments are uint64_t, int64_t, which are unsigned long, long for
|
||||
64-bit in <sgidefs.h>. */
|
||||
#if (_MIPS_SZLONG == 64)
|
||||
#define PRId64 "ld"
|
||||
#define PRIu64 "lu"
|
||||
#endif
|
||||
/* This doesn't match <inttypes.h>, which has "u" here, but the arguments
|
||||
are uintptr_t, which is always unsigned long. */
|
||||
#define PRIuPTR "lu"
|
||||
#endif
|
||||
|
||||
/* Solaris < 10 kludge. */
|
||||
#if defined(__sun__) && defined(__svr4__) && !defined(PRIuPTR)
|
||||
#if defined(__arch64__) || defined (__x86_64__)
|
||||
#define PRIuPTR "lu"
|
||||
#else
|
||||
#define PRIuPTR "u"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef USING_MMAP
|
||||
static inline void *
|
||||
allocate_mmap (size_t size)
|
||||
{
|
||||
void *page;
|
||||
#if defined (HAVE_MMAP_DEV_ZERO)
|
||||
static int dev_zero_fd = -1;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MMAP_DEV_ZERO
|
||||
if (dev_zero_fd == -1)
|
||||
{
|
||||
dev_zero_fd = open ("/dev/zero", O_RDONLY);
|
||||
if (dev_zero_fd == -1)
|
||||
{
|
||||
perror ("open /dev/zero: %m");
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_MMAP_ANON
|
||||
page = mmap (NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
#endif
|
||||
#ifdef HAVE_MMAP_DEV_ZERO
|
||||
page = mmap (NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC,
|
||||
MAP_PRIVATE, dev_zero_fd, 0);
|
||||
#endif
|
||||
|
||||
if (page == (void *) MAP_FAILED)
|
||||
{
|
||||
perror ("virtual memory exhausted");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
#endif
|
||||
342
.pc/msvc-changes/testsuite/libffi.call/huge_struct.c
Normal file
342
.pc/msvc-changes/testsuite/libffi.call/huge_struct.c
Normal file
@@ -0,0 +1,342 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check large structure returns.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: Blake Chaffin 6/18/2007
|
||||
*/
|
||||
|
||||
/* { dg-excess-errors "" { target x86_64-*-mingw* x86_64-*-cygwin* } } */
|
||||
/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
|
||||
/* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */
|
||||
/* { dg-output "" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
|
||||
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct BigStruct{
|
||||
uint8_t a;
|
||||
int8_t b;
|
||||
uint16_t c;
|
||||
int16_t d;
|
||||
uint32_t e;
|
||||
int32_t f;
|
||||
uint64_t g;
|
||||
int64_t h;
|
||||
float i;
|
||||
double j;
|
||||
long double k;
|
||||
char* l;
|
||||
uint8_t m;
|
||||
int8_t n;
|
||||
uint16_t o;
|
||||
int16_t p;
|
||||
uint32_t q;
|
||||
int32_t r;
|
||||
uint64_t s;
|
||||
int64_t t;
|
||||
float u;
|
||||
double v;
|
||||
long double w;
|
||||
char* x;
|
||||
uint8_t y;
|
||||
int8_t z;
|
||||
uint16_t aa;
|
||||
int16_t bb;
|
||||
uint32_t cc;
|
||||
int32_t dd;
|
||||
uint64_t ee;
|
||||
int64_t ff;
|
||||
float gg;
|
||||
double hh;
|
||||
long double ii;
|
||||
char* jj;
|
||||
uint8_t kk;
|
||||
int8_t ll;
|
||||
uint16_t mm;
|
||||
int16_t nn;
|
||||
uint32_t oo;
|
||||
int32_t pp;
|
||||
uint64_t qq;
|
||||
int64_t rr;
|
||||
float ss;
|
||||
double tt;
|
||||
long double uu;
|
||||
char* vv;
|
||||
uint8_t ww;
|
||||
int8_t xx;
|
||||
} BigStruct;
|
||||
|
||||
BigStruct
|
||||
test_large_fn(
|
||||
uint8_t ui8_1,
|
||||
int8_t si8_1,
|
||||
uint16_t ui16_1,
|
||||
int16_t si16_1,
|
||||
uint32_t ui32_1,
|
||||
int32_t si32_1,
|
||||
uint64_t ui64_1,
|
||||
int64_t si64_1,
|
||||
float f_1,
|
||||
double d_1,
|
||||
long double ld_1,
|
||||
char* p_1,
|
||||
uint8_t ui8_2,
|
||||
int8_t si8_2,
|
||||
uint16_t ui16_2,
|
||||
int16_t si16_2,
|
||||
uint32_t ui32_2,
|
||||
int32_t si32_2,
|
||||
uint64_t ui64_2,
|
||||
int64_t si64_2,
|
||||
float f_2,
|
||||
double d_2,
|
||||
long double ld_2,
|
||||
char* p_2,
|
||||
uint8_t ui8_3,
|
||||
int8_t si8_3,
|
||||
uint16_t ui16_3,
|
||||
int16_t si16_3,
|
||||
uint32_t ui32_3,
|
||||
int32_t si32_3,
|
||||
uint64_t ui64_3,
|
||||
int64_t si64_3,
|
||||
float f_3,
|
||||
double d_3,
|
||||
long double ld_3,
|
||||
char* p_3,
|
||||
uint8_t ui8_4,
|
||||
int8_t si8_4,
|
||||
uint16_t ui16_4,
|
||||
int16_t si16_4,
|
||||
uint32_t ui32_4,
|
||||
int32_t si32_4,
|
||||
uint64_t ui64_4,
|
||||
int64_t si64_4,
|
||||
float f_4,
|
||||
double d_4,
|
||||
long double ld_4,
|
||||
char* p_4,
|
||||
uint8_t ui8_5,
|
||||
int8_t si8_5)
|
||||
{
|
||||
BigStruct retVal = {
|
||||
ui8_1 + 1, si8_1 + 1, ui16_1 + 1, si16_1 + 1, ui32_1 + 1, si32_1 + 1,
|
||||
ui64_1 + 1, si64_1 + 1, f_1 + 1, d_1 + 1, ld_1 + 1, (char*)((intptr_t)p_1 + 1),
|
||||
ui8_2 + 2, si8_2 + 2, ui16_2 + 2, si16_2 + 2, ui32_2 + 2, si32_2 + 2,
|
||||
ui64_2 + 2, si64_2 + 2, f_2 + 2, d_2 + 2, ld_2 + 2, (char*)((intptr_t)p_2 + 2),
|
||||
ui8_3 + 3, si8_3 + 3, ui16_3 + 3, si16_3 + 3, ui32_3 + 3, si32_3 + 3,
|
||||
ui64_3 + 3, si64_3 + 3, f_3 + 3, d_3 + 3, ld_3 + 3, (char*)((intptr_t)p_3 + 3),
|
||||
ui8_4 + 4, si8_4 + 4, ui16_4 + 4, si16_4 + 4, ui32_4 + 4, si32_4 + 4,
|
||||
ui64_4 + 4, si64_4 + 4, f_4 + 4, d_4 + 4, ld_4 + 4, (char*)((intptr_t)p_4 + 4),
|
||||
ui8_5 + 5, si8_5 + 5};
|
||||
|
||||
printf("%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 ": "
|
||||
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 "\n",
|
||||
ui8_1, si8_1, ui16_1, si16_1, ui32_1, si32_1, ui64_1, si64_1, f_1, d_1, ld_1, (unsigned long)p_1,
|
||||
ui8_2, si8_2, ui16_2, si16_2, ui32_2, si32_2, ui64_2, si64_2, f_2, d_2, ld_2, (unsigned long)p_2,
|
||||
ui8_3, si8_3, ui16_3, si16_3, ui32_3, si32_3, ui64_3, si64_3, f_3, d_3, ld_3, (unsigned long)p_3,
|
||||
ui8_4, si8_4, ui16_4, si16_4, ui32_4, si32_4, ui64_4, si64_4, f_4, d_4, ld_4, (unsigned long)p_4, ui8_5, si8_5,
|
||||
retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f,
|
||||
retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, (unsigned long)retVal.l,
|
||||
retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r,
|
||||
retVal.s, retVal.t, retVal.u, retVal.v, retVal.w, (unsigned long)retVal.x,
|
||||
retVal.y, retVal.z, retVal.aa, retVal.bb, retVal.cc, retVal.dd,
|
||||
retVal.ee, retVal.ff, retVal.gg, retVal.hh, retVal.ii, (unsigned long)retVal.jj,
|
||||
retVal.kk, retVal.ll, retVal.mm, retVal.nn, retVal.oo, retVal.pp,
|
||||
retVal.qq, retVal.rr, retVal.ss, retVal.tt, retVal.uu, (unsigned long)retVal.vv, retVal.ww, retVal.xx);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_large_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__)
|
||||
{
|
||||
uint8_t ui8_1 = *(uint8_t*)args[0];
|
||||
int8_t si8_1 = *(int8_t*)args[1];
|
||||
uint16_t ui16_1 = *(uint16_t*)args[2];
|
||||
int16_t si16_1 = *(int16_t*)args[3];
|
||||
uint32_t ui32_1 = *(uint32_t*)args[4];
|
||||
int32_t si32_1 = *(int32_t*)args[5];
|
||||
uint64_t ui64_1 = *(uint64_t*)args[6];
|
||||
int64_t si64_1 = *(int64_t*)args[7];
|
||||
float f_1 = *(float*)args[8];
|
||||
double d_1 = *(double*)args[9];
|
||||
long double ld_1 = *(long double*)args[10];
|
||||
char* p_1 = *(char**)args[11];
|
||||
uint8_t ui8_2 = *(uint8_t*)args[12];
|
||||
int8_t si8_2 = *(int8_t*)args[13];
|
||||
uint16_t ui16_2 = *(uint16_t*)args[14];
|
||||
int16_t si16_2 = *(int16_t*)args[15];
|
||||
uint32_t ui32_2 = *(uint32_t*)args[16];
|
||||
int32_t si32_2 = *(int32_t*)args[17];
|
||||
uint64_t ui64_2 = *(uint64_t*)args[18];
|
||||
int64_t si64_2 = *(int64_t*)args[19];
|
||||
float f_2 = *(float*)args[20];
|
||||
double d_2 = *(double*)args[21];
|
||||
long double ld_2 = *(long double*)args[22];
|
||||
char* p_2 = *(char**)args[23];
|
||||
uint8_t ui8_3 = *(uint8_t*)args[24];
|
||||
int8_t si8_3 = *(int8_t*)args[25];
|
||||
uint16_t ui16_3 = *(uint16_t*)args[26];
|
||||
int16_t si16_3 = *(int16_t*)args[27];
|
||||
uint32_t ui32_3 = *(uint32_t*)args[28];
|
||||
int32_t si32_3 = *(int32_t*)args[29];
|
||||
uint64_t ui64_3 = *(uint64_t*)args[30];
|
||||
int64_t si64_3 = *(int64_t*)args[31];
|
||||
float f_3 = *(float*)args[32];
|
||||
double d_3 = *(double*)args[33];
|
||||
long double ld_3 = *(long double*)args[34];
|
||||
char* p_3 = *(char**)args[35];
|
||||
uint8_t ui8_4 = *(uint8_t*)args[36];
|
||||
int8_t si8_4 = *(int8_t*)args[37];
|
||||
uint16_t ui16_4 = *(uint16_t*)args[38];
|
||||
int16_t si16_4 = *(int16_t*)args[39];
|
||||
uint32_t ui32_4 = *(uint32_t*)args[40];
|
||||
int32_t si32_4 = *(int32_t*)args[41];
|
||||
uint64_t ui64_4 = *(uint64_t*)args[42];
|
||||
int64_t si64_4 = *(int64_t*)args[43];
|
||||
float f_4 = *(float*)args[44];
|
||||
double d_4 = *(double*)args[45];
|
||||
long double ld_4 = *(long double*)args[46];
|
||||
char* p_4 = *(char**)args[47];
|
||||
uint8_t ui8_5 = *(uint8_t*)args[48];
|
||||
int8_t si8_5 = *(int8_t*)args[49];
|
||||
|
||||
*(BigStruct*)resp = test_large_fn(
|
||||
ui8_1, si8_1, ui16_1, si16_1, ui32_1, si32_1, ui64_1, si64_1, f_1, d_1, ld_1, p_1,
|
||||
ui8_2, si8_2, ui16_2, si16_2, ui32_2, si32_2, ui64_2, si64_2, f_2, d_2, ld_2, p_2,
|
||||
ui8_3, si8_3, ui16_3, si16_3, ui32_3, si32_3, ui64_3, si64_3, f_3, d_3, ld_3, p_3,
|
||||
ui8_4, si8_4, ui16_4, si16_4, ui32_4, si32_4, ui64_4, si64_4, f_4, d_4, ld_4, p_4,
|
||||
ui8_5, si8_5);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc __UNUSED__, const char** argv __UNUSED__)
|
||||
{
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
|
||||
ffi_cif cif;
|
||||
ffi_type* argTypes[51];
|
||||
void* argValues[51];
|
||||
|
||||
ffi_type ret_struct_type;
|
||||
ffi_type* st_fields[51];
|
||||
BigStruct retVal;
|
||||
|
||||
memset (&retVal, 0, sizeof(retVal));
|
||||
|
||||
ret_struct_type.size = 0;
|
||||
ret_struct_type.alignment = 0;
|
||||
ret_struct_type.type = FFI_TYPE_STRUCT;
|
||||
ret_struct_type.elements = st_fields;
|
||||
|
||||
st_fields[0] = st_fields[12] = st_fields[24] = st_fields[36] = st_fields[48] = &ffi_type_uint8;
|
||||
st_fields[1] = st_fields[13] = st_fields[25] = st_fields[37] = st_fields[49] = &ffi_type_sint8;
|
||||
st_fields[2] = st_fields[14] = st_fields[26] = st_fields[38] = &ffi_type_uint16;
|
||||
st_fields[3] = st_fields[15] = st_fields[27] = st_fields[39] = &ffi_type_sint16;
|
||||
st_fields[4] = st_fields[16] = st_fields[28] = st_fields[40] = &ffi_type_uint32;
|
||||
st_fields[5] = st_fields[17] = st_fields[29] = st_fields[41] = &ffi_type_sint32;
|
||||
st_fields[6] = st_fields[18] = st_fields[30] = st_fields[42] = &ffi_type_uint64;
|
||||
st_fields[7] = st_fields[19] = st_fields[31] = st_fields[43] = &ffi_type_sint64;
|
||||
st_fields[8] = st_fields[20] = st_fields[32] = st_fields[44] = &ffi_type_float;
|
||||
st_fields[9] = st_fields[21] = st_fields[33] = st_fields[45] = &ffi_type_double;
|
||||
st_fields[10] = st_fields[22] = st_fields[34] = st_fields[46] = &ffi_type_longdouble;
|
||||
st_fields[11] = st_fields[23] = st_fields[35] = st_fields[47] = &ffi_type_pointer;
|
||||
|
||||
st_fields[50] = NULL;
|
||||
|
||||
uint8_t ui8 = 1;
|
||||
int8_t si8 = 2;
|
||||
uint16_t ui16 = 3;
|
||||
int16_t si16 = 4;
|
||||
uint32_t ui32 = 5;
|
||||
int32_t si32 = 6;
|
||||
uint64_t ui64 = 7;
|
||||
int64_t si64 = 8;
|
||||
float f = 9;
|
||||
double d = 10;
|
||||
long double ld = 11;
|
||||
char* p = (char*)0x12345678;
|
||||
|
||||
argTypes[0] = argTypes[12] = argTypes[24] = argTypes[36] = argTypes[48] = &ffi_type_uint8;
|
||||
argValues[0] = argValues[12] = argValues[24] = argValues[36] = argValues[48] = &ui8;
|
||||
argTypes[1] = argTypes[13] = argTypes[25] = argTypes[37] = argTypes[49] = &ffi_type_sint8;
|
||||
argValues[1] = argValues[13] = argValues[25] = argValues[37] = argValues[49] = &si8;
|
||||
argTypes[2] = argTypes[14] = argTypes[26] = argTypes[38] = &ffi_type_uint16;
|
||||
argValues[2] = argValues[14] = argValues[26] = argValues[38] = &ui16;
|
||||
argTypes[3] = argTypes[15] = argTypes[27] = argTypes[39] = &ffi_type_sint16;
|
||||
argValues[3] = argValues[15] = argValues[27] = argValues[39] = &si16;
|
||||
argTypes[4] = argTypes[16] = argTypes[28] = argTypes[40] = &ffi_type_uint32;
|
||||
argValues[4] = argValues[16] = argValues[28] = argValues[40] = &ui32;
|
||||
argTypes[5] = argTypes[17] = argTypes[29] = argTypes[41] = &ffi_type_sint32;
|
||||
argValues[5] = argValues[17] = argValues[29] = argValues[41] = &si32;
|
||||
argTypes[6] = argTypes[18] = argTypes[30] = argTypes[42] = &ffi_type_uint64;
|
||||
argValues[6] = argValues[18] = argValues[30] = argValues[42] = &ui64;
|
||||
argTypes[7] = argTypes[19] = argTypes[31] = argTypes[43] = &ffi_type_sint64;
|
||||
argValues[7] = argValues[19] = argValues[31] = argValues[43] = &si64;
|
||||
argTypes[8] = argTypes[20] = argTypes[32] = argTypes[44] = &ffi_type_float;
|
||||
argValues[8] = argValues[20] = argValues[32] = argValues[44] = &f;
|
||||
argTypes[9] = argTypes[21] = argTypes[33] = argTypes[45] = &ffi_type_double;
|
||||
argValues[9] = argValues[21] = argValues[33] = argValues[45] = &d;
|
||||
argTypes[10] = argTypes[22] = argTypes[34] = argTypes[46] = &ffi_type_longdouble;
|
||||
argValues[10] = argValues[22] = argValues[34] = argValues[46] = &ld;
|
||||
argTypes[11] = argTypes[23] = argTypes[35] = argTypes[47] = &ffi_type_pointer;
|
||||
argValues[11] = argValues[23] = argValues[35] = argValues[47] = &p;
|
||||
|
||||
argTypes[50] = NULL;
|
||||
argValues[50] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 50, &ret_struct_type, argTypes) == FFI_OK);
|
||||
|
||||
ffi_call(&cif, FFI_FN(test_large_fn), &retVal, argValues);
|
||||
// { dg-output "1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" }
|
||||
printf("res: %" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 "\n",
|
||||
retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f,
|
||||
retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, (unsigned long)retVal.l,
|
||||
retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r,
|
||||
retVal.s, retVal.t, retVal.u, retVal.v, retVal.w, (unsigned long)retVal.x,
|
||||
retVal.y, retVal.z, retVal.aa, retVal.bb, retVal.cc, retVal.dd,
|
||||
retVal.ee, retVal.ff, retVal.gg, retVal.hh, retVal.ii, (unsigned long)retVal.jj,
|
||||
retVal.kk, retVal.ll, retVal.mm, retVal.nn, retVal.oo, retVal.pp,
|
||||
retVal.qq, retVal.rr, retVal.ss, retVal.tt, retVal.uu, (unsigned long)retVal.vv, retVal.ww, retVal.xx);
|
||||
// { dg-output "\nres: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" }
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_large_fn, NULL, code) == FFI_OK);
|
||||
|
||||
retVal = ((BigStruct(*)(
|
||||
uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*,
|
||||
uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*,
|
||||
uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*,
|
||||
uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*,
|
||||
uint8_t, int8_t))(code))(
|
||||
ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p,
|
||||
ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p,
|
||||
ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p,
|
||||
ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p,
|
||||
ui8, si8);
|
||||
// { dg-output "\n1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" }
|
||||
printf("res: %" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx "
|
||||
"%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 "\n",
|
||||
retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f,
|
||||
retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, (unsigned long)retVal.l,
|
||||
retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r,
|
||||
retVal.s, retVal.t, retVal.u, retVal.v, retVal.w, (unsigned long)retVal.x,
|
||||
retVal.y, retVal.z, retVal.aa, retVal.bb, retVal.cc, retVal.dd,
|
||||
retVal.ee, retVal.ff, retVal.gg, retVal.hh, retVal.ii, (unsigned long)retVal.jj,
|
||||
retVal.kk, retVal.ll, retVal.mm, retVal.nn, retVal.oo, retVal.pp,
|
||||
retVal.qq, retVal.rr, retVal.ss, retVal.tt, retVal.uu, (unsigned long)retVal.vv, retVal.ww, retVal.xx);
|
||||
// { dg-output "\nres: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" }
|
||||
|
||||
return 0;
|
||||
}
|
||||
152
.pc/msvc-changes/testsuite/libffi.call/nested_struct.c
Normal file
152
.pc/msvc-changes/testsuite/libffi.call/nested_struct.c
Normal file
@@ -0,0 +1,152 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Contains structs as parameter of the struct itself.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20030828 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_16byte1 {
|
||||
double a;
|
||||
float b;
|
||||
int c;
|
||||
} cls_struct_16byte1;
|
||||
|
||||
typedef struct cls_struct_16byte2 {
|
||||
int ii;
|
||||
double dd;
|
||||
float ff;
|
||||
} cls_struct_16byte2;
|
||||
|
||||
typedef struct cls_struct_combined {
|
||||
cls_struct_16byte1 d;
|
||||
cls_struct_16byte2 e;
|
||||
} cls_struct_combined;
|
||||
|
||||
cls_struct_combined cls_struct_combined_fn(struct cls_struct_16byte1 b0,
|
||||
struct cls_struct_16byte2 b1,
|
||||
struct cls_struct_combined b2)
|
||||
{
|
||||
struct cls_struct_combined result;
|
||||
|
||||
result.d.a = b0.a + b1.dd + b2.d.a;
|
||||
result.d.b = b0.b + b1.ff + b2.d.b;
|
||||
result.d.c = b0.c + b1.ii + b2.d.c;
|
||||
result.e.ii = b0.c + b1.ii + b2.e.ii;
|
||||
result.e.dd = b0.a + b1.dd + b2.e.dd;
|
||||
result.e.ff = b0.b + b1.ff + b2.e.ff;
|
||||
|
||||
printf("%g %g %d %d %g %g %g %g %d %d %g %g: %g %g %d %d %g %g\n",
|
||||
b0.a, b0.b, b0.c,
|
||||
b1.ii, b1.dd, b1.ff,
|
||||
b2.d.a, b2.d.b, b2.d.c,
|
||||
b2.e.ii, b2.e.dd, b2.e.ff,
|
||||
result.d.a, result.d.b, result.d.c,
|
||||
result.e.ii, result.e.dd, result.e.ff);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
struct cls_struct_16byte1 b0;
|
||||
struct cls_struct_16byte2 b1;
|
||||
struct cls_struct_combined b2;
|
||||
|
||||
b0 = *(struct cls_struct_16byte1*)(args[0]);
|
||||
b1 = *(struct cls_struct_16byte2*)(args[1]);
|
||||
b2 = *(struct cls_struct_combined*)(args[2]);
|
||||
|
||||
|
||||
*(cls_struct_combined*)resp = cls_struct_combined_fn(b0, b1, b2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[5];
|
||||
ffi_type* cls_struct_fields1[5];
|
||||
ffi_type* cls_struct_fields2[5];
|
||||
ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
cls_struct_type1.size = 0;
|
||||
cls_struct_type1.alignment = 0;
|
||||
cls_struct_type1.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type1.elements = cls_struct_fields1;
|
||||
|
||||
cls_struct_type2.size = 0;
|
||||
cls_struct_type2.alignment = 0;
|
||||
cls_struct_type2.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type2.elements = cls_struct_fields2;
|
||||
|
||||
struct cls_struct_16byte1 e_dbl = { 9.0, 2.0, 6};
|
||||
struct cls_struct_16byte2 f_dbl = { 1, 2.0, 3.0};
|
||||
struct cls_struct_combined g_dbl = {{4.0, 5.0, 6},
|
||||
{3, 1.0, 8.0}};
|
||||
struct cls_struct_combined res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_double;
|
||||
cls_struct_fields[1] = &ffi_type_float;
|
||||
cls_struct_fields[2] = &ffi_type_sint;
|
||||
cls_struct_fields[3] = NULL;
|
||||
|
||||
cls_struct_fields1[0] = &ffi_type_sint;
|
||||
cls_struct_fields1[1] = &ffi_type_double;
|
||||
cls_struct_fields1[2] = &ffi_type_float;
|
||||
cls_struct_fields1[3] = NULL;
|
||||
|
||||
cls_struct_fields2[0] = &cls_struct_type;
|
||||
cls_struct_fields2[1] = &cls_struct_type1;
|
||||
cls_struct_fields2[2] = NULL;
|
||||
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type1;
|
||||
dbl_arg_types[2] = &cls_struct_type2;
|
||||
dbl_arg_types[3] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type2,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &e_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = &g_dbl;
|
||||
args_dbl[3] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_combined_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "9 2 6 1 2 3 4 5 6 3 1 8: 15 10 13 10 12 13" } */
|
||||
CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a));
|
||||
CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b));
|
||||
CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c));
|
||||
CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii));
|
||||
CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd));
|
||||
CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff));
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_combined_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_combined(*)(cls_struct_16byte1,
|
||||
cls_struct_16byte2,
|
||||
cls_struct_combined))
|
||||
(code))(e_dbl, f_dbl, g_dbl);
|
||||
/* { dg-output "\n9 2 6 1 2 3 4 5 6 3 1 8: 15 10 13 10 12 13" } */
|
||||
CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a));
|
||||
CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b));
|
||||
CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c));
|
||||
CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii));
|
||||
CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd));
|
||||
CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff));
|
||||
exit(0);
|
||||
}
|
||||
161
.pc/msvc-changes/testsuite/libffi.call/nested_struct1.c
Normal file
161
.pc/msvc-changes/testsuite/libffi.call/nested_struct1.c
Normal file
@@ -0,0 +1,161 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Contains structs as parameter of the struct itself.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20030828 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_16byte1 {
|
||||
double a;
|
||||
float b;
|
||||
int c;
|
||||
} cls_struct_16byte1;
|
||||
|
||||
typedef struct cls_struct_16byte2 {
|
||||
int ii;
|
||||
double dd;
|
||||
float ff;
|
||||
} cls_struct_16byte2;
|
||||
|
||||
typedef struct cls_struct_combined {
|
||||
cls_struct_16byte1 d;
|
||||
cls_struct_16byte2 e;
|
||||
} cls_struct_combined;
|
||||
|
||||
cls_struct_combined cls_struct_combined_fn(struct cls_struct_16byte1 b0,
|
||||
struct cls_struct_16byte2 b1,
|
||||
struct cls_struct_combined b2,
|
||||
struct cls_struct_16byte1 b3)
|
||||
{
|
||||
struct cls_struct_combined result;
|
||||
|
||||
result.d.a = b0.a + b1.dd + b2.d.a;
|
||||
result.d.b = b0.b + b1.ff + b2.d.b;
|
||||
result.d.c = b0.c + b1.ii + b2.d.c;
|
||||
result.e.ii = b0.c + b1.ii + b2.e.ii;
|
||||
result.e.dd = b0.a + b1.dd + b2.e.dd;
|
||||
result.e.ff = b0.b + b1.ff + b2.e.ff;
|
||||
|
||||
printf("%g %g %d %d %g %g %g %g %d %d %g %g %g %g %d: %g %g %d %d %g %g\n",
|
||||
b0.a, b0.b, b0.c,
|
||||
b1.ii, b1.dd, b1.ff,
|
||||
b2.d.a, b2.d.b, b2.d.c,
|
||||
b2.e.ii, b2.e.dd, b2.e.ff,
|
||||
b3.a, b3.b, b3.c,
|
||||
result.d.a, result.d.b, result.d.c,
|
||||
result.e.ii, result.e.dd, result.e.ff);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
struct cls_struct_16byte1 b0;
|
||||
struct cls_struct_16byte2 b1;
|
||||
struct cls_struct_combined b2;
|
||||
struct cls_struct_16byte1 b3;
|
||||
|
||||
b0 = *(struct cls_struct_16byte1*)(args[0]);
|
||||
b1 = *(struct cls_struct_16byte2*)(args[1]);
|
||||
b2 = *(struct cls_struct_combined*)(args[2]);
|
||||
b3 = *(struct cls_struct_16byte1*)(args[3]);
|
||||
|
||||
|
||||
*(cls_struct_combined*)resp = cls_struct_combined_fn(b0, b1, b2, b3);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[5];
|
||||
ffi_type* cls_struct_fields1[5];
|
||||
ffi_type* cls_struct_fields2[5];
|
||||
ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
cls_struct_type1.size = 0;
|
||||
cls_struct_type1.alignment = 0;
|
||||
cls_struct_type1.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type1.elements = cls_struct_fields1;
|
||||
|
||||
cls_struct_type2.size = 0;
|
||||
cls_struct_type2.alignment = 0;
|
||||
cls_struct_type2.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type2.elements = cls_struct_fields2;
|
||||
|
||||
struct cls_struct_16byte1 e_dbl = { 9.0, 2.0, 6};
|
||||
struct cls_struct_16byte2 f_dbl = { 1, 2.0, 3.0};
|
||||
struct cls_struct_combined g_dbl = {{4.0, 5.0, 6},
|
||||
{3, 1.0, 8.0}};
|
||||
struct cls_struct_16byte1 h_dbl = { 3.0, 2.0, 4};
|
||||
struct cls_struct_combined res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_double;
|
||||
cls_struct_fields[1] = &ffi_type_float;
|
||||
cls_struct_fields[2] = &ffi_type_sint;
|
||||
cls_struct_fields[3] = NULL;
|
||||
|
||||
cls_struct_fields1[0] = &ffi_type_sint;
|
||||
cls_struct_fields1[1] = &ffi_type_double;
|
||||
cls_struct_fields1[2] = &ffi_type_float;
|
||||
cls_struct_fields1[3] = NULL;
|
||||
|
||||
cls_struct_fields2[0] = &cls_struct_type;
|
||||
cls_struct_fields2[1] = &cls_struct_type1;
|
||||
cls_struct_fields2[2] = NULL;
|
||||
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type1;
|
||||
dbl_arg_types[2] = &cls_struct_type2;
|
||||
dbl_arg_types[3] = &cls_struct_type;
|
||||
dbl_arg_types[4] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type2,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &e_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = &g_dbl;
|
||||
args_dbl[3] = &h_dbl;
|
||||
args_dbl[4] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_combined_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "9 2 6 1 2 3 4 5 6 3 1 8 3 2 4: 15 10 13 10 12 13" } */
|
||||
CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a));
|
||||
CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b));
|
||||
CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c));
|
||||
CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii));
|
||||
CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd));
|
||||
CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff));
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_combined_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((cls_struct_combined(*)(cls_struct_16byte1,
|
||||
cls_struct_16byte2,
|
||||
cls_struct_combined,
|
||||
cls_struct_16byte1))
|
||||
(code))(e_dbl, f_dbl, g_dbl, h_dbl);
|
||||
/* { dg-output "\n9 2 6 1 2 3 4 5 6 3 1 8 3 2 4: 15 10 13 10 12 13" } */
|
||||
CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a));
|
||||
CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b));
|
||||
CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c));
|
||||
CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii));
|
||||
CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd));
|
||||
CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff));
|
||||
// CHECK( 1 == 0);
|
||||
exit(0);
|
||||
}
|
||||
133
.pc/msvc-changes/testsuite/libffi.call/nested_struct10.c
Normal file
133
.pc/msvc-changes/testsuite/libffi.call/nested_struct10.c
Normal file
@@ -0,0 +1,133 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Contains structs as parameter of the struct itself.
|
||||
Sample taken from Alan Modras patch to src/prep_cif.c.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20051010 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct A {
|
||||
unsigned long long a;
|
||||
unsigned char b;
|
||||
} A;
|
||||
|
||||
typedef struct B {
|
||||
unsigned char y;
|
||||
struct A x;
|
||||
unsigned int z;
|
||||
} B;
|
||||
|
||||
typedef struct C {
|
||||
unsigned long long d;
|
||||
unsigned char e;
|
||||
} C;
|
||||
|
||||
static B B_fn(struct A b2, struct B b3, struct C b4)
|
||||
{
|
||||
struct B result;
|
||||
|
||||
result.x.a = b2.a + b3.x.a + b3.z + b4.d;
|
||||
result.x.b = b2.b + b3.x.b + b3.y + b4.e;
|
||||
result.y = b2.b + b3.x.b + b4.e;
|
||||
|
||||
printf("%d %d %d %d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b,
|
||||
(int)b3.x.a, b3.x.b, b3.y, b3.z, (int)b4.d, b4.e,
|
||||
(int)result.x.a, result.x.b, result.y);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
struct A b0;
|
||||
struct B b1;
|
||||
struct C b2;
|
||||
|
||||
b0 = *(struct A*)(args[0]);
|
||||
b1 = *(struct B*)(args[1]);
|
||||
b2 = *(struct C*)(args[2]);
|
||||
|
||||
*(B*)resp = B_fn(b0, b1, b2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[4];
|
||||
ffi_type* cls_struct_fields[3];
|
||||
ffi_type* cls_struct_fields1[4];
|
||||
ffi_type* cls_struct_fields2[3];
|
||||
ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
|
||||
ffi_type* dbl_arg_types[4];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
cls_struct_type1.size = 0;
|
||||
cls_struct_type1.alignment = 0;
|
||||
cls_struct_type1.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type1.elements = cls_struct_fields1;
|
||||
|
||||
cls_struct_type2.size = 0;
|
||||
cls_struct_type2.alignment = 0;
|
||||
cls_struct_type2.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type2.elements = cls_struct_fields2;
|
||||
|
||||
struct A e_dbl = { 1LL, 7};
|
||||
struct B f_dbl = { 99, {12LL , 127}, 255};
|
||||
struct C g_dbl = { 2LL, 9};
|
||||
|
||||
struct B res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_uint64;
|
||||
cls_struct_fields[1] = &ffi_type_uchar;
|
||||
cls_struct_fields[2] = NULL;
|
||||
|
||||
cls_struct_fields1[0] = &ffi_type_uchar;
|
||||
cls_struct_fields1[1] = &cls_struct_type;
|
||||
cls_struct_fields1[2] = &ffi_type_uint;
|
||||
cls_struct_fields1[3] = NULL;
|
||||
|
||||
cls_struct_fields2[0] = &ffi_type_uint64;
|
||||
cls_struct_fields2[1] = &ffi_type_uchar;
|
||||
cls_struct_fields2[2] = NULL;
|
||||
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type1;
|
||||
dbl_arg_types[2] = &cls_struct_type2;
|
||||
dbl_arg_types[3] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &e_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = &g_dbl;
|
||||
args_dbl[3] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "1 7 12 127 99 255 2 9: 270 242 143" } */
|
||||
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + f_dbl.z + g_dbl.d));
|
||||
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
|
||||
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl);
|
||||
/* { dg-output "\n1 7 12 127 99 255 2 9: 270 242 143" } */
|
||||
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + f_dbl.z + g_dbl.d));
|
||||
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
|
||||
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
|
||||
|
||||
exit(0);
|
||||
}
|
||||
110
.pc/msvc-changes/testsuite/libffi.call/nested_struct2.c
Normal file
110
.pc/msvc-changes/testsuite/libffi.call/nested_struct2.c
Normal file
@@ -0,0 +1,110 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Contains structs as parameter of the struct itself.
|
||||
Sample taken from Alan Modras patch to src/prep_cif.c.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20030911 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct A {
|
||||
unsigned long a;
|
||||
unsigned char b;
|
||||
} A;
|
||||
|
||||
typedef struct B {
|
||||
struct A x;
|
||||
unsigned char y;
|
||||
} B;
|
||||
|
||||
B B_fn(struct A b0, struct B b1)
|
||||
{
|
||||
struct B result;
|
||||
|
||||
result.x.a = b0.a + b1.x.a;
|
||||
result.x.b = b0.b + b1.x.b + b1.y;
|
||||
result.y = b0.b + b1.x.b;
|
||||
|
||||
printf("%lu %d %lu %d %d: %lu %d %d\n", b0.a, b0.b, b1.x.a, b1.x.b, b1.y,
|
||||
result.x.a, result.x.b, result.y);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
struct A b0;
|
||||
struct B b1;
|
||||
|
||||
b0 = *(struct A*)(args[0]);
|
||||
b1 = *(struct B*)(args[1]);
|
||||
|
||||
*(B*)resp = B_fn(b0, b1);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[3];
|
||||
ffi_type* cls_struct_fields[3];
|
||||
ffi_type* cls_struct_fields1[3];
|
||||
ffi_type cls_struct_type, cls_struct_type1;
|
||||
ffi_type* dbl_arg_types[3];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
cls_struct_type1.size = 0;
|
||||
cls_struct_type1.alignment = 0;
|
||||
cls_struct_type1.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type1.elements = cls_struct_fields1;
|
||||
|
||||
struct A e_dbl = { 1, 7};
|
||||
struct B f_dbl = {{12 , 127}, 99};
|
||||
|
||||
struct B res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_ulong;
|
||||
cls_struct_fields[1] = &ffi_type_uchar;
|
||||
cls_struct_fields[2] = NULL;
|
||||
|
||||
cls_struct_fields1[0] = &cls_struct_type;
|
||||
cls_struct_fields1[1] = &ffi_type_uchar;
|
||||
cls_struct_fields1[2] = NULL;
|
||||
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type1;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &e_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "1 7 12 127 99: 13 233 134" } */
|
||||
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
|
||||
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
|
||||
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl);
|
||||
/* { dg-output "\n1 7 12 127 99: 13 233 134" } */
|
||||
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
|
||||
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
|
||||
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
|
||||
|
||||
exit(0);
|
||||
}
|
||||
111
.pc/msvc-changes/testsuite/libffi.call/nested_struct3.c
Normal file
111
.pc/msvc-changes/testsuite/libffi.call/nested_struct3.c
Normal file
@@ -0,0 +1,111 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Contains structs as parameter of the struct itself.
|
||||
Sample taken from Alan Modras patch to src/prep_cif.c.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20030911 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct A {
|
||||
unsigned long long a;
|
||||
unsigned char b;
|
||||
} A;
|
||||
|
||||
typedef struct B {
|
||||
struct A x;
|
||||
unsigned char y;
|
||||
} B;
|
||||
|
||||
B B_fn(struct A b0, struct B b1)
|
||||
{
|
||||
struct B result;
|
||||
|
||||
result.x.a = b0.a + b1.x.a;
|
||||
result.x.b = b0.b + b1.x.b + b1.y;
|
||||
result.y = b0.b + b1.x.b;
|
||||
|
||||
printf("%d %d %d %d %d: %d %d %d\n", (int)b0.a, b0.b,
|
||||
(int)b1.x.a, b1.x.b, b1.y,
|
||||
(int)result.x.a, result.x.b, result.y);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
struct A b0;
|
||||
struct B b1;
|
||||
|
||||
b0 = *(struct A*)(args[0]);
|
||||
b1 = *(struct B*)(args[1]);
|
||||
|
||||
*(B*)resp = B_fn(b0, b1);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[3];
|
||||
ffi_type* cls_struct_fields[3];
|
||||
ffi_type* cls_struct_fields1[3];
|
||||
ffi_type cls_struct_type, cls_struct_type1;
|
||||
ffi_type* dbl_arg_types[3];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
cls_struct_type1.size = 0;
|
||||
cls_struct_type1.alignment = 0;
|
||||
cls_struct_type1.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type1.elements = cls_struct_fields1;
|
||||
|
||||
struct A e_dbl = { 1LL, 7};
|
||||
struct B f_dbl = {{12LL , 127}, 99};
|
||||
|
||||
struct B res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_uint64;
|
||||
cls_struct_fields[1] = &ffi_type_uchar;
|
||||
cls_struct_fields[2] = NULL;
|
||||
|
||||
cls_struct_fields1[0] = &cls_struct_type;
|
||||
cls_struct_fields1[1] = &ffi_type_uchar;
|
||||
cls_struct_fields1[2] = NULL;
|
||||
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type1;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &e_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "1 7 12 127 99: 13 233 134" } */
|
||||
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
|
||||
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
|
||||
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
|
||||
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl);
|
||||
/* { dg-output "\n1 7 12 127 99: 13 233 134" } */
|
||||
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
|
||||
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
|
||||
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
|
||||
exit(0);
|
||||
}
|
||||
111
.pc/msvc-changes/testsuite/libffi.call/nested_struct4.c
Normal file
111
.pc/msvc-changes/testsuite/libffi.call/nested_struct4.c
Normal file
@@ -0,0 +1,111 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Contains structs as parameter of the struct itself.
|
||||
Sample taken from Alan Modras patch to src/prep_cif.c.
|
||||
Limitations: none.
|
||||
PR: PR 25630.
|
||||
Originator: <andreast@gcc.gnu.org> 20051010 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct A {
|
||||
double a;
|
||||
unsigned char b;
|
||||
} A;
|
||||
|
||||
typedef struct B {
|
||||
struct A x;
|
||||
unsigned char y;
|
||||
} B;
|
||||
|
||||
static B B_fn(struct A b2, struct B b3)
|
||||
{
|
||||
struct B result;
|
||||
|
||||
result.x.a = b2.a + b3.x.a;
|
||||
result.x.b = b2.b + b3.x.b + b3.y;
|
||||
result.y = b2.b + b3.x.b;
|
||||
|
||||
printf("%d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b,
|
||||
(int)b3.x.a, b3.x.b, b3.y,
|
||||
(int)result.x.a, result.x.b, result.y);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
struct A b0;
|
||||
struct B b1;
|
||||
|
||||
b0 = *(struct A*)(args[0]);
|
||||
b1 = *(struct B*)(args[1]);
|
||||
|
||||
*(B*)resp = B_fn(b0, b1);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[3];
|
||||
ffi_type* cls_struct_fields[3];
|
||||
ffi_type* cls_struct_fields1[3];
|
||||
ffi_type cls_struct_type, cls_struct_type1;
|
||||
ffi_type* dbl_arg_types[3];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
cls_struct_type1.size = 0;
|
||||
cls_struct_type1.alignment = 0;
|
||||
cls_struct_type1.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type1.elements = cls_struct_fields1;
|
||||
|
||||
struct A e_dbl = { 1.0, 7};
|
||||
struct B f_dbl = {{12.0 , 127}, 99};
|
||||
|
||||
struct B res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_double;
|
||||
cls_struct_fields[1] = &ffi_type_uchar;
|
||||
cls_struct_fields[2] = NULL;
|
||||
|
||||
cls_struct_fields1[0] = &cls_struct_type;
|
||||
cls_struct_fields1[1] = &ffi_type_uchar;
|
||||
cls_struct_fields1[2] = NULL;
|
||||
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type1;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &e_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "1 7 12 127 99: 13 233 134" } */
|
||||
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
|
||||
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
|
||||
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl);
|
||||
/* { dg-output "\n1 7 12 127 99: 13 233 134" } */
|
||||
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
|
||||
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
|
||||
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
|
||||
|
||||
exit(0);
|
||||
}
|
||||
112
.pc/msvc-changes/testsuite/libffi.call/nested_struct5.c
Normal file
112
.pc/msvc-changes/testsuite/libffi.call/nested_struct5.c
Normal file
@@ -0,0 +1,112 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Contains structs as parameter of the struct itself.
|
||||
Sample taken from Alan Modras patch to src/prep_cif.c.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20051010 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct A {
|
||||
long double a;
|
||||
unsigned char b;
|
||||
} A;
|
||||
|
||||
typedef struct B {
|
||||
struct A x;
|
||||
unsigned char y;
|
||||
} B;
|
||||
|
||||
static B B_fn(struct A b2, struct B b3)
|
||||
{
|
||||
struct B result;
|
||||
|
||||
result.x.a = b2.a + b3.x.a;
|
||||
result.x.b = b2.b + b3.x.b + b3.y;
|
||||
result.y = b2.b + b3.x.b;
|
||||
|
||||
printf("%d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b,
|
||||
(int)b3.x.a, b3.x.b, b3.y,
|
||||
(int)result.x.a, result.x.b, result.y);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
struct A b0;
|
||||
struct B b1;
|
||||
|
||||
b0 = *(struct A*)(args[0]);
|
||||
b1 = *(struct B*)(args[1]);
|
||||
|
||||
*(B*)resp = B_fn(b0, b1);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[3];
|
||||
ffi_type* cls_struct_fields[3];
|
||||
ffi_type* cls_struct_fields1[3];
|
||||
ffi_type cls_struct_type, cls_struct_type1;
|
||||
ffi_type* dbl_arg_types[3];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
cls_struct_type1.size = 0;
|
||||
cls_struct_type1.alignment = 0;
|
||||
cls_struct_type1.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type1.elements = cls_struct_fields1;
|
||||
|
||||
struct A e_dbl = { 1.0, 7};
|
||||
struct B f_dbl = {{12.0 , 127}, 99};
|
||||
|
||||
struct B res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_longdouble;
|
||||
cls_struct_fields[1] = &ffi_type_uchar;
|
||||
cls_struct_fields[2] = NULL;
|
||||
|
||||
cls_struct_fields1[0] = &cls_struct_type;
|
||||
cls_struct_fields1[1] = &ffi_type_uchar;
|
||||
cls_struct_fields1[2] = NULL;
|
||||
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type1;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &e_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "1 7 12 127 99: 13 233 134" } */
|
||||
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
|
||||
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
|
||||
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
|
||||
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl);
|
||||
/* { dg-output "\n1 7 12 127 99: 13 233 134" } */
|
||||
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
|
||||
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
|
||||
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
|
||||
|
||||
exit(0);
|
||||
}
|
||||
131
.pc/msvc-changes/testsuite/libffi.call/nested_struct6.c
Normal file
131
.pc/msvc-changes/testsuite/libffi.call/nested_struct6.c
Normal file
@@ -0,0 +1,131 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Contains structs as parameter of the struct itself.
|
||||
Sample taken from Alan Modras patch to src/prep_cif.c.
|
||||
Limitations: none.
|
||||
PR: PR 25630.
|
||||
Originator: <andreast@gcc.gnu.org> 20051010 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct A {
|
||||
double a;
|
||||
unsigned char b;
|
||||
} A;
|
||||
|
||||
typedef struct B {
|
||||
struct A x;
|
||||
unsigned char y;
|
||||
} B;
|
||||
|
||||
typedef struct C {
|
||||
long d;
|
||||
unsigned char e;
|
||||
} C;
|
||||
|
||||
static B B_fn(struct A b2, struct B b3, struct C b4)
|
||||
{
|
||||
struct B result;
|
||||
|
||||
result.x.a = b2.a + b3.x.a + b4.d;
|
||||
result.x.b = b2.b + b3.x.b + b3.y + b4.e;
|
||||
result.y = b2.b + b3.x.b + b4.e;
|
||||
|
||||
printf("%d %d %d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b,
|
||||
(int)b3.x.a, b3.x.b, b3.y, (int)b4.d, b4.e,
|
||||
(int)result.x.a, result.x.b, result.y);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
struct A b0;
|
||||
struct B b1;
|
||||
struct C b2;
|
||||
|
||||
b0 = *(struct A*)(args[0]);
|
||||
b1 = *(struct B*)(args[1]);
|
||||
b2 = *(struct C*)(args[2]);
|
||||
|
||||
*(B*)resp = B_fn(b0, b1, b2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[4];
|
||||
ffi_type* cls_struct_fields[3];
|
||||
ffi_type* cls_struct_fields1[3];
|
||||
ffi_type* cls_struct_fields2[3];
|
||||
ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
|
||||
ffi_type* dbl_arg_types[4];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
cls_struct_type1.size = 0;
|
||||
cls_struct_type1.alignment = 0;
|
||||
cls_struct_type1.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type1.elements = cls_struct_fields1;
|
||||
|
||||
cls_struct_type2.size = 0;
|
||||
cls_struct_type2.alignment = 0;
|
||||
cls_struct_type2.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type2.elements = cls_struct_fields2;
|
||||
|
||||
struct A e_dbl = { 1.0, 7};
|
||||
struct B f_dbl = {{12.0 , 127}, 99};
|
||||
struct C g_dbl = { 2, 9};
|
||||
|
||||
struct B res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_double;
|
||||
cls_struct_fields[1] = &ffi_type_uchar;
|
||||
cls_struct_fields[2] = NULL;
|
||||
|
||||
cls_struct_fields1[0] = &cls_struct_type;
|
||||
cls_struct_fields1[1] = &ffi_type_uchar;
|
||||
cls_struct_fields1[2] = NULL;
|
||||
|
||||
cls_struct_fields2[0] = &ffi_type_slong;
|
||||
cls_struct_fields2[1] = &ffi_type_uchar;
|
||||
cls_struct_fields2[2] = NULL;
|
||||
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type1;
|
||||
dbl_arg_types[2] = &cls_struct_type2;
|
||||
dbl_arg_types[3] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &e_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = &g_dbl;
|
||||
args_dbl[3] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "1 7 12 127 99 2 9: 15 242 143" } */
|
||||
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d));
|
||||
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
|
||||
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl);
|
||||
/* { dg-output "\n1 7 12 127 99 2 9: 15 242 143" } */
|
||||
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d));
|
||||
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
|
||||
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
|
||||
|
||||
exit(0);
|
||||
}
|
||||
111
.pc/msvc-changes/testsuite/libffi.call/nested_struct7.c
Normal file
111
.pc/msvc-changes/testsuite/libffi.call/nested_struct7.c
Normal file
@@ -0,0 +1,111 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Contains structs as parameter of the struct itself.
|
||||
Sample taken from Alan Modras patch to src/prep_cif.c.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20051010 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct A {
|
||||
unsigned long long a;
|
||||
unsigned char b;
|
||||
} A;
|
||||
|
||||
typedef struct B {
|
||||
struct A x;
|
||||
unsigned char y;
|
||||
} B;
|
||||
|
||||
static B B_fn(struct A b2, struct B b3)
|
||||
{
|
||||
struct B result;
|
||||
|
||||
result.x.a = b2.a + b3.x.a;
|
||||
result.x.b = b2.b + b3.x.b + b3.y;
|
||||
result.y = b2.b + b3.x.b;
|
||||
|
||||
printf("%d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b,
|
||||
(int)b3.x.a, b3.x.b, b3.y,
|
||||
(int)result.x.a, result.x.b, result.y);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
struct A b0;
|
||||
struct B b1;
|
||||
|
||||
b0 = *(struct A*)(args[0]);
|
||||
b1 = *(struct B*)(args[1]);
|
||||
|
||||
*(B*)resp = B_fn(b0, b1);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[3];
|
||||
ffi_type* cls_struct_fields[3];
|
||||
ffi_type* cls_struct_fields1[3];
|
||||
ffi_type cls_struct_type, cls_struct_type1;
|
||||
ffi_type* dbl_arg_types[3];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
cls_struct_type1.size = 0;
|
||||
cls_struct_type1.alignment = 0;
|
||||
cls_struct_type1.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type1.elements = cls_struct_fields1;
|
||||
|
||||
struct A e_dbl = { 1LL, 7};
|
||||
struct B f_dbl = {{12.0 , 127}, 99};
|
||||
|
||||
struct B res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_uint64;
|
||||
cls_struct_fields[1] = &ffi_type_uchar;
|
||||
cls_struct_fields[2] = NULL;
|
||||
|
||||
cls_struct_fields1[0] = &cls_struct_type;
|
||||
cls_struct_fields1[1] = &ffi_type_uchar;
|
||||
cls_struct_fields1[2] = NULL;
|
||||
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type1;
|
||||
dbl_arg_types[2] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &e_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "1 7 12 127 99: 13 233 134" } */
|
||||
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
|
||||
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
|
||||
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl);
|
||||
/* { dg-output "\n1 7 12 127 99: 13 233 134" } */
|
||||
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
|
||||
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
|
||||
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
|
||||
|
||||
exit(0);
|
||||
}
|
||||
131
.pc/msvc-changes/testsuite/libffi.call/nested_struct8.c
Normal file
131
.pc/msvc-changes/testsuite/libffi.call/nested_struct8.c
Normal file
@@ -0,0 +1,131 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Contains structs as parameter of the struct itself.
|
||||
Sample taken from Alan Modras patch to src/prep_cif.c.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20051010 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct A {
|
||||
unsigned long long a;
|
||||
unsigned char b;
|
||||
} A;
|
||||
|
||||
typedef struct B {
|
||||
struct A x;
|
||||
unsigned char y;
|
||||
} B;
|
||||
|
||||
typedef struct C {
|
||||
unsigned long long d;
|
||||
unsigned char e;
|
||||
} C;
|
||||
|
||||
static B B_fn(struct A b2, struct B b3, struct C b4)
|
||||
{
|
||||
struct B result;
|
||||
|
||||
result.x.a = b2.a + b3.x.a + b4.d;
|
||||
result.x.b = b2.b + b3.x.b + b3.y + b4.e;
|
||||
result.y = b2.b + b3.x.b + b4.e;
|
||||
|
||||
printf("%d %d %d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b,
|
||||
(int)b3.x.a, b3.x.b, b3.y, (int)b4.d, b4.e,
|
||||
(int)result.x.a, result.x.b, result.y);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
struct A b0;
|
||||
struct B b1;
|
||||
struct C b2;
|
||||
|
||||
b0 = *(struct A*)(args[0]);
|
||||
b1 = *(struct B*)(args[1]);
|
||||
b2 = *(struct C*)(args[2]);
|
||||
|
||||
*(B*)resp = B_fn(b0, b1, b2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[4];
|
||||
ffi_type* cls_struct_fields[3];
|
||||
ffi_type* cls_struct_fields1[3];
|
||||
ffi_type* cls_struct_fields2[3];
|
||||
ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
|
||||
ffi_type* dbl_arg_types[4];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
cls_struct_type1.size = 0;
|
||||
cls_struct_type1.alignment = 0;
|
||||
cls_struct_type1.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type1.elements = cls_struct_fields1;
|
||||
|
||||
cls_struct_type2.size = 0;
|
||||
cls_struct_type2.alignment = 0;
|
||||
cls_struct_type2.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type2.elements = cls_struct_fields2;
|
||||
|
||||
struct A e_dbl = { 1LL, 7};
|
||||
struct B f_dbl = {{12LL , 127}, 99};
|
||||
struct C g_dbl = { 2LL, 9};
|
||||
|
||||
struct B res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_uint64;
|
||||
cls_struct_fields[1] = &ffi_type_uchar;
|
||||
cls_struct_fields[2] = NULL;
|
||||
|
||||
cls_struct_fields1[0] = &cls_struct_type;
|
||||
cls_struct_fields1[1] = &ffi_type_uchar;
|
||||
cls_struct_fields1[2] = NULL;
|
||||
|
||||
cls_struct_fields2[0] = &ffi_type_uint64;
|
||||
cls_struct_fields2[1] = &ffi_type_uchar;
|
||||
cls_struct_fields2[2] = NULL;
|
||||
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type1;
|
||||
dbl_arg_types[2] = &cls_struct_type2;
|
||||
dbl_arg_types[3] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &e_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = &g_dbl;
|
||||
args_dbl[3] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "1 7 12 127 99 2 9: 15 242 143" } */
|
||||
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d));
|
||||
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
|
||||
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl);
|
||||
/* { dg-output "\n1 7 12 127 99 2 9: 15 242 143" } */
|
||||
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d));
|
||||
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
|
||||
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
|
||||
|
||||
exit(0);
|
||||
}
|
||||
131
.pc/msvc-changes/testsuite/libffi.call/nested_struct9.c
Normal file
131
.pc/msvc-changes/testsuite/libffi.call/nested_struct9.c
Normal file
@@ -0,0 +1,131 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure passing with different structure size.
|
||||
Contains structs as parameter of the struct itself.
|
||||
Sample taken from Alan Modras patch to src/prep_cif.c.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: <andreast@gcc.gnu.org> 20051010 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct A {
|
||||
unsigned char a;
|
||||
unsigned long long b;
|
||||
} A;
|
||||
|
||||
typedef struct B {
|
||||
struct A x;
|
||||
unsigned char y;
|
||||
} B;
|
||||
|
||||
typedef struct C {
|
||||
unsigned long d;
|
||||
unsigned char e;
|
||||
} C;
|
||||
|
||||
static B B_fn(struct A b2, struct B b3, struct C b4)
|
||||
{
|
||||
struct B result;
|
||||
|
||||
result.x.a = b2.a + b3.x.a + b4.d;
|
||||
result.x.b = b2.b + b3.x.b + b3.y + b4.e;
|
||||
result.y = b2.b + b3.x.b + b4.e;
|
||||
|
||||
printf("%d %d %d %d %d %d %d: %d %d %d\n", b2.a, (int)b2.b,
|
||||
b3.x.a, (int)b3.x.b, b3.y, (int)b4.d, b4.e,
|
||||
result.x.a, (int)result.x.b, result.y);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
||||
void* userdata __UNUSED__)
|
||||
{
|
||||
struct A b0;
|
||||
struct B b1;
|
||||
struct C b2;
|
||||
|
||||
b0 = *(struct A*)(args[0]);
|
||||
b1 = *(struct B*)(args[1]);
|
||||
b2 = *(struct C*)(args[2]);
|
||||
|
||||
*(B*)resp = B_fn(b0, b1, b2);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[4];
|
||||
ffi_type* cls_struct_fields[3];
|
||||
ffi_type* cls_struct_fields1[3];
|
||||
ffi_type* cls_struct_fields2[3];
|
||||
ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
|
||||
ffi_type* dbl_arg_types[4];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
cls_struct_type1.size = 0;
|
||||
cls_struct_type1.alignment = 0;
|
||||
cls_struct_type1.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type1.elements = cls_struct_fields1;
|
||||
|
||||
cls_struct_type2.size = 0;
|
||||
cls_struct_type2.alignment = 0;
|
||||
cls_struct_type2.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type2.elements = cls_struct_fields2;
|
||||
|
||||
struct A e_dbl = { 1, 7LL};
|
||||
struct B f_dbl = {{12.0 , 127}, 99};
|
||||
struct C g_dbl = { 2, 9};
|
||||
|
||||
struct B res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_uchar;
|
||||
cls_struct_fields[1] = &ffi_type_uint64;
|
||||
cls_struct_fields[2] = NULL;
|
||||
|
||||
cls_struct_fields1[0] = &cls_struct_type;
|
||||
cls_struct_fields1[1] = &ffi_type_uchar;
|
||||
cls_struct_fields1[2] = NULL;
|
||||
|
||||
cls_struct_fields2[0] = &ffi_type_ulong;
|
||||
cls_struct_fields2[1] = &ffi_type_uchar;
|
||||
cls_struct_fields2[2] = NULL;
|
||||
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type1;
|
||||
dbl_arg_types[2] = &cls_struct_type2;
|
||||
dbl_arg_types[3] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &e_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = &g_dbl;
|
||||
args_dbl[3] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "1 7 12 127 99 2 9: 15 242 143" } */
|
||||
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d));
|
||||
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
|
||||
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl);
|
||||
/* { dg-output "\n1 7 12 127 99 2 9: 15 242 143" } */
|
||||
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d));
|
||||
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
|
||||
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
|
||||
|
||||
exit(0);
|
||||
}
|
||||
145
.pc/msvc-changes/testsuite/libffi.call/stret_large.c
Normal file
145
.pc/msvc-changes/testsuite/libffi.call/stret_large.c
Normal file
@@ -0,0 +1,145 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure returning with different structure size.
|
||||
Depending on the ABI. Check bigger struct which overlaps
|
||||
the gp and fp register count on Darwin/AIX/ppc64.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: Blake Chaffin 6/21/2007 */
|
||||
|
||||
/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
|
||||
#include "ffitest.h"
|
||||
|
||||
// 13 FPRs: 104 bytes
|
||||
// 14 FPRs: 112 bytes
|
||||
|
||||
typedef struct struct_108byte {
|
||||
double a;
|
||||
double b;
|
||||
double c;
|
||||
double d;
|
||||
double e;
|
||||
double f;
|
||||
double g;
|
||||
double h;
|
||||
double i;
|
||||
double j;
|
||||
double k;
|
||||
double l;
|
||||
double m;
|
||||
int n;
|
||||
} struct_108byte;
|
||||
|
||||
struct_108byte cls_struct_108byte_fn(
|
||||
struct_108byte b0,
|
||||
struct_108byte b1,
|
||||
struct_108byte b2,
|
||||
struct_108byte b3)
|
||||
{
|
||||
struct_108byte result;
|
||||
|
||||
result.a = b0.a + b1.a + b2.a + b3.a;
|
||||
result.b = b0.b + b1.b + b2.b + b3.b;
|
||||
result.c = b0.c + b1.c + b2.c + b3.c;
|
||||
result.d = b0.d + b1.d + b2.d + b3.d;
|
||||
result.e = b0.e + b1.e + b2.e + b3.e;
|
||||
result.f = b0.f + b1.f + b2.f + b3.f;
|
||||
result.g = b0.g + b1.g + b2.g + b3.g;
|
||||
result.h = b0.h + b1.h + b2.h + b3.h;
|
||||
result.i = b0.i + b1.i + b2.i + b3.i;
|
||||
result.j = b0.j + b1.j + b2.j + b3.j;
|
||||
result.k = b0.k + b1.k + b2.k + b3.k;
|
||||
result.l = b0.l + b1.l + b2.l + b3.l;
|
||||
result.m = b0.m + b1.m + b2.m + b3.m;
|
||||
result.n = b0.n + b1.n + b2.n + b3.n;
|
||||
|
||||
printf("%g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", result.a, result.b, result.c,
|
||||
result.d, result.e, result.f, result.g, result.h, result.i,
|
||||
result.j, result.k, result.l, result.m, result.n);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_108byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__)
|
||||
{
|
||||
struct_108byte b0, b1, b2, b3;
|
||||
|
||||
b0 = *(struct_108byte*)(args[0]);
|
||||
b1 = *(struct_108byte*)(args[1]);
|
||||
b2 = *(struct_108byte*)(args[2]);
|
||||
b3 = *(struct_108byte*)(args[3]);
|
||||
|
||||
*(struct_108byte*)resp = cls_struct_108byte_fn(b0, b1, b2, b3);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[15];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct_108byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 1.0, 2.0, 3.0, 7.0, 2.0, 7 };
|
||||
struct_108byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4.0, 5.0, 7.0, 9.0, 1.0, 4 };
|
||||
struct_108byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 8.0, 6.0, 1.0, 4.0, 0.0, 3 };
|
||||
struct_108byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 9.0, 2.0, 6.0, 5.0, 3.0, 2 };
|
||||
struct_108byte res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_double;
|
||||
cls_struct_fields[1] = &ffi_type_double;
|
||||
cls_struct_fields[2] = &ffi_type_double;
|
||||
cls_struct_fields[3] = &ffi_type_double;
|
||||
cls_struct_fields[4] = &ffi_type_double;
|
||||
cls_struct_fields[5] = &ffi_type_double;
|
||||
cls_struct_fields[6] = &ffi_type_double;
|
||||
cls_struct_fields[7] = &ffi_type_double;
|
||||
cls_struct_fields[8] = &ffi_type_double;
|
||||
cls_struct_fields[9] = &ffi_type_double;
|
||||
cls_struct_fields[10] = &ffi_type_double;
|
||||
cls_struct_fields[11] = &ffi_type_double;
|
||||
cls_struct_fields[12] = &ffi_type_double;
|
||||
cls_struct_fields[13] = &ffi_type_sint32;
|
||||
cls_struct_fields[14] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = &cls_struct_type;
|
||||
dbl_arg_types[3] = &cls_struct_type;
|
||||
dbl_arg_types[4] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &e_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = &g_dbl;
|
||||
args_dbl[3] = &h_dbl;
|
||||
args_dbl[4] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_108byte_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */
|
||||
printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b,
|
||||
res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i,
|
||||
res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n);
|
||||
/* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_108byte_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((struct_108byte(*)(struct_108byte, struct_108byte,
|
||||
struct_108byte, struct_108byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl);
|
||||
/* { dg-output "\n22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */
|
||||
printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b,
|
||||
res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i,
|
||||
res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n);
|
||||
/* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
148
.pc/msvc-changes/testsuite/libffi.call/stret_large2.c
Normal file
148
.pc/msvc-changes/testsuite/libffi.call/stret_large2.c
Normal file
@@ -0,0 +1,148 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure returning with different structure size.
|
||||
Depending on the ABI. Check bigger struct which overlaps
|
||||
the gp and fp register count on Darwin/AIX/ppc64.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: Blake Chaffin 6/21/2007 */
|
||||
|
||||
/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
|
||||
#include "ffitest.h"
|
||||
|
||||
// 13 FPRs: 104 bytes
|
||||
// 14 FPRs: 112 bytes
|
||||
|
||||
typedef struct struct_116byte {
|
||||
double a;
|
||||
double b;
|
||||
double c;
|
||||
double d;
|
||||
double e;
|
||||
double f;
|
||||
double g;
|
||||
double h;
|
||||
double i;
|
||||
double j;
|
||||
double k;
|
||||
double l;
|
||||
double m;
|
||||
double n;
|
||||
int o;
|
||||
} struct_116byte;
|
||||
|
||||
struct_116byte cls_struct_116byte_fn(
|
||||
struct_116byte b0,
|
||||
struct_116byte b1,
|
||||
struct_116byte b2,
|
||||
struct_116byte b3)
|
||||
{
|
||||
struct_116byte result;
|
||||
|
||||
result.a = b0.a + b1.a + b2.a + b3.a;
|
||||
result.b = b0.b + b1.b + b2.b + b3.b;
|
||||
result.c = b0.c + b1.c + b2.c + b3.c;
|
||||
result.d = b0.d + b1.d + b2.d + b3.d;
|
||||
result.e = b0.e + b1.e + b2.e + b3.e;
|
||||
result.f = b0.f + b1.f + b2.f + b3.f;
|
||||
result.g = b0.g + b1.g + b2.g + b3.g;
|
||||
result.h = b0.h + b1.h + b2.h + b3.h;
|
||||
result.i = b0.i + b1.i + b2.i + b3.i;
|
||||
result.j = b0.j + b1.j + b2.j + b3.j;
|
||||
result.k = b0.k + b1.k + b2.k + b3.k;
|
||||
result.l = b0.l + b1.l + b2.l + b3.l;
|
||||
result.m = b0.m + b1.m + b2.m + b3.m;
|
||||
result.n = b0.n + b1.n + b2.n + b3.n;
|
||||
result.o = b0.o + b1.o + b2.o + b3.o;
|
||||
|
||||
printf("%g %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", result.a, result.b, result.c,
|
||||
result.d, result.e, result.f, result.g, result.h, result.i,
|
||||
result.j, result.k, result.l, result.m, result.n, result.o);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_116byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__)
|
||||
{
|
||||
struct_116byte b0, b1, b2, b3;
|
||||
|
||||
b0 = *(struct_116byte*)(args[0]);
|
||||
b1 = *(struct_116byte*)(args[1]);
|
||||
b2 = *(struct_116byte*)(args[2]);
|
||||
b3 = *(struct_116byte*)(args[3]);
|
||||
|
||||
*(struct_116byte*)resp = cls_struct_116byte_fn(b0, b1, b2, b3);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[16];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct_116byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 7 };
|
||||
struct_116byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4.0, 5.0, 7.0, 9.0, 1.0, 6.0, 4 };
|
||||
struct_116byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 8.0, 6.0, 1.0, 4.0, 0.0, 7.0, 3 };
|
||||
struct_116byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 9.0, 2.0, 6.0, 5.0, 3.0, 8.0, 2 };
|
||||
struct_116byte res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_double;
|
||||
cls_struct_fields[1] = &ffi_type_double;
|
||||
cls_struct_fields[2] = &ffi_type_double;
|
||||
cls_struct_fields[3] = &ffi_type_double;
|
||||
cls_struct_fields[4] = &ffi_type_double;
|
||||
cls_struct_fields[5] = &ffi_type_double;
|
||||
cls_struct_fields[6] = &ffi_type_double;
|
||||
cls_struct_fields[7] = &ffi_type_double;
|
||||
cls_struct_fields[8] = &ffi_type_double;
|
||||
cls_struct_fields[9] = &ffi_type_double;
|
||||
cls_struct_fields[10] = &ffi_type_double;
|
||||
cls_struct_fields[11] = &ffi_type_double;
|
||||
cls_struct_fields[12] = &ffi_type_double;
|
||||
cls_struct_fields[13] = &ffi_type_double;
|
||||
cls_struct_fields[14] = &ffi_type_sint32;
|
||||
cls_struct_fields[15] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = &cls_struct_type;
|
||||
dbl_arg_types[3] = &cls_struct_type;
|
||||
dbl_arg_types[4] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &e_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = &g_dbl;
|
||||
args_dbl[3] = &h_dbl;
|
||||
args_dbl[4] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_116byte_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */
|
||||
printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b,
|
||||
res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i,
|
||||
res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n, res_dbl.o);
|
||||
/* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_116byte_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((struct_116byte(*)(struct_116byte, struct_116byte,
|
||||
struct_116byte, struct_116byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl);
|
||||
/* { dg-output "\n22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */
|
||||
printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b,
|
||||
res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i,
|
||||
res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n, res_dbl.o);
|
||||
/* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
124
.pc/msvc-changes/testsuite/libffi.call/stret_medium.c
Normal file
124
.pc/msvc-changes/testsuite/libffi.call/stret_medium.c
Normal file
@@ -0,0 +1,124 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure returning with different structure size.
|
||||
Depending on the ABI. Check bigger struct which overlaps
|
||||
the gp and fp register count on Darwin/AIX/ppc64.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: Blake Chaffin 6/21/2007 */
|
||||
|
||||
/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct struct_72byte {
|
||||
double a;
|
||||
double b;
|
||||
double c;
|
||||
double d;
|
||||
double e;
|
||||
double f;
|
||||
double g;
|
||||
double h;
|
||||
double i;
|
||||
} struct_72byte;
|
||||
|
||||
struct_72byte cls_struct_72byte_fn(
|
||||
struct_72byte b0,
|
||||
struct_72byte b1,
|
||||
struct_72byte b2,
|
||||
struct_72byte b3)
|
||||
{
|
||||
struct_72byte result;
|
||||
|
||||
result.a = b0.a + b1.a + b2.a + b3.a;
|
||||
result.b = b0.b + b1.b + b2.b + b3.b;
|
||||
result.c = b0.c + b1.c + b2.c + b3.c;
|
||||
result.d = b0.d + b1.d + b2.d + b3.d;
|
||||
result.e = b0.e + b1.e + b2.e + b3.e;
|
||||
result.f = b0.f + b1.f + b2.f + b3.f;
|
||||
result.g = b0.g + b1.g + b2.g + b3.g;
|
||||
result.h = b0.h + b1.h + b2.h + b3.h;
|
||||
result.i = b0.i + b1.i + b2.i + b3.i;
|
||||
|
||||
printf("%g %g %g %g %g %g %g %g %g\n", result.a, result.b, result.c,
|
||||
result.d, result.e, result.f, result.g, result.h, result.i);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_72byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__)
|
||||
{
|
||||
struct_72byte b0, b1, b2, b3;
|
||||
|
||||
b0 = *(struct_72byte*)(args[0]);
|
||||
b1 = *(struct_72byte*)(args[1]);
|
||||
b2 = *(struct_72byte*)(args[2]);
|
||||
b3 = *(struct_72byte*)(args[3]);
|
||||
|
||||
*(struct_72byte*)resp = cls_struct_72byte_fn(b0, b1, b2, b3);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[10];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct_72byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 7.0 };
|
||||
struct_72byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4.0 };
|
||||
struct_72byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 3.0 };
|
||||
struct_72byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 2.0 };
|
||||
struct_72byte res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_double;
|
||||
cls_struct_fields[1] = &ffi_type_double;
|
||||
cls_struct_fields[2] = &ffi_type_double;
|
||||
cls_struct_fields[3] = &ffi_type_double;
|
||||
cls_struct_fields[4] = &ffi_type_double;
|
||||
cls_struct_fields[5] = &ffi_type_double;
|
||||
cls_struct_fields[6] = &ffi_type_double;
|
||||
cls_struct_fields[7] = &ffi_type_double;
|
||||
cls_struct_fields[8] = &ffi_type_double;
|
||||
cls_struct_fields[9] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = &cls_struct_type;
|
||||
dbl_arg_types[3] = &cls_struct_type;
|
||||
dbl_arg_types[4] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &e_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = &g_dbl;
|
||||
args_dbl[3] = &h_dbl;
|
||||
args_dbl[4] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_72byte_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "22 15 17 25 6 13 19 18 16" } */
|
||||
printf("res: %g %g %g %g %g %g %g %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c,
|
||||
res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i);
|
||||
/* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_72byte_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((struct_72byte(*)(struct_72byte, struct_72byte,
|
||||
struct_72byte, struct_72byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl);
|
||||
/* { dg-output "\n22 15 17 25 6 13 19 18 16" } */
|
||||
printf("res: %g %g %g %g %g %g %g %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c,
|
||||
res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i);
|
||||
/* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
125
.pc/msvc-changes/testsuite/libffi.call/stret_medium2.c
Normal file
125
.pc/msvc-changes/testsuite/libffi.call/stret_medium2.c
Normal file
@@ -0,0 +1,125 @@
|
||||
/* Area: ffi_call, closure_call
|
||||
Purpose: Check structure returning with different structure size.
|
||||
Depending on the ABI. Check bigger struct which overlaps
|
||||
the gp and fp register count on Darwin/AIX/ppc64.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: Blake Chaffin 6/21/2007 */
|
||||
|
||||
/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
|
||||
/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct struct_72byte {
|
||||
double a;
|
||||
double b;
|
||||
double c;
|
||||
double d;
|
||||
double e;
|
||||
double f;
|
||||
double g;
|
||||
double h;
|
||||
long long i;
|
||||
} struct_72byte;
|
||||
|
||||
struct_72byte cls_struct_72byte_fn(
|
||||
struct_72byte b0,
|
||||
struct_72byte b1,
|
||||
struct_72byte b2,
|
||||
struct_72byte b3)
|
||||
{
|
||||
struct_72byte result;
|
||||
|
||||
result.a = b0.a + b1.a + b2.a + b3.a;
|
||||
result.b = b0.b + b1.b + b2.b + b3.b;
|
||||
result.c = b0.c + b1.c + b2.c + b3.c;
|
||||
result.d = b0.d + b1.d + b2.d + b3.d;
|
||||
result.e = b0.e + b1.e + b2.e + b3.e;
|
||||
result.f = b0.f + b1.f + b2.f + b3.f;
|
||||
result.g = b0.g + b1.g + b2.g + b3.g;
|
||||
result.h = b0.h + b1.h + b2.h + b3.h;
|
||||
result.i = b0.i + b1.i + b2.i + b3.i;
|
||||
|
||||
printf("%g %g %g %g %g %g %g %g %" PRIdLL "\n", result.a, result.b, result.c,
|
||||
result.d, result.e, result.f, result.g, result.h, result.i);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_72byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__)
|
||||
{
|
||||
struct_72byte b0, b1, b2, b3;
|
||||
|
||||
b0 = *(struct_72byte*)(args[0]);
|
||||
b1 = *(struct_72byte*)(args[1]);
|
||||
b2 = *(struct_72byte*)(args[2]);
|
||||
b3 = *(struct_72byte*)(args[3]);
|
||||
|
||||
*(struct_72byte*)resp = cls_struct_72byte_fn(b0, b1, b2, b3);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
void* args_dbl[5];
|
||||
ffi_type* cls_struct_fields[10];
|
||||
ffi_type cls_struct_type;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type.size = 0;
|
||||
cls_struct_type.alignment = 0;
|
||||
cls_struct_type.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type.elements = cls_struct_fields;
|
||||
|
||||
struct_72byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 7 };
|
||||
struct_72byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4 };
|
||||
struct_72byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 3 };
|
||||
struct_72byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 2 };
|
||||
struct_72byte res_dbl;
|
||||
|
||||
cls_struct_fields[0] = &ffi_type_double;
|
||||
cls_struct_fields[1] = &ffi_type_double;
|
||||
cls_struct_fields[2] = &ffi_type_double;
|
||||
cls_struct_fields[3] = &ffi_type_double;
|
||||
cls_struct_fields[4] = &ffi_type_double;
|
||||
cls_struct_fields[5] = &ffi_type_double;
|
||||
cls_struct_fields[6] = &ffi_type_double;
|
||||
cls_struct_fields[7] = &ffi_type_double;
|
||||
cls_struct_fields[8] = &ffi_type_sint64;
|
||||
cls_struct_fields[9] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type;
|
||||
dbl_arg_types[1] = &cls_struct_type;
|
||||
dbl_arg_types[2] = &cls_struct_type;
|
||||
dbl_arg_types[3] = &cls_struct_type;
|
||||
dbl_arg_types[4] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
args_dbl[0] = &e_dbl;
|
||||
args_dbl[1] = &f_dbl;
|
||||
args_dbl[2] = &g_dbl;
|
||||
args_dbl[3] = &h_dbl;
|
||||
args_dbl[4] = NULL;
|
||||
|
||||
ffi_call(&cif, FFI_FN(cls_struct_72byte_fn), &res_dbl, args_dbl);
|
||||
/* { dg-output "22 15 17 25 6 13 19 18 16" } */
|
||||
printf("res: %g %g %g %g %g %g %g %g %" PRIdLL "\n", res_dbl.a, res_dbl.b, res_dbl.c,
|
||||
res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i);
|
||||
/* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_72byte_gn, NULL, code) == FFI_OK);
|
||||
|
||||
res_dbl = ((struct_72byte(*)(struct_72byte, struct_72byte,
|
||||
struct_72byte, struct_72byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl);
|
||||
/* { dg-output "\n22 15 17 25 6 13 19 18 16" } */
|
||||
printf("res: %g %g %g %g %g %g %g %g %" PRIdLL "\n", res_dbl.a, res_dbl.b, res_dbl.c,
|
||||
res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i);
|
||||
/* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
44
.pc/msvc-changes/testsuite/libffi.call/strlen2_win32.c
Normal file
44
.pc/msvc-changes/testsuite/libffi.call/strlen2_win32.c
Normal file
@@ -0,0 +1,44 @@
|
||||
/* Area: ffi_call
|
||||
Purpose: Check fastcall strlen call on X86_WIN32 systems.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: From the original ffitest.c */
|
||||
|
||||
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
|
||||
|
||||
#include "ffitest.h"
|
||||
|
||||
static size_t __attribute__((fastcall)) my_fastcall_strlen(char *s)
|
||||
{
|
||||
return (strlen(s));
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
ffi_type *args[MAX_ARGS];
|
||||
void *values[MAX_ARGS];
|
||||
ffi_arg rint;
|
||||
char *s;
|
||||
args[0] = &ffi_type_pointer;
|
||||
values[0] = (void*) &s;
|
||||
|
||||
/* Initialize the cif */
|
||||
CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 1,
|
||||
&ffi_type_sint, args) == FFI_OK);
|
||||
|
||||
s = "a";
|
||||
ffi_call(&cif, FFI_FN(my_fastcall_strlen), &rint, values);
|
||||
CHECK(rint == 1);
|
||||
|
||||
s = "1234567";
|
||||
ffi_call(&cif, FFI_FN(my_fastcall_strlen), &rint, values);
|
||||
CHECK(rint == 7);
|
||||
|
||||
s = "1234567890123456789012345";
|
||||
ffi_call(&cif, FFI_FN(my_fastcall_strlen), &rint, values);
|
||||
CHECK(rint == 25);
|
||||
|
||||
printf("fastcall strlen tests passed\n");
|
||||
exit(0);
|
||||
}
|
||||
65
.pc/msvc-changes/testsuite/libffi.call/struct1.c
Normal file
65
.pc/msvc-changes/testsuite/libffi.call/struct1.c
Normal file
@@ -0,0 +1,65 @@
|
||||
/* Area: ffi_call
|
||||
Purpose: Check structures.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: From the original ffitest.c */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char uc;
|
||||
double d;
|
||||
unsigned int ui;
|
||||
} test_structure_1;
|
||||
|
||||
static test_structure_1 struct1(test_structure_1 ts)
|
||||
{
|
||||
ts.uc++;
|
||||
ts.d--;
|
||||
ts.ui++;
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
ffi_type *args[MAX_ARGS];
|
||||
void *values[MAX_ARGS];
|
||||
ffi_type ts1_type;
|
||||
ffi_type *ts1_type_elements[4];
|
||||
ts1_type.size = 0;
|
||||
ts1_type.alignment = 0;
|
||||
ts1_type.type = FFI_TYPE_STRUCT;
|
||||
ts1_type.elements = ts1_type_elements;
|
||||
ts1_type_elements[0] = &ffi_type_uchar;
|
||||
ts1_type_elements[1] = &ffi_type_double;
|
||||
ts1_type_elements[2] = &ffi_type_uint;
|
||||
ts1_type_elements[3] = NULL;
|
||||
|
||||
test_structure_1 ts1_arg;
|
||||
/* This is a hack to get a properly aligned result buffer */
|
||||
test_structure_1 *ts1_result =
|
||||
(test_structure_1 *) malloc (sizeof(test_structure_1));
|
||||
|
||||
args[0] = &ts1_type;
|
||||
values[0] = &ts1_arg;
|
||||
|
||||
/* Initialize the cif */
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
|
||||
&ts1_type, args) == FFI_OK);
|
||||
|
||||
ts1_arg.uc = '\x01';
|
||||
ts1_arg.d = 3.14159;
|
||||
ts1_arg.ui = 555;
|
||||
|
||||
ffi_call(&cif, FFI_FN(struct1), ts1_result, values);
|
||||
|
||||
CHECK(ts1_result->ui == 556);
|
||||
CHECK(ts1_result->d == 3.14159 - 1);
|
||||
|
||||
free (ts1_result);
|
||||
exit(0);
|
||||
}
|
||||
65
.pc/msvc-changes/testsuite/libffi.call/struct1_win32.c
Normal file
65
.pc/msvc-changes/testsuite/libffi.call/struct1_win32.c
Normal file
@@ -0,0 +1,65 @@
|
||||
/* Area: ffi_call
|
||||
Purpose: Check structures with fastcall/thiscall convention.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: From the original ffitest.c */
|
||||
|
||||
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char uc;
|
||||
double d;
|
||||
unsigned int ui;
|
||||
} test_structure_1;
|
||||
|
||||
static __attribute__ ((fastcall)) test_structure_1 struct1(test_structure_1 ts)
|
||||
{
|
||||
ts.uc++;
|
||||
ts.d--;
|
||||
ts.ui++;
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
ffi_type *args[MAX_ARGS];
|
||||
void *values[MAX_ARGS];
|
||||
ffi_type ts1_type;
|
||||
ffi_type *ts1_type_elements[4];
|
||||
ts1_type.size = 0;
|
||||
ts1_type.alignment = 0;
|
||||
ts1_type.type = FFI_TYPE_STRUCT;
|
||||
ts1_type.elements = ts1_type_elements;
|
||||
ts1_type_elements[0] = &ffi_type_uchar;
|
||||
ts1_type_elements[1] = &ffi_type_double;
|
||||
ts1_type_elements[2] = &ffi_type_uint;
|
||||
ts1_type_elements[3] = NULL;
|
||||
|
||||
test_structure_1 ts1_arg;
|
||||
/* This is a hack to get a properly aligned result buffer */
|
||||
test_structure_1 *ts1_result =
|
||||
(test_structure_1 *) malloc (sizeof(test_structure_1));
|
||||
|
||||
args[0] = &ts1_type;
|
||||
values[0] = &ts1_arg;
|
||||
|
||||
/* Initialize the cif */
|
||||
CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 1,
|
||||
&ts1_type, args) == FFI_OK);
|
||||
|
||||
ts1_arg.uc = '\x01';
|
||||
ts1_arg.d = 3.14159;
|
||||
ts1_arg.ui = 555;
|
||||
|
||||
ffi_call(&cif, FFI_FN(struct1), ts1_result, values);
|
||||
|
||||
CHECK(ts1_result->ui == 556);
|
||||
CHECK(ts1_result->d == 3.14159 - 1);
|
||||
|
||||
free (ts1_result);
|
||||
exit(0);
|
||||
}
|
||||
67
.pc/msvc-changes/testsuite/libffi.call/struct2.c
Normal file
67
.pc/msvc-changes/testsuite/libffi.call/struct2.c
Normal file
@@ -0,0 +1,67 @@
|
||||
/* Area: ffi_call
|
||||
Purpose: Check structures.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: From the original ffitest.c */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double d1;
|
||||
double d2;
|
||||
} test_structure_2;
|
||||
|
||||
static test_structure_2 struct2(test_structure_2 ts)
|
||||
{
|
||||
ts.d1--;
|
||||
ts.d2--;
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
ffi_type *args[MAX_ARGS];
|
||||
void *values[MAX_ARGS];
|
||||
test_structure_2 ts2_arg;
|
||||
ffi_type ts2_type;
|
||||
ffi_type *ts2_type_elements[3];
|
||||
ts2_type.size = 0;
|
||||
ts2_type.alignment = 0;
|
||||
ts2_type.type = FFI_TYPE_STRUCT;
|
||||
ts2_type.elements = ts2_type_elements;
|
||||
ts2_type_elements[0] = &ffi_type_double;
|
||||
ts2_type_elements[1] = &ffi_type_double;
|
||||
ts2_type_elements[2] = NULL;
|
||||
|
||||
|
||||
/* This is a hack to get a properly aligned result buffer */
|
||||
test_structure_2 *ts2_result =
|
||||
(test_structure_2 *) malloc (sizeof(test_structure_2));
|
||||
|
||||
args[0] = &ts2_type;
|
||||
values[0] = &ts2_arg;
|
||||
|
||||
/* Initialize the cif */
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts2_type, args) == FFI_OK);
|
||||
|
||||
ts2_arg.d1 = 5.55;
|
||||
ts2_arg.d2 = 6.66;
|
||||
|
||||
printf ("%g\n", ts2_arg.d1);
|
||||
printf ("%g\n", ts2_arg.d2);
|
||||
|
||||
ffi_call(&cif, FFI_FN(struct2), ts2_result, values);
|
||||
|
||||
printf ("%g\n", ts2_result->d1);
|
||||
printf ("%g\n", ts2_result->d2);
|
||||
|
||||
CHECK(ts2_result->d1 == 5.55 - 1);
|
||||
CHECK(ts2_result->d2 == 6.66 - 1);
|
||||
|
||||
free (ts2_result);
|
||||
exit(0);
|
||||
}
|
||||
67
.pc/msvc-changes/testsuite/libffi.call/struct2_win32.c
Normal file
67
.pc/msvc-changes/testsuite/libffi.call/struct2_win32.c
Normal file
@@ -0,0 +1,67 @@
|
||||
/* Area: ffi_call
|
||||
Purpose: Check structures in fastcall/stdcall function
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: From the original ffitest.c */
|
||||
|
||||
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double d1;
|
||||
double d2;
|
||||
} test_structure_2;
|
||||
|
||||
static test_structure_2 __attribute__ ((fastcall)) struct2(test_structure_2 ts)
|
||||
{
|
||||
ts.d1--;
|
||||
ts.d2--;
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
ffi_type *args[MAX_ARGS];
|
||||
void *values[MAX_ARGS];
|
||||
test_structure_2 ts2_arg;
|
||||
ffi_type ts2_type;
|
||||
ffi_type *ts2_type_elements[3];
|
||||
ts2_type.size = 0;
|
||||
ts2_type.alignment = 0;
|
||||
ts2_type.type = FFI_TYPE_STRUCT;
|
||||
ts2_type.elements = ts2_type_elements;
|
||||
ts2_type_elements[0] = &ffi_type_double;
|
||||
ts2_type_elements[1] = &ffi_type_double;
|
||||
ts2_type_elements[2] = NULL;
|
||||
|
||||
|
||||
/* This is a hack to get a properly aligned result buffer */
|
||||
test_structure_2 *ts2_result =
|
||||
(test_structure_2 *) malloc (sizeof(test_structure_2));
|
||||
|
||||
args[0] = &ts2_type;
|
||||
values[0] = &ts2_arg;
|
||||
|
||||
/* Initialize the cif */
|
||||
CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 1, &ts2_type, args) == FFI_OK);
|
||||
|
||||
ts2_arg.d1 = 5.55;
|
||||
ts2_arg.d2 = 6.66;
|
||||
|
||||
printf ("%g\n", ts2_arg.d1);
|
||||
printf ("%g\n", ts2_arg.d2);
|
||||
|
||||
ffi_call(&cif, FFI_FN(struct2), ts2_result, values);
|
||||
|
||||
printf ("%g\n", ts2_result->d1);
|
||||
printf ("%g\n", ts2_result->d2);
|
||||
|
||||
CHECK(ts2_result->d1 == 5.55 - 1);
|
||||
CHECK(ts2_result->d2 == 6.66 - 1);
|
||||
|
||||
free (ts2_result);
|
||||
exit(0);
|
||||
}
|
||||
59
.pc/msvc-changes/testsuite/libffi.call/struct3.c
Normal file
59
.pc/msvc-changes/testsuite/libffi.call/struct3.c
Normal file
@@ -0,0 +1,59 @@
|
||||
/* Area: ffi_call
|
||||
Purpose: Check structures.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: From the original ffitest.c */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int si;
|
||||
} test_structure_3;
|
||||
|
||||
static test_structure_3 struct3(test_structure_3 ts)
|
||||
{
|
||||
ts.si = -(ts.si*2);
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
ffi_type *args[MAX_ARGS];
|
||||
void *values[MAX_ARGS];
|
||||
int compare_value;
|
||||
ffi_type ts3_type;
|
||||
ffi_type *ts3_type_elements[2];
|
||||
ts3_type.size = 0;
|
||||
ts3_type.alignment = 0;
|
||||
ts3_type.type = FFI_TYPE_STRUCT;
|
||||
ts3_type.elements = ts3_type_elements;
|
||||
ts3_type_elements[0] = &ffi_type_sint;
|
||||
ts3_type_elements[1] = NULL;
|
||||
|
||||
test_structure_3 ts3_arg;
|
||||
test_structure_3 *ts3_result =
|
||||
(test_structure_3 *) malloc (sizeof(test_structure_3));
|
||||
|
||||
args[0] = &ts3_type;
|
||||
values[0] = &ts3_arg;
|
||||
|
||||
/* Initialize the cif */
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
|
||||
&ts3_type, args) == FFI_OK);
|
||||
|
||||
ts3_arg.si = -123;
|
||||
compare_value = ts3_arg.si;
|
||||
|
||||
ffi_call(&cif, FFI_FN(struct3), ts3_result, values);
|
||||
|
||||
printf ("%d %d\n", ts3_result->si, -(compare_value*2));
|
||||
|
||||
CHECK(ts3_result->si == -(compare_value*2));
|
||||
|
||||
free (ts3_result);
|
||||
exit(0);
|
||||
}
|
||||
63
.pc/msvc-changes/testsuite/libffi.call/struct4.c
Normal file
63
.pc/msvc-changes/testsuite/libffi.call/struct4.c
Normal file
@@ -0,0 +1,63 @@
|
||||
/* Area: ffi_call
|
||||
Purpose: Check structures.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: From the original ffitest.c */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned ui1;
|
||||
unsigned ui2;
|
||||
unsigned ui3;
|
||||
} test_structure_4;
|
||||
|
||||
static test_structure_4 struct4(test_structure_4 ts)
|
||||
{
|
||||
ts.ui3 = ts.ui1 * ts.ui2 * ts.ui3;
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
ffi_type *args[MAX_ARGS];
|
||||
void *values[MAX_ARGS];
|
||||
ffi_type ts4_type;
|
||||
ffi_type *ts4_type_elements[4];
|
||||
ts4_type.size = 0;
|
||||
ts4_type.alignment = 0;
|
||||
ts4_type.type = FFI_TYPE_STRUCT;
|
||||
test_structure_4 ts4_arg;
|
||||
ts4_type.elements = ts4_type_elements;
|
||||
ts4_type_elements[0] = &ffi_type_uint;
|
||||
ts4_type_elements[1] = &ffi_type_uint;
|
||||
ts4_type_elements[2] = &ffi_type_uint;
|
||||
ts4_type_elements[3] = NULL;
|
||||
|
||||
|
||||
/* This is a hack to get a properly aligned result buffer */
|
||||
test_structure_4 *ts4_result =
|
||||
(test_structure_4 *) malloc (sizeof(test_structure_4));
|
||||
|
||||
args[0] = &ts4_type;
|
||||
values[0] = &ts4_arg;
|
||||
|
||||
/* Initialize the cif */
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts4_type, args) == FFI_OK);
|
||||
|
||||
ts4_arg.ui1 = 2;
|
||||
ts4_arg.ui2 = 3;
|
||||
ts4_arg.ui3 = 4;
|
||||
|
||||
ffi_call (&cif, FFI_FN(struct4), ts4_result, values);
|
||||
|
||||
CHECK(ts4_result->ui3 == 2U * 3U * 4U);
|
||||
|
||||
|
||||
free (ts4_result);
|
||||
exit(0);
|
||||
}
|
||||
65
.pc/msvc-changes/testsuite/libffi.call/struct5.c
Normal file
65
.pc/msvc-changes/testsuite/libffi.call/struct5.c
Normal file
@@ -0,0 +1,65 @@
|
||||
/* Area: ffi_call
|
||||
Purpose: Check structures.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: From the original ffitest.c */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
typedef struct
|
||||
{
|
||||
char c1;
|
||||
char c2;
|
||||
} test_structure_5;
|
||||
|
||||
static test_structure_5 struct5(test_structure_5 ts1, test_structure_5 ts2)
|
||||
{
|
||||
ts1.c1 += ts2.c1;
|
||||
ts1.c2 -= ts2.c2;
|
||||
|
||||
return ts1;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
ffi_type *args[MAX_ARGS];
|
||||
void *values[MAX_ARGS];
|
||||
ffi_type ts5_type;
|
||||
ffi_type *ts5_type_elements[3];
|
||||
ts5_type.size = 0;
|
||||
ts5_type.alignment = 0;
|
||||
ts5_type.type = FFI_TYPE_STRUCT;
|
||||
ts5_type.elements = ts5_type_elements;
|
||||
ts5_type_elements[0] = &ffi_type_schar;
|
||||
ts5_type_elements[1] = &ffi_type_schar;
|
||||
ts5_type_elements[2] = NULL;
|
||||
|
||||
test_structure_5 ts5_arg1, ts5_arg2;
|
||||
|
||||
/* This is a hack to get a properly aligned result buffer */
|
||||
test_structure_5 *ts5_result =
|
||||
(test_structure_5 *) malloc (sizeof(test_structure_5));
|
||||
|
||||
args[0] = &ts5_type;
|
||||
args[1] = &ts5_type;
|
||||
values[0] = &ts5_arg1;
|
||||
values[1] = &ts5_arg2;
|
||||
|
||||
/* Initialize the cif */
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ts5_type, args) == FFI_OK);
|
||||
|
||||
ts5_arg1.c1 = 2;
|
||||
ts5_arg1.c2 = 6;
|
||||
ts5_arg2.c1 = 5;
|
||||
ts5_arg2.c2 = 3;
|
||||
|
||||
ffi_call (&cif, FFI_FN(struct5), ts5_result, values);
|
||||
|
||||
CHECK(ts5_result->c1 == 7);
|
||||
CHECK(ts5_result->c2 == 3);
|
||||
|
||||
|
||||
free (ts5_result);
|
||||
exit(0);
|
||||
}
|
||||
64
.pc/msvc-changes/testsuite/libffi.call/struct6.c
Normal file
64
.pc/msvc-changes/testsuite/libffi.call/struct6.c
Normal file
@@ -0,0 +1,64 @@
|
||||
/* Area: ffi_call
|
||||
Purpose: Check structures.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: From the original ffitest.c */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
typedef struct
|
||||
{
|
||||
float f;
|
||||
double d;
|
||||
} test_structure_6;
|
||||
|
||||
static test_structure_6 struct6 (test_structure_6 ts)
|
||||
{
|
||||
ts.f += 1;
|
||||
ts.d += 1;
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
ffi_type *args[MAX_ARGS];
|
||||
void *values[MAX_ARGS];
|
||||
ffi_type ts6_type;
|
||||
ffi_type *ts6_type_elements[3];
|
||||
ts6_type.size = 0;
|
||||
ts6_type.alignment = 0;
|
||||
ts6_type.type = FFI_TYPE_STRUCT;
|
||||
ts6_type.elements = ts6_type_elements;
|
||||
ts6_type_elements[0] = &ffi_type_float;
|
||||
ts6_type_elements[1] = &ffi_type_double;
|
||||
ts6_type_elements[2] = NULL;
|
||||
|
||||
|
||||
test_structure_6 ts6_arg;
|
||||
|
||||
/* This is a hack to get a properly aligned result buffer */
|
||||
test_structure_6 *ts6_result =
|
||||
(test_structure_6 *) malloc (sizeof(test_structure_6));
|
||||
|
||||
args[0] = &ts6_type;
|
||||
values[0] = &ts6_arg;
|
||||
|
||||
/* Initialize the cif */
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts6_type, args) == FFI_OK);
|
||||
|
||||
ts6_arg.f = 5.55f;
|
||||
ts6_arg.d = 6.66;
|
||||
|
||||
printf ("%g\n", ts6_arg.f);
|
||||
printf ("%g\n", ts6_arg.d);
|
||||
|
||||
ffi_call(&cif, FFI_FN(struct6), ts6_result, values);
|
||||
|
||||
CHECK(ts6_result->f == 5.55f + 1);
|
||||
CHECK(ts6_result->d == 6.66 + 1);
|
||||
|
||||
free (ts6_result);
|
||||
exit(0);
|
||||
}
|
||||
74
.pc/msvc-changes/testsuite/libffi.call/struct7.c
Normal file
74
.pc/msvc-changes/testsuite/libffi.call/struct7.c
Normal file
@@ -0,0 +1,74 @@
|
||||
/* Area: ffi_call
|
||||
Purpose: Check structures.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: From the original ffitest.c */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
typedef struct
|
||||
{
|
||||
float f1;
|
||||
float f2;
|
||||
double d;
|
||||
} test_structure_7;
|
||||
|
||||
static test_structure_7 struct7 (test_structure_7 ts)
|
||||
{
|
||||
ts.f1 += 1;
|
||||
ts.f2 += 1;
|
||||
ts.d += 1;
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
ffi_type *args[MAX_ARGS];
|
||||
void *values[MAX_ARGS];
|
||||
ffi_type ts7_type;
|
||||
ffi_type *ts7_type_elements[4];
|
||||
ts7_type.size = 0;
|
||||
ts7_type.alignment = 0;
|
||||
ts7_type.type = FFI_TYPE_STRUCT;
|
||||
ts7_type.elements = ts7_type_elements;
|
||||
ts7_type_elements[0] = &ffi_type_float;
|
||||
ts7_type_elements[1] = &ffi_type_float;
|
||||
ts7_type_elements[2] = &ffi_type_double;
|
||||
ts7_type_elements[3] = NULL;
|
||||
|
||||
|
||||
test_structure_7 ts7_arg;
|
||||
|
||||
/* This is a hack to get a properly aligned result buffer */
|
||||
test_structure_7 *ts7_result =
|
||||
(test_structure_7 *) malloc (sizeof(test_structure_7));
|
||||
|
||||
args[0] = &ts7_type;
|
||||
values[0] = &ts7_arg;
|
||||
|
||||
/* Initialize the cif */
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts7_type, args) == FFI_OK);
|
||||
|
||||
ts7_arg.f1 = 5.55f;
|
||||
ts7_arg.f2 = 55.5f;
|
||||
ts7_arg.d = 6.66;
|
||||
|
||||
printf ("%g\n", ts7_arg.f1);
|
||||
printf ("%g\n", ts7_arg.f2);
|
||||
printf ("%g\n", ts7_arg.d);
|
||||
|
||||
ffi_call(&cif, FFI_FN(struct7), ts7_result, values);
|
||||
|
||||
printf ("%g\n", ts7_result->f1);
|
||||
printf ("%g\n", ts7_result->f2);
|
||||
printf ("%g\n", ts7_result->d);
|
||||
|
||||
CHECK(ts7_result->f1 == 5.55f + 1);
|
||||
CHECK(ts7_result->f2 == 55.5f + 1);
|
||||
CHECK(ts7_result->d == 6.66 + 1);
|
||||
|
||||
free (ts7_result);
|
||||
exit(0);
|
||||
}
|
||||
80
.pc/msvc-changes/testsuite/libffi.call/struct8.c
Normal file
80
.pc/msvc-changes/testsuite/libffi.call/struct8.c
Normal file
@@ -0,0 +1,80 @@
|
||||
/* Area: ffi_call
|
||||
Purpose: Check structures.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: From the original ffitest.c */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
typedef struct
|
||||
{
|
||||
float f1;
|
||||
float f2;
|
||||
float f3;
|
||||
float f4;
|
||||
} test_structure_8;
|
||||
|
||||
static test_structure_8 struct8 (test_structure_8 ts)
|
||||
{
|
||||
ts.f1 += 1;
|
||||
ts.f2 += 1;
|
||||
ts.f3 += 1;
|
||||
ts.f4 += 1;
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
ffi_type *args[MAX_ARGS];
|
||||
void *values[MAX_ARGS];
|
||||
ffi_type ts8_type;
|
||||
ffi_type *ts8_type_elements[5];
|
||||
ts8_type.size = 0;
|
||||
ts8_type.alignment = 0;
|
||||
ts8_type.type = FFI_TYPE_STRUCT;
|
||||
ts8_type.elements = ts8_type_elements;
|
||||
ts8_type_elements[0] = &ffi_type_float;
|
||||
ts8_type_elements[1] = &ffi_type_float;
|
||||
ts8_type_elements[2] = &ffi_type_float;
|
||||
ts8_type_elements[3] = &ffi_type_float;
|
||||
ts8_type_elements[4] = NULL;
|
||||
|
||||
test_structure_8 ts8_arg;
|
||||
|
||||
/* This is a hack to get a properly aligned result buffer */
|
||||
test_structure_8 *ts8_result =
|
||||
(test_structure_8 *) malloc (sizeof(test_structure_8));
|
||||
|
||||
args[0] = &ts8_type;
|
||||
values[0] = &ts8_arg;
|
||||
|
||||
/* Initialize the cif */
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts8_type, args) == FFI_OK);
|
||||
|
||||
ts8_arg.f1 = 5.55f;
|
||||
ts8_arg.f2 = 55.5f;
|
||||
ts8_arg.f3 = -5.55f;
|
||||
ts8_arg.f4 = -55.5f;
|
||||
|
||||
printf ("%g\n", ts8_arg.f1);
|
||||
printf ("%g\n", ts8_arg.f2);
|
||||
printf ("%g\n", ts8_arg.f3);
|
||||
printf ("%g\n", ts8_arg.f4);
|
||||
|
||||
ffi_call(&cif, FFI_FN(struct8), ts8_result, values);
|
||||
|
||||
printf ("%g\n", ts8_result->f1);
|
||||
printf ("%g\n", ts8_result->f2);
|
||||
printf ("%g\n", ts8_result->f3);
|
||||
printf ("%g\n", ts8_result->f4);
|
||||
|
||||
CHECK(ts8_result->f1 == 5.55f + 1);
|
||||
CHECK(ts8_result->f2 == 55.5f + 1);
|
||||
CHECK(ts8_result->f3 == -5.55f + 1);
|
||||
CHECK(ts8_result->f4 == -55.5f + 1);
|
||||
|
||||
free (ts8_result);
|
||||
exit(0);
|
||||
}
|
||||
67
.pc/msvc-changes/testsuite/libffi.call/struct9.c
Normal file
67
.pc/msvc-changes/testsuite/libffi.call/struct9.c
Normal file
@@ -0,0 +1,67 @@
|
||||
/* Area: ffi_call
|
||||
Purpose: Check structures.
|
||||
Limitations: none.
|
||||
PR: none.
|
||||
Originator: From the original ffitest.c */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float f;
|
||||
int i;
|
||||
} test_structure_9;
|
||||
|
||||
static test_structure_9 struct9 (test_structure_9 ts)
|
||||
{
|
||||
ts.f += 1;
|
||||
ts.i += 1;
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
ffi_type *args[MAX_ARGS];
|
||||
void *values[MAX_ARGS];
|
||||
ffi_type ts9_type;
|
||||
ffi_type *ts9_type_elements[3];
|
||||
ts9_type.size = 0;
|
||||
ts9_type.alignment = 0;
|
||||
ts9_type.type = FFI_TYPE_STRUCT;
|
||||
ts9_type.elements = ts9_type_elements;
|
||||
ts9_type_elements[0] = &ffi_type_float;
|
||||
ts9_type_elements[1] = &ffi_type_sint;
|
||||
ts9_type_elements[2] = NULL;
|
||||
|
||||
test_structure_9 ts9_arg;
|
||||
|
||||
/* This is a hack to get a properly aligned result buffer */
|
||||
test_structure_9 *ts9_result =
|
||||
(test_structure_9 *) malloc (sizeof(test_structure_9));
|
||||
|
||||
args[0] = &ts9_type;
|
||||
values[0] = &ts9_arg;
|
||||
|
||||
/* Initialize the cif */
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts9_type, args) == FFI_OK);
|
||||
|
||||
ts9_arg.f = 5.55f;
|
||||
ts9_arg.i = 5;
|
||||
|
||||
printf ("%g\n", ts9_arg.f);
|
||||
printf ("%d\n", ts9_arg.i);
|
||||
|
||||
ffi_call(&cif, FFI_FN(struct9), ts9_result, values);
|
||||
|
||||
printf ("%g\n", ts9_result->f);
|
||||
printf ("%d\n", ts9_result->i);
|
||||
|
||||
CHECK(ts9_result->f == 5.55f + 1);
|
||||
CHECK(ts9_result->i == 5 + 1);
|
||||
|
||||
free (ts9_result);
|
||||
exit(0);
|
||||
}
|
||||
70
.pc/msvc-changes/testsuite/libffi.call/testclosure.c
Normal file
70
.pc/msvc-changes/testsuite/libffi.call/testclosure.c
Normal file
@@ -0,0 +1,70 @@
|
||||
/* Area: closure_call
|
||||
Purpose: Check return value float.
|
||||
Limitations: none.
|
||||
PR: 41908.
|
||||
Originator: <rfm@gnu.org> 20091102 */
|
||||
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_combined {
|
||||
float a;
|
||||
float b;
|
||||
float c;
|
||||
float d;
|
||||
} cls_struct_combined;
|
||||
|
||||
void cls_struct_combined_fn(struct cls_struct_combined arg)
|
||||
{
|
||||
printf("%g %g %g %g\n",
|
||||
arg.a, arg.b,
|
||||
arg.c, arg.d);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
static void
|
||||
cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__,
|
||||
void** args, void* userdata __UNUSED__)
|
||||
{
|
||||
struct cls_struct_combined a0;
|
||||
|
||||
a0 = *(struct cls_struct_combined*)(args[0]);
|
||||
|
||||
cls_struct_combined_fn(a0);
|
||||
}
|
||||
|
||||
|
||||
int main (void)
|
||||
{
|
||||
ffi_cif cif;
|
||||
void *code;
|
||||
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
||||
ffi_type* cls_struct_fields0[5];
|
||||
ffi_type cls_struct_type0;
|
||||
ffi_type* dbl_arg_types[5];
|
||||
|
||||
cls_struct_type0.size = 0;
|
||||
cls_struct_type0.alignment = 0;
|
||||
cls_struct_type0.type = FFI_TYPE_STRUCT;
|
||||
cls_struct_type0.elements = cls_struct_fields0;
|
||||
|
||||
struct cls_struct_combined g_dbl = {4.0, 5.0, 1.0, 8.0};
|
||||
|
||||
cls_struct_fields0[0] = &ffi_type_float;
|
||||
cls_struct_fields0[1] = &ffi_type_float;
|
||||
cls_struct_fields0[2] = &ffi_type_float;
|
||||
cls_struct_fields0[3] = &ffi_type_float;
|
||||
cls_struct_fields0[4] = NULL;
|
||||
|
||||
dbl_arg_types[0] = &cls_struct_type0;
|
||||
dbl_arg_types[1] = NULL;
|
||||
|
||||
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_void,
|
||||
dbl_arg_types) == FFI_OK);
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_combined_gn, NULL, code) == FFI_OK);
|
||||
|
||||
((void(*)(cls_struct_combined)) (code))(g_dbl);
|
||||
/* { dg-output "4 5 1 8" } */
|
||||
exit(0);
|
||||
}
|
||||
Reference in New Issue
Block a user