blob: 6c143ad81b35991b618ebb3c4179ec41d1ead7f7 [file] [log] [blame]
Christopher Ferris04954a42013-02-26 01:30:00 -08001/*
Christopher Ferris796cbe22013-04-08 18:35:30 -07002 * Copyright (C) 2013 The Android Open Source Project
Christopher Ferris04954a42013-02-26 01:30:00 -08003 * 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 <machine/cpu-features.h>
30#include <machine/asm.h>
Christopher Ferris59a13c12013-08-01 13:13:33 -070031#include "libc_events.h"
Christopher Ferris04954a42013-02-26 01:30:00 -080032
Christopher Ferris59a13c12013-08-01 13:13:33 -070033 /*
34 * Optimized memset() for ARM.
Christopher Ferris04954a42013-02-26 01:30:00 -080035 *
36 * memset() returns its first argument.
Christopher Ferris59a13c12013-08-01 13:13:33 -070037 */
Christopher Ferris04954a42013-02-26 01:30:00 -080038
Christopher Ferris796cbe22013-04-08 18:35:30 -070039 .fpu neon
40 .syntax unified
Christopher Ferris04954a42013-02-26 01:30:00 -080041
Christopher Ferris59a13c12013-08-01 13:13:33 -070042ENTRY(__memset_chk)
43 cmp r2, r3
44 bls done
45
46 ldr r0, error_message
47 ldr r1, error_code
481:
49 add r0, pc
50 bl __fortify_chk_fail
51error_code:
52 .word BIONIC_EVENT_MEMSET_BUFFER_OVERFLOW
53error_message:
54 .word error_string-(1b+8)
55
56END(__memset_chk)
57
Christopher Ferris04954a42013-02-26 01:30:00 -080058ENTRY(bzero)
Christopher Ferris796cbe22013-04-08 18:35:30 -070059 mov r2, r1
60 mov r1, #0
Christopher Ferris59a13c12013-08-01 13:13:33 -070061
62done:
Christopher Ferris04954a42013-02-26 01:30:00 -080063 // Fall through to memset...
64END(bzero)
65
66ENTRY(memset)
67 .save {r0}
68 stmfd sp!, {r0}
69
Christopher Ferris796cbe22013-04-08 18:35:30 -070070 // The new algorithm is slower for copies < 16 so use the old
71 // neon code in that case.
Christopher Ferris04954a42013-02-26 01:30:00 -080072 cmp r2, #16
Christopher Ferris796cbe22013-04-08 18:35:30 -070073 blo set_less_than_16_unknown_align
Christopher Ferris04954a42013-02-26 01:30:00 -080074
Christopher Ferris796cbe22013-04-08 18:35:30 -070075 // Use strd which requires an even and odd register so move the
76 // values so that:
77 // r0 and r1 contain the memset value
78 // r2 is the number of bytes to set
79 // r3 is the destination pointer
80 mov r3, r0
Christopher Ferris04954a42013-02-26 01:30:00 -080081
Christopher Ferris796cbe22013-04-08 18:35:30 -070082 // Copy the byte value in every byte of r1.
83 mov r1, r1, lsl #24
84 orr r1, r1, r1, lsr #8
85 orr r1, r1, r1, lsr #16
Christopher Ferris04954a42013-02-26 01:30:00 -080086
Christopher Ferris796cbe22013-04-08 18:35:30 -070087check_alignment:
88 // Align destination to a double word to avoid the strd crossing
89 // a cache line boundary.
90 ands ip, r3, #7
91 bne do_double_word_align
Christopher Ferris04954a42013-02-26 01:30:00 -080092
Christopher Ferris796cbe22013-04-08 18:35:30 -070093double_word_aligned:
94 mov r0, r1
Christopher Ferris04954a42013-02-26 01:30:00 -080095
Christopher Ferris796cbe22013-04-08 18:35:30 -070096 subs r2, #64
97 blo set_less_than_64
Christopher Ferris04954a42013-02-26 01:30:00 -080098
Christopher Ferris796cbe22013-04-08 18:35:30 -0700991: // Main loop sets 64 bytes at a time.
100 .irp offset, #0, #8, #16, #24, #32, #40, #48, #56
101 strd r0, r1, [r3, \offset]
102 .endr
Christopher Ferris04954a42013-02-26 01:30:00 -0800103
Christopher Ferris796cbe22013-04-08 18:35:30 -0700104 add r3, #64
105 subs r2, #64
106 bge 1b
107
108set_less_than_64:
109 // Restore r2 to the count of bytes left to set.
110 add r2, #64
111 lsls ip, r2, #27
112 bcc set_less_than_32
113 // Set 32 bytes.
114 .irp offset, #0, #8, #16, #24
115 strd r0, r1, [r3, \offset]
116 .endr
117 add r3, #32
118
119set_less_than_32:
120 bpl set_less_than_16
121 // Set 16 bytes.
122 .irp offset, #0, #8
123 strd r0, r1, [r3, \offset]
124 .endr
125 add r3, #16
126
127set_less_than_16:
128 // Less than 16 bytes to set.
129 lsls ip, r2, #29
130 bcc set_less_than_8
131
132 // Set 8 bytes.
133 strd r0, r1, [r3], #8
134
135set_less_than_8:
136 bpl set_less_than_4
137 // Set 4 bytes
138 str r1, [r3], #4
139
140set_less_than_4:
141 lsls ip, r2, #31
142 it ne
143 strbne r1, [r3], #1
144 itt cs
145 strbcs r1, [r3], #1
146 strbcs r1, [r3]
147
148 ldmfd sp!, {r0}
149 bx lr
150
151do_double_word_align:
152 rsb ip, ip, #8
153 sub r2, r2, ip
154 movs r0, ip, lsl #31
155 it mi
156 strbmi r1, [r3], #1
157 itt cs
158 strbcs r1, [r3], #1
159 strbcs r1, [r3], #1
160
161 // Dst is at least word aligned by this point.
162 cmp ip, #4
163 blo double_word_aligned
164 str r1, [r3], #4
165 b double_word_aligned
166
167set_less_than_16_unknown_align:
168 // Set up to 15 bytes.
169 vdup.8 d0, r1
Christopher Ferris04954a42013-02-26 01:30:00 -0800170 movs ip, r2, lsl #29
171 bcc 1f
172 vst1.8 {d0}, [r0]!
1731: bge 2f
174 vst1.32 {d0[0]}, [r0]!
1752: movs ip, r2, lsl #31
Christopher Ferris796cbe22013-04-08 18:35:30 -0700176 it mi
177 strbmi r1, [r0], #1
178 itt cs
179 strbcs r1, [r0], #1
180 strbcs r1, [r0], #1
Christopher Ferris04954a42013-02-26 01:30:00 -0800181 ldmfd sp!, {r0}
182 bx lr
183END(memset)
Christopher Ferris59a13c12013-08-01 13:13:33 -0700184
185 .data
186error_string:
187 .string "memset buffer overflow"