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

« back to all changes in this revision

Viewing changes to src/linaro-a9/strlen.S

  • Committer: Will Newton
  • Date: 2013-06-18 18:06:27 UTC
  • Revision ID: will.newton@linaro.org-20130618180627-urv0s5ywnk3ozbpw
Switch to new implementation of strlen.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (c) 2010-2011, Linaro Limited
2
 
   All rights reserved.
3
 
 
4
 
   Redistribution and use in source and binary forms, with or without
5
 
   modification, are permitted provided that the following conditions
6
 
   are met:
7
 
 
8
 
      * Redistributions of source code must retain the above copyright
9
 
      notice, this list of conditions and the following disclaimer.
10
 
 
11
 
      * 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
 
 
15
 
      * Neither the name of Linaro Limited nor the names of its
16
 
      contributors may be used to endorse or promote products derived
17
 
      from this software without specific prior written permission.
18
 
 
19
 
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
 
   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
 
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
 
   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
 
   HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
 
   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
 
   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
 
   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
 
   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
 
   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
 
   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
 
 
31
 
   Written by Dave Gilbert <david.gilbert@linaro.org>
32
 
 
33
 
   This strlen routine is optimised on a Cortex-A9 and should work on
34
 
   all ARMv7 processors.   This routine is reasonably fast for short
35
 
   strings, but is probably slower than a simple implementation if all
36
 
   your strings are very short */
37
 
 
38
 
@ 2011-02-08 david.gilbert@linaro.org
39
 
@    Extracted from local git 6848613a
40
 
 
41
 
 
42
 
@ this lets us check a flag in a 00/ff byte easily in either endianness
43
 
#ifdef __ARMEB__
44
 
#define CHARTSTMASK(c) 1<<(31-(c*8))
45
 
#else
46
 
#define CHARTSTMASK(c) 1<<(c*8)
47
 
#endif
48
 
 
49
 
@-----------------------------------------------------------------------------------------------------------------------------
50
 
        .syntax unified
51
 
        .arch armv7-a
52
 
 
53
 
        .thumb_func
54
 
        .align 2
55
 
        .p2align 4,,15
56
 
        .global strlen
57
 
        .type strlen,%function
58
 
strlen:
59
 
        @ r0 = string
60
 
        @ returns count of bytes in string not including terminator
61
 
        mov     r1, r0
62
 
        push    { r4,r6 }
63
 
        mvns    r6, #0          @ all F
64
 
        movs    r4, #0
65
 
        tst     r0, #7
66
 
        beq     2f
67
 
 
68
 
1:
69
 
        ldrb    r2, [r1], #1
70
 
        tst     r1, #7          @ Hit alignment yet?
71
 
        cbz     r2, 10f         @ Exit if we found the 0
72
 
        bne     1b
73
 
 
74
 
        @ So we're now aligned
75
 
2:
76
 
        ldmia   r1!,{r2,r3}
77
 
        uadd8   r2, r2, r6      @ Parallel add 0xff - sets the GE bits for anything that wasn't 0
78
 
        sel     r2, r4, r6      @ bytes are 00 for none-00 bytes, or ff for 00 bytes - NOTE INVERSION
79
 
        uadd8   r3, r3, r6      @ Parallel add 0xff - sets the GE bits for anything that wasn't 0
80
 
        sel     r3, r2, r6      @ bytes are 00 for none-00 bytes, or ff for 00 bytes - NOTE INVERSION
81
 
        cmp     r3, #0
82
 
        beq     2b
83
 
 
84
 
strlenendtmp:
85
 
        @ One (or more) of the bytes we loaded was 0 - but which one?
86
 
        @ r2 has the mask corresponding to the first loaded word
87
 
        @ r3 has a combined mask of the two words - but if r2 was all-non 0 
88
 
        @ then it's just the 2nd words
89
 
        cmp     r2, #0
90
 
        itte    eq
91
 
        moveq   r2, r3          @ the end is in the 2nd word
92
 
        subeq   r1,r1,#3
93
 
        subne   r1,r1,#7
94
 
 
95
 
        @ r1 currently points to the 2nd byte of the word containing the 0
96
 
        tst     r2, # CHARTSTMASK(0)    @ 1st character
97
 
        bne     10f
98
 
        adds    r1,r1,#1
99
 
        tst     r2, # CHARTSTMASK(1)    @ 2nd character
100
 
        ittt    eq
101
 
        addeq   r1,r1,#1
102
 
        tsteq   r2, # (3<<15)   @ 2nd & 3rd character
103
 
        @ If not the 3rd must be the last one
104
 
        addeq   r1,r1,#1
105
 
 
106
 
10:
107
 
        @ r0 is still at the beginning, r1 is pointing 1 byte after the terminator
108
 
        sub     r0, r1, r0
109
 
        subs    r0, r0, #1
110
 
        pop     { r4, r6 }
111
 
        bx      lr