Fixed 64-bit integer bug introduced by x86-64 ABI work.

Now I need to check that the x86-64 stuff still works.
master
James Lyon 2013-04-19 22:55:09 +01:00
parent cbce6d2bac
commit 23f73e92f3
2 changed files with 12 additions and 13 deletions

View File

@ -790,11 +790,14 @@ ST_FUNC int gv(int rc)
r = get_reg(rc); r = get_reg(rc);
#ifdef TCC_TARGET_X86_64 #ifdef TCC_TARGET_X86_64
if (((vtop->type.t & VT_BTYPE) == VT_QLONG) || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT)) { if (((vtop->type.t & VT_BTYPE) == VT_QLONG) || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT)) {
int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
#else #else
if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
#endif #endif
int r2; int r2, original_type;
unsigned long long ll; unsigned long long ll;
original_type = vtop->type.t;
/* two register type load : expand to two words /* two register type load : expand to two words
temporarily */ temporarily */
#ifndef TCC_TARGET_X86_64 #ifndef TCC_TARGET_X86_64
@ -809,11 +812,6 @@ ST_FUNC int gv(int rc)
#endif #endif
if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */ if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
(vtop->r & VT_LVAL)) { (vtop->r & VT_LVAL)) {
#ifdef TCC_TARGET_X86_64
int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
#else
int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
#endif
/* We do not want to modifier the long long /* We do not want to modifier the long long
pointer here, so the safest (and less pointer here, so the safest (and less
efficient) is to save all the other registers efficient) is to save all the other registers
@ -845,6 +843,7 @@ ST_FUNC int gv(int rc)
vpop(); vpop();
/* write second register */ /* write second register */
vtop->r2 = r2; vtop->r2 = r2;
vtop->type.t = original_type;
} else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) { } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
int t1, t; int t1, t;
/* lvalue of scalar type : need to use lvalue type /* lvalue of scalar type : need to use lvalue type

View File

@ -38,10 +38,10 @@ static int run_callback(const char *src, callback_type callback) {
return result; return result;
} }
#define RET_PRIMITIVE_TEST(name, type) \ #define RET_PRIMITIVE_TEST(name, type, val) \
static int ret_ ## name ## _test_callback(void *ptr) { \ static int ret_ ## name ## _test_callback(void *ptr) { \
type (*callback) (type) = (type(*)(type))ptr; \ type (*callback) (type) = (type(*)(type))ptr; \
type x = 29; \ type x = val; \
type y = callback(x); \ type y = callback(x); \
return (y == x+x) ? 0 : -1; \ return (y == x+x) ? 0 : -1; \
} \ } \
@ -51,11 +51,11 @@ static int run_callback(const char *src, callback_type callback) {
return run_callback(src, ret_ ## name ## _test_callback); \ return run_callback(src, ret_ ## name ## _test_callback); \
} }
RET_PRIMITIVE_TEST(int, int) RET_PRIMITIVE_TEST(int, int, 70000)
RET_PRIMITIVE_TEST(longlong, long long) RET_PRIMITIVE_TEST(longlong, long long, 4333369356528LL)
RET_PRIMITIVE_TEST(float, float) RET_PRIMITIVE_TEST(float, float, 63.0)
RET_PRIMITIVE_TEST(double, double) RET_PRIMITIVE_TEST(double, double, 14789798.0)
RET_PRIMITIVE_TEST(longdouble, long double) RET_PRIMITIVE_TEST(longdouble, long double, 378943892.0)
/* /*
* ret_2float_test: * ret_2float_test: