tinycc-devel
[Top][All Lists]
Advanced

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

[Tinycc-devel] Libtcc bug ?


From: kwisatz haderach
Subject: [Tinycc-devel] Libtcc bug ?
Date: Tue, 1 Jan 2008 21:10:47 +0000


I am compiling TCC on Windows XP using Visual Studio 8. I had to make a few changes to the original code but it works well now.
I am mainly using Libtcc, so I compile a string and use the function from code compile using VC8.

I think I found a problem with the FPU registers are managed by TCC.

Here is the code:


#define DF(n) double s ## n = n

DF(1);
DF(2);
DF(3);
DF(4);
DF(5);
DF(6);
DF(7);
DF(8);

double heavy()
{
       double a1 = s1 + s2;
       double a2 = (a1 - s3) * a1;
       double a3 = a2 + s4;
       double a4 = a2 + s4 + s5;
       double a5 = a2 + s4 + s5 + s6;
       double a6 = a2 + s4 + s5 + s6 + s7;
       double a7 = a2 + s4 + s5 + s6 + s7 + s8;
       double a8 = a2 + s4 + s5 + s6 + s7 + s8 + a7;
       return a1+a2+a3+a4+a5+a6+a7+a8;
}

void main()
{
    const char* program =
        "void dummy()"
        "{"
        "    double f = 1.0;"
        "    double g = f + 3.0;"
        "}";

    double res;

    void (*dummy)();
    unsigned long addr;

    TCCState *s;
    s = tcc_new();

    tcc_compile_string(s, program);
    tcc_relocate(s);
    tcc_get_symbol(s, &addr, "dummy");
    dummy = (void (*)())((void*)addr);

    // call to TCC compiled function
    (*dummy)();

    // call to VC8 compiled function
    res = heavy();
}

The problem comes from the code compiled by TCC. Here is the assembly:

void dummy()
{
       double f = 1.0;
       double g = f + 3.0;
}

00424C18  push       ebp
00424C19  mov        ebp,esp
00424C1B  sub         esp,10h
00424C21  nop
00424C22  fld          qword ptr ds:[424500h]     <---------- 1st register used
00424C28  fst          qword ptr [ebp-8]             
00424C2B  fstp        st(1)                                <---------- still one register used
00424C2D  fld         qword ptr ds:[424508h]     <---------- 2 registers used
00424C33  fadd       qword ptr [ebp-8]
00424C36  fst          qword ptr [ebp-10h]
00424C39  fstp        st(1)                                <---------- 1 register used
00424C3B  leave
00424C3C  ret

The stack of floating point registers is empty at the begining of the function. At the end, because the fstp st(1) leaves one register in use, the stack is not empty.
The problem comes from the fact that the compiler using Libtcc, here VC8 but I am sure gcc works the same way, expects a function with this signature (dummy) to leave the FPU in the same state as before the function call, i.e. no registers should be in use.

Therefore if you then manage to create a function that will use all the 8 registers of the stack ( VC8 in release /O2 compiles the heavy function so it uses 8 registers ) you will get a stack overflow and the variable res won't be 143 as expected because it is trying to use 9 registers.
If you re-run the same program after commenting the call to "dummy" out, it works as expected.

If you only use TCC as a standalone compiler, it does not matter. But as an API, it won't work as soon as you are using functions making an heavy use of the FPU.

As anybody ever encountered the same issue ? Did anyone think about a fix ?

Thanks for your help.







Sounds like? How many syllables? Guess and win prizes with Search Charades!

reply via email to

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