Alien-TinyCCx
view release on metacpan or search on metacpan
src/tests/abitest.c view on Meta::CPAN
* SSE register (VT_DOUBLE is used for this purpose).
*/
typedef struct ret_2float_test_type_s {float x, y;} ret_2float_test_type;
typedef ret_2float_test_type (*ret_2float_test_function_type) (ret_2float_test_type);
static int ret_2float_test_callback(void *ptr) {
ret_2float_test_function_type f = (ret_2float_test_function_type)ptr;
ret_2float_test_type a = {10, 35};
ret_2float_test_type r;
r = f(a);
return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1;
}
static int ret_2float_test(void) {
const char *src =
"typedef struct ret_2float_test_type_s {float x, y;} ret_2float_test_type;"
"ret_2float_test_type f(ret_2float_test_type a) {\n"
" ret_2float_test_type r = {a.x*5, a.y*3};\n"
" return r;\n"
"}\n";
return run_callback(src, ret_2float_test_callback);
}
/*
* ret_2double_test:
*
* On x86-64, a struct with 2 doubles should be passed in two SSE
* registers.
*/
typedef struct ret_2double_test_type_s {double x, y;} ret_2double_test_type;
typedef ret_2double_test_type (*ret_2double_test_function_type) (ret_2double_test_type);
static int ret_2double_test_callback(void *ptr) {
ret_2double_test_function_type f = (ret_2double_test_function_type)ptr;
ret_2double_test_type a = {10, 35};
ret_2double_test_type r;
r = f(a);
return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1;
}
static int ret_2double_test(void) {
const char *src =
"typedef struct ret_2double_test_type_s {double x, y;} ret_2double_test_type;"
"ret_2double_test_type f(ret_2double_test_type a) {\n"
" ret_2double_test_type r = {a.x*5, a.y*3};\n"
" return r;\n"
"}\n";
return run_callback(src, ret_2double_test_callback);
}
/*
* ret_8plus2double_test:
*
* This catches a corner case in the x86_64 ABI code: the first 7
* arguments fit into registers, the 8th doesn't, but the 9th argument
* fits into the 8th XMM register.
*
* Note that the purpose of the 10th argument is to avoid a situation
* in which gcc would accidentally put the double at the right
* address, thus causing a success message even though TCC actually
* generated incorrect code.
*/
typedef ret_2double_test_type (*ret_8plus2double_test_function_type) (double, double, double, double, double, double, double, ret_2double_test_type, double, double);
static int ret_8plus2double_test_callback(void *ptr) {
ret_8plus2double_test_function_type f = (ret_8plus2double_test_function_type)ptr;
ret_2double_test_type a = {10, 35};
ret_2double_test_type r;
r = f(0, 0, 0, 0, 0, 0, 0, a, 37, 38);
return ((r.x == 37) && (r.y == 37)) ? 0 : -1;
}
static int ret_8plus2double_test(void) {
const char *src =
"typedef struct ret_2double_test_type_s {double x, y;} ret_2double_test_type;"
"ret_2double_test_type f(double x1, double x2, double x3, double x4, double x5, double x6, double x7, ret_2double_test_type a, double x8, double x9) {\n"
" ret_2double_test_type r = { x8, x8 };\n"
" return r;\n"
"}\n";
return run_callback(src, ret_8plus2double_test_callback);
}
/*
* ret_mixed_test:
*
* On x86-64, a struct with a double and a 64-bit integer should be
* passed in one SSE register and one integer register.
*/
typedef struct ret_mixed_test_type_s {double x; long long y;} ret_mixed_test_type;
typedef ret_mixed_test_type (*ret_mixed_test_function_type) (ret_mixed_test_type);
static int ret_mixed_test_callback(void *ptr) {
ret_mixed_test_function_type f = (ret_mixed_test_function_type)ptr;
ret_mixed_test_type a = {10, 35};
ret_mixed_test_type r;
r = f(a);
return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1;
}
static int ret_mixed_test(void) {
const char *src =
"typedef struct ret_mixed_test_type_s {double x; long long y;} ret_mixed_test_type;"
"ret_mixed_test_type f(ret_mixed_test_type a) {\n"
" ret_mixed_test_type r = {a.x*5, a.y*3};\n"
" return r;\n"
"}\n";
return run_callback(src, ret_mixed_test_callback);
}
/*
* ret_mixed2_test:
*
* On x86-64, a struct with two floats and two 32-bit integers should
* be passed in one SSE register and one integer register.
*/
typedef struct ret_mixed2_test_type_s {float x,x2; int y,y2;} ret_mixed2_test_type;
typedef ret_mixed2_test_type (*ret_mixed2_test_function_type) (ret_mixed2_test_type);
src/tests/abitest.c view on Meta::CPAN
/*
* reg_pack_test: return a small struct which should be packed into
* registers (Win32) during return.
*/
typedef struct reg_pack_test_type_s {int x, y;} reg_pack_test_type;
typedef reg_pack_test_type (*reg_pack_test_function_type) (reg_pack_test_type);
static int reg_pack_test_callback(void *ptr) {
reg_pack_test_function_type f = (reg_pack_test_function_type)ptr;
reg_pack_test_type a = {10, 35};
reg_pack_test_type r;
r = f(a);
return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1;
}
static int reg_pack_test(void) {
const char *src =
"typedef struct reg_pack_test_type_s {int x, y;} reg_pack_test_type;"
"reg_pack_test_type f(reg_pack_test_type a) {\n"
" reg_pack_test_type r = {a.x*5, a.y*3};\n"
" return r;\n"
"}\n";
return run_callback(src, reg_pack_test_callback);
}
/*
* reg_pack_longlong_test: return a small struct which should be packed into
* registers (x86-64) during return.
*/
typedef struct reg_pack_longlong_test_type_s {long long x, y;} reg_pack_longlong_test_type;
typedef reg_pack_longlong_test_type (*reg_pack_longlong_test_function_type) (reg_pack_longlong_test_type);
static int reg_pack_longlong_test_callback(void *ptr) {
reg_pack_longlong_test_function_type f = (reg_pack_longlong_test_function_type)ptr;
reg_pack_longlong_test_type a = {10, 35};
reg_pack_longlong_test_type r;
r = f(a);
return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1;
}
static int reg_pack_longlong_test(void) {
const char *src =
"typedef struct reg_pack_longlong_test_type_s {long long x, y;} reg_pack_longlong_test_type;"
"reg_pack_longlong_test_type f(reg_pack_longlong_test_type a) {\n"
" reg_pack_longlong_test_type r = {a.x*5, a.y*3};\n"
" return r;\n"
"}\n";
return run_callback(src, reg_pack_longlong_test_callback);
}
/*
* ret_6plus2longlong_test:
*
* This catches a corner case in the x86_64 ABI code: the first 5
* arguments fit into registers, the 6th doesn't, but the 7th argument
* fits into the 6th argument integer register, %r9.
*
* Note that the purpose of the 10th argument is to avoid a situation
* in which gcc would accidentally put the longlong at the right
* address, thus causing a success message even though TCC actually
* generated incorrect code.
*/
typedef reg_pack_longlong_test_type (*ret_6plus2longlong_test_function_type) (long long, long long, long long, long long, long long, reg_pack_longlong_test_type, long long, long long);
static int ret_6plus2longlong_test_callback(void *ptr) {
ret_6plus2longlong_test_function_type f = (ret_6plus2longlong_test_function_type)ptr;
reg_pack_longlong_test_type a = {10, 35};
reg_pack_longlong_test_type r;
r = f(0, 0, 0, 0, 0, a, 37, 38);
return ((r.x == 37) && (r.y == 37)) ? 0 : -1;
}
static int ret_6plus2longlong_test(void) {
const char *src =
"typedef struct reg_pack_longlong_test_type_s {long long x, y;} reg_pack_longlong_test_type;"
"reg_pack_longlong_test_type f(long long x1, long long x2, long long x3, long long x4, long long x5, reg_pack_longlong_test_type a, long long x8, long long x9) {\n"
" reg_pack_longlong_test_type r = { x8, x8 };\n"
" return r;\n"
"}\n";
return run_callback(src, ret_6plus2longlong_test_callback);
}
/*
* sret_test: Create a struct large enough to be returned via sret
* (hidden pointer as first function argument)
*/
typedef struct sret_test_type_s {long long a, b, c;} sret_test_type;
typedef sret_test_type (*sret_test_function_type) (sret_test_type);
static int sret_test_callback(void *ptr) {
sret_test_function_type f = (sret_test_function_type)(ptr);
sret_test_type x = {5436LL, 658277698LL, 43878957LL};
sret_test_type r = f(x);
return ((r.a==x.a*35)&&(r.b==x.b*19)&&(r.c==x.c*21)) ? 0 : -1;
}
static int sret_test(void) {
const char *src =
"typedef struct sret_test_type_s {long long a, b, c;} sret_test_type;\n"
"sret_test_type f(sret_test_type x) {\n"
" sret_test_type r = {x.a*35, x.b*19, x.c*21};\n"
" return r;\n"
"}\n";
return run_callback(src, sret_test_callback);
}
/*
* one_member_union_test:
*
* In the x86-64 ABI a union should always be passed on the stack. However
* it appears that a single member union is treated by GCC as its member.
*/
typedef union one_member_union_test_type_u {int x;} one_member_union_test_type;
typedef one_member_union_test_type (*one_member_union_test_function_type) (one_member_union_test_type);
static int one_member_union_test_callback(void *ptr) {
one_member_union_test_function_type f = (one_member_union_test_function_type)ptr;
( run in 0.517 second using v1.01-cache-2.11-cpan-13bb782fe5a )