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