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.
The current approach to inlined assembly is causing a stack overflow on the floating point registers.
For example
compiles down to
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
tofstp x
, or by omitting the return statement, which MSVC implicitly adds anyway. That is, the following code works without any warning:and generates the following assembly
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.