~linaro-toolchain-dev/cortex-strings/trunk

« back to all changes in this revision

Viewing changes to src/reference/glibc/memcpy.S

  • Committer: Michael Hope
  • Date: 2010-08-26 22:19:29 UTC
  • Revision ID: michael.hope@linaro.org-20100826221929-ppeg01mnpx34aqrp
Pulled in the initial versions

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2006, 2009 Free Software Foundation, Inc.
 
2
   This file is part of the GNU C Library.
 
3
 
 
4
   Contributed by MontaVista Software, Inc. (written by Nicolas Pitre)
 
5
 
 
6
   The GNU C Library is free software; you can redistribute it and/or
 
7
   modify it under the terms of the GNU Lesser General Public
 
8
   License as published by the Free Software Foundation; either
 
9
   version 2.1 of the License, or (at your option) any later version.
 
10
 
 
11
   The GNU C Library is distributed in the hope that it will be useful,
 
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
   Lesser General Public License for more details.
 
15
 
 
16
   You should have received a copy of the GNU Lesser General Public
 
17
   License along with the GNU C Library; if not, write to the Free
 
18
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 
19
   02111-1307 USA.  */
 
20
 
 
21
#include <sysdep.h>
 
22
 
 
23
/*
 
24
 * Data preload for architectures that support it (ARM V5TE and above)
 
25
 */
 
26
#if (!defined (__ARM_ARCH_2__) && !defined (__ARM_ARCH_3__) \
 
27
     && !defined (__ARM_ARCH_3M__) && !defined (__ARM_ARCH_4__) \
 
28
     && !defined (__ARM_ARCH_4T__) && !defined (__ARM_ARCH_5__) \
 
29
     && !defined (__ARM_ARCH_5T__))
 
30
#define PLD(code...)    code
 
31
#else
 
32
#define PLD(code...)
 
33
#endif
 
34
 
 
35
/*
 
36
 * This can be used to enable code to cacheline align the source pointer.
 
37
 * Experiments on tested architectures (StrongARM and XScale) didn't show
 
38
 * this a worthwhile thing to do.  That might be different in the future.
 
39
 */
 
40
//#define CALGN(code...)        code
 
41
#define CALGN(code...)
 
42
 
 
43
/*
 
44
 * Endian independent macros for shifting bytes within registers.
 
45
 */
 
46
#ifndef __ARMEB__
 
47
#define pull            lsr
 
48
#define push            lsl
 
49
#else
 
50
#define pull            lsl
 
51
#define push            lsr
 
52
#endif
 
53
 
 
54
                .text
 
55
 
 
56
/* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
 
57
 
 
58
ENTRY(memcpy)
 
59
 
 
60
                stmfd   sp!, {r0, r4, lr}
 
61
 
 
62
                subs    r2, r2, #4
 
63
                blt     8f
 
64
                ands    ip, r0, #3
 
65
        PLD(    pld     [r1, #0]                )
 
66
                bne     9f
 
67
                ands    ip, r1, #3
 
68
                bne     10f
 
69
 
 
70
1:              subs    r2, r2, #(28)
 
71
                stmfd   sp!, {r5 - r8}
 
72
                blt     5f
 
73
 
 
74
        CALGN(  ands    ip, r1, #31             )
 
75
        CALGN(  rsb     r3, ip, #32             )
 
76
        CALGN(  sbcnes  r4, r3, r2              )  @ C is always set here
 
77
        CALGN(  bcs     2f                      )
 
78
        CALGN(  adr     r4, 6f                  )
 
79
        CALGN(  subs    r2, r2, r3              )  @ C gets set
 
80
        CALGN(  add     pc, r4, ip              )
 
81
 
 
82
        PLD(    pld     [r1, #0]                )
 
83
2:      PLD(    subs    r2, r2, #96             )
 
84
        PLD(    pld     [r1, #28]               )
 
85
        PLD(    blt     4f                      )
 
86
        PLD(    pld     [r1, #60]               )
 
87
        PLD(    pld     [r1, #92]               )
 
88
 
 
89
3:      PLD(    pld     [r1, #124]              )
 
90
4:              ldmia   r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
 
91
                subs    r2, r2, #32
 
92
                stmia   r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
 
93
                bge     3b
 
94
        PLD(    cmn     r2, #96                 )
 
95
        PLD(    bge     4b                      )
 
96
 
 
97
5:              ands    ip, r2, #28
 
98
                rsb     ip, ip, #32
 
99
                addne   pc, pc, ip              @ C is always clear here
 
100
                b       7f
 
101
6:              nop
 
102
                ldr     r3, [r1], #4
 
103
                ldr     r4, [r1], #4
 
104
                ldr     r5, [r1], #4
 
105
                ldr     r6, [r1], #4
 
106
                ldr     r7, [r1], #4
 
107
                ldr     r8, [r1], #4
 
108
                ldr     lr, [r1], #4
 
109
 
 
110
                add     pc, pc, ip
 
111
                nop
 
112
                nop
 
113
                str     r3, [r0], #4
 
114
                str     r4, [r0], #4
 
115
                str     r5, [r0], #4
 
116
                str     r6, [r0], #4
 
117
                str     r7, [r0], #4
 
118
                str     r8, [r0], #4
 
119
                str     lr, [r0], #4
 
120
 
 
121
        CALGN(  bcs     2b                      )
 
122
 
 
123
7:              ldmfd   sp!, {r5 - r8}
 
124
 
 
125
8:              movs    r2, r2, lsl #31
 
126
                ldrneb  r3, [r1], #1
 
127
                ldrcsb  r4, [r1], #1
 
128
                ldrcsb  ip, [r1]
 
129
                strneb  r3, [r0], #1
 
130
                strcsb  r4, [r0], #1
 
131
                strcsb  ip, [r0]
 
132
 
 
133
#if defined (__ARM_ARCH_4T__) && defined(__THUMB_INTERWORK__)
 
134
                ldmfd   sp!, {r0, r4, lr}
 
135
                bx      lr
 
136
#else
 
137
                ldmfd   sp!, {r0, r4, pc}
 
138
#endif
 
139
 
 
140
9:              rsb     ip, ip, #4
 
141
                cmp     ip, #2
 
142
                ldrgtb  r3, [r1], #1
 
143
                ldrgeb  r4, [r1], #1
 
144
                ldrb    lr, [r1], #1
 
145
                strgtb  r3, [r0], #1
 
146
                strgeb  r4, [r0], #1
 
147
                subs    r2, r2, ip
 
148
                strb    lr, [r0], #1
 
149
                blt     8b
 
150
                ands    ip, r1, #3
 
151
                beq     1b
 
152
 
 
153
10:             bic     r1, r1, #3
 
154
                cmp     ip, #2
 
155
                ldr     lr, [r1], #4
 
156
                beq     17f
 
157
                bgt     18f
 
158
 
 
159
 
 
160
                .macro  forward_copy_shift pull push
 
161
 
 
162
                subs    r2, r2, #28
 
163
                blt     14f
 
164
 
 
165
        CALGN(  ands    ip, r1, #31             )
 
166
        CALGN(  rsb     ip, ip, #32             )
 
167
        CALGN(  sbcnes  r4, ip, r2              )  @ C is always set here
 
168
        CALGN(  subcc   r2, r2, ip              )
 
169
        CALGN(  bcc     15f                     )
 
170
 
 
171
11:             stmfd   sp!, {r5 - r9}
 
172
 
 
173
        PLD(    pld     [r1, #0]                )
 
174
        PLD(    subs    r2, r2, #96             )
 
175
        PLD(    pld     [r1, #28]               )
 
176
        PLD(    blt     13f                     )
 
177
        PLD(    pld     [r1, #60]               )
 
178
        PLD(    pld     [r1, #92]               )
 
179
 
 
180
12:     PLD(    pld     [r1, #124]              )
 
181
13:             ldmia   r1!, {r4, r5, r6, r7}
 
182
                mov     r3, lr, pull #\pull
 
183
                subs    r2, r2, #32
 
184
                ldmia   r1!, {r8, r9, ip, lr}
 
185
                orr     r3, r3, r4, push #\push
 
186
                mov     r4, r4, pull #\pull
 
187
                orr     r4, r4, r5, push #\push
 
188
                mov     r5, r5, pull #\pull
 
189
                orr     r5, r5, r6, push #\push
 
190
                mov     r6, r6, pull #\pull
 
191
                orr     r6, r6, r7, push #\push
 
192
                mov     r7, r7, pull #\pull
 
193
                orr     r7, r7, r8, push #\push
 
194
                mov     r8, r8, pull #\pull
 
195
                orr     r8, r8, r9, push #\push
 
196
                mov     r9, r9, pull #\pull
 
197
                orr     r9, r9, ip, push #\push
 
198
                mov     ip, ip, pull #\pull
 
199
                orr     ip, ip, lr, push #\push
 
200
                stmia   r0!, {r3, r4, r5, r6, r7, r8, r9, ip}
 
201
                bge     12b
 
202
        PLD(    cmn     r2, #96                 )
 
203
        PLD(    bge     13b                     )
 
204
 
 
205
                ldmfd   sp!, {r5 - r9}
 
206
 
 
207
14:             ands    ip, r2, #28
 
208
                beq     16f
 
209
 
 
210
15:             mov     r3, lr, pull #\pull
 
211
                ldr     lr, [r1], #4
 
212
                subs    ip, ip, #4
 
213
                orr     r3, r3, lr, push #\push
 
214
                str     r3, [r0], #4
 
215
                bgt     15b
 
216
        CALGN(  cmp     r2, #0                  )
 
217
        CALGN(  bge     11b                     )
 
218
 
 
219
16:             sub     r1, r1, #(\push / 8)
 
220
                b       8b
 
221
 
 
222
                .endm
 
223
 
 
224
 
 
225
                forward_copy_shift      pull=8  push=24
 
226
 
 
227
17:             forward_copy_shift      pull=16 push=16
 
228
 
 
229
18:             forward_copy_shift      pull=24 push=8
 
230
 
 
231
END(memcpy)
 
232
libc_hidden_builtin_def (memcpy)