TianoCore EDK2 master
Loading...
Searching...
No Matches
CopyMem.c
Go to the documentation of this file.
1
14#include "MemLibInternals.h"
15
26VOID *
27EFIAPI
29 OUT VOID *DestinationBuffer,
30 IN CONST VOID *SourceBuffer,
31 IN UINTN Length
32 )
33{
34 //
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()
38 //
39 volatile UINT8 *Destination8;
40 CONST UINT8 *Source8;
41 volatile UINT32 *Destination32;
42 CONST UINT32 *Source32;
43 volatile UINT64 *Destination64;
44 CONST UINT64 *Source64;
45 UINTN Alignment;
46
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;
51 while (Length >= 8) {
52 *(Destination64++) = *(Source64++);
53 Length -= 8;
54 }
55
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++);
61 }
62 } else if (SourceBuffer < DestinationBuffer) {
63 Destination64 = (UINT64 *)((UINTN)DestinationBuffer + Length);
64 Source64 = (CONST UINT64 *)((UINTN)SourceBuffer + Length);
65
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
68 // anymore.
69
70 Alignment = Length & 0x7;
71 if (Alignment != 0) {
72 Destination8 = (UINT8 *)Destination64;
73 Source8 = (CONST UINT8 *)Source64;
74
75 while (Alignment-- != 0) {
76 *(--Destination8) = *(--Source8);
77 --Length;
78 }
79
80 Destination64 = (UINT64 *)Destination8;
81 Source64 = (CONST UINT64 *)Source8;
82 }
83
84 while (Length > 0) {
85 *(--Destination64) = *(--Source64);
86 Length -= 8;
87 }
88 }
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;
93 while (Length >= 4) {
94 *(Destination32++) = *(Source32++);
95 Length -= 4;
96 }
97
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++);
103 }
104 } else if (SourceBuffer < DestinationBuffer) {
105 Destination32 = (UINT32 *)((UINTN)DestinationBuffer + Length);
106 Source32 = (CONST UINT32 *)((UINTN)SourceBuffer + Length);
107
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
110 // anymore.
111
112 Alignment = Length & 0x3;
113 if (Alignment != 0) {
114 Destination8 = (UINT8 *)Destination32;
115 Source8 = (CONST UINT8 *)Source32;
116
117 while (Alignment-- != 0) {
118 *(--Destination8) = *(--Source8);
119 --Length;
120 }
121
122 Destination32 = (UINT32 *)Destination8;
123 Source32 = (CONST UINT32 *)Source8;
124 }
125
126 while (Length > 0) {
127 *(--Destination32) = *(--Source32);
128 Length -= 4;
129 }
130 }
131 } else {
132 if (SourceBuffer > DestinationBuffer) {
133 Destination8 = (UINT8 *)DestinationBuffer;
134 Source8 = (CONST UINT8 *)SourceBuffer;
135 while (Length-- != 0) {
136 *(Destination8++) = *(Source8++);
137 }
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--);
143 }
144 }
145 }
146
147 return DestinationBuffer;
148}
UINT64 UINTN
#define CONST
Definition: Base.h:259
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
VOID *EFIAPI InternalMemCopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
Definition: CopyMem.c:28