chaotic-society / theoretica

A C++ math library for scientific computing with a simple and elegant interface.
https://chaotic-society.github.io/theoretica/
GNU Lesser General Public License v3.0
21 stars 4 forks source link

Floating Point Stack Overflow on MSVC #8

Closed SophieLabs closed 7 years ago

SophieLabs commented 7 years ago

The current approach to inlined assembly is causing a stack overflow on the floating point registers.

For example

inline real sqrt(real x) {
#ifdef MSVC_ASM
__asm {
    fld x
    fsqrt
    fst x
}
#endif
return x;

compiles down to

fld         qword ptr [x]  
fsqrt  
fst         qword ptr [x]  
fld         qword ptr [x]  
//function outro

Note the injected fld (push) at the end. This unbalances the pushes and pops, which causes a stack overflow and garbage on the stack.

This can be resolved by either changing fst x to fstp x, or by omitting the return statement, which MSVC implicitly adds anyway. That is, the following code works without any warning:

inline real sqrt(real x) {
#ifdef MSVC_ASM
__asm {
    fld x
    fsqrt
}
#endif

and generates the following assembly

fld         qword ptr [x]  
fsqrt  
//function outro - exactly as above

This works for all the affected functions, as they all work on register ST0 which is also used for returning.

I'm submitting a PR to implement this latter approach.

mattiaisgro commented 7 years ago

Thanks for pointing out