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

« back to all changes in this revision

Viewing changes to src/neon/memcpy.S

  • Committer: Dr. David Alan Gilbert
  • Date: 2011-09-12 11:16:55 UTC
  • Revision ID: david.gilbert@linaro.org-20110912111655-gy18oe3f3zns2zwl
remove old memcpy.S, memset.S and strlen.c from linaro build that were from 3rd parties

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (C) 2008 The Android Open Source Project
3
 
 * All rights reserved.
4
 
 *
5
 
 * Redistribution and use in source and binary forms, with or without
6
 
 * modification, are permitted provided that the following conditions
7
 
 * are met:
8
 
 *  * Redistributions of source code must retain the above copyright
9
 
 *    notice, this list of conditions and the following disclaimer.
10
 
 *  * Redistributions in binary form must reproduce the above copyright
11
 
 *    notice, this list of conditions and the following disclaimer in
12
 
 *    the documentation and/or other materials provided with the
13
 
 *    distribution.
14
 
 *
15
 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16
 
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17
 
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18
 
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19
 
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20
 
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21
 
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22
 
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23
 
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24
 
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25
 
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
 
 * SUCH DAMAGE.
27
 
 */
28
 
 
29
 
/* For GLIBC: #include <sysdep.h> */
30
 
 
31
 
        .text
32
 
        .fpu    neon
33
 
 
34
 
        .global memcpy
35
 
        .type memcpy, %function
36
 
        .align 4
37
 
 
38
 
/* a prefetch distance of 4 cache-lines works best experimentally */
39
 
#define CACHE_LINE_SIZE     64
40
 
#define PREFETCH_DISTANCE   (CACHE_LINE_SIZE*4)
41
 
 
42
 
memcpy:
43
 
        .fnstart
44
 
        .save       {r0, lr}
45
 
        stmfd       sp!, {r0, lr}
46
 
 
47
 
        /* start preloading as early as possible */
48
 
        pld         [r1, #(CACHE_LINE_SIZE*0)]
49
 
        pld         [r1, #(CACHE_LINE_SIZE*1)]
50
 
 
51
 
        /* do we have at least 16-bytes to copy (needed for alignment below) */
52
 
        cmp         r2, #16
53
 
        blo         5f
54
 
 
55
 
        /* align destination to half cache-line for the write-buffer */
56
 
        rsb         r3, r0, #0
57
 
        ands        r3, r3, #0xF
58
 
        beq         0f
59
 
 
60
 
        /* copy up to 15-bytes (count in r3) */
61
 
        sub         r2, r2, r3
62
 
        movs        ip, r3, lsl #31
63
 
        ldrmib      lr, [r1], #1
64
 
        strmib      lr, [r0], #1
65
 
        ldrcsb      ip, [r1], #1
66
 
        ldrcsb      lr, [r1], #1
67
 
        strcsb      ip, [r0], #1
68
 
        strcsb      lr, [r0], #1
69
 
        movs        ip, r3, lsl #29
70
 
        bge         1f
71
 
        // copies 4 bytes, destination 32-bits aligned
72
 
        vld4.8      {d0[0], d1[0], d2[0], d3[0]}, [r1]!
73
 
        vst4.8      {d0[0], d1[0], d2[0], d3[0]}, [r0, :32]!
74
 
1:      bcc         2f
75
 
        // copies 8 bytes, destination 64-bits aligned
76
 
        vld1.8      {d0}, [r1]!
77
 
        vst1.8      {d0}, [r0, :64]!
78
 
2:
79
 
 
80
 
0:      /* preload immediately the next cache line, which we may need */
81
 
        pld         [r1, #(CACHE_LINE_SIZE*0)]
82
 
        pld         [r1, #(CACHE_LINE_SIZE*1)]
83
 
 
84
 
        /* make sure we have at least 64 bytes to copy */
85
 
        subs        r2, r2, #64
86
 
        blo         2f
87
 
 
88
 
        /* preload all the cache lines we need.
89
 
         * NOTE: the number of pld below depends on PREFETCH_DISTANCE,
90
 
         * ideally would would increase the distance in the main loop to
91
 
         * avoid the goofy code below. In practice this doesn't seem to make
92
 
         * a big difference.
93
 
         */
94
 
        pld         [r1, #(CACHE_LINE_SIZE*2)]
95
 
        pld         [r1, #(CACHE_LINE_SIZE*3)]
96
 
        pld         [r1, #(PREFETCH_DISTANCE)]
97
 
 
98
 
1:      /* The main loop copies 64 bytes at a time */
99
 
        vld1.8      {d0  - d3},   [r1]!
100
 
        vld1.8      {d4  - d7},   [r1]!
101
 
        pld         [r1, #(PREFETCH_DISTANCE)]
102
 
        subs        r2, r2, #64
103
 
        vst1.8      {d0  - d3},   [r0, :128]!
104
 
        vst1.8      {d4  - d7},   [r0, :128]!
105
 
        bhs         1b
106
 
 
107
 
2:      /* fix-up the remaining count and make sure we have >= 32 bytes left */
108
 
        add         r2, r2, #64
109
 
        subs        r2, r2, #32
110
 
        blo         4f
111
 
 
112
 
3:      /* 32 bytes at a time. These cache lines were already preloaded */
113
 
        vld1.8      {d0 - d3},  [r1]!
114
 
        subs        r2, r2, #32
115
 
        vst1.8      {d0 - d3},  [r0, :128]!
116
 
        bhs         3b
117
 
 
118
 
4:      /* less than 32 left */
119
 
        add         r2, r2, #32
120
 
        tst         r2, #0x10
121
 
        beq         5f
122
 
        // copies 16 bytes, 128-bits aligned
123
 
        vld1.8      {d0, d1}, [r1]!
124
 
        vst1.8      {d0, d1}, [r0, :128]!
125
 
 
126
 
5:      /* copy up to 15-bytes (count in r2) */
127
 
        movs        ip, r2, lsl #29
128
 
        bcc         1f
129
 
        vld1.8      {d0}, [r1]!
130
 
        vst1.8      {d0}, [r0]!
131
 
1:      bge         2f
132
 
        vld4.8      {d0[0], d1[0], d2[0], d3[0]}, [r1]!
133
 
        vst4.8      {d0[0], d1[0], d2[0], d3[0]}, [r0]!
134
 
2:      movs        ip, r2, lsl #31
135
 
        ldrmib      r3, [r1], #1
136
 
        ldrcsb      ip, [r1], #1
137
 
        ldrcsb      lr, [r1], #1
138
 
        strmib      r3, [r0], #1
139
 
        strcsb      ip, [r0], #1
140
 
        strcsb      lr, [r0], #1
141
 
 
142
 
        ldmfd       sp!, {r0, lr}
143
 
        bx          lr
144
 
        .fnend
145
 
 
146
 
/* For GLIBC: libc_hidden_builtin_def (memcpy) */