]>
git.proxmox.com Git - mirror_edk2.git/blob - ArmPkg/Library/BaseMemoryLibStm/AArch64/CopyMem.c
3 Copyright (c) 2012-2013, ARM Ltd. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "MemLibInternals.h"
18 Copy Length bytes from Source to Destination.
20 @param DestinationBuffer Target of copy
21 @param SourceBuffer Place to copy from
22 @param Length Number of bytes to copy
30 OUT VOID
*DestinationBuffer
,
31 IN CONST VOID
*SourceBuffer
,
36 // Declare the local variables that actually move the data elements as
37 // volatile to prevent the optimizer from replacing this function with
38 // the intrinsic memcpy()
40 volatile UINT8
*Destination8
;
42 volatile UINT32
*Destination32
;
43 CONST UINT32
*Source32
;
44 volatile UINT64
*Destination64
;
45 CONST UINT64
*Source64
;
48 if ((((UINTN
)DestinationBuffer
& 0x7) == 0) && (((UINTN
)SourceBuffer
& 0x7) == 0) && (Length
>= 8)) {
49 if (SourceBuffer
> DestinationBuffer
) {
50 Destination64
= (UINT64
*)DestinationBuffer
;
51 Source64
= (CONST UINT64
*)SourceBuffer
;
53 *(Destination64
++) = *(Source64
++);
57 // Finish if there are still some bytes to copy
58 Destination8
= (UINT8
*)Destination64
;
59 Source8
= (CONST UINT8
*)Source64
;
60 while (Length
-- != 0) {
61 *(Destination8
++) = *(Source8
++);
63 } else if (SourceBuffer
< DestinationBuffer
) {
64 Destination64
= (UINT64
*)((UINTN
)DestinationBuffer
+ Length
);
65 Source64
= (CONST UINT64
*)((UINTN
)SourceBuffer
+ Length
);
67 // Destination64 and Source64 were aligned on a 64-bit boundary
68 // but if length is not a multiple of 8 bytes then they won't be
71 Alignment
= Length
& 0x7;
73 Destination8
= (UINT8
*)Destination64
;
74 Source8
= (CONST UINT8
*)Source64
;
76 while (Alignment
-- != 0) {
77 *(--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
);
121 Destination32
= (UINT32
*)Destination8
;
122 Source32
= (CONST UINT32
*)Source8
;
126 *(--Destination32
) = *(--Source32
);
131 if (SourceBuffer
> DestinationBuffer
) {
132 Destination8
= (UINT8
*)DestinationBuffer
;
133 Source8
= (CONST UINT8
*)SourceBuffer
;
134 while (Length
-- != 0) {
135 *(Destination8
++) = *(Source8
++);
137 } else if (SourceBuffer
< DestinationBuffer
) {
138 Destination8
= (UINT8
*)DestinationBuffer
+ Length
;
139 Source8
= (CONST UINT8
*)SourceBuffer
+ Length
;
140 while (Length
-- != 0) {
141 *(--Destination8
) = *(--Source8
);
145 return DestinationBuffer
;