i386-gen: preserve fp control word in gen_cvt_ftoi

- Use runtime function for conversion
- Also initialize fp with tcc -run on windows

This fixes a bug where
  double x = 1.0;
  double y = 1.0000000000000001;
  double z = x < y ? 0 : sqrt (x*x - y*y);
caused a bad sqrt because rounding precision for the x < y comparison
was different to the one used within the sqrt function.

This also fixes a bug where
  printf("%d, %d", (int)pow(10, 2), (int)pow(10, 2));
would print
  100, 99

Unrelated:
  win32: document relative include & lib lookup
  win32: normalize_slashes: do not mirror silly gcc behavior
  This reverts part of commit 8a81f9e103
  winapi: add missing WINAPI decl. for some functions
This commit is contained in:
grischka
2013-08-28 22:55:05 +02:00
parent 69c2e7f96c
commit 73faaea227
11 changed files with 77 additions and 107 deletions

View File

@ -478,13 +478,24 @@ long long __ashldi3(long long a, int b)
#endif
}
#if defined(__i386__)
/* FPU control word for rounding to nearest mode */
unsigned short __tcc_fpu_control = 0x137f;
/* FPU control word for round to zero mode for int conversion */
unsigned short __tcc_int_fpu_control = 0x137f | 0x0c00;
#ifndef _WIN32
void __tcc_fpinit(void)
{
unsigned c = 0x137F;
__asm__ __volatile__ ("fldcw %0" : "=m" (c));
}
#endif
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 /* !__x86_64__ */
/* XXX: fix tcc's code generator to do this instead */