• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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; This program and the accompanying materials
12; are licensed and made available under the terms and conditions of the BSD License
13; which accompanies this distribution.  The full text of the license may be found at
14; http://opensource.org/licenses/bsd-license.php
15;
16; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
17; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18;
19;------------------------------------------------------------------------------
20
21    EXPORT  InternalMemCopyMem
22    AREA    SetMem, CODE, READONLY
23    THUMB
24
25InternalMemCopyMem
26  stmfd  sp!, {r4-r11, lr}
27  // Save the input parameters in extra registers (r11 = destination, r14 = source, r12 = length)
28  mov  r11, r0
29  mov  r10, r0
30  mov  r12, r2
31  mov  r14, r1
32
33memcopy_check_overlapped
34  cmp  r11, r1
35  // If (dest < source)
36  bcc  memcopy_check_optim_default
37
38  // If (source + length < dest)
39  rsb  r3, r1, r11
40  cmp  r12, r3
41  bcc  memcopy_check_optim_default
42  b     memcopy_check_optim_overlap
43
44memcopy_check_optim_default
45  // Check if we can use an optimized path ((length >= 32) && destination word-aligned && source word-aligned) for the memcopy (optimized path if r0 == 1)
46  tst  r0, #0xF
47  movne  r0, #0
48  bne   memcopy_default
49  tst  r1, #0xF
50  movne  r3, #0
51  moveq  r3, #1
52  cmp  r2, #31
53  movls  r0, #0
54  andhi  r0, r3, #1
55  b     memcopy_default
56
57memcopy_check_optim_overlap
58  // r10 = dest_end, r14 = source_end
59  add  r10, r11, r12
60  add  r14, r12, r1
61
62  // Are we in the optimized case ((length >= 32) && dest_end word-aligned && source_end word-aligned)
63  cmp  r2, #31
64  movls  r0, #0
65  movhi  r0, #1
66  tst  r10, #0xF
67  movne  r0, #0
68  tst  r14, #0xF
69  movne  r0, #0
70  b  memcopy_overlapped
71
72memcopy_overlapped_non_optim
73  // We read 1 byte from the end of the source buffer
74  sub  r3, r14, #1
75  sub  r12, r12, #1
76  ldrb  r3, [r3, #0]
77  sub  r2, r10, #1
78  cmp  r12, #0
79  // We write 1 byte at the end of the dest buffer
80  sub  r10, r10, #1
81  sub  r14, r14, #1
82  strb  r3, [r2, #0]
83  bne  memcopy_overlapped_non_optim
84  b   memcopy_end
85
86// r10 = dest_end, r14 = source_end
87memcopy_overlapped
88  // Are we in the optimized case ?
89  cmp  r0, #0
90  beq  memcopy_overlapped_non_optim
91
92  // Optimized Overlapped - Read 32 bytes
93  sub  r14, r14, #32
94  sub  r12, r12, #32
95  cmp  r12, #31
96  ldmia  r14, {r2-r9}
97
98  // If length is less than 32 then disable optim
99  movls  r0, #0
100
101  cmp  r12, #0
102
103  // Optimized Overlapped - Write 32 bytes
104  sub  r10, r10, #32
105  stmia  r10, {r2-r9}
106
107  // while (length != 0)
108  bne  memcopy_overlapped
109  b   memcopy_end
110
111memcopy_default_non_optim
112  // Byte copy
113  ldrb  r3, [r14], #1
114  sub  r12, r12, #1
115  strb  r3, [r10], #1
116
117memcopy_default
118  cmp  r12, #0
119  beq  memcopy_end
120
121// r10 = dest, r14 = source
122memcopy_default_loop
123  cmp  r0, #0
124  beq  memcopy_default_non_optim
125
126  // Optimized memcopy - Read 32 Bytes
127  sub  r12, r12, #32
128  cmp  r12, #31
129  ldmia  r14!, {r2-r9}
130
131  // If length is less than 32 then disable optim
132  movls  r0, #0
133
134  cmp  r12, #0
135
136  // Optimized memcopy - Write 32 Bytes
137  stmia  r10!, {r2-r9}
138
139  // while (length != 0)
140  bne  memcopy_default_loop
141
142memcopy_end
143  mov  r0, r11
144  ldmfd  sp!, {r4-r11, pc}
145
146  END
147
148