Page 1 of 1

FPU register volatility

Posted: Fri Jan 01, 2016 2:27 pm
by garfield
Hi,

I'm currently trying to implement a pow-function with the x87 FPU's functions fyl2x and f2xm1. For that, I have to use the registers ST0 and ST1. My question is whether GCC assumes that the content of these registers does not change in a function call, which means I would have to save them on the stack. I only found information about the volatility of the XMM registers (for the Visual C++ compiler, anyway).

Thanks in advance,
Garfield

Re: FPU register volatility

Posted: Fri Jan 01, 2016 3:16 pm
by Brendan
Hi,
garfield wrote:Hi,

I'm currently trying to implement a pow-function with the x87 FPU's functions fyl2x and f2xm1. For that, I have to use the registers ST0 and ST1. My question is whether GCC assumes that the content of these registers does not change in a function call, which means I would have to save them on the stack. I only found information about the volatility of the XMM registers (for the Visual C++ compiler, anyway).
For which calling convention/ABI?

According to wikipedia's page, for "cdecl" (the typical calling convention C uses for 32-bit code on 80x86) FPU registers must be empty when calling a function, and should be empty when returning from a function unless the function returns a (double or float) value in ST0.

I think most 64-bit calling conventions just use SSE instead of FPU.

Of course you can cheat - e.g. use inline assembly (with clobber list) within a C wrapper and let the compiler figure it out.


Cheers,

Brendan

Re: FPU register volatility

Posted: Sat Jan 02, 2016 5:42 am
by jnc100
Additionally, in the sysV x86_64 ABI, ST0-7 are not preserved across function calls, so you are free to use them as you will. The only caveat is that if you switch to using them as MMX registers, you need to return back to x87 mode (with e.g. EMMS) before leaving the function. long double arguments are returned in ST0, other float/double return values in xmm0.

Regards,
John.

Re: FPU register volatility

Posted: Mon Jan 04, 2016 3:35 am
by garfield
Hi,

thanks for the replies! For some reason I did not suspect that the registers status was part of the calling convention (which seems obvious now, as the status of the general purpose registers is specified there, too). But am I correct in the assumption that when SSE is supported, ST0 is a part of XMM0?

Garfield

Re: FPU register volatility

Posted: Mon Jan 04, 2016 5:39 am
by jnc100
garfield wrote:But am I correct in the assumption that when SSE is supported, ST0 is a part of XMM0?
ST0 aliases to MM0 (i.e. the first MMX register), ST0 to MM1 etc., thus if you put them into MMX mode in your function you need to return to FPU mode before exiting. The XMM0+ registers are separate and therfore don't affect the FPU registers. The confusion comes in that SSE version 1 performs packed integer operations on the MMX registers, rather than the XMM ones. Floating point SSE instructions and packed integer instructions in later SSE versions use XMM registers.

Regards,
John.

Re: FPU register volatility

Posted: Mon Jan 04, 2016 2:00 pm
by garfield
I see, the naming is a bit confusing :D Whose idea was it to name them XMM and MMX...

Thanks,
Garfield