partial revert of the commit 4ad186c5ef

A test program:

    /* result of the new version inroduced in 4ad186c5ef: t2a = 44100312 */
    #include<stdio.h>
    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;
    }
This commit is contained in:
seyko 2015-03-04 16:25:51 +03:00
parent bfb7b0d959
commit 664c19ad5e
3 changed files with 41 additions and 0 deletions

View File

@ -982,6 +982,28 @@ ST_FUNC void gen_cvt_itof(int t)
/* convert fp to int 't' type */ /* convert fp to int 't' type */
ST_FUNC void gen_cvt_ftoi(int t) 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<stdio.h>
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; int bt = vtop->type.t & VT_BTYPE;
if (bt == VT_FLOAT) if (bt == VT_FLOAT)
vpush_global_sym(&func_old_type, TOK___fixsfdi); vpush_global_sym(&func_old_type, TOK___fixsfdi);
@ -994,6 +1016,7 @@ ST_FUNC void gen_cvt_ftoi(int t)
vpushi(0); vpushi(0);
vtop->r = REG_IRET; vtop->r = REG_IRET;
vtop->r2 = REG_LRET; vtop->r2 = REG_LRET;
#endif
} }
/* convert from one floating point type to another */ /* convert from one floating point type to another */

View File

@ -480,6 +480,20 @@ long long __ashldi3(long long a, int b)
#endif #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__ */ #endif /* !__x86_64__ */
/* XXX: fix tcc's code generator to do this instead */ /* XXX: fix tcc's code generator to do this instead */

View File

@ -229,6 +229,10 @@
DEF(TOK___fixsfdi, "__fixsfdi") DEF(TOK___fixsfdi, "__fixsfdi")
DEF(TOK___fixdfdi, "__fixdfdi") DEF(TOK___fixdfdi, "__fixdfdi")
DEF(TOK___fixxfdi, "__fixxfdi") DEF(TOK___fixxfdi, "__fixxfdi")
#ifndef COMMIT_4ad186c5ef61_IS_FIXED
DEF(TOK___tcc_cvt_ftol, "__tcc_cvt_ftol")
#endif
#endif #endif
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64