Subversion Repositories freemyipod

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
286 theseven 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
#define ASM_FILE
26
#include "global.h"
27
 
28
/* ARMv4T doesn't switch the T bit when popping pc directly, we must use BX */
29
.macro ldmpc cond="", order="ia", regs
30
#if ARM_ARCH == 4 && defined(USE_THUMB)
31
    ldm\cond\order sp!, { \regs, lr }
32
    bx\cond lr
33
#else
34
    ldm\cond\order sp!, { \regs, pc }
35
#endif
36
.endm
37
.macro ldrpc cond=""
38
#if ARM_ARCH == 4 && defined(USE_THUMB)
39
    ldr\cond lr, [sp], #4
40
    bx\cond  lr
41
#else
42
    ldr\cond pc, [sp], #4
43
#endif
44
.endm
45
 
46
/*
47
 * Endian independent macros for shifting bytes within registers.
48
 */
49
#ifndef __ARMEB__
50
#define pull            lsr
51
#define push            lsl
52
#else
53
#define pull            lsl
54
#define push            lsr
55
#endif
56
 
57
/* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
58
 
59
    .section    .icode,"ax",%progbits
60
 
61
    .align      2
62
    .global     memcpy
63
    .type       memcpy,%function
64
 
65
memcpy:
66
        stmfd   sp!, {r0, r4, lr}
67
 
68
        subs    r2, r2, #4
69
        blt 8f
70
        ands    ip, r0, #3
71
        bne 9f
72
        ands    ip, r1, #3
73
        bne 10f
74
 
75
1:      subs    r2, r2, #(28)
76
        stmfd   sp!, {r5 - r8}
77
        blt 5f
78
 
79
2:
80
3:
81
4:      ldmia   r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
82
        subs    r2, r2, #32
83
        stmia   r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
84
        bge 3b
85
 
86
5:      ands    ip, r2, #28
87
        rsb ip, ip, #32
88
        addne   pc, pc, ip      @ C is always clear here
89
        b   7f
90
6:      nop
91
        ldr r3, [r1], #4
92
        ldr r4, [r1], #4
93
        ldr r5, [r1], #4
94
        ldr r6, [r1], #4
95
        ldr r7, [r1], #4
96
        ldr r8, [r1], #4
97
        ldr lr, [r1], #4
98
 
99
        add pc, pc, ip
100
        nop
101
        nop
102
        str r3, [r0], #4
103
        str r4, [r0], #4
104
        str r5, [r0], #4
105
        str r6, [r0], #4
106
        str r7, [r0], #4
107
        str r8, [r0], #4
108
        str lr, [r0], #4
109
 
110
7:      ldmfd   sp!, {r5 - r8}
111
 
112
8:      movs    r2, r2, lsl #31
113
        ldrneb  r3, [r1], #1
114
        ldrcsb  r4, [r1], #1
115
        ldrcsb  ip, [r1]
116
        strneb  r3, [r0], #1
117
        strcsb  r4, [r0], #1
118
        strcsb  ip, [r0]
119
 
120
        ldmpc   regs="r0, r4"
121
 
122
9:      rsb ip, ip, #4
123
        cmp ip, #2
124
        ldrgtb  r3, [r1], #1
125
        ldrgeb  r4, [r1], #1
126
        ldrb    lr, [r1], #1
127
        strgtb  r3, [r0], #1
128
        strgeb  r4, [r0], #1
129
        subs    r2, r2, ip
130
        strb    lr, [r0], #1
131
        blt 8b
132
        ands    ip, r1, #3
133
        beq 1b
134
 
135
10:     bic r1, r1, #3
136
        cmp ip, #2
137
        ldr lr, [r1], #4
138
        beq 17f
139
        bgt 18f
140
 
141
 
142
        .macro  forward_copy_shift pull push
143
 
144
        subs    r2, r2, #28
145
        blt 14f
146
 
147
11:     stmfd   sp!, {r5 - r9}
148
 
149
12:
150
13:     ldmia   r1!, {r4, r5, r6, r7}
151
        mov r3, lr, pull #\pull
152
        subs    r2, r2, #32
153
        ldmia   r1!, {r8, r9, ip, lr}
154
        orr r3, r3, r4, push #\push
155
        mov r4, r4, pull #\pull
156
        orr r4, r4, r5, push #\push
157
        mov r5, r5, pull #\pull
158
        orr r5, r5, r6, push #\push
159
        mov r6, r6, pull #\pull
160
        orr r6, r6, r7, push #\push
161
        mov r7, r7, pull #\pull
162
        orr r7, r7, r8, push #\push
163
        mov r8, r8, pull #\pull
164
        orr r8, r8, r9, push #\push
165
        mov r9, r9, pull #\pull
166
        orr r9, r9, ip, push #\push
167
        mov ip, ip, pull #\pull
168
        orr ip, ip, lr, push #\push
169
        stmia   r0!, {r3, r4, r5, r6, r7, r8, r9, ip}
170
        bge 12b
171
 
172
        ldmfd   sp!, {r5 - r9}
173
 
174
14:     ands    ip, r2, #28
175
        beq 16f
176
 
177
15:     mov r3, lr, pull #\pull
178
        ldr lr, [r1], #4
179
        subs    ip, ip, #4
180
        orr r3, r3, lr, push #\push
181
        str r3, [r0], #4
182
        bgt 15b
183
 
184
16:     sub r1, r1, #(\push / 8)
185
        b   8b
186
 
187
        .endm
188
 
189
 
190
        forward_copy_shift  pull=8  push=24
191
 
192
17:     forward_copy_shift  pull=16 push=16
193
 
194
18:     forward_copy_shift  pull=24 push=8
195