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

« back to all changes in this revision

Viewing changes to reference/bionic/strcmp.S

  • Committer: Michael Hope
  • Date: 2012-06-12 03:21:36 UTC
  • Revision ID: michael.hope@linaro.org-20120612032136-00aiq3he862b0d0t
Added the new, Newlib derrived, string routines from Bionic.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2011 The Android Open Source Project
 
3
 * Copyright (c) 2008 ARM Ltd
 
4
 * All rights reserved.
 
5
 *
 
6
 * Redistribution and use in source and binary forms, with or without
 
7
 * modification, are permitted provided that the following conditions
 
8
 * are met:
 
9
 * 1. Redistributions of source code must retain the above copyright
 
10
 *    notice, this list of conditions and the following disclaimer.
 
11
 * 2. Redistributions in binary form must reproduce the above copyright
 
12
 *    notice, this list of conditions and the following disclaimer in the
 
13
 *    documentation and/or other materials provided with the distribution.
 
14
 * 3. The name of the company may not be used to endorse or promote
 
15
 *    products derived from this software without specific prior written
 
16
 *    permission.
 
17
 *
 
18
 * THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
 
19
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 
20
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 
21
 * IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
22
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 
23
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 
24
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 
25
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 
26
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 
27
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
28
 */
 
29
 
 
30
        .text
 
31
        .globl strcmp
 
32
        
 
33
#ifdef __ARMEB__
 
34
#define SHFT2LSB lsl
 
35
#define SHFT2LSBEQ lsleq
 
36
#define SHFT2MSB lsr
 
37
#define SHFT2MSBEQ lsreq
 
38
#define MSB 0x000000ff
 
39
#define LSB 0xff000000
 
40
#else
 
41
#define SHFT2LSB lsr
 
42
#define SHFT2LSBEQ lsreq
 
43
#define SHFT2MSB lsl
 
44
#define SHFT2MSBEQ lsleq
 
45
#define MSB 0xff000000
 
46
#define LSB 0x000000ff
 
47
#endif
 
48
 
 
49
#define magic1(REG) REG
 
50
#define magic2(REG) REG, lsl #7
 
51
 
 
52
strcmp:
 
53
        .fnstart
 
54
        PLD [r0, #0]
 
55
        PLD [r1, #0]
 
56
        eor     r2, r0, r1
 
57
        tst     r2, #3
 
58
 
 
59
        /* Strings not at same byte offset from a word boundary.  */
 
60
        bne     .Lstrcmp_unaligned
 
61
        ands    r2, r0, #3
 
62
        bic     r0, r0, #3
 
63
        bic     r1, r1, #3
 
64
        ldr     ip, [r0], #4
 
65
        it      eq
 
66
        ldreq   r3, [r1], #4
 
67
        beq     1f
 
68
 
 
69
        /* Although s1 and s2 have identical initial alignment, they are
 
70
         * not currently word aligned.  Rather than comparing bytes,
 
71
         * make sure that any bytes fetched from before the addressed
 
72
         * bytes are forced to 0xff.  Then they will always compare
 
73
         * equal.
 
74
         */
 
75
        eor     r2, r2, #3
 
76
        lsl     r2, r2, #3
 
77
        mvn     r3, #MSB
 
78
        SHFT2LSB        r2, r3, r2
 
79
        ldr     r3, [r1], #4
 
80
        orr     ip, ip, r2
 
81
        orr     r3, r3, r2
 
82
1:
 
83
        /* Load the 'magic' constant 0x01010101. */
 
84
        str     r4, [sp, #-4]!
 
85
        mov     r4, #1
 
86
        orr     r4, r4, r4, lsl #8
 
87
        orr     r4, r4, r4, lsl #16
 
88
        .p2align        2
 
89
4:
 
90
        PLD [r0, #8]
 
91
        PLD [r1, #8]
 
92
        sub     r2, ip, magic1(r4)
 
93
        cmp     ip, r3
 
94
        itttt   eq
 
95
 
 
96
        /* check for any zero bytes in first word */
 
97
        biceq   r2, r2, ip
 
98
        tsteq   r2, magic2(r4)
 
99
        ldreq   ip, [r0], #4
 
100
        ldreq   r3, [r1], #4
 
101
        beq     4b
 
102
2:
 
103
        /* There's a zero or a different byte in the word */
 
104
        SHFT2MSB        r0, ip, #24
 
105
        SHFT2LSB        ip, ip, #8
 
106
        cmp     r0, #1
 
107
        it      cs
 
108
        cmpcs   r0, r3, SHFT2MSB #24
 
109
        it      eq
 
110
        SHFT2LSBEQ r3, r3, #8
 
111
        beq     2b
 
112
        /* On a big-endian machine, r0 contains the desired byte in bits
 
113
         * 0-7; on a little-endian machine they are in bits 24-31.  In
 
114
         * both cases the other bits in r0 are all zero.  For r3 the
 
115
         * interesting byte is at the other end of the word, but the
 
116
         * other bits are not necessarily zero.  We need a signed result
 
117
         * representing the differnece in the unsigned bytes, so for the
 
118
         * little-endian case we can't just shift the interesting bits up.
 
119
         */
 
120
#ifdef __ARMEB__
 
121
        sub     r0, r0, r3, lsr #24
 
122
#else
 
123
        and     r3, r3, #255
 
124
        /* No RSB instruction in Thumb2 */
 
125
#ifdef __thumb2__
 
126
        lsr     r0, r0, #24
 
127
        sub     r0, r0, r3
 
128
#else
 
129
        rsb     r0, r3, r0, lsr #24
 
130
#endif
 
131
#endif
 
132
        ldr     r4, [sp], #4
 
133
        bx      lr
 
134
 
 
135
.Lstrcmp_unaligned:
 
136
        wp1 .req r0
 
137
        wp2 .req r1
 
138
        b1  .req r2
 
139
        w1  .req r4
 
140
        w2  .req r5
 
141
        t1  .req ip
 
142
        @ r3 is scratch
 
143
 
 
144
        /* First of all, compare bytes until wp1(sp1) is word-aligned. */
 
145
1:
 
146
        tst     wp1, #3
 
147
        beq     2f
 
148
        ldrb    r2, [wp1], #1
 
149
        ldrb    r3, [wp2], #1
 
150
        cmp     r2, #1
 
151
        it      cs
 
152
        cmpcs   r2, r3
 
153
        beq     1b
 
154
        sub     r0, r2, r3
 
155
        bx      lr
 
156
 
 
157
2:
 
158
        str     r5, [sp, #-4]!
 
159
        str     r4, [sp, #-4]!
 
160
        mov     b1, #1
 
161
        orr     b1, b1, b1, lsl #8
 
162
        orr     b1, b1, b1, lsl #16
 
163
 
 
164
        and     t1, wp2, #3
 
165
        bic     wp2, wp2, #3
 
166
        ldr     w1, [wp1], #4
 
167
        ldr     w2, [wp2], #4
 
168
        cmp     t1, #2
 
169
        beq     2f
 
170
        bhi     3f
 
171
 
 
172
        /* Critical inner Loop: Block with 3 bytes initial overlap */
 
173
        .p2align        2
 
174
1:
 
175
        bic     t1, w1, #MSB
 
176
        cmp     t1, w2, SHFT2LSB #8
 
177
        sub     r3, w1, b1
 
178
        bic     r3, r3, w1
 
179
        bne     4f
 
180
        ands    r3, r3, b1, lsl #7
 
181
        it      eq
 
182
        ldreq   w2, [wp2], #4
 
183
        bne     5f
 
184
        eor     t1, t1, w1
 
185
        cmp     t1, w2, SHFT2MSB #24
 
186
        bne     6f
 
187
        ldr     w1, [wp1], #4
 
188
        b       1b
 
189
4:
 
190
        SHFT2LSB        w2, w2, #8
 
191
        b       8f
 
192
 
 
193
5:
 
194
#ifdef __ARMEB__
 
195
        /* The syndrome value may contain false ones if the string ends
 
196
         * with the bytes 0x01 0x00
 
197
         */
 
198
        tst     w1, #0xff000000
 
199
        itt     ne
 
200
        tstne   w1, #0x00ff0000
 
201
        tstne   w1, #0x0000ff00
 
202
        beq     7f
 
203
#else
 
204
        bics    r3, r3, #0xff000000
 
205
        bne     7f
 
206
#endif
 
207
        ldrb    w2, [wp2]
 
208
        SHFT2LSB        t1, w1, #24
 
209
#ifdef __ARMEB__
 
210
        lsl     w2, w2, #24
 
211
#endif
 
212
        b       8f
 
213
 
 
214
6:
 
215
        SHFT2LSB        t1, w1, #24
 
216
        and     w2, w2, #LSB
 
217
        b       8f
 
218
 
 
219
        /* Critical inner Loop: Block with 2 bytes initial overlap */
 
220
        .p2align        2
 
221
2:
 
222
        SHFT2MSB        t1, w1, #16
 
223
        sub     r3, w1, b1
 
224
        SHFT2LSB        t1, t1, #16
 
225
        bic     r3, r3, w1
 
226
        cmp     t1, w2, SHFT2LSB #16
 
227
        bne     4f
 
228
        ands    r3, r3, b1, lsl #7
 
229
        it      eq
 
230
        ldreq   w2, [wp2], #4
 
231
        bne     5f
 
232
        eor     t1, t1, w1
 
233
        cmp     t1, w2, SHFT2MSB #16
 
234
        bne     6f
 
235
        ldr     w1, [wp1], #4
 
236
        b       2b
 
237
 
 
238
5:
 
239
#ifdef __ARMEB__
 
240
        /* The syndrome value may contain false ones if the string ends
 
241
         * with the bytes 0x01 0x00
 
242
         */
 
243
        tst     w1, #0xff000000
 
244
        it      ne
 
245
        tstne   w1, #0x00ff0000
 
246
        beq     7f
 
247
#else
 
248
        lsls    r3, r3, #16
 
249
        bne     7f
 
250
#endif
 
251
        ldrh    w2, [wp2]
 
252
        SHFT2LSB        t1, w1, #16
 
253
#ifdef __ARMEB__
 
254
        lsl     w2, w2, #16
 
255
#endif
 
256
        b       8f
 
257
 
 
258
6:
 
259
        SHFT2MSB        w2, w2, #16
 
260
        SHFT2LSB        t1, w1, #16
 
261
4:
 
262
        SHFT2LSB        w2, w2, #16
 
263
        b       8f
 
264
 
 
265
        /* Critical inner Loop: Block with 1 byte initial overlap */
 
266
        .p2align        2
 
267
3:
 
268
        and     t1, w1, #LSB
 
269
        cmp     t1, w2, SHFT2LSB #24
 
270
        sub     r3, w1, b1
 
271
        bic     r3, r3, w1
 
272
        bne     4f
 
273
        ands    r3, r3, b1, lsl #7
 
274
        it      eq
 
275
        ldreq   w2, [wp2], #4
 
276
        bne     5f
 
277
        eor     t1, t1, w1
 
278
        cmp     t1, w2, SHFT2MSB #8
 
279
        bne     6f
 
280
        ldr     w1, [wp1], #4
 
281
        b       3b
 
282
4:
 
283
        SHFT2LSB        w2, w2, #24
 
284
        b       8f
 
285
5:
 
286
        /* The syndrome value may contain false ones if the string ends
 
287
         * with the bytes 0x01 0x00
 
288
         */
 
289
        tst     w1, #LSB
 
290
        beq     7f
 
291
        ldr     w2, [wp2], #4
 
292
6:
 
293
        SHFT2LSB        t1, w1, #8
 
294
        bic     w2, w2, #MSB
 
295
        b       8f
 
296
7:
 
297
        mov     r0, #0
 
298
        ldr     r4, [sp], #4
 
299
        ldr     r5, [sp], #4
 
300
        bx      lr
 
301
 
 
302
8:
 
303
        and     r2, t1, #LSB
 
304
        and     r0, w2, #LSB
 
305
        cmp     r0, #1
 
306
        it      cs
 
307
        cmpcs   r0, r2
 
308
        itt     eq
 
309
        SHFT2LSBEQ      t1, t1, #8
 
310
        SHFT2LSBEQ      w2, w2, #8
 
311
        beq     8b
 
312
        sub     r0, r2, r0
 
313
        ldr     r4, [sp], #4
 
314
        ldr     r5, [sp], #4
 
315
        bx      lr
 
316
 
 
317
        .fnend