231
|
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\common\win32\cmem.cpp
|
|
15 |
//
|
|
16 |
//
|
|
17 |
|
|
18 |
#include "common.h"
|
|
19 |
|
|
20 |
#ifdef __MEMMOVE_MACHINE_CODED__
|
|
21 |
|
|
22 |
extern "C" {
|
|
23 |
|
|
24 |
// See header file e32cmn.h for the in-source documentation.
|
|
25 |
EXPORT_C __NAKED__ TAny* memmove(TAny* , const TAny* , unsigned int)
|
|
26 |
{
|
|
27 |
_asm push ebx ; // Save used registers
|
|
28 |
_asm push esi
|
|
29 |
_asm push edi
|
|
30 |
_asm push ebp
|
|
31 |
|
|
32 |
_asm cmp dword ptr [esp+0x1c],0x0 ; // Is aLength == 0?
|
|
33 |
_asm mov eax,dword ptr [esp+0x14] ; // Ptr to destination
|
|
34 |
_asm mov ebx,dword ptr [esp+0x18] ; // Ptr to source
|
|
35 |
_asm je End ; // aLength is 0, just return
|
|
36 |
|
|
37 |
_asm mov ecx,eax ; // Copy destination
|
|
38 |
_asm xor ebp,ebp ; // ebp = 0
|
|
39 |
_asm test ecx,0x3 ; // Dest word aligned?
|
|
40 |
_asm mov edx,ebx ; // Copy ptr to source
|
|
41 |
_asm jne Misaligned ; // No
|
|
42 |
_asm test edx,0x3 ; // Source word aligned?
|
|
43 |
_asm jne Misaligned ; // No
|
|
44 |
_asm mov ebp,dword ptr [esp+0x1c] ; // ebp = aLength
|
|
45 |
_asm shr ebp,0x2 ; // ebp = aLength in words
|
|
46 |
|
|
47 |
Misaligned:
|
|
48 |
|
|
49 |
_asm lea edx,dword ptr [ebp*4+0x0] ; // edx = aLength in words
|
|
50 |
_asm sal ebp,0x2 ; // ebp = aLength in bytes
|
|
51 |
_asm add ebp,ecx ; // Point to end of destination
|
|
52 |
_asm mov edi,dword ptr [esp+0x1c] ; // Get number of bytes to copy
|
|
53 |
_asm sub edi,edx ; // Find remainder (aLength % 3)
|
|
54 |
_asm cmp eax,ebx ; // Dest >= source?
|
|
55 |
_asm mov edx,ebp ; // Ptr to end of destination
|
|
56 |
_asm jae DoDescendingCopy ; // Yes, copy downwards
|
|
57 |
|
|
58 |
_asm jmp AscendingCopy ; // No, copy upwards
|
|
59 |
|
|
60 |
AscendingCopyLoop:
|
|
61 |
|
|
62 |
_asm mov ebp,dword ptr [ebx] ; // Get a word
|
|
63 |
_asm mov dword ptr [ecx],ebp ; // And store it
|
|
64 |
_asm add ebx,0x4 ; // Increment source by a word
|
|
65 |
_asm add ecx,0x4 ; // Increment destination by a word
|
|
66 |
|
|
67 |
AscendingCopy:
|
|
68 |
|
|
69 |
_asm cmp ecx,edx ; // Still data to copy?
|
|
70 |
_asm jb AscendingCopyLoop ; // Yes
|
|
71 |
|
|
72 |
_asm mov ebp,eax ; // Copy ptr to destination
|
|
73 |
_asm add ebp,dword ptr [esp+0x1c] ; // Point to end of destination
|
|
74 |
_asm jmp CopyRemainder ; // Copy left over (aLength % 3) bytes
|
|
75 |
|
|
76 |
CopyRemainderLoop:
|
|
77 |
|
|
78 |
_asm movzx edx,byte ptr [ebx] ; // Get a byte
|
|
79 |
_asm mov byte ptr [ecx],dl ; // And store it
|
|
80 |
_asm inc ebx ; // Increment source by a byte
|
|
81 |
_asm inc ecx ; // Increment destination by a byte
|
|
82 |
|
|
83 |
CopyRemainder:
|
|
84 |
|
|
85 |
_asm cmp ecx,ebp ; // Any remaining bytes to copy?
|
|
86 |
_asm jb CopyRemainderLoop ; // Yes, go do it
|
|
87 |
|
|
88 |
_asm jmp End ; // All done
|
|
89 |
|
|
90 |
DoDescendingCopy:
|
|
91 |
|
|
92 |
_asm cmp eax,ebx ; // Still data to copy?
|
|
93 |
_asm jbe End ; // No, all done
|
|
94 |
|
|
95 |
_asm lea esi,dword ptr [edi+ebp] ; // Get ptr to end of destination
|
|
96 |
_asm mov edi,ebx ; // Get ptr to source
|
|
97 |
_asm add edi,dword ptr [esp+0x1c] ; // Point to end of source
|
|
98 |
_asm jmp DescendingCopyRemainder ; // Copy copy some data
|
|
99 |
|
|
100 |
DescendingCopyRemainderLoop:
|
|
101 |
|
|
102 |
_asm dec edi ; // Decrement source by a byte
|
|
103 |
_asm dec esi ; // Decrement dest by a byte
|
|
104 |
_asm movzx ebx,byte ptr [edi] ; // Get a byte
|
|
105 |
_asm mov byte ptr [esi],bl ; // And store it
|
|
106 |
|
|
107 |
DescendingCopyRemainder:
|
|
108 |
|
|
109 |
_asm cmp esi,ebp ; // Still data to copy?
|
|
110 |
_asm ja DescendingCopyRemainderLoop ; // Yes, go do it
|
|
111 |
|
|
112 |
_asm jmp DescendingCopy ; // Go copy the bulk of the data
|
|
113 |
|
|
114 |
DescendingCopyLoop:
|
|
115 |
|
|
116 |
_asm sub edi,0x4 ; // Decrement source by a word
|
|
117 |
_asm sub edx,0x4 ; // Decrement dest by a word
|
|
118 |
_asm mov ebx,dword ptr [edi] ; // Get a word
|
|
119 |
_asm mov dword ptr [edx],ebx ; // And store it
|
|
120 |
|
|
121 |
DescendingCopy:
|
|
122 |
|
|
123 |
_asm cmp edx,ecx ; // Still data to copy
|
|
124 |
_asm ja DescendingCopyLoop ; // Yes, go do it
|
|
125 |
|
|
126 |
End:
|
|
127 |
|
|
128 |
_asm pop ebp ; // Restore used registers
|
|
129 |
_asm pop edi
|
|
130 |
_asm pop esi
|
|
131 |
_asm pop ebx
|
|
132 |
_asm ret
|
|
133 |
}
|
|
134 |
|
|
135 |
// See header file e32cmn.h for the in-source documentation.
|
|
136 |
EXPORT_C __NAKED__ TAny* memcpy(TAny* , const TAny* , unsigned int)
|
|
137 |
{
|
|
138 |
__asm jmp (memmove); ; // memmove() will perform the same function
|
|
139 |
}
|
|
140 |
}
|
|
141 |
|
|
142 |
#endif // defined(__MEMMOVE_MACHINE_CODED__)
|