summaryrefslogtreecommitdiff
path: root/firmware/asm/arm/memcpy.S
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/asm/arm/memcpy.S')
-rw-r--r--firmware/asm/arm/memcpy.S176
1 files changed, 176 insertions, 0 deletions
diff --git a/firmware/asm/arm/memcpy.S b/firmware/asm/arm/memcpy.S
new file mode 100644
index 0000000000..2a55fb5656
--- /dev/null
+++ b/firmware/asm/arm/memcpy.S
@@ -0,0 +1,176 @@
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 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
22 *
23 ****************************************************************************/
24
25#include "config.h"
26
27/*
28 * Endian independent macros for shifting bytes within registers.
29 */
30#ifndef __ARMEB__
31#define pull lsr
32#define push lsl
33#else
34#define pull lsl
35#define push lsr
36#endif
37
38/* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
39
40 .section .icode,"ax",%progbits
41
42 .align 2
43 .global memcpy
44 .type memcpy,%function
45
46memcpy:
47 stmfd sp!, {r0, r4, lr}
48
49 subs r2, r2, #4
50 blt 8f
51 ands ip, r0, #3
52 bne 9f
53 ands ip, r1, #3
54 bne 10f
55
561: subs r2, r2, #(28)
57 stmfd sp!, {r5 - r8}
58 blt 5f
59
602:
613:
624: ldmia r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
63 subs r2, r2, #32
64 stmia r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
65 bge 3b
66
675: ands ip, r2, #28
68 rsb ip, ip, #32
69 addne pc, pc, ip @ C is always clear here
70 b 7f
716: nop
72 ldr r3, [r1], #4
73 ldr r4, [r1], #4
74 ldr r5, [r1], #4
75 ldr r6, [r1], #4
76 ldr r7, [r1], #4
77 ldr r8, [r1], #4
78 ldr lr, [r1], #4
79
80 add pc, pc, ip
81 nop
82 nop
83 str r3, [r0], #4
84 str r4, [r0], #4
85 str r5, [r0], #4
86 str r6, [r0], #4
87 str r7, [r0], #4
88 str r8, [r0], #4
89 str lr, [r0], #4
90
917: ldmfd sp!, {r5 - r8}
92
938: movs r2, r2, lsl #31
94 ldrneb r3, [r1], #1
95 ldrcsb r4, [r1], #1
96 ldrcsb ip, [r1]
97 strneb r3, [r0], #1
98 strcsb r4, [r0], #1
99 strcsb ip, [r0]
100
101 ldmpc regs="r0, r4"
102
1039: rsb ip, ip, #4
104 cmp ip, #2
105 ldrgtb r3, [r1], #1
106 ldrgeb r4, [r1], #1
107 ldrb lr, [r1], #1
108 strgtb r3, [r0], #1
109 strgeb r4, [r0], #1
110 subs r2, r2, ip
111 strb lr, [r0], #1
112 blt 8b
113 ands ip, r1, #3
114 beq 1b
115
11610: bic r1, r1, #3
117 cmp ip, #2
118 ldr lr, [r1], #4
119 beq 17f
120 bgt 18f
121
122
123 .macro forward_copy_shift pull push
124
125 subs r2, r2, #28
126 blt 14f
127
12811: stmfd sp!, {r5 - r9}
129
13012:
13113: ldmia r1!, {r4, r5, r6, r7}
132 mov r3, lr, pull #\pull
133 subs r2, r2, #32
134 ldmia r1!, {r8, r9, ip, lr}
135 orr r3, r3, r4, push #\push
136 mov r4, r4, pull #\pull
137 orr r4, r4, r5, push #\push
138 mov r5, r5, pull #\pull
139 orr r5, r5, r6, push #\push
140 mov r6, r6, pull #\pull
141 orr r6, r6, r7, push #\push
142 mov r7, r7, pull #\pull
143 orr r7, r7, r8, push #\push
144 mov r8, r8, pull #\pull
145 orr r8, r8, r9, push #\push
146 mov r9, r9, pull #\pull
147 orr r9, r9, ip, push #\push
148 mov ip, ip, pull #\pull
149 orr ip, ip, lr, push #\push
150 stmia r0!, {r3, r4, r5, r6, r7, r8, r9, ip}
151 bge 12b
152
153 ldmfd sp!, {r5 - r9}
154
15514: ands ip, r2, #28
156 beq 16f
157
15815: mov r3, lr, pull #\pull
159 ldr lr, [r1], #4
160 subs ip, ip, #4
161 orr r3, r3, lr, push #\push
162 str r3, [r0], #4
163 bgt 15b
164
16516: sub r1, r1, #(\push / 8)
166 b 8b
167
168 .endm
169
170
171 forward_copy_shift pull=8 push=24
172
17317: forward_copy_shift pull=16 push=16
174
17518: forward_copy_shift pull=24 push=8
176