]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseMemoryLibOptDxe/Arm/CopyMem.asm
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdePkg / Library / BaseMemoryLibOptDxe / Arm / CopyMem.asm
1 ;------------------------------------------------------------------------------
2 ;
3 ; CopyMem() worker for ARM
4 ;
5 ; This file started out as C code that did 64 bit moves if the buffer was
6 ; 32-bit aligned, else it does a byte copy. It also does a byte copy for
7 ; any trailing bytes. It was updated to do 32-byte copies using stm/ldm.
8 ;
9 ; Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
10 ; Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
11 ; SPDX-License-Identifier: BSD-2-Clause-Patent
12 ;
13 ;------------------------------------------------------------------------------
14
15 EXPORT InternalMemCopyMem
16 AREA SetMem, CODE, READONLY
17 THUMB
18
19 InternalMemCopyMem
20 stmfd sp!, {r4-r11, lr}
21 // Save the input parameters in extra registers (r11 = destination, r14 = source, r12 = length)
22 mov r11, r0
23 mov r10, r0
24 mov r12, r2
25 mov r14, r1
26
27 memcopy_check_overlapped
28 cmp r11, r1
29 // If (dest < source)
30 bcc memcopy_check_optim_default
31
32 // If (source + length < dest)
33 rsb r3, r1, r11
34 cmp r12, r3
35 bcc memcopy_check_optim_default
36 b memcopy_check_optim_overlap
37
38 memcopy_check_optim_default
39 // Check if we can use an optimized path ((length >= 32) && destination word-aligned && source word-aligned) for the memcopy (optimized path if r0 == 1)
40 tst r0, #0xF
41 movne r0, #0
42 bne memcopy_default
43 tst r1, #0xF
44 movne r3, #0
45 moveq r3, #1
46 cmp r2, #31
47 movls r0, #0
48 andhi r0, r3, #1
49 b memcopy_default
50
51 memcopy_check_optim_overlap
52 // r10 = dest_end, r14 = source_end
53 add r10, r11, r12
54 add r14, r12, r1
55
56 // Are we in the optimized case ((length >= 32) && dest_end word-aligned && source_end word-aligned)
57 cmp r2, #31
58 movls r0, #0
59 movhi r0, #1
60 tst r10, #0xF
61 movne r0, #0
62 tst r14, #0xF
63 movne r0, #0
64 b memcopy_overlapped
65
66 memcopy_overlapped_non_optim
67 // We read 1 byte from the end of the source buffer
68 sub r3, r14, #1
69 sub r12, r12, #1
70 ldrb r3, [r3, #0]
71 sub r2, r10, #1
72 cmp r12, #0
73 // We write 1 byte at the end of the dest buffer
74 sub r10, r10, #1
75 sub r14, r14, #1
76 strb r3, [r2, #0]
77 bne memcopy_overlapped_non_optim
78 b memcopy_end
79
80 // r10 = dest_end, r14 = source_end
81 memcopy_overlapped
82 // Are we in the optimized case ?
83 cmp r0, #0
84 beq memcopy_overlapped_non_optim
85
86 // Optimized Overlapped - Read 32 bytes
87 sub r14, r14, #32
88 sub r12, r12, #32
89 cmp r12, #31
90 ldmia r14, {r2-r9}
91
92 // If length is less than 32 then disable optim
93 movls r0, #0
94
95 cmp r12, #0
96
97 // Optimized Overlapped - Write 32 bytes
98 sub r10, r10, #32
99 stmia r10, {r2-r9}
100
101 // while (length != 0)
102 bne memcopy_overlapped
103 b memcopy_end
104
105 memcopy_default_non_optim
106 // Byte copy
107 ldrb r3, [r14], #1
108 sub r12, r12, #1
109 strb r3, [r10], #1
110
111 memcopy_default
112 cmp r12, #0
113 beq memcopy_end
114
115 // r10 = dest, r14 = source
116 memcopy_default_loop
117 cmp r0, #0
118 beq memcopy_default_non_optim
119
120 // Optimized memcopy - Read 32 Bytes
121 sub r12, r12, #32
122 cmp r12, #31
123 ldmia r14!, {r2-r9}
124
125 // If length is less than 32 then disable optim
126 movls r0, #0
127
128 cmp r12, #0
129
130 // Optimized memcopy - Write 32 Bytes
131 stmia r10!, {r2-r9}
132
133 // while (length != 0)
134 bne memcopy_default_loop
135
136 memcopy_end
137 mov r0, r11
138 ldmfd sp!, {r4-r11, pc}
139
140 END
141