Thread overview | |||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
February 28, 2013 Linux 64bit Calling Convention | ||||
---|---|---|---|---|
| ||||
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 Re: Linux 64bit Calling Convention | ||||
---|---|---|---|---|
| ||||
Posted in reply to Maxime Chevalier | 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 Re: Linux 64bit Calling Convention | ||||
---|---|---|---|---|
| ||||
Posted in reply to Maxime Chevalier | 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 Re: Linux 64bit Calling Convention | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | > 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 Re: Linux 64bit Calling Convention | ||||
---|---|---|---|---|
| ||||
Posted in reply to Maxime Chevalier | 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 Re: Linux 64bit Calling Convention | ||||
---|---|---|---|---|
| ||||
Posted in reply to Maxime Chevalier | 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 Re: Linux 64bit Calling Convention | ||||
---|---|---|---|---|
| ||||
Posted in reply to Maxime Chevalier | 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 Re: Linux 64bit Calling Convention | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | 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 Re: Linux 64bit Calling Convention | ||||
---|---|---|---|---|
| ||||
Posted in reply to Trass3r | 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 Re: Linux 64bit Calling Convention | ||||
---|---|---|---|---|
| ||||
Posted in reply to Trass3r | 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?
|
Copyright © 1999-2021 by the D Language Foundation