]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - android-sdk/platform-bionic.git/blob - libc/arch-arm/cortex-a15/bionic/memset.S
Merge "syslog needs a valid socket path for _PATH_LOG"
[android-sdk/platform-bionic.git] / libc / arch-arm / cortex-a15 / bionic / memset.S
1 /*
2  * Copyright (C) 2013 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  */
29 #include <machine/cpu-features.h>
30 #include <machine/asm.h>
32                 /*
33                  * Optimized memset() for ARM.
34          *
35          * memset() returns its first argument.
36                  */
38         .fpu        neon
39         .syntax     unified
41 ENTRY(bzero)
42         mov         r2, r1
43         mov         r1, #0
44         // Fall through to memset...
45 END(bzero)
47 ENTRY(memset)
48         .save       {r0}
49         stmfd       sp!, {r0}
51         // The new algorithm is slower for copies < 16 so use the old
52         // neon code in that case.
53         cmp         r2, #16
54         blo         set_less_than_16_unknown_align
56         // Use strd which requires an even and odd register so move the
57         // values so that:
58         //   r0 and r1 contain the memset value
59         //   r2 is the number of bytes to set
60         //   r3 is the destination pointer
61         mov         r3, r0
63         // Copy the byte value in every byte of r1.
64         mov         r1, r1, lsl #24
65         orr         r1, r1, r1, lsr #8
66         orr         r1, r1, r1, lsr #16
68 check_alignment:
69         // Align destination to a double word to avoid the strd crossing
70         // a cache line boundary.
71         ands        ip, r3, #7
72         bne         do_double_word_align
74 double_word_aligned:
75         mov         r0, r1
77         subs        r2, #64
78         blo         set_less_than_64
80 1:      // Main loop sets 64 bytes at a time.
81         .irp        offset, #0, #8, #16, #24, #32, #40, #48, #56
82         strd        r0, r1, [r3, \offset]
83         .endr
85         add         r3, #64
86         subs        r2, #64
87         bge         1b
89 set_less_than_64:
90         // Restore r2 to the count of bytes left to set.
91         add         r2, #64
92         lsls        ip, r2, #27
93         bcc         set_less_than_32
94         // Set 32 bytes.
95         .irp        offset, #0, #8, #16, #24
96         strd        r0, r1, [r3, \offset]
97         .endr
98         add         r3, #32
100 set_less_than_32:
101         bpl         set_less_than_16
102         // Set 16 bytes.
103         .irp        offset, #0, #8
104         strd        r0, r1, [r3, \offset]
105         .endr
106         add         r3, #16
108 set_less_than_16:
109         // Less than 16 bytes to set.
110         lsls        ip, r2, #29
111         bcc         set_less_than_8
113         // Set 8 bytes.
114         strd        r0, r1, [r3], #8
116 set_less_than_8:
117         bpl         set_less_than_4
118         // Set 4 bytes
119         str         r1, [r3], #4
121 set_less_than_4:
122         lsls        ip, r2, #31
123         it          ne
124         strbne      r1, [r3], #1
125         itt         cs
126         strbcs      r1, [r3], #1
127         strbcs      r1, [r3]
129         ldmfd       sp!, {r0}
130         bx          lr
132 do_double_word_align:
133         rsb         ip, ip, #8
134         sub         r2, r2, ip
135         movs        r0, ip, lsl #31
136         it          mi
137         strbmi      r1, [r3], #1
138         itt         cs
139         strbcs      r1, [r3], #1
140         strbcs      r1, [r3], #1
142         // Dst is at least word aligned by this point.
143         cmp         ip, #4
144         blo         double_word_aligned
145         str         r1, [r3], #4
146         b           double_word_aligned
148 set_less_than_16_unknown_align:
149         // Set up to 15 bytes.
150         vdup.8      d0, r1
151         movs        ip, r2, lsl #29
152         bcc         1f
153         vst1.8      {d0}, [r0]!
154 1:      bge         2f
155         vst1.32     {d0[0]}, [r0]!
156 2:      movs        ip, r2, lsl #31
157         it          mi
158         strbmi      r1, [r0], #1
159         itt         cs
160         strbcs      r1, [r0], #1
161         strbcs      r1, [r0], #1
162         ldmfd       sp!, {r0}
163         bx          lr
164 END(memset)