symport/e32/euser/epoc/x86/uc_utl.cia
changeset 1 0a7b44b10206
child 2 806186ab5e14
equal deleted inserted replaced
0:c55016431358 1:0a7b44b10206
       
     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 "Symbian Foundation License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.symbianfoundation.org/legal/sfl-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