digitalmars.D - Linux 64bit Calling Convention
- Maxime Chevalier (19/19) Feb 27 2013 I'm implementing a JIT compiler and having to call into D
- Maxime Chevalier (23/23) Feb 27 2013 I did some further testing:
- Walter Bright (4/5) Feb 27 2013 To use the C calling convention, specify "extern (C)" for the function.
- Maxime Chevalier (2/5) Feb 27 2013 The ABI page (http://dlang.org/abi.html) doesn't make it very
- Walter Bright (2/4) Feb 27 2013 Should file a bugzilla report about that!
- deadalnix (3/8) Feb 27 2013 Be careful with that page. Other compiler may use other ABI.
- Trass3r (3/8) Oct 25 2014 This is about extern(D).
- Trass3r (7/7) Oct 25 2014 Looking at the code extern(D) is in the _revfunc list in optabgen.
- Sean Kelly (4/6) Oct 25 2014 Yep. I thought the D calling convention matched the C calling
- Trass3r (3/3) Oct 25 2014 Yes it's clearly stated on the ABI page (and sane).
- Trass3r (1/1) Oct 27 2014 https://github.com/D-Programming-Language/dmd/pull/4092
- David Nadlinger (8/8) Nov 14 2014 Ping.
- Iain Buclaw via Digitalmars-d (4/7) Nov 14 2014 Really? I say this all the time. (OK, maybe not so much over the last
- David Nadlinger (6/9) Nov 14 2014 Yeah, and if I remember correctly, we both went to DConf 2013
- Iain Buclaw via Digitalmars-d (6/14) Nov 15 2014 Suddenly I have a reason to be vocal about it again.
- safety0ff (10/13) Nov 14 2014 I've hit it a few times, I wasn't sure if it was me or the
- Trass3r (6/29) Oct 25 2014 True.
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?
Feb 27 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.
Feb 27 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.
Feb 27 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.
Feb 27 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!
Feb 27 2013
On Thursday, 28 February 2013 at 02:36:07 UTC, Maxime Chevalier wrote:Be careful with that page. Other compiler may use other ABI.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.
Feb 27 2013
On Thursday, 28 February 2013 at 02:02:09 UTC, Walter Bright wrote:On 2/27/2013 5:03 PM, Maxime Chevalier wrote:This is about extern(D).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.
Oct 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.
Oct 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?
Oct 25 2014
Yes it's clearly stated on the ABI page (and sane). Nobody ever noticed cause it's hard to spot this in assembly. But it was very salient and disturbing in llvm IR.
Oct 25 2014
Ping. I'm all for the proposal, as it brings DMD and LDC in line with what the docs say (or rather do not say) and also with what GDC does. However, as this is a breaking change (think naked inline asm), I want to be sure that DMD is on board before going through with it on our (LDC) side. Cheers, David
Nov 14 2014
On 25 October 2014 17:14, Trass3r via Digitalmars-d <digitalmars-d puremagic.com> wrote:Yes it's clearly stated on the ABI page (and sane). Nobody ever noticed cause it's hard to spot this in assembly. But it was very salient and disturbing in llvm IR.Really? I say this all the time. (OK, maybe not so much over the last 5 or so months :)
Nov 14 2014
On Friday, 14 November 2014 at 20:19:56 UTC, Iain Buclaw via Digitalmars-d wrote:Really? I say this all the time. (OK, maybe not so much over the last 5 or so months :)Yeah, and if I remember correctly, we both went to DConf 2013 intending to pester Walter about it. Unfortunately, I don't recall if we actually did, or what his response was. David
Nov 14 2014
On 14 November 2014 20:27, David Nadlinger via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Friday, 14 November 2014 at 20:19:56 UTC, Iain Buclaw via Digitalmars-d wrote:Suddenly I have a reason to be vocal about it again. https://github.com/D-Programming-Language/dmd/pull/3670 You wouldn't need to swap around the parameters if DMD passed parameters in the right order.Really? I say this all the time. (OK, maybe not so much over the last 5 or so months :)Yeah, and if I remember correctly, we both went to DConf 2013 intending to pester Walter about it. Unfortunately, I don't recall if we actually did, or what his response was.
Nov 15 2014
On Saturday, 25 October 2014 at 16:14:30 UTC, Trass3r wrote:Yes it's clearly stated on the ABI page (and sane). Nobody ever noticed cause it's hard to spot this in assembly.I've hit it a few times, I wasn't sure if it was me or the compiler that was mistaken so I didn't create a report, I just swapped my registers and moved on. On Friday, 14 November 2014 at 19:42:54 UTC, David Nadlinger wrote:However, as this is a breaking change (think naked inline asm)I'm probably not the only user who has adjusted their registers and moved on. As usual, this is the biggest hindrance to fixing the bug, silently swapping the registers between versions is unacceptable.
Nov 14 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?
Oct 25 2014