os/kernelhwsrv/kernel/eka/euser/epoc/x86/uc_utl.cia
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // e32\euser\epoc\x86\uc_utl.cia
    15 // 
    16 //
    17 
    18 #include <u32exec.h>
    19 #include <e32base.h>
    20 #include <e32rom.h>
    21 #include <e32svr.h>
    22 #include <e32hashtab.h>
    23 
    24 
    25 // Dummy so we can use same DEF file as WINS
    26 EXPORT_C void BootEpoc(TBool)
    27 	{
    28 	}
    29 
    30 
    31 EXPORT_C __NAKED__ void RFastLock::Wait()
    32 	{
    33 	THISCALL_PROLOG0()
    34 	asm("lock sub dword ptr [ecx+4], 1");
    35 	asm("jnc fast_lock_wait_sem");
    36 	THISCALL_EPILOG0()
    37 	asm("fast_lock_wait_sem:");
    38 	asm("mov eax, %0": : "i"(EExecSemaphoreWait));
    39 	asm("mov ecx, [ecx]");
    40 	asm("xor edx, edx");
    41 	asm("int 0x21");
    42 	THISCALL_EPILOG0()
    43 	}
    44 
    45 EXPORT_C __NAKED__ void RFastLock::Signal()
    46 	{
    47 	THISCALL_PROLOG0()
    48 	asm("lock add dword ptr [ecx+4], 1");
    49 	asm("jne fast_lock_signal_sem");
    50 	THISCALL_EPILOG0()
    51 	asm("fast_lock_signal_sem:");
    52 	asm("mov eax, %0": : "i"(EExecSemaphoreSignal1));
    53 	asm("mov ecx, [ecx]");
    54 	asm("int 0x21");
    55 	THISCALL_EPILOG0()
    56 	}
    57 
    58 #ifdef __MEM_MACHINE_CODED__
    59 __NAKED__ EXPORT_C void Mem::Swap( TAny* /*aPtr1*/, TAny* /*aPtr2*/, TInt /*aLength*/ )
    60 /**
    61 Swaps a number of bytes of data between two specified locations.
    62 
    63 The source and target areas can overlap.
    64 
    65 @param aPtr1   A pointer to the first location taking part in the swap. 
    66 @param aPtr2   A pointer to second location taking part in the swap. 
    67 @param aLength The number of bytes to be swapped between the two locations. 
    68                This value must not be negative.
    69 
    70 @panic USER 94 In debug builds only, if aLength is negative.
    71 */
    72 
    73 //
    74 //	Swap the contents of *aPtr1 with *aPtr2.
    75 //	NB We assume ES=DS on entry.
    76 //
    77 	{
    78 	asm("push esi");
    79 	asm("push edi");
    80 	asm("mov edi,[esp+12]");// aPtr1 address into edi
    81 	asm("mov esi,[esp+16]");// aPtr2 address into esi
    82 	asm("mov ecx,[esp+20]");// byte count into ecx
    83 	asm("pushfd");
    84 
    85 	asm("test ecx,ecx");	//
    86 	asm("jz short memswap0");// if length=0, nothing to do
    87 	asm("cld");				// go forwards through array
    88 	asm("cmp ecx,7");		// if length<7 don't bother with alignment check
    89 	asm("jc short memswap1");//
    90 	asm("mov edx,ecx");		// length into edx
    91 	// number of bytes to align aPtr1 = 4-(edi mod 4)
    92 	asm("mov ecx,4");		
    93 	asm("sub ecx,edi");		//
    94 	asm("and ecx,3");		// into ecx
    95 	asm("jz short memswap2");// if aligned, proceed with dword swap
    96 	asm("sub edx,ecx");		// subtract number of bytes from length
    97 	asm("memswap3:");
    98 	asm("mov al,[edi]");	// al = *aPtr1
    99 	asm("mov ah,[esi]");	// ah = *aPtr2
   100 	asm("mov [esi],al");	// *aPtr2=al
   101 	asm("mov [edi],ah");	// *aPtr1=ah
   102 	asm("inc esi");			// aPtr2++
   103 	asm("inc edi");			// aPtr1++
   104 	asm("dec ecx");			//
   105 	asm("jnz short memswap3");// loop ecx times - edi is now dword aligned
   106 	asm("memswap2:");
   107 	asm("push ebx");		// preserve ebx
   108 	asm("mov ecx,edx");		// length back into ecx
   109 	asm("mov ah,cl");		// save lower two bits of dword count in ah bits 3,2
   110 	asm("add ecx,12");		// divide dword count by 4, rounding to next higher integer
   111 	asm("shr ecx,4");		// this gives loop count for unfolded loop
   112 	asm("shl ah,4");		// lower two bits of dword count into ah bits 7,6
   113 	asm("sahf");			// and into SF,ZF
   114 	asm("jns short memswap8");// branch if lower two bits of dword count = 0 or 1
   115 	asm("jz short memswap5");// if lower two bits = 3, miss out first unfolding of loop
   116 	asm("jnz short memswap6");	// if lower two bits = 2, miss out first two unfoldings
   117 	asm("memswap8:");
   118 	asm("jz short memswap7");// if lower two bits = 1, miss out first three unfoldings
   119 	asm("memswap4:");
   120 	asm("mov eax,[edi]");	// eax = *aPtr1
   121 	asm("mov ebx,[esi]");	// ebx = *aPtr2
   122 	asm("mov [esi],eax");	// *aPtr2=eax
   123 	asm("mov [edi],ebx");	// *aPtr1=ebx
   124 	asm("add edi,4");		// aPtr1++
   125 	asm("add esi,4");		// aPtr2++
   126 	asm("memswap5:");
   127 	asm("mov eax,[edi]");	// eax = *aPtr1
   128 	asm("mov ebx,[esi]");	// ebx = *aPtr2
   129 	asm("mov [esi],eax");	// *aPtr2=eax
   130 	asm("mov [edi],ebx");	// *aPtr1=ebx
   131 	asm("add edi,4");		// aPtr1++
   132 	asm("add esi,4");		// aPtr2++
   133 	asm("memswap6:");
   134 	asm("mov eax,[edi]");	// eax = *aPtr1
   135 	asm("mov ebx,[esi]");	// ebx = *aPtr2
   136 	asm("mov [esi],eax");	// *aPtr2=eax
   137 	asm("mov [edi],ebx");	// *aPtr1=ebx
   138 	asm("add edi,4");		// aPtr1++
   139 	asm("add esi,4");		// aPtr2++
   140 	asm("memswap7:");
   141 	asm("mov eax,[edi]");	// eax = *aPtr1
   142 	asm("mov ebx,[esi]");	// ebx = *aPtr2
   143 	asm("mov [esi],eax");	// *aPtr2=eax
   144 	asm("mov [edi],ebx");	// *aPtr1=ebx
   145 	asm("add edi,4");		// aPtr1++
   146 	asm("add esi,4");		// aPtr2++
   147 	asm("dec ecx");
   148 	asm("jnz short memswap4");	// loop ecx times to do main part of swap
   149 	asm("mov ecx,edx");		// length back into ecx
   150 	asm("pop ebx");			// restore ebx
   151 	asm("and ecx,3");		// number of remaining bytes to move
   152 	asm("jz short memswap0");// if zero, we are finished
   153 	asm("memswap1:");		// *** come here for small swap
   154 	asm("mov al,[edi]");	// al = *aPtr1
   155 	asm("mov ah,[esi]");	// ah = *aPtr2
   156 	asm("mov [esi],al");	// *aPtr2=al
   157 	asm("mov [edi],ah");	// *aPtr1=ah
   158 	asm("inc esi");			// aPtr2++
   159 	asm("inc edi");			// aPtr1++
   160 	asm("dec ecx");			//
   161 	asm("jnz short memswap1");	// loop ecx times - edi is now dword aligned
   162 
   163 	asm("memswap0:");
   164 	asm("popfd");
   165 	asm("pop edi");
   166 	asm("pop esi");
   167 	asm("ret");
   168 	}
   169 #endif
   170 
   171 // Hash an 8 bit string at aPtr, length aLen bytes.
   172 __NAKED__ TUint32 DefaultStringHash(const TUint8* /*aPtr*/, TInt /*aLen*/)
   173 	{
   174 	asm("push esi");
   175 	asm("mov esi, [esp+8]");
   176 	asm("mov ecx, [esp+12]");
   177 	asm("xor eax, eax");
   178 	asm("sub ecx, 4");
   179 	asm("jb lt4");
   180 	asm("ge4:");
   181 	asm("xor eax, [esi]");
   182 	asm("add esi, 4");
   183 	asm("mov edx, 0x9E3779B9");
   184 	asm("mul edx");
   185 	asm("sub ecx, 4");
   186 	asm("jae ge4");
   187 	asm("lt4:");
   188 	asm("add ecx, 4");
   189 	asm("jz done");
   190 	asm("xor edx, edx");
   191 	asm("cmp ecx, 2");
   192 	asm("jbe le2");
   193 	asm("mov dl, [esi+2]");
   194 	asm("shl edx, 16");
   195 	asm("le2:");
   196 	asm("cmp ecx, 2");
   197 	asm("jb onemore");
   198 	asm("mov dh, [esi+1]");
   199 	asm("onemore:");
   200 	asm("mov dl, [esi]");
   201 	asm("xor eax, edx");
   202 	asm("mov edx, 0x9E3779B9");
   203 	asm("mul edx");
   204 	asm("done:");
   205 	asm("pop esi");
   206 	asm("ret");
   207 	}
   208 
   209 // Hash a 16 bit string at aPtr, length aLen bytes.
   210 __NAKED__ TUint32 DefaultWStringHash(const TUint16* /*aPtr*/, TInt /*aLen*/)
   211 	{
   212 	asm("push esi");
   213 	asm("mov esi, [esp+8]");
   214 	asm("mov ecx, [esp+12]");
   215 	asm("xor eax, eax");
   216 	asm("sub ecx, 8");
   217 	asm("jb lt8");
   218 	asm("ge8:");
   219 	asm("mov edx, [esi+4]");
   220 	asm("xor eax, [esi]");
   221 	asm("add esi, 8");
   222 	asm("rol edx, 8");
   223 	asm("xor eax, edx");
   224 	asm("mov edx, 0x9E3779B9");
   225 	asm("mul edx");
   226 	asm("sub ecx, 8");
   227 	asm("jae ge8");
   228 	asm("lt8:");
   229 	asm("add ecx, 8");
   230 	asm("jz done_defwstrhash");
   231 	asm("xor edx, edx");
   232 	asm("cmp ecx, 4");
   233 	asm("jbe le4");
   234 	asm("mov dx, [esi+4]");
   235 	asm("rol edx, 8");
   236 	asm("xor eax, edx");
   237 	asm("xor edx, edx");
   238 	asm("le4:");
   239 	asm("cmp ecx, 4");
   240 	asm("jb onemore_defwstrhash");
   241 	asm("mov dx, [esi+2]");
   242 	asm("shl edx, 16");
   243 	asm("onemore_defwstrhash:");
   244 	asm("mov dx, [esi]");
   245 	asm("xor eax, edx");
   246 	asm("mov edx, 0x9E3779B9");
   247 	asm("mul edx");
   248 	asm("done_defwstrhash:");
   249 	asm("pop esi");
   250 	asm("ret");
   251 	}
   252 
   253 
   254 /**
   255 @publishedAll
   256 @released
   257 
   258 Calculate a 32 bit hash from a 32 bit integer.
   259 
   260 @param	aInt	The integer to be hashed.
   261 @return			The calculated 32 bit hash value.
   262 */
   263 EXPORT_C __NAKED__ TUint32 DefaultHash::Integer(const TInt& /*aInt*/)
   264 	{
   265 	asm("mov edx, [esp+4]");
   266 	asm("mov eax, 0x9E3779B9");
   267 	asm("mul dword ptr [edx]");
   268 	asm("ret");
   269 	}
   270