|
|
#ifndef _ASSEMBLY_HPP_
#define _ASSEMBLY_HPP_
// Ruler
// 1 2 3 4 5 6 7 8
//345678901234567890123456789012345678901234567890123456789012345678901234567890
/********************************************************************/ /* */ /* The standard layout. */ /* */ /* The standard layout for 'hpp' files for this code is as */ /* follows: */ /* */ /* 1. Include files. */ /* 2. Constants exported from the class. */ /* 3. Data structures exported from the class. */ /* 4. Forward references to other data structures. */ /* 5. Class specifications (including inline functions). */ /* 6. Additional large inline functions. */ /* */ /* Any portion that is not required is simply omitted. */ /* */ /********************************************************************/
#include "Global.hpp"
/********************************************************************/ /* */ /* Constants exported from the class. */ /* */ /* The assembly constants indicate the location of the thread */ /* local store. */ /* */ /********************************************************************/
#define PcTeb 0x18
#define IDTeb 0x24
#ifdef WINDOWS_95
CONST SBIT32 TebSlot = 0x88; #else
CONST SBIT32 TebSlot = 0xE10; #endif
#ifndef ASSEMBLY_PREFETCH_SUPPORT
#define prefetcht0 __asm _emit 0x0f __asm _emit 0x18 __asm _emit 0x08
#define prefetcht1 __asm _emit 0x0f __asm _emit 0x18 __asm _emit 0x10
#define prefetcht2 __asm _emit 0x0f __asm _emit 0x18 __asm _emit 0x18
#define prefetchnta __asm _emit 0x0f __asm _emit 0x18 __asm _emit 0x00
#endif
#pragma warning( disable : 4035 )
/********************************************************************/ /* */ /* Assembly language for ultra high performance. */ /* */ /* We have coded a few functions in assembly language for */ /* ultra high performance. */ /* */ /********************************************************************/
class ASSEMBLY { public: //
// Public inline functions.
//
ASSEMBLY( VOID ) { /* void */ }
STATIC INLINE SBIT32 AtomicAdd ( VOLATILE SBIT32 *Address, SBIT32 Value ) { #ifdef ASSEMBLY_X86
__asm { mov ecx,Address // Load the address.
mov eax,Value // Load the value.
lock xadd dword ptr[ecx],eax // Increment the value.
} #else
return ( (SBIT32) InterlockedExchangeAdd ( ((LPLONG) Address), ((LONG) Value) ) ); #endif
}
STATIC INLINE SBIT32 AtomicCompareExchange ( VOLATILE SBIT32 *Address, SBIT32 NewValue, SBIT32 Value ) { #ifdef ASSEMBLY_X86
__asm { mov ecx,Address // Load the address.
mov edx,NewValue // Load the new value.
mov eax,Value // Load the value.
lock cmpxchg dword ptr[ecx],edx // Update the value.
} #else
return ( (SBIT32) InterlockedCompareExchange ( ((VOID**) Address), ((VOID*) NewValue), ((VOID*) Value) ) ); #endif
} #ifdef ASSEMBLY_X86
STATIC INLINE SBIT64 AtomicCompareExchange64 ( VOLATILE SBIT64 *Address, SBIT64 NewValue, SBIT64 Value ) { __asm { mov esi, Address // Load the adrress.
mov ebx, dword ptr NewValue[0] // Load the new value.
mov ecx, dword ptr NewValue[4] // Load the new value.
mov eax, dword ptr Value[0] // Load the value.
mov edx, dword ptr Value[4] // Load the value.
lock cmpxchg8b [esi] // Update the value.
} } #endif
STATIC INLINE SBIT32 AtomicDecrement( VOLATILE SBIT32 *Address ) { #ifdef ASSEMBLY_X86
__asm { mov ecx,Address // Load the Address.
mov eax,-1 // Load constant.
lock xadd dword ptr[ecx],eax // Decrement value.
dec eax // Correct result.
} #else
return ((SBIT32) InterlockedDecrement( ((LONG*) Address) )); #endif
}
STATIC INLINE SBIT32 AtomicExchange ( VOLATILE SBIT32 *Address, SBIT32 NewValue ) { #ifdef ASSEMBLY_X86
__asm { mov ecx,Address // Load the Address.
mov eax,NewValue // Load the value.
lock xchg dword ptr[ecx],eax // Exchange new value.
} #else
return ( (SBIT32) InterlockedExchange ( ((LONG*) Address), ((LONG) NewValue) ) ); #endif
}
STATIC INLINE SBIT32 AtomicIncrement( VOLATILE SBIT32 *Address ) { #ifdef ASSEMBLY_X86
__asm { mov ecx,Address // Load the Address.
mov eax,1 // Load constant.
lock xadd dword ptr[ecx],eax // Increment value.
inc eax // Correct result.
} #else
return ((SBIT32) InterlockedIncrement( ((LONG*) Address) )); #endif
}
STATIC INLINE SBIT32 GetThreadId( VOID ) { #ifdef ASSEMBLY_X86
#ifdef ENABLE_NON_STANDARD_ASSEMBLY
__asm { mov eax,fs:[PcTeb] // Load TEB base address.
mov eax,dword ptr[eax+IDTeb] // Load thread ID.
} #else
return ((SBIT32) GetCurrentThreadId()); #endif
#else
return ((SBIT32) GetCurrentThreadId()); #endif
}
STATIC INLINE VOID PrefetchL1( VOID *Address ) { #ifdef ASSEMBLY_X86
__asm { mov eax,Address // Load Address.
#ifdef ASSEMBLY_PREFETCH_SUPPORT
prefetcht0 [eax] // Prefetch into the L1.
#else
prefetcht0 // Prefetch into the L1.
#endif
} #endif
}
STATIC INLINE VOID PrefetchL2( VOID *Address ) { #ifdef ASSEMBLY_X86
__asm { mov eax,Address // Load Address.
#ifdef ASSEMBLY_PREFETCH_SUPPORT
prefetcht1 [eax] // Prefetch into the L2.
#else
prefetcht1 // Prefetch into the L2.
#endif
} #endif
}
STATIC INLINE VOID PrefetchL3( VOID *Address ) { #ifdef ASSEMBLY_X86
__asm { mov eax,Address // Load Address.
#ifdef ASSEMBLY_PREFETCH_SUPPORT
prefetcht2 [eax] // Prefetch into the L3.
#else
prefetcht2 // Prefetch into the L3.
#endif
} #endif
}
STATIC INLINE VOID PrefetchNta( VOID *Address ) { #ifdef ASSEMBLY_X86
__asm { mov eax,Address // Load Address.
#ifdef ASSEMBLY_PREFETCH_SUPPORT
prefetchnta [eax] // Prefetch into the L1.
#else
prefetchnta // Prefetch into the L1.
#endif
} #endif
}
#ifdef ASSEMBLY_X86
#ifdef ENABLE_NON_STANDARD_ASSEMBLY
STATIC INLINE VOID *GetTlsAddress( SBIT32 TlsOffset ) { __asm { mov eax,TlsOffset // Load TLS offset.
add eax,fs:[PcTeb] // Add TEB base address.
} } #endif
#endif
STATIC INLINE VOID *GetTlsValue( SBIT32 TlsIndex,SBIT32 TlsOffset ) { #ifdef ASSEMBLY_X86
#ifdef ENABLE_NON_STANDARD_ASSEMBLY
__asm { mov eax,TlsOffset // Load TLS offset.
add eax,fs:[PcTeb] // Add TEB base address.
mov eax,[eax] // Load TLS value.
} #else
return (TlsGetValue( ((DWORD) TlsIndex) )); #endif
#else
return (TlsGetValue( ((DWORD) TlsIndex) )); #endif
}
STATIC INLINE VOID SetTlsValue ( SBIT32 TlsIndex, SBIT32 TlsOffset, VOID *NewPointer ) { #ifdef ASSEMBLY_X86
#ifdef ENABLE_NON_STANDARD_ASSEMBLY
__asm { mov eax,TlsOffset // Load TLS offset.
add eax,fs:[PcTeb] // Add TEB base address.
mov edx,NewPointer // Load new TLS value.
mov [eax],edx // Store new TLS value.
} #else
(VOID) TlsSetValue( ((DWORD) TlsIndex),NewPointer ); #endif
#else
(VOID) TlsSetValue( ((DWORD) TlsIndex),NewPointer ); #endif
}
~ASSEMBLY( VOID ) { /* void */ }
private: //
// Disabled operations.
//
ASSEMBLY( CONST ASSEMBLY & Copy );
VOID operator=( CONST ASSEMBLY & Copy ); };
#pragma warning( default : 4035 )
#endif
|