dlang.org icon indicating copy to clipboard operation
dlang.org copied to clipboard

spec: abi: clarify calling convention for other architectures other than x86

Open ljmf00 opened this issue 4 years ago • 6 comments

Observing the assembly generated by the following source file in either DMD and LDC:

extern (C) void ccall( size_t a, size_t b, size_t c );
extern (D) void dcall( size_t a, size_t b, size_t c );

//...

ccall( a, b, c ); // RDI, RSI, RDX
dcall( a, b, c ); // RDX, RSI, RDI

The parameters are passed in the reverse order in functions with extern(D) linkage. Furthermore, on x86 the calling convention seems to be what is described by the current subsections, not only matching Windows x86, but also appears to be the same behaviour on System V ABI.

Fixes #20204 .

Signed-off-by: Luís Ferreira [email protected]


For more context: https://godbolt.org/z/sWz4x37bb

ljmf00 avatar Nov 09 '21 18:11 ljmf00

Thanks for your pull request, @ljmf00!

Bugzilla references

Auto-close Bugzilla Severity Description
20204 normal need to fix ABI about registers using

dlang-bot avatar Nov 09 '21 18:11 dlang-bot

I've always regarded this as an ABI spec violation of both DMD and LDC, unfortunately not that simple to fix mainly because of existing DMD-style inline asm in druntime/Phobos and user code. If given the choice, I'd definitely fix the implementation rather than the spec.

kinke avatar Nov 09 '21 19:11 kinke

I've always regarded this as an ABI spec violation of both DMD and LDC, unfortunately not that simple to fix mainly because of existing DMD-style inline asm in druntime/Phobos and user code. If given the choice, I'd definitely fix the implementation rather than the spec.

I agree with you because it doesn't make much sense. I don't get the rationale for the x86 special case either. On the other hand, changing the implementation make binaries incompatible leading to a huge breaking change with old shared objects.

I'm kinda divided here, to be honest, but inclined to the "clean way", which is to fix the implementation.

ljmf00 avatar Nov 09 '21 20:11 ljmf00

changing the implementation make binaries incompatible leading to a huge breaking change with old shared objects

That's not that big a deal, we have had numerous breaking ABI changes in the past, so binaries compiled with different compiler versions aren't expected to be compatible.

The only real problem I see is that efforts should probably be synchronized across DMD and LDC, in order to tell people that from D 2.100 on (or so), the params aren't reversed for extern(D) anymore (except for 32-bit x86), for both DMD and LDC. So if they've been accessing parameter registers directly in DMD-style inline asm, they need to adapt those, but it'll work with both DMD and LDC at least.

I'm more than happy to finally do this for LDC (I've had a go at this some 5 years ago already).

kinke avatar Nov 11 '21 16:11 kinke

This parameter reversal has been a PITA at multiple occasions, e.g., https://github.com/dlang/dmd/pull/11630.

kinke avatar Nov 11 '21 16:11 kinke

changing the implementation make binaries incompatible leading to a huge breaking change with old shared objects

That's not that big a deal, we have had numerous breaking ABI changes in the past, so binaries compiled with different compiler versions aren't expected to be compatible.

The only real problem I see is that efforts should probably be synchronized across DMD and LDC, in order to tell people that from D 2.100 on (or so), the params aren't reversed for extern(D) anymore (except for 32-bit x86), for both DMD and LDC. So if they've been accessing parameter registers directly in DMD-style inline asm, they need to adapt those, but it'll work with both DMD and LDC at least.

I'm more than happy to finally do this for LDC (I've had a go at this some 5 years ago already).

Sure, I can see what I can do about it. I'm not into deep backend stuff like target codegen. What about the 32-bit x86? Why is the calling convention different there too?

This parameter reversal has been a PITA at multiple occasions, e.g., dlang/dmd#11630.

At a first glance, it appears to me that this is being fixed in the wrong place. This parameter reverse order behaviour appears to be intentional on the IR generation: https://github.com/dlang/dmd/blob/master/src/dmd/e2ir.d#L5261

ljmf00 avatar Nov 11 '21 18:11 ljmf00