[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Tinycc-devel] [PATCH] libtcc1.c: Fix 'Floating point exception' test fa

From: Ramsay Jones
Subject: [Tinycc-devel] [PATCH] libtcc1.c: Fix 'Floating point exception' test failures
Date: Mon, 09 Sep 2013 23:49:16 +0100
User-agent: Mozilla/5.0 (X11; Linux i686; rv:17.0) Gecko/20130803 Thunderbird/17.0.8

Since commit 73faaea2 ("i386-gen: preserve fp control word in
gen_cvt_ftoi", 28-08-2013) the tests have failed, like so:

  address@hidden $ make test
  ------------ test3 ------------
  ../tcc -B.. -I.. -I.. -I../include -DCONFIG_LDDIR="\"lib/i386-linux-gnu\""
  -DCONFIG_MULTIARCHDIR="\"i386-linux-gnu\"" -DTCC_TARGET_I386 -DONE_SOURCE -run
  ../tcc.c -B.. -I.. -I.. -I../include -DCONFIG_LDDIR="\"lib/i386-linux-gnu\""
  -DCONFIG_MULTIARCHDIR="\"i386-linux-gnu\"" -DTCC_TARGET_I386 -DONE_SOURCE -run
  ../tcc.c -B.. -I.. -I.. -I../include -DCONFIG_LDDIR="\"lib/i386-linux-gnu\""
  -DCONFIG_MULTIARCHDIR="\"i386-linux-gnu\"" -DTCC_TARGET_I386 -DONE_SOURCE -run
  ../tcc.c -B.. -I.. -I.. -I../include -run ../tests/tcctest.c > test.out3
  Floating point exception
  make[1]: *** [test3] Error 136
  make[1]: Leaving directory `/home/ramsay/tinycc/tests'
  make: *** [test] Error 2
  address@hidden $

Commit 73faaea2, in part, introduces two functions (__tcc_fpinit
and __tcc_cvt_ftol) which initialize and manipulate the floating
point control register from inline assembler. This code, despite
the use of __asm__ __volatile__, gets mangled by the gcc compiler
when optimizations are enabled. For example, with optimizations
disabled (-O0), __tcc_fpinit looks like:

  000005a2 <__tcc_fpinit>:
   5a2: 55                      push   %ebp
   5a3: 89 e5                   mov    %esp,%ebp
   5a5: 83 ec 10                sub    $0x10,%esp
   5a8: c7 45 fc 7f 13 00 00    movl   $0x137f,-0x4(%ebp)
   5af: d9 6d fc                fldcw  -0x4(%ebp)
   5b2: c9                      leave
   5b3: c3                      ret

With optimizations enabled (with default CFLAGS, -O2):

  00000400 <__tcc_fpinit>:
   400: 83 ec 10                sub    $0x10,%esp
   403: d9 6c 24 0c             fldcw  0xc(%esp)
   407: 83 c4 10                add    $0x10,%esp
   40a: c3                      ret

The mangling is caused by incorrectly applying output constraints
to an input of the assembler instruction. Using __tcc_fpinit as
an example:

    void __tcc_fpinit(void)
        unsigned c = 0x137F;
        __asm__ __volatile__ ("fldcw %0" : "=m" (c));

Here, the variable 'c' is clearly an input to the instruction, but
it has an output constraint applied. As a result, since the variable
is not used after the instruction, the gcc optimizer feels free to
remove the dead variable. If we correct the assembler constraints,
then the new -O2 code looks like:

  00000400 <__tcc_fpinit>:
   400: 83 ec 10                sub    $0x10,%esp
   403: c7 44 24 0c 7f 13 00    movl   $0x137f,0xc(%esp)
   40a: 00
   40b: d9 6c 24 0c             fldcw  0xc(%esp)
   40f: 83 c4 10                add    $0x10,%esp
   412: c3                      ret

Similar comments apply to __tcc_cvt_ftol.

Signed-off-by: Ramsay Jones <address@hidden>


This is the same patch I sent yesterday, but with a proper
commit message.

Ramsay Jones

 lib/libtcc1.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/lib/libtcc1.c b/lib/libtcc1.c
index a94a82d..a717701 100644
--- a/lib/libtcc1.c
+++ b/lib/libtcc1.c
@@ -482,7 +482,7 @@ long long __ashldi3(long long a, int b)
 void __tcc_fpinit(void)
     unsigned c = 0x137F;
-    __asm__ __volatile__ ("fldcw %0" : "=m" (c));
+    __asm__ __volatile__ ("fldcw %0" : : "m" (c));
 long long __tcc_cvt_ftol(long double x)
@@ -491,9 +491,9 @@ long long __tcc_cvt_ftol(long double x)
     long long ret;
     __asm__ __volatile__ ("fnstcw %0" : "=m" (c0));
     c1 = c0 | 0x0C00;
-    __asm__ __volatile__ ("fldcw %0" : "=m" (c1));
+    __asm__ __volatile__ ("fldcw %0" : : "m" (c1));
     __asm__ __volatile__ ("fistpll %0"  : "=m" (ret));
-    __asm__ __volatile__ ("fldcw %0" : "=m" (c0));
+    __asm__ __volatile__ ("fldcw %0" : : "m" (c0));
     return ret;
 #endif /* !__x86_64__ */

reply via email to

[Prev in Thread] Current Thread [Next in Thread]