summaryrefslogtreecommitdiff
path: root/firmware/target/arm/memmove-arm.S
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/memmove-arm.S')
-rw-r--r--firmware/target/arm/memmove-arm.S188
1 files changed, 188 insertions, 0 deletions
diff --git a/firmware/target/arm/memmove-arm.S b/firmware/target/arm/memmove-arm.S
new file mode 100644
index 0000000000..94103c0c35
--- /dev/null
+++ b/firmware/target/arm/memmove-arm.S
@@ -0,0 +1,188 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 Free Software Foundation, Inc.
11 * This file was originally part of the GNU C Library
12 * Contributed to glibc by MontaVista Software, Inc. (written by Nicolas Pitre)
13 * Adapted for Rockbox by Daniel Ankers
14 *
15 * All files in this archive are subject to the GNU General Public License.
16 * See the file COPYING in the source tree root for full license agreement.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22
23#include "config.h"
24
25/*
26 * Endian independent macros for shifting bytes within registers.
27 */
28#ifndef __ARMEB__
29#define pull lsr
30#define push lsl
31#else
32#define pull lsl
33#define push lsr
34#endif
35
36 .text
37
38/*
39 * Prototype: void *memmove(void *dest, const void *src, size_t n);
40 *
41 * Note:
42 *
43 * If the memory regions don't overlap, we simply branch to memcpy which is
44 * normally a bit faster. Otherwise the copy is done going downwards.
45 */
46
47 .section .icode,"ax",%progbits
48
49 .align 2
50 .global memmove
51 .type memmove,%function
52
53memmove:
54
55 subs ip, r0, r1
56 cmphi r2, ip
57 bls memcpy
58
59 stmfd sp!, {r0, r4, lr}
60 add r1, r1, r2
61 add r0, r0, r2
62 subs r2, r2, #4
63 blt 8f
64 ands ip, r0, #3
65 bne 9f
66 ands ip, r1, #3
67 bne 10f
68
691: subs r2, r2, #(28)
70 stmfd sp!, {r5 - r8}
71 blt 5f
72
732:
743:
754: ldmdb r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
76 subs r2, r2, #32
77 stmdb r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
78 bge 3b
79
805: ands ip, r2, #28
81 rsb ip, ip, #32
82 addne pc, pc, ip @ C is always clear here
83 b 7f
846: nop
85 ldr r3, [r1, #-4]!
86 ldr r4, [r1, #-4]!
87 ldr r5, [r1, #-4]!
88 ldr r6, [r1, #-4]!
89 ldr r7, [r1, #-4]!
90 ldr r8, [r1, #-4]!
91 ldr lr, [r1, #-4]!
92
93 add pc, pc, ip
94 nop
95 nop
96 str r3, [r0, #-4]!
97 str r4, [r0, #-4]!
98 str r5, [r0, #-4]!
99 str r6, [r0, #-4]!
100 str r7, [r0, #-4]!
101 str r8, [r0, #-4]!
102 str lr, [r0, #-4]!
103
1047: ldmfd sp!, {r5 - r8}
105
1068: movs r2, r2, lsl #31
107 ldrneb r3, [r1, #-1]!
108 ldrcsb r4, [r1, #-1]!
109 ldrcsb ip, [r1, #-1]
110 strneb r3, [r0, #-1]!
111 strcsb r4, [r0, #-1]!
112 strcsb ip, [r0, #-1]
113 ldmfd sp!, {r0, r4, pc}
114
1159: cmp ip, #2
116 ldrgtb r3, [r1, #-1]!
117 ldrgeb r4, [r1, #-1]!
118 ldrb lr, [r1, #-1]!
119 strgtb r3, [r0, #-1]!
120 strgeb r4, [r0, #-1]!
121 subs r2, r2, ip
122 strb lr, [r0, #-1]!
123 blt 8b
124 ands ip, r1, #3
125 beq 1b
126
12710: bic r1, r1, #3
128 cmp ip, #2
129 ldr r3, [r1, #0]
130 beq 17f
131 blt 18f
132
133
134 .macro backward_copy_shift push pull
135
136 subs r2, r2, #28
137 blt 14f
138
13911: stmfd sp!, {r5 - r9}
140
14112:
14213: ldmdb r1!, {r7, r8, r9, ip}
143 mov lr, r3, push #\push
144 subs r2, r2, #32
145 ldmdb r1!, {r3, r4, r5, r6}
146 orr lr, lr, ip, pull #\pull
147 mov ip, ip, push #\push
148 orr ip, ip, r9, pull #\pull
149 mov r9, r9, push #\push
150 orr r9, r9, r8, pull #\pull
151 mov r8, r8, push #\push
152 orr r8, r8, r7, pull #\pull
153 mov r7, r7, push #\push
154 orr r7, r7, r6, pull #\pull
155 mov r6, r6, push #\push
156 orr r6, r6, r5, pull #\pull
157 mov r5, r5, push #\push
158 orr r5, r5, r4, pull #\pull
159 mov r4, r4, push #\push
160 orr r4, r4, r3, pull #\pull
161 stmdb r0!, {r4 - r9, ip, lr}
162 bge 12b
163
164 ldmfd sp!, {r5 - r9}
165
16614: ands ip, r2, #28
167 beq 16f
168
16915: mov lr, r3, push #\push
170 ldr r3, [r1, #-4]!
171 subs ip, ip, #4
172 orr lr, lr, r3, pull #\pull
173 str lr, [r0, #-4]!
174 bgt 15b
175
17616: add r1, r1, #(\pull / 8)
177 b 8b
178
179 .endm
180
181
182 backward_copy_shift push=8 pull=24
183
18417: backward_copy_shift push=16 pull=16
185
18618: backward_copy_shift push=24 pull=8
187
188