1753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris/*
2753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris * Copyright (C) 2014 The Android Open Source Project
3753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris * All rights reserved.
4753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris *
5753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris * Redistribution and use in source and binary forms, with or without
6753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris * modification, are permitted provided that the following conditions
7753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris * are met:
8753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris *  * Redistributions of source code must retain the above copyright
9753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris *    notice, this list of conditions and the following disclaimer.
10753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris *  * Redistributions in binary form must reproduce the above copyright
11753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris *    notice, this list of conditions and the following disclaimer in
12753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris *    the documentation and/or other materials provided with the
13753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris *    distribution.
14753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris *
15753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris * SUCH DAMAGE.
27753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris */
2815581383153c5da29befb7f5cdc30bc21e9da54bElliott Hughes
2915581383153c5da29befb7f5cdc30bc21e9da54bElliott Hughes/*
3015581383153c5da29befb7f5cdc30bc21e9da54bElliott Hughes   Copyright (c) 2014, Linaro Limited
31753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris   All rights reserved.
32753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris
33753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris   Redistribution and use in source and binary forms, with or without
34753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris   modification, are permitted provided that the following conditions are met:
35753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris       * Redistributions of source code must retain the above copyright
36753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris         notice, this list of conditions and the following disclaimer.
37753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris       * Redistributions in binary form must reproduce the above copyright
38753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris         notice, this list of conditions and the following disclaimer in the
39753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris         documentation and/or other materials provided with the distribution.
40753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris       * Neither the name of the Linaro nor the
41753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris         names of its contributors may be used to endorse or promote products
42753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris         derived from this software without specific prior written permission.
43753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris
44753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
45753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
46753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
47753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
48753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris   HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
49753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
50753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
51753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
52753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
53753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
54753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
55753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris*/
56753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris
57753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris/* Assumptions:
58753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris *
59753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris * ARMv8-a, AArch64
60753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris */
61753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris
62753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#if !defined(STPCPY) && !defined(STRCPY)
63753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#error "Either STPCPY or STRCPY must be defined."
64753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#endif
65753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris
66753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#include <private/bionic_asm.h>
67753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris
68753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris/* Arguments and results.  */
69753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#if defined(STPCPY)
70753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#define dst         x0
71753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#elif defined(STRCPY)
72753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#define dstin       x0
73753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#endif
74753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#define src         x1
75753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris
76753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris/* Locals and temporaries.  */
77753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#if defined(STRCPY)
78753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#define dst         x2
79753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#endif
80753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#define data1       x3
81753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#define data1_w     w3
82753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#define data2       x4
83753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#define data2_w     w4
84753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#define has_nul1    x5
85753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#define has_nul1_w  w5
86753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#define has_nul2    x6
87753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#define tmp1        x7
88753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#define tmp2        x8
89753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#define tmp3        x9
90753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#define tmp4        x10
91753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#define zeroones    x11
92753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#define zeroones_w  w11
93753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#define pos         x12
94753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris
95753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#define REP8_01 0x0101010101010101
96753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#define REP8_7f 0x7f7f7f7f7f7f7f7f
97753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#define REP8_80 0x8080808080808080
98753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris
99753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#if defined(STPCPY)
100753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher FerrisENTRY(stpcpy)
101753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#elif defined(STRCPY)
102753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher FerrisENTRY(strcpy)
103753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#endif
104753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    mov     zeroones, #REP8_01
105753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#if defined(STRCPY)
106753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    mov     dst, dstin
107753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#endif
108753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    ands    tmp1, src, #15
109753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    b.ne    .Lmisaligned
110753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    // NUL detection works on the principle that (X - 1) & (~X) & 0x80
111753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    // (=> (X - 1) & ~(X | 0x7f)) is non-zero iff a byte is zero, and
112753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    // can be done in parallel across the entire word.
113753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    // The inner loop deals with two Dwords at a time.  This has a
114753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    // slightly higher start-up cost, but we should win quite quickly,
115753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    // especially on cores with a high number of issue slots per
116753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    // cycle, as we get much better parallelism out of the operations.
117753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris.Lloop:
118753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    ldp     data1, data2, [src], #16
119753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    sub     tmp1, data1, zeroones
120753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    orr     tmp2, data1, #REP8_7f
121753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    bic     has_nul1, tmp1, tmp2
122753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    cbnz    has_nul1, .Lnul_in_data1
123753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    sub     tmp3, data2, zeroones
124753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    orr     tmp4, data2, #REP8_7f
125753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    bic     has_nul2, tmp3, tmp4
126753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    cbnz    has_nul2, .Lnul_in_data2
127753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    // No NUL in either register, copy it in a single instruction.
128753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    stp     data1, data2, [dst], #16
129753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    b       .Lloop
130753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris
131753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris.Lnul_in_data1:
132753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    rev     has_nul1, has_nul1
133753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    clz     pos, has_nul1
134753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    add     tmp1, pos, #0x8
135753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris
136753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    tbz     tmp1, #6, 1f
137753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#if defined(STPCPY)
138753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    str     data1, [dst], #7
139753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#elif defined(STRCPY)
140753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    str     data1, [dst]
141753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#endif
142753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    ret
143753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris1:
144753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    tbz     tmp1, #5, 1f
145753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    str     data1_w, [dst], #4
146753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    lsr     data1, data1, #32
147753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris1:
148753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    tbz     tmp1, #4, 1f
149753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    strh    data1_w, [dst], #2
150753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    lsr     data1, data1, #16
151753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris1:
152753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    tbz     tmp1, #3, 1f
153753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    strb    data1_w, [dst]
154753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#if defined(STPCPY)
155753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    ret
156753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#endif
157753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris1:
158753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#if defined(STPCPY)
159753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    // Back up one so that dst points to the '\0' string terminator.
160753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    sub     dst, dst, #1
161753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#endif
162753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    ret
163753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris
164753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris.Lnul_in_data2:
165753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    str     data1, [dst], #8
166753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    rev     has_nul2, has_nul2
167753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    clz     pos, has_nul2
168753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    add     tmp1, pos, #0x8
169753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris
170753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    tbz     tmp1, #6, 1f
171753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#if defined(STPCPY)
172753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    str     data2, [dst], #7
173753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#elif defined(STRCPY)
174753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    str     data2, [dst]
175753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#endif
176753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    ret
177753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris1:
178753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    tbz     tmp1, #5, 1f
179753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    str     data2_w, [dst], #4
180753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    lsr     data2, data2, #32
181753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris1:
182753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    tbz     tmp1, #4, 1f
183753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    strh    data2_w, [dst], #2
184753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    lsr     data2, data2, #16
185753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris1:
186753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    tbz     tmp1, #3, 1f
187753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    strb    data2_w, [dst]
188753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#if defined(STPCPY)
189753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    ret
190753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#endif
191753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris1:
192753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#if defined(STPCPY)
193753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    // Back up one so that dst points to the '\0' string terminator.
194753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    sub     dst, dst, #1
195753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#endif
196753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    ret
197753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris
198753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris.Lmisaligned:
199753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    tbz     src, #0, 1f
200753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    ldrb    data1_w, [src], #1
201753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    strb    data1_w, [dst], #1
202753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    cbnz    data1_w, 1f
203753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#if defined(STPCPY)
204753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    // Back up one so that dst points to the '\0' string terminator.
205753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    sub     dst, dst, #1
206753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#endif
207753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    ret
208753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris1:
209753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    tbz     src, #1, 1f
210753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    ldrb    data1_w, [src], #1
211753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    strb    data1_w, [dst], #1
212753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    cbz     data1_w, .Ldone
213753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    ldrb    data2_w, [src], #1
214753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    strb    data2_w, [dst], #1
215753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    cbnz    data2_w, 1f
216753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris.Ldone:
217753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#if defined(STPCPY)
218753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    // Back up one so that dst points to the '\0' string terminator.
219753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    sub     dst, dst, #1
220753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#endif
221753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    ret
222753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris1:
223753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    tbz     src, #2, 1f
224753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    ldr     data1_w, [src], #4
225753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    // Check for a zero.
226753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    sub     has_nul1_w, data1_w, zeroones_w
227753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    bic     has_nul1_w, has_nul1_w, data1_w
228753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    ands    has_nul1_w, has_nul1_w, #0x80808080
229753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    b.ne    .Lnul_in_data1
230753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    str     data1_w, [dst], #4
231753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris1:
232753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    tbz     src, #3, .Lloop
233753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    ldr     data1, [src], #8
234753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    // Check for a zero.
235753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    sub     tmp1, data1, zeroones
236753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    orr     tmp2, data1, #REP8_7f
237753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    bics    has_nul1, tmp1, tmp2
238753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    b.ne    .Lnul_in_data1
239753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    str     data1, [dst], #8
240753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris    b       .Lloop
241753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#if defined(STPCPY)
242753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher FerrisEND(stpcpy)
243753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#elif defined(STRCPY)
244753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher FerrisEND(strcpy)
245753eb7f07e7736ba3bd73b2653cbfb8863da2278Christopher Ferris#endif
246