Jump to page: 1 2
Thread overview
Linux 64bit Calling Convention
Feb 28, 2013
Maxime Chevalier
Feb 28, 2013
Maxime Chevalier
Feb 28, 2013
Walter Bright
Feb 28, 2013
Maxime Chevalier
Feb 28, 2013
Walter Bright
Feb 28, 2013
deadalnix
Oct 25, 2014
Trass3r
Oct 25, 2014
Trass3r
Oct 25, 2014
Sean Kelly
Oct 25, 2014
Trass3r
Oct 27, 2014
Trass3r
Nov 14, 2014
David Nadlinger
Nov 14, 2014
Iain Buclaw
Nov 14, 2014
David Nadlinger
Nov 15, 2014
Iain Buclaw
Nov 15, 2014
safety0ff
Oct 25, 2014
Trass3r
February 28, 2013
I'm implementing a JIT compiler and having to call into D functions from machine code I generated. Unfortunately, I seem to be experiencing a problem where the arguments are passed in the reverse order of what I would expect.

The functions I'm calling are global functions with 2 class pointer arguments. E.g.:

void foo(ClassA ptrA, ClassB ptrB) { ... }

The ABI page on dlang.org seems to imply that D uses the C calling convention on Linux. Now, using the C convention on 64-bit linux, this should mean that the first class pointer (ptrA) get passed in register RDI, and the second one (ptrB) in RSI. This is what I would expect but when I actually call a D function, the two arguments are reversed.

I understand that this isn't necessarily super clear without looking at code, but I just wanted to know if there was something obvious I might be overlooking with regards to the D calling convention on Linux/AMD64.

Is it because ptrA automatically gets treated as a "this" pointer, as if the function were a method of ClassA?
February 28, 2013
I did some further testing:

void foo(int a, int b)
{
    writefln("a: %s", a);
    writefln("b: %s", b);
}

unittest
{
    foo(1, 2);

    asm
    {
        mov RDI, 1;
        mov RSI, 2;
        call foo;
    }
}

Produces:

a: 1
b: 2
a: 2
b: 1

Unless I'm mistaken, DMD does not respect the C calling convention on Linux/AMD64.
February 28, 2013
On 2/27/2013 5:03 PM, Maxime Chevalier wrote:
> Unless I'm mistaken, DMD does not respect the C calling convention on Linux/AMD64.

To use the C calling convention, specify "extern (C)" for the function.

BTW, if this did not work, very little of D would work, as there's a lot of reliance on the C standard library and the Linux API functions.
February 28, 2013
> BTW, if this did not work, very little of D would work, as there's a lot of reliance on the C standard library and the Linux API functions.

The ABI page (http://dlang.org/abi.html) doesn't make it very clear what calling convention DMD uses by default.
February 28, 2013
On 2/27/2013 6:36 PM, Maxime Chevalier wrote:
> The ABI page (http://dlang.org/abi.html) doesn't make it very clear what calling
> convention DMD uses by default.

Should file a bugzilla report about that!
February 28, 2013
On Thursday, 28 February 2013 at 02:36:07 UTC, Maxime Chevalier wrote:
>> BTW, if this did not work, very little of D would work, as there's a lot of reliance on the C standard library and the Linux API functions.
>
> The ABI page (http://dlang.org/abi.html) doesn't make it very clear what calling convention DMD uses by default.

Be careful with that page. Other compiler may use other ABI.
October 25, 2014
On Thursday, 28 February 2013 at 01:03:08 UTC, Maxime Chevalier wrote:
> I did some further testing:
>
> void foo(int a, int b)
> {
>     writefln("a: %s", a);
>     writefln("b: %s", b);
> }
>
> unittest
> {
>     foo(1, 2);
>
>     asm
>     {
>         mov RDI, 1;
>         mov RSI, 2;
>         call foo;
>     }
> }
>
> Produces:
>
> a: 1
> b: 2
> a: 2
> b: 1
>
> Unless I'm mistaken, DMD does not respect the C calling convention on Linux/AMD64.

True.
For extern(D) dmd passes parameters in reverse order on Win64 and Linux64!
What the heck?
October 25, 2014
On Thursday, 28 February 2013 at 02:02:09 UTC, Walter Bright wrote:
> On 2/27/2013 5:03 PM, Maxime Chevalier wrote:
>> Unless I'm mistaken, DMD does not respect the C calling convention on Linux/AMD64.
>
> To use the C calling convention, specify "extern (C)" for the function.

This is about extern(D).
October 25, 2014
Looking at the code extern(D) is in the _revfunc list in optabgen.
Which seems to cause params to be reversed independent of the architecture in FuncDeclaration::toObjFile // Reverse params[] entries.
Meaning Linux x32 would also be affected.

This totally smells like a remnant as the code matches the initial custom Win32 D ABI.
October 25, 2014
On Saturday, 25 October 2014 at 15:20:53 UTC, Trass3r wrote:
>
> This totally smells like a remnant as the code matches the initial custom Win32 D ABI.

Yep.  I thought the D calling convention matched the C calling convention on 64-bit.  Didn't Walter even state this explicitly at some point?
« First   ‹ Prev
1 2