Returning floats in xmm?

Humus

Crazy coder
Veteran
Anyone know if it's possible to tell the compiler (MSVC 6.0 or .NET) that I return floats in an SSE xmm register or perhaps in a regular register like eax with inline assembly? Normally it expects ints in eax and floats in ST(0) on the FPU stack, but it feels a bit inconvenient to have to move your float values to memory and that load it to the FPU stack just to return it.
 
Check out: __declspec( naked ) ("Microsoft Specific")
Probably you will have to write your own prolog and epilog code...
 
Humus said:
Anyone know if it's possible to tell the compiler (MSVC 6.0 or .NET) that I return floats in an SSE xmm register or perhaps in a regular register like eax with inline assembly? Normally it expects ints in eax and floats in ST(0) on the FPU stack, but it feels a bit inconvenient to have to move your float values to memory and that load it to the FPU stack just to return it.
AFAIK xmms don't integrate at all with MSVC. GCC might support some spiffy experimental ABI variation that allow this. Dunno.

But you certainly can typedef unsigned int pseudo_float, and use this to pass floats around in integer registers. Return values in all x86 calling conventions are stored in EAX if they are no larger than 32 bits. Structs and unions, too. I.e. if you write all code that manipulates the type yourself, in assembly, and never let the compiler touch it, any type that's 32 bits wide is fine.
There's one case I'm not sure about:
struct PseudoFloat {float val;};
The compiler might actually be smart enough to unwrap the struct and get straight at the float. Should be easy enough to find out with a debugger.

To be safe, something like this would be in order:
Code:
class
PseudoFloat
{
public:
   PseudoFloat(float v){set(v);}
   PseudoFloat(const PseudoFloat& rhs);
public:
   bool operator ==(const PseudoFloat& rhs)const;
   void set(float v);
   float get();
private:
   PseudoFloat();   //disallow default constructor
private:
   uint v;
};

PS: MSDN says that a 64 bit large struct, when it's the return value, is stored in EDX:EAX (EDX contains MSBs), but that's an MSVC thing and may break compatibility with other compilers.
 
zeckensack said:
PS: MSDN says that a 64 bit large struct, when it's the return value, is stored in EDX:EAX (EDX contains MSBs), but that's an MSVC thing and may break compatibility with other compilers.

edx:eax is the common convention for returning 64-bit (u)ints on the x86. it originates in the mul/div ops implementation on the 8086, where the dx:ax pair representes a 32bit (u)int product/dividend.
 
What I wanted this for initially was to squeeze the last few cycles out of the field function for the MetaBalls demo. I tried using a pseudo_float integer, but I saw no performance difference, so I'm back to just returning a float.
 
Back
Top