|
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__) |