On 03/11/2012 10:57 PM, Robert Jacques wrote:
On Sun, 11 Mar 2012 15:38:21 -0500, Timon Gehr <[email protected]> wrote:
On 03/11/2012 09:30 PM, Robert Jacques wrote:
Manu, why are you assuming that the struct is returned in any sort of
fixed memory layout?
Because that is what the ABI says.
* 1, 2 and 4 byte structs are returned in EAX.
* 8 byte structs are returned in EDX,EAX, where EDX gets the most
significant half.
* For other struct sizes, the return value is stored through a hidden
pointer passed as an argument to the function.
You made my point. Manu is arguing that structs small enough to be worth
passing in registers must maintain some sort of fixed memory layout;
They do.
i.e. they can't broken up across a desperate set of registers.
That was not his point. If you have:
struct S{
float a;
float b;
}
S foo();
Then EDX and EAX contain float data upon function return. That is not
something you want.
You can _not_ take the memory address, etc of a
register so maintaining the layout of a struct is a) impossible and b)
not necessary, if you're returning it via registers. The compiler is
free to use XMM registers for floats/doubles and GPRs for pointers/ints.
And there's no need for the caller to place those struct register values
on the stack if they're never used. Furthermore, even on the stack, the
struct's memory layout is only ever valid immediately before (and
forever after due to pointer escapes) a non-inlined function call or
address taking. At a low level, MRV is a structured set of value, ergo
it's a struct.
Multiple function arguments are a structured set of values too.
And the call structure for multiple arguments is virtually identical for
structs and multiple arguments. In fact, I've used this duality on
various cross-language calls, defining arguments in one language and a
struct in the other.
Wtf. Good luck porting that code to an architecture with a different
calling convention.