Payload structure problem using inline asm
John Colvin
john.loughran.colvin at gmail.com
Wed Jul 17 10:11:18 PDT 2013
On Wednesday, 17 July 2013 at 17:09:30 UTC, John Colvin wrote:
> On Wednesday, 17 July 2013 at 16:52:40 UTC, Baz wrote:
>> Hello, I've defined a simple template used in a double linked
>> list implementation:
>>
>> template tDLListItem(T)
>> {
>> const cPrevOffs = size_t.sizeof;
>> const cNextOffs = size_t.sizeof + size_t.sizeof;
>> void* NewItemCaps(T* aData, void* aPrevious, void* aNext)
>> {
>> auto lPt = std.c.stdlib.malloc( 3 * size_t.sizeof );
>> if (!lPt)
>> {
>> throw new OutOfMemoryError();
>> }
>> *cast(size_t*) lPt = cast(size_t) aData;
>> *cast(size_t*) (lPt + cPrevOffs) = cast(size_t) aPrevious;
>> *cast(size_t*) (lPt + cNextOffs) = cast(size_t) aNext;
>> return lPt;
>> }
>> void DeleteItemCaps(void* aItemCaps)
>> {
>> std.c.stdlib.free(aItemCaps);
>> }
>> void SetItemCapsPrev(void* aItemCaps, void* aPrevious)
>> {
>> *cast(size_t*) (aItemCaps + cPrevOffs) = cast(size_t)
>> aPrevious;
>> }
>> void SetItemCapsNext(void* aItemCaps, void* aNext)
>> {
>> *cast(size_t*) (aItemCaps + cNextOffs) = cast(size_t) aNext;
>> }
>> void SetItemCapsData(void* aItemCaps, T* aData)
>> {
>> *cast(size_t*) aItemCaps = cast(size_t) aData;
>> }
>> T* GetItemCapsData(void* aItemCaps)
>> {
>> version(X86) asm
>> {
>> naked;
>> mov EAX, [EAX];
>> ret;
>> }
>> else version(none) asm
>> {
>> naked;
>> mov RAX, [RAX];
>> ret;
>> }
>> else
>> {
>> return *cast(T**) (aItemCaps);
>> }
>> }
>> void* PreviousItemCaps(void* aItemCaps)
>> {
>> version(X86) asm
>> {
>> naked;
>> mov EAX, [EAX + cPrevOffs];
>> ret;
>> }
>> else version(none) asm
>> {
>> naked;
>> mov RAX, [RAX + cPrevOffs];
>> ret;
>> }
>> else
>> {
>> return *cast(size_t**) (aItemCaps + cPrevOffs);
>> }
>> }
>> void* NextItemCaps(void* aItemCaps)
>> {
>> version(X86) asm
>> {
>> naked;
>> mov EAX, [EAX + cNextOffs];
>> ret;
>> }
>> else version(none) asm
>> {
>> naked;
>> mov RAX, [RAX + cNextOffs];
>> ret;
>> }
>> else
>> {
>> return *cast(size_t**) (aItemCaps + cNextOffs);
>> }
>> }
>> }
>>
>> It's used as a struct. (BTW I call the "payload" a "capsule",
>> a "caps"). In x86 (tested on win) I can optimize the access
>> into the "capsule" to a simple member (I return the data
>> pointed by the parameter by digging using the param +
>> memberoffset as an address...
>>
>> But it doesn't work in x86_64 (tested on nux). What's wrong
>> with that ? Does I miss something in the parameters
>> convention/ABI for x64 (that's why the x64 versions are
>> surounded by version(none) instead of version (X86_64) )) ?
>>
>> Does dmd produce real x86_64 code or is it possible for a 64
>> bit appli to work with 32 bit pointers ?
>> (I know this Q coulds look weird but I've already seen some
>> false x86_64 while doing some static analysis)
>>
>> WTF.MEH.
>
> AFAIK on windows dmd uses the optlink calling convention, so
> the 1st argument is in EAX
>
> On linux 32bit (cdecl) the first argument will be on the top of
> the stack.
>
> On linux 64bit (system V) the first argument will be in RDX
>
> see:
> http://en.wikipedia.org/wiki/X86_calling_conventions
> or find a copy of the system V abi docs somewhere.
big woops there, linux x64 arguments are RDI first, not RDX
The order is RDI RSI RDX RCX R8 R9
More information about the Digitalmars-d-learn
mailing list