]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPkg/Library/BaseMemoryLibStm/AArch64/CopyMem.c
BeagleBoardPkg: remove dependency on ArmPkg/BaseMemoryLibStm
[mirror_edk2.git] / ArmPkg / Library / BaseMemoryLibStm / AArch64 / CopyMem.c
CommitLineData
25402f5d
HL
1/** @file\r
2\r
3 Copyright (c) 2012-2013, ARM Ltd. All rights reserved.<BR>\r
4\r
5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "MemLibInternals.h"\r
16\r
17/**\r
18 Copy Length bytes from Source to Destination.\r
19\r
20 @param DestinationBuffer Target of copy\r
21 @param SourceBuffer Place to copy from\r
22 @param Length Number of bytes to copy\r
23\r
24 @return Destination\r
25\r
26**/\r
27VOID *\r
28EFIAPI\r
29InternalMemCopyMem (\r
30 OUT VOID *DestinationBuffer,\r
31 IN CONST VOID *SourceBuffer,\r
32 IN UINTN Length\r
33 )\r
34{\r
35 //\r
36 // Declare the local variables that actually move the data elements as\r
37 // volatile to prevent the optimizer from replacing this function with\r
38 // the intrinsic memcpy()\r
39 //\r
40 volatile UINT8 *Destination8;\r
41 CONST UINT8 *Source8;\r
42 volatile UINT32 *Destination32;\r
43 CONST UINT32 *Source32;\r
44 volatile UINT64 *Destination64;\r
45 CONST UINT64 *Source64;\r
46 UINTN Alignment;\r
47\r
48 if ((((UINTN)DestinationBuffer & 0x7) == 0) && (((UINTN)SourceBuffer & 0x7) == 0) && (Length >= 8)) {\r
49 if (SourceBuffer > DestinationBuffer) {\r
50 Destination64 = (UINT64*)DestinationBuffer;\r
51 Source64 = (CONST UINT64*)SourceBuffer;\r
52 while (Length >= 8) {\r
53 *(Destination64++) = *(Source64++);\r
54 Length -= 8;\r
55 }\r
56\r
57 // Finish if there are still some bytes to copy\r
58 Destination8 = (UINT8*)Destination64;\r
59 Source8 = (CONST UINT8*)Source64;\r
60 while (Length-- != 0) {\r
61 *(Destination8++) = *(Source8++);\r
62 }\r
63 } else if (SourceBuffer < DestinationBuffer) {\r
64 Destination64 = (UINT64*)((UINTN)DestinationBuffer + Length);\r
65 Source64 = (CONST UINT64*)((UINTN)SourceBuffer + Length);\r
66\r
67 // Destination64 and Source64 were aligned on a 64-bit boundary\r
68 // but if length is not a multiple of 8 bytes then they won't be\r
69 // anymore.\r
70\r
71 Alignment = Length & 0x7;\r
72 if (Alignment != 0) {\r
73 Destination8 = (UINT8*)Destination64;\r
74 Source8 = (CONST UINT8*)Source64;\r
75\r
76 while (Alignment-- != 0) {\r
77 *(--Destination8) = *(--Source8);\r
78 --Length;\r
79 }\r
80 Destination64 = (UINT64*)Destination8;\r
81 Source64 = (CONST UINT64*)Source8;\r
82 }\r
83\r
84 while (Length > 0) {\r
85 *(--Destination64) = *(--Source64);\r
86 Length -= 8;\r
87 }\r
88 }\r
89 } else if ((((UINTN)DestinationBuffer & 0x3) == 0) && (((UINTN)SourceBuffer & 0x3) == 0) && (Length >= 4)) {\r
90 if (SourceBuffer > DestinationBuffer) {\r
91 Destination32 = (UINT32*)DestinationBuffer;\r
92 Source32 = (CONST UINT32*)SourceBuffer;\r
93 while (Length >= 4) {\r
94 *(Destination32++) = *(Source32++);\r
95 Length -= 4;\r
96 }\r
97\r
98 // Finish if there are still some bytes to copy\r
99 Destination8 = (UINT8*)Destination32;\r
100 Source8 = (CONST UINT8*)Source32;\r
101 while (Length-- != 0) {\r
102 *(Destination8++) = *(Source8++);\r
103 }\r
104 } else if (SourceBuffer < DestinationBuffer) {\r
105 Destination32 = (UINT32*)((UINTN)DestinationBuffer + Length);\r
106 Source32 = (CONST UINT32*)((UINTN)SourceBuffer + Length);\r
107\r
108 // Destination32 and Source32 were aligned on a 32-bit boundary\r
109 // but if length is not a multiple of 4 bytes then they won't be\r
110 // anymore.\r
111\r
112 Alignment = Length & 0x3;\r
113 if (Alignment != 0) {\r
114 Destination8 = (UINT8*)Destination32;\r
115 Source8 = (CONST UINT8*)Source32;\r
116\r
117 while (Alignment-- != 0) {\r
118 *(--Destination8) = *(--Source8);\r
119 --Length;\r
120 }\r
121 Destination32 = (UINT32*)Destination8;\r
122 Source32 = (CONST UINT32*)Source8;\r
123 }\r
124\r
125 while (Length > 0) {\r
126 *(--Destination32) = *(--Source32);\r
127 Length -= 4;\r
128 }\r
129 }\r
130 } else {\r
131 if (SourceBuffer > DestinationBuffer) {\r
132 Destination8 = (UINT8*)DestinationBuffer;\r
133 Source8 = (CONST UINT8*)SourceBuffer;\r
134 while (Length-- != 0) {\r
135 *(Destination8++) = *(Source8++);\r
136 }\r
137 } else if (SourceBuffer < DestinationBuffer) {\r
138 Destination8 = (UINT8*)DestinationBuffer + Length;\r
139 Source8 = (CONST UINT8*)SourceBuffer + Length;\r
140 while (Length-- != 0) {\r
141 *(--Destination8) = *(--Source8);\r
142 }\r
143 }\r
144 }\r
145 return DestinationBuffer;\r
146}\r