]>
git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseMemoryLib/CopyMem.c
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
17 #include "MemLibInternals.h"
20 Copy Length bytes from Source to Destination.
22 @param DestinationBuffer The target of the copy request.
23 @param SourceBuffer The place to copy from.
24 @param Length The number of bytes to copy.
32 OUT VOID
*DestinationBuffer
,
33 IN CONST VOID
*SourceBuffer
,
38 // Declare the local variables that actually move the data elements as
39 // volatile to prevent the optimizer from replacing this function with
40 // the intrinsic memcpy()
42 volatile UINT8
*Destination8
;
44 volatile UINT32
*Destination32
;
45 CONST UINT32
*Source32
;
46 volatile UINT64
*Destination64
;
47 CONST UINT64
*Source64
;
50 if ((((UINTN
)DestinationBuffer
& 0x7) == 0) && (((UINTN
)SourceBuffer
& 0x7) == 0) && (Length
>= 8)) {
51 if (SourceBuffer
> DestinationBuffer
) {
52 Destination64
= (UINT64
*)DestinationBuffer
;
53 Source64
= (CONST UINT64
*)SourceBuffer
;
55 *(Destination64
++) = *(Source64
++);
59 // Finish if there are still some bytes to copy
60 Destination8
= (UINT8
*)Destination64
;
61 Source8
= (CONST UINT8
*)Source64
;
62 while (Length
-- != 0) {
63 *(Destination8
++) = *(Source8
++);
65 } else if (SourceBuffer
< DestinationBuffer
) {
66 Destination64
= (UINT64
*)((UINTN
)DestinationBuffer
+ Length
);
67 Source64
= (CONST UINT64
*)((UINTN
)SourceBuffer
+ Length
);
69 // Destination64 and Source64 were aligned on a 64-bit boundary
70 // but if length is not a multiple of 8 bytes then they won't be
73 Alignment
= Length
& 0x7;
75 Destination8
= (UINT8
*)Destination64
;
76 Source8
= (CONST UINT8
*)Source64
;
78 while (Alignment
-- != 0) {
79 *(--Destination8
) = *(--Source8
);
82 Destination64
= (UINT64
*)Destination8
;
83 Source64
= (CONST UINT64
*)Source8
;
87 *(--Destination64
) = *(--Source64
);
91 } else if ((((UINTN
)DestinationBuffer
& 0x3) == 0) && (((UINTN
)SourceBuffer
& 0x3) == 0) && (Length
>= 4)) {
92 if (SourceBuffer
> DestinationBuffer
) {
93 Destination32
= (UINT32
*)DestinationBuffer
;
94 Source32
= (CONST UINT32
*)SourceBuffer
;
96 *(Destination32
++) = *(Source32
++);
100 // Finish if there are still some bytes to copy
101 Destination8
= (UINT8
*)Destination32
;
102 Source8
= (CONST UINT8
*)Source32
;
103 while (Length
-- != 0) {
104 *(Destination8
++) = *(Source8
++);
106 } else if (SourceBuffer
< DestinationBuffer
) {
107 Destination32
= (UINT32
*)((UINTN
)DestinationBuffer
+ Length
);
108 Source32
= (CONST UINT32
*)((UINTN
)SourceBuffer
+ Length
);
110 // Destination32 and Source32 were aligned on a 32-bit boundary
111 // but if length is not a multiple of 4 bytes then they won't be
114 Alignment
= Length
& 0x3;
115 if (Alignment
!= 0) {
116 Destination8
= (UINT8
*)Destination32
;
117 Source8
= (CONST UINT8
*)Source32
;
119 while (Alignment
-- != 0) {
120 *(--Destination8
) = *(--Source8
);
123 Destination32
= (UINT32
*)Destination8
;
124 Source32
= (CONST UINT32
*)Source8
;
128 *(--Destination32
) = *(--Source32
);
133 if (SourceBuffer
> DestinationBuffer
) {
134 Destination8
= (UINT8
*)DestinationBuffer
;
135 Source8
= (CONST UINT8
*)SourceBuffer
;
136 while (Length
-- != 0) {
137 *(Destination8
++) = *(Source8
++);
139 } else if (SourceBuffer
< DestinationBuffer
) {
140 Destination8
= (UINT8
*)DestinationBuffer
+ (Length
- 1);
141 Source8
= (CONST UINT8
*)SourceBuffer
+ (Length
- 1);
142 while (Length
-- != 0) {
143 *(Destination8
--) = *(Source8
--);
147 return DestinationBuffer
;