FS#11335 by me: make ARM assembly functions thumb-friendly
[kugel-rb.git] / firmware / target / arm / memcpy-arm.S
blob2a55fb5656ee55d99c5b080a33e550fa787f0183
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  ****************************************************************************/
25 #include "config.h"
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
38 /* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
40     .section    .icode,"ax",%progbits
42     .align      2
43     .global     memcpy
44     .type       memcpy,%function
46 memcpy:
47         stmfd   sp!, {r0, r4, lr}
49         subs    r2, r2, #4
50         blt 8f
51         ands    ip, r0, #3
52         bne 9f
53         ands    ip, r1, #3
54         bne 10f
56 1:      subs    r2, r2, #(28)
57         stmfd   sp!, {r5 - r8}
58         blt 5f
62 4:      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
67 5:      ands    ip, r2, #28
68         rsb ip, ip, #32
69         addne   pc, pc, ip      @ C is always clear here
70         b   7f
71 6:      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
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
91 7:      ldmfd   sp!, {r5 - r8}
93 8:      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]
101         ldmpc   regs="r0, r4"
103 9:      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
116 10:     bic r1, r1, #3
117         cmp ip, #2
118         ldr lr, [r1], #4
119         beq 17f
120         bgt 18f
123         .macro  forward_copy_shift pull push
125         subs    r2, r2, #28
126         blt 14f
128 11:     stmfd   sp!, {r5 - r9}
131 13:     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
153         ldmfd   sp!, {r5 - r9}
155 14:     ands    ip, r2, #28
156         beq 16f
158 15:     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
165 16:     sub r1, r1, #(\push / 8)
166         b   8b
168         .endm
171         forward_copy_shift  pull=8  push=24
173 17:     forward_copy_shift  pull=16 push=16
175 18:     forward_copy_shift  pull=24 push=8