1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kernel/eka/euser/epoc/x86/uc_utl.cia Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,270 @@
1.4 +// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32\euser\epoc\x86\uc_utl.cia
1.18 +//
1.19 +//
1.20 +
1.21 +#include <u32exec.h>
1.22 +#include <e32base.h>
1.23 +#include <e32rom.h>
1.24 +#include <e32svr.h>
1.25 +#include <e32hashtab.h>
1.26 +
1.27 +
1.28 +// Dummy so we can use same DEF file as WINS
1.29 +EXPORT_C void BootEpoc(TBool)
1.30 + {
1.31 + }
1.32 +
1.33 +
1.34 +EXPORT_C __NAKED__ void RFastLock::Wait()
1.35 + {
1.36 + THISCALL_PROLOG0()
1.37 + asm("lock sub dword ptr [ecx+4], 1");
1.38 + asm("jnc fast_lock_wait_sem");
1.39 + THISCALL_EPILOG0()
1.40 + asm("fast_lock_wait_sem:");
1.41 + asm("mov eax, %0": : "i"(EExecSemaphoreWait));
1.42 + asm("mov ecx, [ecx]");
1.43 + asm("xor edx, edx");
1.44 + asm("int 0x21");
1.45 + THISCALL_EPILOG0()
1.46 + }
1.47 +
1.48 +EXPORT_C __NAKED__ void RFastLock::Signal()
1.49 + {
1.50 + THISCALL_PROLOG0()
1.51 + asm("lock add dword ptr [ecx+4], 1");
1.52 + asm("jne fast_lock_signal_sem");
1.53 + THISCALL_EPILOG0()
1.54 + asm("fast_lock_signal_sem:");
1.55 + asm("mov eax, %0": : "i"(EExecSemaphoreSignal1));
1.56 + asm("mov ecx, [ecx]");
1.57 + asm("int 0x21");
1.58 + THISCALL_EPILOG0()
1.59 + }
1.60 +
1.61 +#ifdef __MEM_MACHINE_CODED__
1.62 +__NAKED__ EXPORT_C void Mem::Swap( TAny* /*aPtr1*/, TAny* /*aPtr2*/, TInt /*aLength*/ )
1.63 +/**
1.64 +Swaps a number of bytes of data between two specified locations.
1.65 +
1.66 +The source and target areas can overlap.
1.67 +
1.68 +@param aPtr1 A pointer to the first location taking part in the swap.
1.69 +@param aPtr2 A pointer to second location taking part in the swap.
1.70 +@param aLength The number of bytes to be swapped between the two locations.
1.71 + This value must not be negative.
1.72 +
1.73 +@panic USER 94 In debug builds only, if aLength is negative.
1.74 +*/
1.75 +
1.76 +//
1.77 +// Swap the contents of *aPtr1 with *aPtr2.
1.78 +// NB We assume ES=DS on entry.
1.79 +//
1.80 + {
1.81 + asm("push esi");
1.82 + asm("push edi");
1.83 + asm("mov edi,[esp+12]");// aPtr1 address into edi
1.84 + asm("mov esi,[esp+16]");// aPtr2 address into esi
1.85 + asm("mov ecx,[esp+20]");// byte count into ecx
1.86 + asm("pushfd");
1.87 +
1.88 + asm("test ecx,ecx"); //
1.89 + asm("jz short memswap0");// if length=0, nothing to do
1.90 + asm("cld"); // go forwards through array
1.91 + asm("cmp ecx,7"); // if length<7 don't bother with alignment check
1.92 + asm("jc short memswap1");//
1.93 + asm("mov edx,ecx"); // length into edx
1.94 + // number of bytes to align aPtr1 = 4-(edi mod 4)
1.95 + asm("mov ecx,4");
1.96 + asm("sub ecx,edi"); //
1.97 + asm("and ecx,3"); // into ecx
1.98 + asm("jz short memswap2");// if aligned, proceed with dword swap
1.99 + asm("sub edx,ecx"); // subtract number of bytes from length
1.100 + asm("memswap3:");
1.101 + asm("mov al,[edi]"); // al = *aPtr1
1.102 + asm("mov ah,[esi]"); // ah = *aPtr2
1.103 + asm("mov [esi],al"); // *aPtr2=al
1.104 + asm("mov [edi],ah"); // *aPtr1=ah
1.105 + asm("inc esi"); // aPtr2++
1.106 + asm("inc edi"); // aPtr1++
1.107 + asm("dec ecx"); //
1.108 + asm("jnz short memswap3");// loop ecx times - edi is now dword aligned
1.109 + asm("memswap2:");
1.110 + asm("push ebx"); // preserve ebx
1.111 + asm("mov ecx,edx"); // length back into ecx
1.112 + asm("mov ah,cl"); // save lower two bits of dword count in ah bits 3,2
1.113 + asm("add ecx,12"); // divide dword count by 4, rounding to next higher integer
1.114 + asm("shr ecx,4"); // this gives loop count for unfolded loop
1.115 + asm("shl ah,4"); // lower two bits of dword count into ah bits 7,6
1.116 + asm("sahf"); // and into SF,ZF
1.117 + asm("jns short memswap8");// branch if lower two bits of dword count = 0 or 1
1.118 + asm("jz short memswap5");// if lower two bits = 3, miss out first unfolding of loop
1.119 + asm("jnz short memswap6"); // if lower two bits = 2, miss out first two unfoldings
1.120 + asm("memswap8:");
1.121 + asm("jz short memswap7");// if lower two bits = 1, miss out first three unfoldings
1.122 + asm("memswap4:");
1.123 + asm("mov eax,[edi]"); // eax = *aPtr1
1.124 + asm("mov ebx,[esi]"); // ebx = *aPtr2
1.125 + asm("mov [esi],eax"); // *aPtr2=eax
1.126 + asm("mov [edi],ebx"); // *aPtr1=ebx
1.127 + asm("add edi,4"); // aPtr1++
1.128 + asm("add esi,4"); // aPtr2++
1.129 + asm("memswap5:");
1.130 + asm("mov eax,[edi]"); // eax = *aPtr1
1.131 + asm("mov ebx,[esi]"); // ebx = *aPtr2
1.132 + asm("mov [esi],eax"); // *aPtr2=eax
1.133 + asm("mov [edi],ebx"); // *aPtr1=ebx
1.134 + asm("add edi,4"); // aPtr1++
1.135 + asm("add esi,4"); // aPtr2++
1.136 + asm("memswap6:");
1.137 + asm("mov eax,[edi]"); // eax = *aPtr1
1.138 + asm("mov ebx,[esi]"); // ebx = *aPtr2
1.139 + asm("mov [esi],eax"); // *aPtr2=eax
1.140 + asm("mov [edi],ebx"); // *aPtr1=ebx
1.141 + asm("add edi,4"); // aPtr1++
1.142 + asm("add esi,4"); // aPtr2++
1.143 + asm("memswap7:");
1.144 + asm("mov eax,[edi]"); // eax = *aPtr1
1.145 + asm("mov ebx,[esi]"); // ebx = *aPtr2
1.146 + asm("mov [esi],eax"); // *aPtr2=eax
1.147 + asm("mov [edi],ebx"); // *aPtr1=ebx
1.148 + asm("add edi,4"); // aPtr1++
1.149 + asm("add esi,4"); // aPtr2++
1.150 + asm("dec ecx");
1.151 + asm("jnz short memswap4"); // loop ecx times to do main part of swap
1.152 + asm("mov ecx,edx"); // length back into ecx
1.153 + asm("pop ebx"); // restore ebx
1.154 + asm("and ecx,3"); // number of remaining bytes to move
1.155 + asm("jz short memswap0");// if zero, we are finished
1.156 + asm("memswap1:"); // *** come here for small swap
1.157 + asm("mov al,[edi]"); // al = *aPtr1
1.158 + asm("mov ah,[esi]"); // ah = *aPtr2
1.159 + asm("mov [esi],al"); // *aPtr2=al
1.160 + asm("mov [edi],ah"); // *aPtr1=ah
1.161 + asm("inc esi"); // aPtr2++
1.162 + asm("inc edi"); // aPtr1++
1.163 + asm("dec ecx"); //
1.164 + asm("jnz short memswap1"); // loop ecx times - edi is now dword aligned
1.165 +
1.166 + asm("memswap0:");
1.167 + asm("popfd");
1.168 + asm("pop edi");
1.169 + asm("pop esi");
1.170 + asm("ret");
1.171 + }
1.172 +#endif
1.173 +
1.174 +// Hash an 8 bit string at aPtr, length aLen bytes.
1.175 +__NAKED__ TUint32 DefaultStringHash(const TUint8* /*aPtr*/, TInt /*aLen*/)
1.176 + {
1.177 + asm("push esi");
1.178 + asm("mov esi, [esp+8]");
1.179 + asm("mov ecx, [esp+12]");
1.180 + asm("xor eax, eax");
1.181 + asm("sub ecx, 4");
1.182 + asm("jb lt4");
1.183 + asm("ge4:");
1.184 + asm("xor eax, [esi]");
1.185 + asm("add esi, 4");
1.186 + asm("mov edx, 0x9E3779B9");
1.187 + asm("mul edx");
1.188 + asm("sub ecx, 4");
1.189 + asm("jae ge4");
1.190 + asm("lt4:");
1.191 + asm("add ecx, 4");
1.192 + asm("jz done");
1.193 + asm("xor edx, edx");
1.194 + asm("cmp ecx, 2");
1.195 + asm("jbe le2");
1.196 + asm("mov dl, [esi+2]");
1.197 + asm("shl edx, 16");
1.198 + asm("le2:");
1.199 + asm("cmp ecx, 2");
1.200 + asm("jb onemore");
1.201 + asm("mov dh, [esi+1]");
1.202 + asm("onemore:");
1.203 + asm("mov dl, [esi]");
1.204 + asm("xor eax, edx");
1.205 + asm("mov edx, 0x9E3779B9");
1.206 + asm("mul edx");
1.207 + asm("done:");
1.208 + asm("pop esi");
1.209 + asm("ret");
1.210 + }
1.211 +
1.212 +// Hash a 16 bit string at aPtr, length aLen bytes.
1.213 +__NAKED__ TUint32 DefaultWStringHash(const TUint16* /*aPtr*/, TInt /*aLen*/)
1.214 + {
1.215 + asm("push esi");
1.216 + asm("mov esi, [esp+8]");
1.217 + asm("mov ecx, [esp+12]");
1.218 + asm("xor eax, eax");
1.219 + asm("sub ecx, 8");
1.220 + asm("jb lt8");
1.221 + asm("ge8:");
1.222 + asm("mov edx, [esi+4]");
1.223 + asm("xor eax, [esi]");
1.224 + asm("add esi, 8");
1.225 + asm("rol edx, 8");
1.226 + asm("xor eax, edx");
1.227 + asm("mov edx, 0x9E3779B9");
1.228 + asm("mul edx");
1.229 + asm("sub ecx, 8");
1.230 + asm("jae ge8");
1.231 + asm("lt8:");
1.232 + asm("add ecx, 8");
1.233 + asm("jz done_defwstrhash");
1.234 + asm("xor edx, edx");
1.235 + asm("cmp ecx, 4");
1.236 + asm("jbe le4");
1.237 + asm("mov dx, [esi+4]");
1.238 + asm("rol edx, 8");
1.239 + asm("xor eax, edx");
1.240 + asm("xor edx, edx");
1.241 + asm("le4:");
1.242 + asm("cmp ecx, 4");
1.243 + asm("jb onemore_defwstrhash");
1.244 + asm("mov dx, [esi+2]");
1.245 + asm("shl edx, 16");
1.246 + asm("onemore_defwstrhash:");
1.247 + asm("mov dx, [esi]");
1.248 + asm("xor eax, edx");
1.249 + asm("mov edx, 0x9E3779B9");
1.250 + asm("mul edx");
1.251 + asm("done_defwstrhash:");
1.252 + asm("pop esi");
1.253 + asm("ret");
1.254 + }
1.255 +
1.256 +
1.257 +/**
1.258 +@publishedAll
1.259 +@released
1.260 +
1.261 +Calculate a 32 bit hash from a 32 bit integer.
1.262 +
1.263 +@param aInt The integer to be hashed.
1.264 +@return The calculated 32 bit hash value.
1.265 +*/
1.266 +EXPORT_C __NAKED__ TUint32 DefaultHash::Integer(const TInt& /*aInt*/)
1.267 + {
1.268 + asm("mov edx, [esp+4]");
1.269 + asm("mov eax, 0x9E3779B9");
1.270 + asm("mul dword ptr [edx]");
1.271 + asm("ret");
1.272 + }
1.273 +