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

« back to all changes in this revision

Viewing changes to src/reference/glibc/memmove.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, 2008, 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
/*
 
57
 * Prototype: void *memmove(void *dest, const void *src, size_t n);
 
58
 *
 
59
 * Note:
 
60
 *
 
61
 * If the memory regions don't overlap, we simply branch to memcpy which is
 
62
 * normally a bit faster. Otherwise the copy is done going downwards.
 
63
 */
 
64
 
 
65
ENTRY(memmove)
 
66
 
 
67
                subs    ip, r0, r1
 
68
                cmphi   r2, ip
 
69
#ifdef NOT_IN_libc
 
70
                bls     memcpy
 
71
#else
 
72
                bls     HIDDEN_JUMPTARGET(memcpy)
 
73
#endif
 
74
 
 
75
                stmfd   sp!, {r0, r4, lr}
 
76
                add     r1, r1, r2
 
77
                add     r0, r0, r2
 
78
                subs    r2, r2, #4
 
79
                blt     8f
 
80
                ands    ip, r0, #3
 
81
        PLD(    pld     [r1, #-4]               )
 
82
                bne     9f
 
83
                ands    ip, r1, #3
 
84
                bne     10f
 
85
 
 
86
1:              subs    r2, r2, #(28)
 
87
                stmfd   sp!, {r5 - r8}
 
88
                blt     5f
 
89
 
 
90
        CALGN(  ands    ip, r1, #31             )
 
91
        CALGN(  sbcnes  r4, ip, r2              )  @ C is always set here
 
92
        CALGN(  bcs     2f                      )
 
93
        CALGN(  adr     r4, 6f                  )
 
94
        CALGN(  subs    r2, r2, ip              )  @ C is set here
 
95
        CALGN(  add     pc, r4, ip              )
 
96
 
 
97
        PLD(    pld     [r1, #-4]               )
 
98
2:      PLD(    subs    r2, r2, #96             )
 
99
        PLD(    pld     [r1, #-32]              )
 
100
        PLD(    blt     4f                      )
 
101
        PLD(    pld     [r1, #-64]              )
 
102
        PLD(    pld     [r1, #-96]              )
 
103
 
 
104
3:      PLD(    pld     [r1, #-128]             )
 
105
4:              ldmdb   r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
 
106
                subs    r2, r2, #32
 
107
                stmdb   r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
 
108
                bge     3b
 
109
        PLD(    cmn     r2, #96                 )
 
110
        PLD(    bge     4b                      )
 
111
 
 
112
5:              ands    ip, r2, #28
 
113
                rsb     ip, ip, #32
 
114
                addne   pc, pc, ip              @ C is always clear here
 
115
                b       7f
 
116
6:              nop
 
117
                ldr     r3, [r1, #-4]!
 
118
                ldr     r4, [r1, #-4]!
 
119
                ldr     r5, [r1, #-4]!
 
120
                ldr     r6, [r1, #-4]!
 
121
                ldr     r7, [r1, #-4]!
 
122
                ldr     r8, [r1, #-4]!
 
123
                ldr     lr, [r1, #-4]!
 
124
 
 
125
                add     pc, pc, ip
 
126
                nop
 
127
                nop
 
128
                str     r3, [r0, #-4]!
 
129
                str     r4, [r0, #-4]!
 
130
                str     r5, [r0, #-4]!
 
131
                str     r6, [r0, #-4]!
 
132
                str     r7, [r0, #-4]!
 
133
                str     r8, [r0, #-4]!
 
134
                str     lr, [r0, #-4]!
 
135
 
 
136
        CALGN(  bcs     2b                      )
 
137
 
 
138
7:              ldmfd   sp!, {r5 - r8}
 
139
 
 
140
8:              movs    r2, r2, lsl #31
 
141
                ldrneb  r3, [r1, #-1]!
 
142
                ldrcsb  r4, [r1, #-1]!
 
143
                ldrcsb  ip, [r1, #-1]
 
144
                strneb  r3, [r0, #-1]!
 
145
                strcsb  r4, [r0, #-1]!
 
146
                strcsb  ip, [r0, #-1]
 
147
#if defined (__ARM_ARCH_4T__) && defined (__THUMB_INTERWORK__)
 
148
                ldmfd   sp!, {r0, r4, lr}
 
149
                bx      lr
 
150
#else
 
151
                ldmfd   sp!, {r0, r4, pc}
 
152
#endif
 
153
 
 
154
9:              cmp     ip, #2
 
155
                ldrgtb  r3, [r1, #-1]!
 
156
                ldrgeb  r4, [r1, #-1]!
 
157
                ldrb    lr, [r1, #-1]!
 
158
                strgtb  r3, [r0, #-1]!
 
159
                strgeb  r4, [r0, #-1]!
 
160
                subs    r2, r2, ip
 
161
                strb    lr, [r0, #-1]!
 
162
                blt     8b
 
163
                ands    ip, r1, #3
 
164
                beq     1b
 
165
 
 
166
10:             bic     r1, r1, #3
 
167
                cmp     ip, #2
 
168
                ldr     r3, [r1, #0]
 
169
                beq     17f
 
170
                blt     18f
 
171
 
 
172
 
 
173
                .macro  backward_copy_shift push pull
 
174
 
 
175
                subs    r2, r2, #28
 
176
                blt     14f
 
177
 
 
178
        CALGN(  ands    ip, r1, #31             )
 
179
        CALGN(  rsb     ip, ip, #32             )
 
180
        CALGN(  sbcnes  r4, ip, r2              )  @ C is always set here
 
181
        CALGN(  subcc   r2, r2, ip              )
 
182
        CALGN(  bcc     15f                     )
 
183
 
 
184
11:             stmfd   sp!, {r5 - r9}
 
185
 
 
186
        PLD(    pld     [r1, #-4]               )
 
187
        PLD(    subs    r2, r2, #96             )
 
188
        PLD(    pld     [r1, #-32]              )
 
189
        PLD(    blt     13f                     )
 
190
        PLD(    pld     [r1, #-64]              )
 
191
        PLD(    pld     [r1, #-96]              )
 
192
 
 
193
12:     PLD(    pld     [r1, #-128]             )
 
194
13:             ldmdb   r1!, {r7, r8, r9, ip}
 
195
                mov     lr, r3, push #\push
 
196
                subs    r2, r2, #32
 
197
                ldmdb   r1!, {r3, r4, r5, r6}
 
198
                orr     lr, lr, ip, pull #\pull
 
199
                mov     ip, ip, push #\push
 
200
                orr     ip, ip, r9, pull #\pull
 
201
                mov     r9, r9, push #\push
 
202
                orr     r9, r9, r8, pull #\pull
 
203
                mov     r8, r8, push #\push
 
204
                orr     r8, r8, r7, pull #\pull
 
205
                mov     r7, r7, push #\push
 
206
                orr     r7, r7, r6, pull #\pull
 
207
                mov     r6, r6, push #\push
 
208
                orr     r6, r6, r5, pull #\pull
 
209
                mov     r5, r5, push #\push
 
210
                orr     r5, r5, r4, pull #\pull
 
211
                mov     r4, r4, push #\push
 
212
                orr     r4, r4, r3, pull #\pull
 
213
                stmdb   r0!, {r4 - r9, ip, lr}
 
214
                bge     12b
 
215
        PLD(    cmn     r2, #96                 )
 
216
        PLD(    bge     13b                     )
 
217
 
 
218
                ldmfd   sp!, {r5 - r9}
 
219
 
 
220
14:             ands    ip, r2, #28
 
221
                beq     16f
 
222
 
 
223
15:             mov     lr, r3, push #\push
 
224
                ldr     r3, [r1, #-4]!
 
225
                subs    ip, ip, #4
 
226
                orr     lr, lr, r3, pull #\pull
 
227
                str     lr, [r0, #-4]!
 
228
                bgt     15b
 
229
        CALGN(  cmp     r2, #0                  )
 
230
        CALGN(  bge     11b                     )
 
231
 
 
232
16:             add     r1, r1, #(\pull / 8)
 
233
                b       8b
 
234
 
 
235
                .endm
 
236
 
 
237
 
 
238
                backward_copy_shift     push=8  pull=24
 
239
 
 
240
17:             backward_copy_shift     push=16 pull=16
 
241
 
 
242
18:             backward_copy_shift     push=24 pull=8
 
243
 
 
244
 
 
245
END(memmove)
 
246
libc_hidden_builtin_def (memmove)