]>
git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseMemoryLib/CopyMem.c
929f7007478fe13a743f7cf1d5198ed00fba20c7
2 Implementation of the InternalMemCopyMem routine. This function is broken
3 out into its own source file so that it can be excluded from a build for a
4 particular platform easily if an optimized version is desired.
6 Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
7 Copyright (c) 2012 - 2013, ARM Ltd. All rights reserved.<BR>
8 Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
10 SPDX-License-Identifier: BSD-2-Clause-Patent
14 #include "MemLibInternals.h"
17 Copy Length bytes from Source to Destination.
19 @param DestinationBuffer The target of the copy request.
20 @param SourceBuffer The place to copy from.
21 @param Length The number of bytes to copy.
29 OUT VOID
*DestinationBuffer
,
30 IN CONST VOID
*SourceBuffer
,
35 // Declare the local variables that actually move the data elements as
36 // volatile to prevent the optimizer from replacing this function with
37 // the intrinsic memcpy()
39 volatile UINT8
*Destination8
;
41 volatile UINT32
*Destination32
;
42 CONST UINT32
*Source32
;
43 volatile UINT64
*Destination64
;
44 CONST UINT64
*Source64
;
47 if ((((UINTN
)DestinationBuffer
& 0x7) == 0) && (((UINTN
)SourceBuffer
& 0x7) == 0) && (Length
>= 8)) {
48 if (SourceBuffer
> DestinationBuffer
) {
49 Destination64
= (UINT64
*)DestinationBuffer
;
50 Source64
= (CONST UINT64
*)SourceBuffer
;
52 *(Destination64
++) = *(Source64
++);
56 // Finish if there are still some bytes to copy
57 Destination8
= (UINT8
*)Destination64
;
58 Source8
= (CONST UINT8
*)Source64
;
59 while (Length
-- != 0) {
60 *(Destination8
++) = *(Source8
++);
62 } else if (SourceBuffer
< DestinationBuffer
) {
63 Destination64
= (UINT64
*)((UINTN
)DestinationBuffer
+ Length
);
64 Source64
= (CONST UINT64
*)((UINTN
)SourceBuffer
+ Length
);
66 // Destination64 and Source64 were aligned on a 64-bit boundary
67 // but if length is not a multiple of 8 bytes then they won't be
70 Alignment
= Length
& 0x7;
72 Destination8
= (UINT8
*)Destination64
;
73 Source8
= (CONST UINT8
*)Source64
;
75 while (Alignment
-- != 0) {
76 *(--Destination8
) = *(--Source8
);
80 Destination64
= (UINT64
*)Destination8
;
81 Source64
= (CONST UINT64
*)Source8
;
85 *(--Destination64
) = *(--Source64
);
89 } else if ((((UINTN
)DestinationBuffer
& 0x3) == 0) && (((UINTN
)SourceBuffer
& 0x3) == 0) && (Length
>= 4)) {
90 if (SourceBuffer
> DestinationBuffer
) {
91 Destination32
= (UINT32
*)DestinationBuffer
;
92 Source32
= (CONST UINT32
*)SourceBuffer
;
94 *(Destination32
++) = *(Source32
++);
98 // Finish if there are still some bytes to copy
99 Destination8
= (UINT8
*)Destination32
;
100 Source8
= (CONST UINT8
*)Source32
;
101 while (Length
-- != 0) {
102 *(Destination8
++) = *(Source8
++);
104 } else if (SourceBuffer
< DestinationBuffer
) {
105 Destination32
= (UINT32
*)((UINTN
)DestinationBuffer
+ Length
);
106 Source32
= (CONST UINT32
*)((UINTN
)SourceBuffer
+ Length
);
108 // Destination32 and Source32 were aligned on a 32-bit boundary
109 // but if length is not a multiple of 4 bytes then they won't be
112 Alignment
= Length
& 0x3;
113 if (Alignment
!= 0) {
114 Destination8
= (UINT8
*)Destination32
;
115 Source8
= (CONST UINT8
*)Source32
;
117 while (Alignment
-- != 0) {
118 *(--Destination8
) = *(--Source8
);
122 Destination32
= (UINT32
*)Destination8
;
123 Source32
= (CONST UINT32
*)Source8
;
127 *(--Destination32
) = *(--Source32
);
132 if (SourceBuffer
> DestinationBuffer
) {
133 Destination8
= (UINT8
*)DestinationBuffer
;
134 Source8
= (CONST UINT8
*)SourceBuffer
;
135 while (Length
-- != 0) {
136 *(Destination8
++) = *(Source8
++);
138 } else if (SourceBuffer
< DestinationBuffer
) {
139 Destination8
= (UINT8
*)DestinationBuffer
+ (Length
- 1);
140 Source8
= (CONST UINT8
*)SourceBuffer
+ (Length
- 1);
141 while (Length
-- != 0) {
142 *(Destination8
--) = *(Source8
--);
147 return DestinationBuffer
;