sl@0: // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // e32\euser\epoc\x86\uc_utl.cia sl@0: // sl@0: // sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: sl@0: // Dummy so we can use same DEF file as WINS sl@0: EXPORT_C void BootEpoc(TBool) sl@0: { sl@0: } sl@0: sl@0: sl@0: EXPORT_C __NAKED__ void RFastLock::Wait() sl@0: { sl@0: THISCALL_PROLOG0() sl@0: asm("lock sub dword ptr [ecx+4], 1"); sl@0: asm("jnc fast_lock_wait_sem"); sl@0: THISCALL_EPILOG0() sl@0: asm("fast_lock_wait_sem:"); sl@0: asm("mov eax, %0": : "i"(EExecSemaphoreWait)); sl@0: asm("mov ecx, [ecx]"); sl@0: asm("xor edx, edx"); sl@0: asm("int 0x21"); sl@0: THISCALL_EPILOG0() sl@0: } sl@0: sl@0: EXPORT_C __NAKED__ void RFastLock::Signal() sl@0: { sl@0: THISCALL_PROLOG0() sl@0: asm("lock add dword ptr [ecx+4], 1"); sl@0: asm("jne fast_lock_signal_sem"); sl@0: THISCALL_EPILOG0() sl@0: asm("fast_lock_signal_sem:"); sl@0: asm("mov eax, %0": : "i"(EExecSemaphoreSignal1)); sl@0: asm("mov ecx, [ecx]"); sl@0: asm("int 0x21"); sl@0: THISCALL_EPILOG0() sl@0: } sl@0: sl@0: #ifdef __MEM_MACHINE_CODED__ sl@0: __NAKED__ EXPORT_C void Mem::Swap( TAny* /*aPtr1*/, TAny* /*aPtr2*/, TInt /*aLength*/ ) sl@0: /** sl@0: Swaps a number of bytes of data between two specified locations. sl@0: sl@0: The source and target areas can overlap. sl@0: sl@0: @param aPtr1 A pointer to the first location taking part in the swap. sl@0: @param aPtr2 A pointer to second location taking part in the swap. sl@0: @param aLength The number of bytes to be swapped between the two locations. sl@0: This value must not be negative. sl@0: sl@0: @panic USER 94 In debug builds only, if aLength is negative. sl@0: */ sl@0: sl@0: // sl@0: // Swap the contents of *aPtr1 with *aPtr2. sl@0: // NB We assume ES=DS on entry. sl@0: // sl@0: { sl@0: asm("push esi"); sl@0: asm("push edi"); sl@0: asm("mov edi,[esp+12]");// aPtr1 address into edi sl@0: asm("mov esi,[esp+16]");// aPtr2 address into esi sl@0: asm("mov ecx,[esp+20]");// byte count into ecx sl@0: asm("pushfd"); sl@0: sl@0: asm("test ecx,ecx"); // sl@0: asm("jz short memswap0");// if length=0, nothing to do sl@0: asm("cld"); // go forwards through array sl@0: asm("cmp ecx,7"); // if length<7 don't bother with alignment check sl@0: asm("jc short memswap1");// sl@0: asm("mov edx,ecx"); // length into edx sl@0: // number of bytes to align aPtr1 = 4-(edi mod 4) sl@0: asm("mov ecx,4"); sl@0: asm("sub ecx,edi"); // sl@0: asm("and ecx,3"); // into ecx sl@0: asm("jz short memswap2");// if aligned, proceed with dword swap sl@0: asm("sub edx,ecx"); // subtract number of bytes from length sl@0: asm("memswap3:"); sl@0: asm("mov al,[edi]"); // al = *aPtr1 sl@0: asm("mov ah,[esi]"); // ah = *aPtr2 sl@0: asm("mov [esi],al"); // *aPtr2=al sl@0: asm("mov [edi],ah"); // *aPtr1=ah sl@0: asm("inc esi"); // aPtr2++ sl@0: asm("inc edi"); // aPtr1++ sl@0: asm("dec ecx"); // sl@0: asm("jnz short memswap3");// loop ecx times - edi is now dword aligned sl@0: asm("memswap2:"); sl@0: asm("push ebx"); // preserve ebx sl@0: asm("mov ecx,edx"); // length back into ecx sl@0: asm("mov ah,cl"); // save lower two bits of dword count in ah bits 3,2 sl@0: asm("add ecx,12"); // divide dword count by 4, rounding to next higher integer sl@0: asm("shr ecx,4"); // this gives loop count for unfolded loop sl@0: asm("shl ah,4"); // lower two bits of dword count into ah bits 7,6 sl@0: asm("sahf"); // and into SF,ZF sl@0: asm("jns short memswap8");// branch if lower two bits of dword count = 0 or 1 sl@0: asm("jz short memswap5");// if lower two bits = 3, miss out first unfolding of loop sl@0: asm("jnz short memswap6"); // if lower two bits = 2, miss out first two unfoldings sl@0: asm("memswap8:"); sl@0: asm("jz short memswap7");// if lower two bits = 1, miss out first three unfoldings sl@0: asm("memswap4:"); sl@0: asm("mov eax,[edi]"); // eax = *aPtr1 sl@0: asm("mov ebx,[esi]"); // ebx = *aPtr2 sl@0: asm("mov [esi],eax"); // *aPtr2=eax sl@0: asm("mov [edi],ebx"); // *aPtr1=ebx sl@0: asm("add edi,4"); // aPtr1++ sl@0: asm("add esi,4"); // aPtr2++ sl@0: asm("memswap5:"); sl@0: asm("mov eax,[edi]"); // eax = *aPtr1 sl@0: asm("mov ebx,[esi]"); // ebx = *aPtr2 sl@0: asm("mov [esi],eax"); // *aPtr2=eax sl@0: asm("mov [edi],ebx"); // *aPtr1=ebx sl@0: asm("add edi,4"); // aPtr1++ sl@0: asm("add esi,4"); // aPtr2++ sl@0: asm("memswap6:"); sl@0: asm("mov eax,[edi]"); // eax = *aPtr1 sl@0: asm("mov ebx,[esi]"); // ebx = *aPtr2 sl@0: asm("mov [esi],eax"); // *aPtr2=eax sl@0: asm("mov [edi],ebx"); // *aPtr1=ebx sl@0: asm("add edi,4"); // aPtr1++ sl@0: asm("add esi,4"); // aPtr2++ sl@0: asm("memswap7:"); sl@0: asm("mov eax,[edi]"); // eax = *aPtr1 sl@0: asm("mov ebx,[esi]"); // ebx = *aPtr2 sl@0: asm("mov [esi],eax"); // *aPtr2=eax sl@0: asm("mov [edi],ebx"); // *aPtr1=ebx sl@0: asm("add edi,4"); // aPtr1++ sl@0: asm("add esi,4"); // aPtr2++ sl@0: asm("dec ecx"); sl@0: asm("jnz short memswap4"); // loop ecx times to do main part of swap sl@0: asm("mov ecx,edx"); // length back into ecx sl@0: asm("pop ebx"); // restore ebx sl@0: asm("and ecx,3"); // number of remaining bytes to move sl@0: asm("jz short memswap0");// if zero, we are finished sl@0: asm("memswap1:"); // *** come here for small swap sl@0: asm("mov al,[edi]"); // al = *aPtr1 sl@0: asm("mov ah,[esi]"); // ah = *aPtr2 sl@0: asm("mov [esi],al"); // *aPtr2=al sl@0: asm("mov [edi],ah"); // *aPtr1=ah sl@0: asm("inc esi"); // aPtr2++ sl@0: asm("inc edi"); // aPtr1++ sl@0: asm("dec ecx"); // sl@0: asm("jnz short memswap1"); // loop ecx times - edi is now dword aligned sl@0: sl@0: asm("memswap0:"); sl@0: asm("popfd"); sl@0: asm("pop edi"); sl@0: asm("pop esi"); sl@0: asm("ret"); sl@0: } sl@0: #endif sl@0: sl@0: // Hash an 8 bit string at aPtr, length aLen bytes. sl@0: __NAKED__ TUint32 DefaultStringHash(const TUint8* /*aPtr*/, TInt /*aLen*/) sl@0: { sl@0: asm("push esi"); sl@0: asm("mov esi, [esp+8]"); sl@0: asm("mov ecx, [esp+12]"); sl@0: asm("xor eax, eax"); sl@0: asm("sub ecx, 4"); sl@0: asm("jb lt4"); sl@0: asm("ge4:"); sl@0: asm("xor eax, [esi]"); sl@0: asm("add esi, 4"); sl@0: asm("mov edx, 0x9E3779B9"); sl@0: asm("mul edx"); sl@0: asm("sub ecx, 4"); sl@0: asm("jae ge4"); sl@0: asm("lt4:"); sl@0: asm("add ecx, 4"); sl@0: asm("jz done"); sl@0: asm("xor edx, edx"); sl@0: asm("cmp ecx, 2"); sl@0: asm("jbe le2"); sl@0: asm("mov dl, [esi+2]"); sl@0: asm("shl edx, 16"); sl@0: asm("le2:"); sl@0: asm("cmp ecx, 2"); sl@0: asm("jb onemore"); sl@0: asm("mov dh, [esi+1]"); sl@0: asm("onemore:"); sl@0: asm("mov dl, [esi]"); sl@0: asm("xor eax, edx"); sl@0: asm("mov edx, 0x9E3779B9"); sl@0: asm("mul edx"); sl@0: asm("done:"); sl@0: asm("pop esi"); sl@0: asm("ret"); sl@0: } sl@0: sl@0: // Hash a 16 bit string at aPtr, length aLen bytes. sl@0: __NAKED__ TUint32 DefaultWStringHash(const TUint16* /*aPtr*/, TInt /*aLen*/) sl@0: { sl@0: asm("push esi"); sl@0: asm("mov esi, [esp+8]"); sl@0: asm("mov ecx, [esp+12]"); sl@0: asm("xor eax, eax"); sl@0: asm("sub ecx, 8"); sl@0: asm("jb lt8"); sl@0: asm("ge8:"); sl@0: asm("mov edx, [esi+4]"); sl@0: asm("xor eax, [esi]"); sl@0: asm("add esi, 8"); sl@0: asm("rol edx, 8"); sl@0: asm("xor eax, edx"); sl@0: asm("mov edx, 0x9E3779B9"); sl@0: asm("mul edx"); sl@0: asm("sub ecx, 8"); sl@0: asm("jae ge8"); sl@0: asm("lt8:"); sl@0: asm("add ecx, 8"); sl@0: asm("jz done_defwstrhash"); sl@0: asm("xor edx, edx"); sl@0: asm("cmp ecx, 4"); sl@0: asm("jbe le4"); sl@0: asm("mov dx, [esi+4]"); sl@0: asm("rol edx, 8"); sl@0: asm("xor eax, edx"); sl@0: asm("xor edx, edx"); sl@0: asm("le4:"); sl@0: asm("cmp ecx, 4"); sl@0: asm("jb onemore_defwstrhash"); sl@0: asm("mov dx, [esi+2]"); sl@0: asm("shl edx, 16"); sl@0: asm("onemore_defwstrhash:"); sl@0: asm("mov dx, [esi]"); sl@0: asm("xor eax, edx"); sl@0: asm("mov edx, 0x9E3779B9"); sl@0: asm("mul edx"); sl@0: asm("done_defwstrhash:"); sl@0: asm("pop esi"); sl@0: asm("ret"); sl@0: } sl@0: sl@0: sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Calculate a 32 bit hash from a 32 bit integer. sl@0: sl@0: @param aInt The integer to be hashed. sl@0: @return The calculated 32 bit hash value. sl@0: */ sl@0: EXPORT_C __NAKED__ TUint32 DefaultHash::Integer(const TInt& /*aInt*/) sl@0: { sl@0: asm("mov edx, [esp+4]"); sl@0: asm("mov eax, 0x9E3779B9"); sl@0: asm("mul dword ptr [edx]"); sl@0: asm("ret"); sl@0: } sl@0: