Payload structure problem using inline asm

Baz burg.basile at yahoo.com
Wed Jul 17 09:52:38 PDT 2013


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.


More information about the Digitalmars-d-learn mailing list