Payload structure problem using inline asm
John Colvin
john.loughran.colvin at gmail.com
Wed Jul 17 10:09:27 PDT 2013
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.
More information about the Digitalmars-d-learn
mailing list