From 664c19ad5ef16f3463087a33ecfe5d5ac24f81ec Mon Sep 17 00:00:00 2001 From: seyko Date: Wed, 4 Mar 2015 16:25:51 +0300 Subject: [PATCH] partial revert of the commit 4ad186c5ef61 A test program: /* result of the new version inroduced in 4ad186c5ef61: t2a = 44100312 */ #include int main() { int t1 = 176401255; float f = 0.25f; int t2a = (int)(t1 * f); // must be 44100313 int t2b = (int)(t1 * (float)0.25f); printf("t2a=%d t2b=%d \n",t2a,t2b); return 0; } --- i386-gen.c | 23 +++++++++++++++++++++++ lib/libtcc1.c | 14 ++++++++++++++ tcctok.h | 4 ++++ 3 files changed, 41 insertions(+) diff --git a/i386-gen.c b/i386-gen.c index eca4dddd..9bdf9980 100644 --- a/i386-gen.c +++ b/i386-gen.c @@ -982,6 +982,28 @@ ST_FUNC void gen_cvt_itof(int t) /* convert fp to int 't' type */ ST_FUNC void gen_cvt_ftoi(int t) { + #ifndef COMMIT_4ad186c5ef61_IS_FIXED + /* a good version but it takes a more time to execute */ + gv(RC_FLOAT); + save_reg(TREG_EAX); + save_reg(TREG_EDX); + gen_static_call(TOK___tcc_cvt_ftol); + vtop->r = TREG_EAX; /* mark reg as used */ + if (t == VT_LLONG) + vtop->r2 = TREG_EDX; + #else + /* a new version with a bug: t2a = 44100312 */ + /* + #include + int main() { + int t1 = 176401255; + float f = 0.25f; + int t2a = (int)(t1 * f); // must be 44100313 + int t2b = (int)(t1 * (float)0.25f); + printf("t2a=%d t2b=%d \n",t2a,t2b); + return 0; + } + */ int bt = vtop->type.t & VT_BTYPE; if (bt == VT_FLOAT) vpush_global_sym(&func_old_type, TOK___fixsfdi); @@ -994,6 +1016,7 @@ ST_FUNC void gen_cvt_ftoi(int t) vpushi(0); vtop->r = REG_IRET; vtop->r2 = REG_LRET; + #endif } /* convert from one floating point type to another */ diff --git a/lib/libtcc1.c b/lib/libtcc1.c index d8a5e713..4a923a22 100644 --- a/lib/libtcc1.c +++ b/lib/libtcc1.c @@ -480,6 +480,20 @@ long long __ashldi3(long long a, int b) #endif } +#ifndef COMMIT_4ad186c5ef61_IS_FIXED +long long __tcc_cvt_ftol(long double x) +{ + unsigned c0, c1; + long long ret; + __asm__ __volatile__ ("fnstcw %0" : "=m" (c0)); + c1 = c0 | 0x0C00; + __asm__ __volatile__ ("fldcw %0" : : "m" (c1)); + __asm__ __volatile__ ("fistpll %0" : "=m" (ret)); + __asm__ __volatile__ ("fldcw %0" : : "m" (c0)); + return ret; +} +#endif + #endif /* !__x86_64__ */ /* XXX: fix tcc's code generator to do this instead */ diff --git a/tcctok.h b/tcctok.h index 64d1288f..9fba4556 100644 --- a/tcctok.h +++ b/tcctok.h @@ -229,6 +229,10 @@ DEF(TOK___fixsfdi, "__fixsfdi") DEF(TOK___fixdfdi, "__fixdfdi") DEF(TOK___fixxfdi, "__fixxfdi") + + #ifndef COMMIT_4ad186c5ef61_IS_FIXED + DEF(TOK___tcc_cvt_ftol, "__tcc_cvt_ftol") + #endif #endif #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 -- 2.11.4.GIT