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

« back to all changes in this revision

Viewing changes to reference/bionic/strlen.c

  • Committer: Will Newton
  • Date: 2013-04-30 14:31:08 UTC
  • Revision ID: will.newton@linaro.org-20130430143108-ww31c741wek8dnus
Split bionic reference code into A15 and A9 versions.

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
 
#include <string.h>
30
 
#include <stdint.h>
31
 
#undef strlen
32
 
 
33
 
#define __ARM_HAVE_PLD  1
34
 
 
35
 
size_t strlen(const char *s)
36
 
{
37
 
    __builtin_prefetch(s);
38
 
    __builtin_prefetch(s+32);
39
 
    
40
 
    union {
41
 
        const char      *b;
42
 
        const uint32_t  *w;
43
 
        uintptr_t       i;
44
 
    } u;
45
 
    
46
 
    // these are some scratch variables for the asm code below
47
 
    uint32_t v, t;
48
 
    
49
 
    // initialize the string length to zero
50
 
    size_t l = 0;
51
 
 
52
 
    // align the pointer to a 32-bit word boundary
53
 
    u.b = s;
54
 
    while (u.i & 0x3)  {
55
 
        if (__builtin_expect(*u.b++ == 0, 0)) {
56
 
            goto done;
57
 
        }
58
 
        l++;
59
 
    }
60
 
 
61
 
    // loop for each word, testing if it contains a zero byte
62
 
    // if so, exit the loop and update the length.
63
 
    // We need to process 32 bytes per loop to schedule PLD properly
64
 
    // and achieve the maximum bus speed.
65
 
    asm(
66
 
        "ldr     %[v], [%[s]], #4         \n"
67
 
        "sub     %[l], %[l], %[s]           \n"
68
 
        "0:                                 \n"
69
 
#if __ARM_HAVE_PLD
70
 
        "pld     [%[s], #64]              \n"
71
 
#endif
72
 
        "sub     %[t], %[v], %[mask], lsr #7\n"
73
 
        "and     %[t], %[t], %[mask]        \n"
74
 
        "bics    %[t], %[t], %[v]           \n"
75
 
        "ldreq   %[v], [%[s]], #4         \n"
76
 
#if !defined(__OPTIMIZE_SIZE__)
77
 
        "bne     1f                         \n"
78
 
        "sub     %[t], %[v], %[mask], lsr #7\n"
79
 
        "and     %[t], %[t], %[mask]        \n"
80
 
        "bics    %[t], %[t], %[v]           \n"
81
 
        "ldreq   %[v], [%[s]], #4         \n"
82
 
        "bne     1f                         \n"
83
 
        "sub     %[t], %[v], %[mask], lsr #7\n"
84
 
        "and     %[t], %[t], %[mask]        \n"
85
 
        "bics    %[t], %[t], %[v]           \n"
86
 
        "ldreq   %[v], [%[s]], #4         \n"
87
 
        "bne     1f                         \n"
88
 
        "sub     %[t], %[v], %[mask], lsr #7\n"
89
 
        "and     %[t], %[t], %[mask]        \n"
90
 
        "bics    %[t], %[t], %[v]           \n"
91
 
        "ldreq   %[v], [%[s]], #4         \n"
92
 
        "bne     1f                         \n"
93
 
        "sub     %[t], %[v], %[mask], lsr #7\n"
94
 
        "and     %[t], %[t], %[mask]        \n"
95
 
        "bics    %[t], %[t], %[v]           \n"
96
 
        "ldreq   %[v], [%[s]], #4         \n"
97
 
        "bne     1f                         \n"
98
 
        "sub     %[t], %[v], %[mask], lsr #7\n"
99
 
        "and     %[t], %[t], %[mask]        \n"
100
 
        "bics    %[t], %[t], %[v]           \n"
101
 
        "ldreq   %[v], [%[s]], #4         \n"
102
 
        "bne     1f                         \n"
103
 
        "sub     %[t], %[v], %[mask], lsr #7\n"
104
 
        "and     %[t], %[t], %[mask]        \n"
105
 
        "bics    %[t], %[t], %[v]           \n"
106
 
        "ldreq   %[v], [%[s]] , #4         \n"
107
 
        "bne     1f                         \n"
108
 
        "sub     %[t], %[v], %[mask], lsr #7\n"
109
 
        "and     %[t], %[t], %[mask]        \n"
110
 
        "bics    %[t], %[t], %[v]           \n"
111
 
        "ldreq   %[v], [%[s]], #4         \n"
112
 
#endif
113
 
        "beq     0b                         \n"
114
 
        "1:                                 \n"
115
 
        "add     %[l], %[l], %[s]           \n"
116
 
        "tst     %[v], #0xFF                \n"
117
 
        "beq     2f                         \n"
118
 
        "add     %[l], %[l], #1             \n"
119
 
        "tst     %[v], #0xFF00              \n"
120
 
        "beq     2f                         \n"
121
 
        "add     %[l], %[l], #1             \n"
122
 
        "tst     %[v], #0xFF0000            \n"
123
 
        "addne   %[l], %[l], #1             \n"
124
 
        "2:                                 \n"
125
 
        : [l]"=&r"(l), [v]"=&r"(v), [t]"=&r"(t), [s]"=&r"(u.b)
126
 
        : "%[l]"(l), "%[s]"(u.b), [mask]"r"(0x80808080UL)
127
 
        : "cc"
128
 
    );
129
 
    
130
 
done:
131
 
    return l;
132
 
}