extern(C) System V ABI choices

John Colvin john.loughran.colvin at gmail.com
Mon Apr 22 07:54:56 PDT 2013


Currently complex types are not passed in accordance with the 
System V ABI when using extern(C) on linux x64, (dmd git master, 
no flags):

extern(C):

cfloat cf(cfloat a)
{
     return a;
}
// a is expected on the stack (not the fpu stack) and returned in 
XMM0:XMM1 (real in one, imaginary in the other I presume. Lots of 
empty space.)

cdouble cd(cdouble a)
{
     return a;
}
// a is expected in XMM0:XMM1, a hidden pointer argument to some 
stack space is expected in RDI, filled from a and is returned in 
RAX

creal cr(creal a)
{
     return a;
}
// a is expected on the stack (not fpu stack), a hidden pointer 
argument to some stack space is passed in RDI, filled from a and 
is returned in RAX.


/*********

Would it not be better to make these compliant with the 
equivalent types specified in the System V ABI (when using 
extern(C) on linux x64)? It would ease interactions with other 
languages.

*********/


As specified here: 
http://refspecs.linuxfoundation.org/elf/x86_64-abi-0.95.pdf

cfloat would be passed as real -> XMM<n> and imag -> XMM<n+1>
and returned identically

cdouble would be passed as real -> XMM<n> and imag -> XMM<n+1>
and returned identically

creal would be passed on the stack (not fpu)
and returned as real -> ST<n> and imag -> ST<n+1>


I recognise that these types are supposed to be phased out in 
favour of std.complex. However, seeing as that doesn't seem to be 
happening any time soon, getting the ABI right would be good for 
now.


More information about the Digitalmars-d mailing list