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

« back to all changes in this revision

Viewing changes to reference/bionic/memcpy.S

  • Committer: Michael Hope
  • Date: 2012-06-12 03:20:20 UTC
  • Revision ID: michael.hope@linaro.org-20120612032020-zzfhquws5xkaiib7
Updated the Bionic routines and shifted the C only routines out.

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
 */
28
28
 
29
29
#define __ARM_NEON__
 
30
#define HAVE_32_BYTE_CACHE_LINE
30
31
 
31
32
#if defined(__ARM_NEON__)
32
33
 
33
34
        .text
34
35
        .fpu    neon
35
 
 
36
36
        .global memcpy
37
37
        .type memcpy, %function
38
38
        .align 4
39
39
 
 
40
#ifdef HAVE_32_BYTE_CACHE_LINE
 
41
/* a prefetch distance of 2 cache-lines */
 
42
#define CACHE_LINE_SIZE     32
 
43
#define PREFETCH_DISTANCE   (CACHE_LINE_SIZE*2)
 
44
#else
40
45
/* a prefetch distance of 4 cache-lines works best experimentally */
41
46
#define CACHE_LINE_SIZE     64
42
47
#define PREFETCH_DISTANCE   (CACHE_LINE_SIZE*4)
 
48
#endif
43
49
 
44
50
memcpy:
45
 
        .fnstart
 
51
        .fnstart
46
52
        .save       {r0, lr}
 
53
        /* start preloading as early as possible */
 
54
        pld         [r1, #(CACHE_LINE_SIZE*0)]
47
55
        stmfd       sp!, {r0, lr}
48
 
 
49
 
        /* start preloading as early as possible */
50
 
        pld         [r1, #(CACHE_LINE_SIZE*0)]
51
56
        pld         [r1, #(CACHE_LINE_SIZE*1)]
52
57
 
53
58
        /* do we have at least 16-bytes to copy (needed for alignment below) */
54
59
        cmp         r2, #16
55
60
        blo         5f
56
61
 
57
 
        /* align destination to half cache-line for the write-buffer */
 
62
        /* align destination to cache-line for the write-buffer */
58
63
        rsb         r3, r0, #0
59
64
        ands        r3, r3, #0xF
60
65
        beq         0f
83
88
        pld         [r1, #(CACHE_LINE_SIZE*0)]
84
89
        pld         [r1, #(CACHE_LINE_SIZE*1)]
85
90
 
 
91
#ifdef HAVE_32_BYTE_CACHE_LINE
 
92
        /* make sure we have at least 32 bytes to copy */
 
93
        subs        r2, r2, #32
 
94
        blo         4f
 
95
 
 
96
        /* preload all the cache lines we need.
 
97
         * NOTE: the number of pld below depends on PREFETCH_DISTANCE,
 
98
         * ideally would would increase the distance in the main loop to
 
99
         * avoid the goofy code below. In practice this doesn't seem to make
 
100
         * a big difference.
 
101
         */
 
102
        pld         [r1, #(PREFETCH_DISTANCE)]
 
103
 
 
104
1:      /* The main loop copies 32 bytes at a time */
 
105
        vld1.8      {d0  - d3},   [r1]!
 
106
        pld         [r1, #(PREFETCH_DISTANCE)]
 
107
        subs        r2, r2, #32
 
108
        vst1.8      {d0  - d3},   [r0, :128]!
 
109
        bhs         1b
 
110
#else
86
111
        /* make sure we have at least 64 bytes to copy */
87
112
        subs        r2, r2, #64
88
113
        blo         2f
116
141
        subs        r2, r2, #32
117
142
        vst1.8      {d0 - d3},  [r0, :128]!
118
143
        bhs         3b
119
 
 
 
144
#endif
120
145
4:      /* less than 32 left */
121
146
        add         r2, r2, #32
122
147
        tst         r2, #0x10
143
168
 
144
169
        ldmfd       sp!, {r0, lr}
145
170
        bx          lr
146
 
        .fnend
 
171
        .fnend
147
172
 
148
173
 
149
174
#else   /* __ARM_ARCH__ < 7 */
150
175
 
151
176
 
152
 
        .text
153
 
 
154
 
    .global memcpy
155
 
    .type memcpy, %function
156
 
    .align 4
157
 
 
158
177
                /*
159
178
                 * Optimized memcpy() for ARM.
160
179
         *
162
181
                 * so we have to preserve R0.
163
182
                 */
164
183
 
165
 
memcpy:
 
184
ENTRY(memcpy)
166
185
                /* The stack must always be 64-bits aligned to be compliant with the
167
186
                 * ARM ABI. Since we have to save R0, we might as well save R4
168
187
                 * which we can use for better pipelining of the reads below
169
188
                 */
170
 
        .fnstart
171
189
        .save       {r0, r4, lr}
172
190
        stmfd       sp!, {r0, r4, lr}
173
191
        /* Making room for r5-r11 which will be spilled later */
504
522
        add         sp,  sp, #28
505
523
                ldmfd           sp!, {r0, r4, lr}
506
524
                bx                      lr
507
 
        .fnend
 
525
END(memcpy)
508
526
 
509
527
 
510
528
#endif    /* __ARM_ARCH__ < 7 */