blob: a5057eb04c4443e969f5614839803b7d066bc740 [file] [log] [blame]
Christopher Ferris7c83a1e2013-02-26 01:30:00 -08001/*
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
Elliott Hughes851e68a2014-02-19 16:53:20 -080029#include <private/bionic_asm.h>
30#include <private/libc_events.h>
Christopher Ferris7c83a1e2013-02-26 01:30:00 -080031
32/*
33 * This code assumes it is running on a processor that supports all arm v7
34 * instructions and that supports neon instructions.
35 */
36
37 .fpu neon
38
Christopher Ferris59a13c12013-08-01 13:13:33 -070039ENTRY(__memset_chk)
40 cmp r2, r3
Christopher Ferris5f45d582013-08-07 13:09:51 -070041 bls .L_done
42
43 // Preserve lr for backtrace.
44 push {lr}
Christopher Ferrisa57c9c02013-08-21 09:41:12 -070045 .save {lr}
Christopher Ferris5f45d582013-08-07 13:09:51 -070046 .cfi_def_cfa_offset 4
47 .cfi_rel_offset lr, 0
Christopher Ferris59a13c12013-08-01 13:13:33 -070048
49 ldr r0, error_message
50 ldr r1, error_code
511:
52 add r0, pc
53 bl __fortify_chk_fail
54error_code:
55 .word BIONIC_EVENT_MEMSET_BUFFER_OVERFLOW
56error_message:
57 .word error_string-(1b+8)
Christopher Ferris59a13c12013-08-01 13:13:33 -070058END(__memset_chk)
59
Christopher Ferris7c83a1e2013-02-26 01:30:00 -080060ENTRY(bzero)
61 mov r2, r1
62 mov r1, #0
Christopher Ferris59a13c12013-08-01 13:13:33 -070063
Christopher Ferris5f45d582013-08-07 13:09:51 -070064.L_done:
Christopher Ferris59a13c12013-08-01 13:13:33 -070065 // Fall through to memset...
Christopher Ferris7c83a1e2013-02-26 01:30:00 -080066END(bzero)
67
68/* memset() returns its first argument. */
69ENTRY(memset)
Christopher Ferris507cfe22013-11-19 13:45:27 -080070 // The neon memset only wins for less than 132.
Christopher Ferris7c83a1e2013-02-26 01:30:00 -080071 cmp r2, #132
Christopher Ferrisa57c9c02013-08-21 09:41:12 -070072 bhi __memset_large_copy
Christopher Ferris7c83a1e2013-02-26 01:30:00 -080073
Christopher Ferris7c83a1e2013-02-26 01:30:00 -080074 stmfd sp!, {r0}
Christopher Ferrisa57c9c02013-08-21 09:41:12 -070075 .save {r0}
Christopher Ferris5f45d582013-08-07 13:09:51 -070076 .cfi_def_cfa_offset 4
77 .cfi_rel_offset r0, 0
Christopher Ferris7c83a1e2013-02-26 01:30:00 -080078
79 vdup.8 q0, r1
80
81 /* make sure we have at least 32 bytes to write */
82 subs r2, r2, #32
83 blo 2f
84 vmov q1, q0
85
861: /* The main loop writes 32 bytes at a time */
87 subs r2, r2, #32
88 vst1.8 {d0 - d3}, [r0]!
89 bhs 1b
90
912: /* less than 32 left */
92 add r2, r2, #32
93 tst r2, #0x10
94 beq 3f
95
96 // writes 16 bytes, 128-bits aligned
97 vst1.8 {d0, d1}, [r0]!
983: /* write up to 15-bytes (count in r2) */
99 movs ip, r2, lsl #29
100 bcc 1f
101 vst1.8 {d0}, [r0]!
1021: bge 2f
103 vst1.32 {d0[0]}, [r0]!
1042: movs ip, r2, lsl #31
105 strmib r1, [r0], #1
106 strcsb r1, [r0], #1
107 strcsb r1, [r0], #1
108 ldmfd sp!, {r0}
109 bx lr
Christopher Ferrisa57c9c02013-08-21 09:41:12 -0700110END(memset)
111
Nick Kralevich32bbf8a2013-10-02 16:54:58 -0700112ENTRY_PRIVATE(__memset_large_copy)
Christopher Ferris7c83a1e2013-02-26 01:30:00 -0800113 /* compute the offset to align the destination
114 * offset = (4-(src&3))&3 = -src & 3
115 */
Christopher Ferris7c83a1e2013-02-26 01:30:00 -0800116 stmfd sp!, {r0, r4-r7, lr}
Christopher Ferrisa57c9c02013-08-21 09:41:12 -0700117 .save {r0, r4-r7, lr}
Christopher Ferris5f45d582013-08-07 13:09:51 -0700118 .cfi_def_cfa_offset 24
119 .cfi_rel_offset r0, 0
120 .cfi_rel_offset r4, 4
121 .cfi_rel_offset r5, 8
122 .cfi_rel_offset r6, 12
123 .cfi_rel_offset r7, 16
124 .cfi_rel_offset lr, 20
125
Christopher Ferris7c83a1e2013-02-26 01:30:00 -0800126 rsb r3, r0, #0
127 ands r3, r3, #3
128 cmp r3, r2
129 movhi r3, r2
130
131 /* splat r1 */
132 mov r1, r1, lsl #24
133 orr r1, r1, r1, lsr #8
134 orr r1, r1, r1, lsr #16
135
136 movs r12, r3, lsl #31
137 strcsb r1, [r0], #1 /* can't use strh (alignment unknown) */
138 strcsb r1, [r0], #1
139 strmib r1, [r0], #1
140 subs r2, r2, r3
141 ldmlsfd sp!, {r0, r4-r7, lr} /* return */
142 bxls lr
143
144 /* align the destination to a cache-line */
145 mov r12, r1
146 mov lr, r1
147 mov r4, r1
148 mov r5, r1
149 mov r6, r1
150 mov r7, r1
151
152 rsb r3, r0, #0
153 ands r3, r3, #0x1C
154 beq 3f
155 cmp r3, r2
156 andhi r3, r2, #0x1C
157 sub r2, r2, r3
158
159 /* conditionally writes 0 to 7 words (length in r3) */
160 movs r3, r3, lsl #28
161 stmcsia r0!, {r1, lr}
162 stmcsia r0!, {r1, lr}
163 stmmiia r0!, {r1, lr}
164 movs r3, r3, lsl #2
165 strcs r1, [r0], #4
166
1673:
168 subs r2, r2, #32
169 mov r3, r1
170 bmi 2f
1711: subs r2, r2, #32
172 stmia r0!, {r1,r3,r4,r5,r6,r7,r12,lr}
173 bhs 1b
1742: add r2, r2, #32
175
176 /* conditionally stores 0 to 31 bytes */
177 movs r2, r2, lsl #28
178 stmcsia r0!, {r1,r3,r12,lr}
179 stmmiia r0!, {r1, lr}
180 movs r2, r2, lsl #2
181 strcs r1, [r0], #4
182 strmih r1, [r0], #2
183 movs r2, r2, lsl #2
184 strcsb r1, [r0]
185 ldmfd sp!, {r0, r4-r7, lr}
186 bx lr
Christopher Ferrisa57c9c02013-08-21 09:41:12 -0700187END(__memset_large_copy)
Christopher Ferris59a13c12013-08-01 13:13:33 -0700188
189 .data
190error_string:
Elliott Hughes68b67112013-10-15 17:17:05 -0700191 .string "memset: prevented write past end of buffer"