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.